forked from blue/squawk
Roster changes handeling
This commit is contained in:
parent
76f9ece344
commit
de21036456
@ -18,7 +18,11 @@ Account::Account(const QString& p_login, const QString& p_server, const QString&
|
|||||||
|
|
||||||
|
|
||||||
QXmppRosterManager& rm = client.rosterManager();
|
QXmppRosterManager& rm = client.rosterManager();
|
||||||
|
|
||||||
QObject::connect(&rm, SIGNAL(rosterReceived()), this, SLOT(onRosterReceived()));
|
QObject::connect(&rm, SIGNAL(rosterReceived()), this, SLOT(onRosterReceived()));
|
||||||
|
QObject::connect(&rm, SIGNAL(itemAdded(const QString&)), this, SLOT(onRosterItemAdded(const QString&)));
|
||||||
|
QObject::connect(&rm, SIGNAL(itemRemoved(const QString&)), this, SLOT(onRosterItemRemoved(const QString&)));
|
||||||
|
QObject::connect(&rm, SIGNAL(itemChanged(const QString&)), this, SLOT(onRosterItemChanged(const QString&)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Account::~Account()
|
Account::~Account()
|
||||||
@ -30,7 +34,6 @@ Shared::ConnectionState Core::Account::getState() const
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Core::Account::connect()
|
void Core::Account::connect()
|
||||||
{
|
{
|
||||||
if (state == Shared::disconnected) {
|
if (state == Shared::disconnected) {
|
||||||
@ -97,17 +100,101 @@ void Core::Account::onRosterReceived()
|
|||||||
QStringList bj = rm.getRosterBareJids();
|
QStringList bj = rm.getRosterBareJids();
|
||||||
for (int i = 0; i < bj.size(); ++i) {
|
for (int i = 0; i < bj.size(); ++i) {
|
||||||
const QString& jid = bj[i];
|
const QString& jid = bj[i];
|
||||||
|
addedAccount(jid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Core::Account::onRosterItemAdded(const QString& bareJid)
|
||||||
|
{
|
||||||
|
addedAccount(bareJid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Core::Account::onRosterItemChanged(const QString& bareJid)
|
||||||
|
{
|
||||||
|
QXmppRosterManager& rm = client.rosterManager();
|
||||||
|
QXmppRosterIq::Item re = rm.getRosterEntry(bareJid);
|
||||||
|
QSet<QString> newGroups = re.groups();
|
||||||
|
QSet<QString> oldGroups;
|
||||||
|
|
||||||
|
emit changeContact(bareJid, re.name());
|
||||||
|
|
||||||
|
for (std::map<QString, std::set<QString>>::iterator itr = groups.begin(), end = groups.end(); itr != end; ++itr) {
|
||||||
|
std::set<QString>& contacts = itr->second;
|
||||||
|
std::set<QString>::const_iterator cItr = contacts.find(bareJid);
|
||||||
|
if (cItr != contacts.end()) {
|
||||||
|
oldGroups.insert(itr->first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QSet<QString> toRemove = oldGroups - newGroups;
|
||||||
|
QSet<QString> toAdd = newGroups - oldGroups;
|
||||||
|
|
||||||
|
QSet<QString> removeGroups;
|
||||||
|
for (QSet<QString>::iterator itr = toRemove.begin(), end = toRemove.end(); itr != end; ++itr) {
|
||||||
|
const QString& groupName = *itr;
|
||||||
|
std::set<QString>& contacts = groups.find(groupName)->second;
|
||||||
|
contacts.erase(bareJid);
|
||||||
|
emit removeContact(bareJid, groupName);
|
||||||
|
if (contacts.size() == 0) {
|
||||||
|
removeGroups.insert(groupName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (QSet<QString>::iterator itr = toAdd.begin(), end = toAdd.end(); itr != end; ++itr) {
|
||||||
|
const QString& groupName = *itr;
|
||||||
|
std::map<QString, std::set<QString>>::iterator cItr = groups.find(groupName);
|
||||||
|
if (cItr == groups.end()) {
|
||||||
|
cItr = groups.insert(std::make_pair(groupName, std::set<QString>())).first;
|
||||||
|
emit addGroup(groupName);
|
||||||
|
}
|
||||||
|
cItr->second.insert(bareJid);
|
||||||
|
emit addContact(bareJid, re.name(), groupName);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (QSet<QString>::iterator itr = removeGroups.begin(), end = removeGroups.end(); itr != end; ++itr) {
|
||||||
|
const QString& groupName = *itr;
|
||||||
|
emit removeGroup(groupName);
|
||||||
|
groups.erase(groupName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Core::Account::onRosterItemRemoved(const QString& bareJid)
|
||||||
|
{
|
||||||
|
emit removeContact(bareJid);
|
||||||
|
|
||||||
|
QSet<QString> toRemove;
|
||||||
|
for (std::map<QString, std::set<QString>>::iterator itr = groups.begin(), end = groups.end(); itr != end; ++itr) {
|
||||||
|
std::set<QString> contacts = itr->second;
|
||||||
|
std::set<QString>::const_iterator cItr = contacts.find(bareJid);
|
||||||
|
if (cItr != contacts.end()) {
|
||||||
|
contacts.erase(cItr);
|
||||||
|
if (contacts.size() == 0) {
|
||||||
|
toRemove.insert(itr->first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (QSet<QString>::iterator itr = toRemove.begin(), end = toRemove.end(); itr != end; ++itr) {
|
||||||
|
const QString& groupName = *itr;
|
||||||
|
emit removeGroup(groupName);
|
||||||
|
groups.erase(groupName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Core::Account::addedAccount(const QString& jid)
|
||||||
|
{
|
||||||
|
QXmppRosterManager& rm = client.rosterManager();
|
||||||
QXmppRosterIq::Item re = rm.getRosterEntry(jid);
|
QXmppRosterIq::Item re = rm.getRosterEntry(jid);
|
||||||
QSet<QString> gr = re.groups();
|
QSet<QString> gr = re.groups();
|
||||||
int grCount = 0;
|
int grCount = 0;
|
||||||
for (QSet<QString>::const_iterator itr = gr.begin(), end = gr.end(); itr != end; ++itr) {
|
for (QSet<QString>::const_iterator itr = gr.begin(), end = gr.end(); itr != end; ++itr) {
|
||||||
const QString& groupName = *itr;
|
const QString& groupName = *itr;
|
||||||
std::map<QString, int>::iterator gItr = groups.find(groupName);
|
std::map<QString, std::set<QString>>::iterator gItr = groups.find(groupName);
|
||||||
if (gItr == groups.end()) {
|
if (gItr == groups.end()) {
|
||||||
gItr = groups.insert(std::make_pair(groupName, 0)).first;
|
gItr = groups.insert(std::make_pair(groupName, std::set<QString>())).first;
|
||||||
emit addGroup(groupName);
|
emit addGroup(groupName);
|
||||||
}
|
}
|
||||||
gItr->second++;
|
gItr->second.insert(jid);
|
||||||
emit addContact(jid, re.name(), groupName);
|
emit addContact(jid, re.name(), groupName);
|
||||||
grCount++;
|
grCount++;
|
||||||
}
|
}
|
||||||
@ -116,5 +203,4 @@ void Core::Account::onRosterReceived()
|
|||||||
emit addContact(jid, re.name(), "");
|
emit addContact(jid, re.name(), "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <QtCore/QObject>
|
#include <QtCore/QObject>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
#include <qxmpp/QXmppClient.h>
|
#include <qxmpp/QXmppClient.h>
|
||||||
#include "../global.h"
|
#include "../global.h"
|
||||||
@ -31,6 +32,9 @@ signals:
|
|||||||
void addGroup(const QString& name);
|
void addGroup(const QString& name);
|
||||||
void removeGroup(const QString& name);
|
void removeGroup(const QString& name);
|
||||||
void addContact(const QString& jid, const QString& name, const QString& group);
|
void addContact(const QString& jid, const QString& name, const QString& group);
|
||||||
|
void removeContact(const QString& jid);
|
||||||
|
void removeContact(const QString& jid, const QString& group);
|
||||||
|
void changeContact(const QString& jid, const QString& name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString name;
|
QString name;
|
||||||
@ -39,13 +43,18 @@ private:
|
|||||||
QString password;
|
QString password;
|
||||||
QXmppClient client;
|
QXmppClient client;
|
||||||
Shared::ConnectionState state;
|
Shared::ConnectionState state;
|
||||||
std::map<QString, int> groups;
|
std::map<QString, std::set<QString>> groups;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onClientConnected();
|
void onClientConnected();
|
||||||
void onClientDisconnected();
|
void onClientDisconnected();
|
||||||
void onRosterReceived();
|
void onRosterReceived();
|
||||||
|
void onRosterItemAdded(const QString &bareJid);
|
||||||
|
void onRosterItemChanged(const QString &bareJid);
|
||||||
|
void onRosterItemRemoved(const QString &bareJid);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void addedAccount(const QString &bareJid);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -77,6 +77,9 @@ void Core::Squawk::addAccount(const QString& login, const QString& server, const
|
|||||||
connect(acc, SIGNAL(addContact(const QString&, const QString&, const QString&)), this, SLOT(onAccountAddContact(const QString&, const QString&, const QString&)));
|
connect(acc, SIGNAL(addContact(const QString&, const QString&, const QString&)), this, SLOT(onAccountAddContact(const QString&, const QString&, const QString&)));
|
||||||
connect(acc, SIGNAL(addGroup(const QString&)), this, SLOT(onAccountAddGroup(const QString&)));
|
connect(acc, SIGNAL(addGroup(const QString&)), this, SLOT(onAccountAddGroup(const QString&)));
|
||||||
connect(acc, SIGNAL(removeGroup(const QString&)), this, SLOT(onAccountRemoveGroup(const QString&)));
|
connect(acc, SIGNAL(removeGroup(const QString&)), this, SLOT(onAccountRemoveGroup(const QString&)));
|
||||||
|
connect(acc, SIGNAL(removeContact(const QString&)), this, SLOT(onAccountRemoveContact(const QString&)));
|
||||||
|
connect(acc, SIGNAL(removeContact(const QString&, const QString&)), this, SLOT(onAccountRemoveContact(const QString&, const QString&)));
|
||||||
|
connect(acc, SIGNAL(changeContact(const QString&, const QString&)), this, SLOT(onAccountChangeContact(const QString&, const QString&)));
|
||||||
|
|
||||||
QMap<QString, QVariant> map = {
|
QMap<QString, QVariant> map = {
|
||||||
{"login", login},
|
{"login", login},
|
||||||
@ -132,3 +135,21 @@ void Core::Squawk::onAccountRemoveGroup(const QString& name)
|
|||||||
Account* acc = static_cast<Account*>(sender());
|
Account* acc = static_cast<Account*>(sender());
|
||||||
emit removeGroup(acc->getName(), name);
|
emit removeGroup(acc->getName(), name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Core::Squawk::onAccountChangeContact(const QString& jid, const QString& name)
|
||||||
|
{
|
||||||
|
Account* acc = static_cast<Account*>(sender());
|
||||||
|
emit changeContact(acc->getName(), jid, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Core::Squawk::onAccountRemoveContact(const QString& jid)
|
||||||
|
{
|
||||||
|
Account* acc = static_cast<Account*>(sender());
|
||||||
|
emit removeContact(acc->getName(), jid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Core::Squawk::onAccountRemoveContact(const QString& jid, const QString& group)
|
||||||
|
{
|
||||||
|
Account* acc = static_cast<Account*>(sender());
|
||||||
|
emit removeContact(acc->getName(), jid, group);
|
||||||
|
}
|
||||||
|
@ -28,6 +28,9 @@ signals:
|
|||||||
void addGroup(const QString& account, const QString& name);
|
void addGroup(const QString& account, const QString& name);
|
||||||
void removeGroup(const QString& account, const QString& name);
|
void removeGroup(const QString& account, const QString& name);
|
||||||
void addContact(const QString& account, const QString& jid, const QString& name, const QString& group);
|
void addContact(const QString& account, const QString& jid, const QString& name, const QString& group);
|
||||||
|
void removeContact(const QString& account, const QString& jid);
|
||||||
|
void removeContact(const QString& account, const QString& jid, const QString& group);
|
||||||
|
void changeContact(const QString& account, const QString& jid, const QString& name);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void start();
|
void start();
|
||||||
@ -51,6 +54,9 @@ private slots:
|
|||||||
void onAccountAddGroup(const QString& name);
|
void onAccountAddGroup(const QString& name);
|
||||||
void onAccountRemoveGroup(const QString& name);
|
void onAccountRemoveGroup(const QString& name);
|
||||||
void onAccountAddContact(const QString& jid, const QString& name, const QString& group);
|
void onAccountAddContact(const QString& jid, const QString& name, const QString& group);
|
||||||
|
void onAccountRemoveContact(const QString& jid);
|
||||||
|
void onAccountRemoveContact(const QString& jid, const QString& group);
|
||||||
|
void onAccountChangeContact(const QString& jid, const QString& name);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
3
main.cpp
3
main.cpp
@ -38,6 +38,9 @@ int main(int argc, char *argv[])
|
|||||||
&w, SLOT(addContact(const QString&, const QString&, const QString&, const QString&)));
|
&w, SLOT(addContact(const QString&, const QString&, const QString&, const QString&)));
|
||||||
QObject::connect(squawk, SIGNAL(addGroup(const QString&, const QString&)), &w, SLOT(addGroup(const QString&, const QString&)));
|
QObject::connect(squawk, SIGNAL(addGroup(const QString&, const QString&)), &w, SLOT(addGroup(const QString&, const QString&)));
|
||||||
QObject::connect(squawk, SIGNAL(removeGroup(const QString&, const QString&)), &w, SLOT(removeGroup(const QString&, const QString&)));
|
QObject::connect(squawk, SIGNAL(removeGroup(const QString&, const QString&)), &w, SLOT(removeGroup(const QString&, const QString&)));
|
||||||
|
QObject::connect(squawk, SIGNAL(removeContact(const QString&, const QString&)), &w, SLOT(removeContact(const QString&, const QString&)));
|
||||||
|
QObject::connect(squawk, SIGNAL(removeContact(const QString&, const QString&, const QString&)), &w, SLOT(removeContact(const QString&, const QString&, const QString&)));
|
||||||
|
QObject::connect(squawk, SIGNAL(changeContact(const QString&, const QString&, const QString&)), &w, SLOT(changeContact(const QString&, const QString&, const QString&)));
|
||||||
|
|
||||||
coreThread->start();
|
coreThread->start();
|
||||||
|
|
||||||
|
@ -332,7 +332,7 @@ void Models::Roster::removeGroup(const QString& account, const QString& name)
|
|||||||
Item* parent = item->parentItem();
|
Item* parent = item->parentItem();
|
||||||
int row = item->row();
|
int row = item->row();
|
||||||
|
|
||||||
beginRemoveRows(createIndex(parent->row(), 1, parent), row, row);
|
beginRemoveRows(createIndex(parent->row(), 0, parent), row, row);
|
||||||
parent->removeChild(row);
|
parent->removeChild(row);
|
||||||
endRemoveRows();
|
endRemoveRows();
|
||||||
|
|
||||||
@ -372,3 +372,76 @@ void Models::Roster::removeGroup(const QString& account, const QString& name)
|
|||||||
delete item;
|
delete item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Models::Roster::changeContact(const QString& account, const QString& jid, const QString& name)
|
||||||
|
{
|
||||||
|
ElId id(account, jid);
|
||||||
|
std::multimap<ElId, Contact*>::iterator cBeg = contacts.lower_bound(id);
|
||||||
|
std::multimap<ElId, Contact*>::iterator cEnd = contacts.upper_bound(id);
|
||||||
|
|
||||||
|
for (; cBeg != cEnd; ++cBeg) {
|
||||||
|
cBeg->second->setName(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Models::Roster::removeContact(const QString& account, const QString& jid)
|
||||||
|
{
|
||||||
|
ElId id(account, jid);
|
||||||
|
std::multimap<ElId, Contact*>::iterator cBeg = contacts.lower_bound(id);
|
||||||
|
std::multimap<ElId, Contact*>::iterator cEnd = contacts.upper_bound(id);
|
||||||
|
|
||||||
|
QSet<QString> toRemove;
|
||||||
|
for (; cBeg != cEnd; ++cBeg) {
|
||||||
|
Contact* contact = cBeg->second;
|
||||||
|
Item* parent = contact->parentItem();
|
||||||
|
if (parent->type == Item::group && parent->childCount() == 1) {
|
||||||
|
toRemove.insert(parent->getName());
|
||||||
|
}
|
||||||
|
int row = contact->row();
|
||||||
|
beginRemoveRows(createIndex(parent->row(), 0, parent), row, row);
|
||||||
|
parent->removeChild(row);
|
||||||
|
endRemoveRows();
|
||||||
|
delete contact;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (QSet<QString>::const_iterator itr = toRemove.begin(), end = toRemove.end(); itr != end; ++itr) {
|
||||||
|
removeGroup(account, *itr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Models::Roster::removeContact(const QString& account, const QString& jid, const QString& group)
|
||||||
|
{
|
||||||
|
ElId contactId(account, jid);
|
||||||
|
ElId groupId(account, group);
|
||||||
|
|
||||||
|
std::map<ElId, Item*>::iterator gItr = groups.find(groupId);
|
||||||
|
if (gItr == groups.end()) {
|
||||||
|
qDebug() << "An attempt to remove contact " << jid << " from non existing group " << group << " of account " << account <<", skipping";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Item* gr = gItr->second;
|
||||||
|
Contact* cont = 0;
|
||||||
|
|
||||||
|
std::multimap<ElId, Contact*>::iterator cBeg = contacts.lower_bound(contactId);
|
||||||
|
std::multimap<ElId, Contact*>::iterator cEnd = contacts.upper_bound(contactId);
|
||||||
|
for (;cBeg != cEnd; ++cBeg) {
|
||||||
|
if (cBeg->second->parentItem() == gr) {
|
||||||
|
cont = cBeg->second;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cont == 0) {
|
||||||
|
qDebug() << "An attempt to remove contact " << jid << " of account " << account << " from group " << group <<", but there is no such contact in that group, skipping";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int row = cont->row();
|
||||||
|
beginRemoveRows(createIndex(gr->row(), 0, gr), row, row);
|
||||||
|
gr->removeChild(row);
|
||||||
|
endRemoveRows();
|
||||||
|
delete cont;
|
||||||
|
|
||||||
|
if (gr->childCount() == 0) {
|
||||||
|
removeGroup(account, group);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -27,6 +27,9 @@ public:
|
|||||||
void addGroup(const QString& account, const QString& name);
|
void addGroup(const QString& account, const QString& name);
|
||||||
void removeGroup(const QString& account, const QString& name);
|
void removeGroup(const QString& account, const QString& name);
|
||||||
void addContact(const QString& account, const QString& jid, const QString& name, const QString& group);
|
void addContact(const QString& account, const QString& jid, const QString& name, const QString& group);
|
||||||
|
void removeContact(const QString& account, const QString& jid, const QString& group);
|
||||||
|
void removeContact(const QString& account, const QString& jid);
|
||||||
|
void changeContact(const QString& account, const QString& jid, const QString& name);
|
||||||
|
|
||||||
QVariant data ( const QModelIndex& index, int role ) const override;
|
QVariant data ( const QModelIndex& index, int role ) const override;
|
||||||
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
Qt::ItemFlags flags(const QModelIndex &index) const override;
|
||||||
|
@ -98,8 +98,23 @@ void Squawk::addGroup(const QString& account, const QString& name)
|
|||||||
|
|
||||||
void Squawk::removeGroup(const QString& account, const QString& name)
|
void Squawk::removeGroup(const QString& account, const QString& name)
|
||||||
{
|
{
|
||||||
|
rosterModel.removeGroup(account, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Squawk::changeContact(const QString& account, const QString& jid, const QString& name)
|
||||||
|
{
|
||||||
|
rosterModel.changeContact(account, jid, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Squawk::removeContact(const QString& account, const QString& jid)
|
||||||
|
{
|
||||||
|
rosterModel.removeContact(account, jid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Squawk::removeContact(const QString& account, const QString& jid, const QString& group)
|
||||||
|
{
|
||||||
|
rosterModel.removeContact(account, jid, group);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,6 +35,9 @@ public slots:
|
|||||||
void addGroup(const QString& account, const QString& name);
|
void addGroup(const QString& account, const QString& name);
|
||||||
void removeGroup(const QString& account, const QString& name);
|
void removeGroup(const QString& account, const QString& name);
|
||||||
void addContact(const QString& account, const QString& jid, const QString& name, const QString& group);
|
void addContact(const QString& account, const QString& jid, const QString& name, const QString& group);
|
||||||
|
void removeContact(const QString& account, const QString& jid, const QString& group);
|
||||||
|
void removeContact(const QString& account, const QString& jid);
|
||||||
|
void changeContact(const QString& account, const QString& jid, const QString& name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QScopedPointer<Ui::Squawk> m_ui;
|
QScopedPointer<Ui::Squawk> m_ui;
|
||||||
|
Loading…
Reference in New Issue
Block a user