forked from blue/squawk
new contact handeling in core
This commit is contained in:
parent
7aa519c4ad
commit
6124c46a1c
240
core/account.cpp
240
core/account.cpp
@ -48,6 +48,9 @@ Account::Account(const QString& p_login, const QString& p_server, const QString&
|
|||||||
|
|
||||||
Account::~Account()
|
Account::~Account()
|
||||||
{
|
{
|
||||||
|
for (std::map<QString, Contact*>::const_iterator itr = contacts.begin(), end = contacts.end(); itr != end; ++itr) {
|
||||||
|
delete itr->second;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Shared::ConnectionState Core::Account::getState() const
|
Shared::ConnectionState Core::Account::getState() const
|
||||||
@ -133,121 +136,82 @@ void Core::Account::onRosterItemAdded(const QString& bareJid)
|
|||||||
|
|
||||||
void Core::Account::onRosterItemChanged(const QString& bareJid)
|
void Core::Account::onRosterItemChanged(const QString& bareJid)
|
||||||
{
|
{
|
||||||
|
std::map<QString, Contact*>::const_iterator itr = contacts.find(bareJid);
|
||||||
|
if (itr == contacts.end()) {
|
||||||
|
qDebug() << "An attempt to change non existing contact" << bareJid << "from account" << name << ", skipping";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Contact* contact = itr->second;
|
||||||
QXmppRosterManager& rm = client.rosterManager();
|
QXmppRosterManager& rm = client.rosterManager();
|
||||||
QXmppRosterIq::Item re = rm.getRosterEntry(bareJid);
|
QXmppRosterIq::Item re = rm.getRosterEntry(bareJid);
|
||||||
QSet<QString> newGroups = re.groups();
|
|
||||||
QSet<QString> oldGroups;
|
|
||||||
|
|
||||||
|
|
||||||
QStringList res = rm.getResources(bareJid);
|
QStringList res = rm.getResources(bareJid);
|
||||||
unsigned int state = re.subscriptionType();
|
Shared::SubscriptionState state = castSubscriptionState(re.subscriptionType());
|
||||||
if (state == QXmppRosterIq::Item::NotSet) {
|
|
||||||
state = Shared::unknown;
|
|
||||||
}
|
|
||||||
QMap<QString, QVariant> cData({
|
|
||||||
{"name", re.name()},
|
|
||||||
{"state", state}
|
|
||||||
});
|
|
||||||
|
|
||||||
emit changeContact(bareJid, cData);
|
contact->setGroups(re.groups());
|
||||||
|
contact->setSubscriptionState(state);
|
||||||
for (std::map<QString, std::set<QString>>::iterator itr = groups.begin(), end = groups.end(); itr != end; ++itr) {
|
contact->setName(name);
|
||||||
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, groupName, cData);
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
void Core::Account::onRosterItemRemoved(const QString& bareJid)
|
||||||
{
|
{
|
||||||
|
std::map<QString, Contact*>::const_iterator itr = contacts.find(bareJid);
|
||||||
|
if (itr == contacts.end()) {
|
||||||
|
qDebug() << "An attempt to remove non existing contact" << bareJid << "from account" << name << ", skipping";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Contact* contact = itr->second;
|
||||||
|
QSet<QString> cGroups = contact->getGroups();
|
||||||
|
for (QSet<QString>::const_iterator itr = cGroups.begin(), end = cGroups.end(); itr != end; ++itr) {
|
||||||
|
removeFromGroup(bareJid, *itr);
|
||||||
|
}
|
||||||
emit removeContact(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)
|
void Core::Account::addedAccount(const QString& jid)
|
||||||
{
|
{
|
||||||
QXmppRosterManager& rm = client.rosterManager();
|
QXmppRosterManager& rm = client.rosterManager();
|
||||||
|
|
||||||
std::map<QString, Contact*>::const_iterator itr = contacts.find(jid);
|
std::map<QString, Contact*>::const_iterator itr = contacts.find(jid);
|
||||||
if (itr == contacts.end()) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
QXmppRosterIq::Item re = rm.getRosterEntry(jid);
|
QXmppRosterIq::Item re = rm.getRosterEntry(jid);
|
||||||
QSet<QString> gr = re.groups();
|
Contact* contact;
|
||||||
unsigned int state = re.subscriptionType();
|
bool newContact = false;
|
||||||
if (state == QXmppRosterIq::Item::NotSet) {
|
if (itr == contacts.end()) {
|
||||||
state = Shared::unknown;
|
newContact = true;
|
||||||
}
|
contact = new Contact(jid, name);
|
||||||
QMap<QString, QVariant> cData({
|
contacts.insert(std::make_pair(jid, contact));
|
||||||
{"name", re.name()},
|
|
||||||
{"state", state}
|
} else {
|
||||||
});
|
contact = itr->second;
|
||||||
int grCount = 0;
|
|
||||||
for (QSet<QString>::const_iterator itr = gr.begin(), end = gr.end(); itr != end; ++itr) {
|
|
||||||
const QString& groupName = *itr;
|
|
||||||
std::map<QString, std::set<QString>>::iterator gItr = groups.find(groupName);
|
|
||||||
if (gItr == groups.end()) {
|
|
||||||
gItr = groups.insert(std::make_pair(groupName, std::set<QString>())).first;
|
|
||||||
emit addGroup(groupName);
|
|
||||||
}
|
|
||||||
gItr->second.insert(jid);
|
|
||||||
emit addContact(jid, groupName, cData);
|
|
||||||
grCount++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (grCount == 0) {
|
QSet<QString> gr = re.groups();
|
||||||
emit addContact(jid, "", cData);
|
Shared::SubscriptionState state = castSubscriptionState(re.subscriptionType());
|
||||||
|
contact->setGroups(gr);
|
||||||
|
contact->setSubscriptionState(state);
|
||||||
|
contact->setName(re.name());
|
||||||
|
|
||||||
|
if (newContact) {
|
||||||
|
QMap<QString, QVariant> cData({
|
||||||
|
{"name", re.name()},
|
||||||
|
{"state", state}
|
||||||
|
});
|
||||||
|
int grCount = 0;
|
||||||
|
for (QSet<QString>::const_iterator itr = gr.begin(), end = gr.end(); itr != end; ++itr) {
|
||||||
|
const QString& groupName = *itr;
|
||||||
|
addToGroup(jid, groupName);
|
||||||
|
emit addContact(jid, groupName, cData);
|
||||||
|
grCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (grCount == 0) {
|
||||||
|
emit addContact(jid, "", cData);
|
||||||
|
}
|
||||||
|
|
||||||
|
QObject::connect(contact, SIGNAL(groupAdded(const QString&)), this, SLOT(onContactGroupAdded(const QString&)));
|
||||||
|
QObject::connect(contact, SIGNAL(groupRemoved(const QString&)), this, SLOT(onContactGroupRemoved(const QString&)));
|
||||||
|
QObject::connect(contact, SIGNAL(nameChanged(const QString&)), this, SLOT(onContactNameChanged(const QString&)));
|
||||||
|
QObject::connect(contact, SIGNAL(subscriptionStateChanged(Shared::SubscriptionState)),
|
||||||
|
this, SLOT(onContactSubscriptionStateChanged(Shared::SubscriptionState)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -486,3 +450,87 @@ void Core::Account::onMamResultsReceived(const QString& queryId, const QXmppResu
|
|||||||
achiveQueries.insert(std::make_pair(nQ, jid));
|
achiveQueries.insert(std::make_pair(nQ, jid));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Core::Account::onContactGroupAdded(const QString& group)
|
||||||
|
{
|
||||||
|
Contact* contact = static_cast<Contact*>(sender());
|
||||||
|
if (contact->groupsCount() == 1) {
|
||||||
|
// not sure i need to handle it here, the situation with grouped and ungrouped contacts handled on the client anyway
|
||||||
|
}
|
||||||
|
|
||||||
|
QMap<QString, QVariant> cData({
|
||||||
|
{"name", contact->getName()},
|
||||||
|
{"state", contact->getSubscriptionState()}
|
||||||
|
});
|
||||||
|
addToGroup(contact->jid, group);
|
||||||
|
emit addContact(contact->jid, group, cData);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Core::Account::onContactGroupRemoved(const QString& group)
|
||||||
|
{
|
||||||
|
Contact* contact = static_cast<Contact*>(sender());
|
||||||
|
if (contact->groupsCount() == 0) {
|
||||||
|
// not sure i need to handle it here, the situation with grouped and ungrouped contacts handled on the client anyway
|
||||||
|
}
|
||||||
|
|
||||||
|
emit removeContact(contact->jid, group);
|
||||||
|
removeFromGroup(contact->jid, group);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Core::Account::onContactNameChanged(const QString& cname)
|
||||||
|
{
|
||||||
|
Contact* contact = static_cast<Contact*>(sender());
|
||||||
|
QMap<QString, QVariant> cData({
|
||||||
|
{"name", cname},
|
||||||
|
});
|
||||||
|
emit changeContact(contact->jid, cData);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Core::Account::onContactSubscriptionStateChanged(Shared::SubscriptionState cstate)
|
||||||
|
{
|
||||||
|
Contact* contact = static_cast<Contact*>(sender());
|
||||||
|
QMap<QString, QVariant> cData({
|
||||||
|
{"state", cstate},
|
||||||
|
});
|
||||||
|
emit changeContact(contact->jid, cData);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Core::Account::addToGroup(const QString& jid, const QString& group)
|
||||||
|
{
|
||||||
|
std::map<QString, std::set<QString>>::iterator gItr = groups.find(group);
|
||||||
|
if (gItr == groups.end()) {
|
||||||
|
gItr = groups.insert(std::make_pair(group, std::set<QString>())).first;
|
||||||
|
emit addGroup(group);
|
||||||
|
}
|
||||||
|
gItr->second.insert(jid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Core::Account::removeFromGroup(const QString& jid, const QString& group)
|
||||||
|
{
|
||||||
|
QSet<QString> toRemove;
|
||||||
|
std::map<QString, std::set<QString>>::iterator itr = groups.find(group);
|
||||||
|
if (itr == groups.end()) {
|
||||||
|
qDebug() << "An attempt to remove contact" << jid << "of account" << name << "from non existing group" << group << ", skipping";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::set<QString> contacts = itr->second;
|
||||||
|
std::set<QString>::const_iterator cItr = contacts.find(jid);
|
||||||
|
if (cItr != contacts.end()) {
|
||||||
|
contacts.erase(cItr);
|
||||||
|
if (contacts.size() == 0) {
|
||||||
|
emit removeGroup(group);
|
||||||
|
groups.erase(group);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Shared::SubscriptionState Core::Account::castSubscriptionState(QXmppRosterIq::Item::SubscriptionType qs) const
|
||||||
|
{
|
||||||
|
Shared::SubscriptionState state;
|
||||||
|
if (qs == QXmppRosterIq::Item::NotSet) {
|
||||||
|
state = Shared::unknown;
|
||||||
|
} else {
|
||||||
|
state = static_cast<Shared::SubscriptionState>(qs);
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
@ -71,21 +71,33 @@ private:
|
|||||||
private slots:
|
private slots:
|
||||||
void onClientConnected();
|
void onClientConnected();
|
||||||
void onClientDisconnected();
|
void onClientDisconnected();
|
||||||
|
|
||||||
void onRosterReceived();
|
void onRosterReceived();
|
||||||
void onRosterItemAdded(const QString& bareJid);
|
void onRosterItemAdded(const QString& bareJid);
|
||||||
void onRosterItemChanged(const QString& bareJid);
|
void onRosterItemChanged(const QString& bareJid);
|
||||||
void onRosterItemRemoved(const QString& bareJid);
|
void onRosterItemRemoved(const QString& bareJid);
|
||||||
void onRosterPresenceChanged(const QString& bareJid, const QString& resource);
|
void onRosterPresenceChanged(const QString& bareJid, const QString& resource);
|
||||||
|
|
||||||
void onPresenceReceived(const QXmppPresence& presence);
|
void onPresenceReceived(const QXmppPresence& presence);
|
||||||
void onMessageReceived(const QXmppMessage& message);
|
void onMessageReceived(const QXmppMessage& message);
|
||||||
|
|
||||||
void onCarbonMessageReceived(const QXmppMessage& message);
|
void onCarbonMessageReceived(const QXmppMessage& message);
|
||||||
void onCarbonMessageSent(const QXmppMessage& message);
|
void onCarbonMessageSent(const QXmppMessage& message);
|
||||||
|
|
||||||
void onMamMessageReceived(const QString& bareJid, const QXmppMessage& message);
|
void onMamMessageReceived(const QString& bareJid, const QXmppMessage& message);
|
||||||
void onMamResultsReceived(const QString &queryId, const QXmppResultSetReply &resultSetReply, bool complete);
|
void onMamResultsReceived(const QString &queryId, const QXmppResultSetReply &resultSetReply, bool complete);
|
||||||
|
|
||||||
|
void onContactGroupAdded(const QString& group);
|
||||||
|
void onContactGroupRemoved(const QString& group);
|
||||||
|
void onContactNameChanged(const QString& name);
|
||||||
|
void onContactSubscriptionStateChanged(Shared::SubscriptionState state);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void addedAccount(const QString &bareJid);
|
void addedAccount(const QString &bareJid);
|
||||||
bool handleChatMessage(const QXmppMessage& msg, bool outgoing = false, bool forwarded = false, bool guessing = false);
|
bool handleChatMessage(const QXmppMessage& msg, bool outgoing = false, bool forwarded = false, bool guessing = false);
|
||||||
|
void addToGroup(const QString& jid, const QString& group);
|
||||||
|
void removeFromGroup(const QString& jid, const QString& group);
|
||||||
|
Shared::SubscriptionState castSubscriptionState(QXmppRosterIq::Item::SubscriptionType qs) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -23,8 +23,9 @@ Core::Contact::Contact(const QString& pJid, const QString& account, QObject* par
|
|||||||
jid(pJid),
|
jid(pJid),
|
||||||
name(),
|
name(),
|
||||||
groups(),
|
groups(),
|
||||||
state(empty),
|
archiveState(empty),
|
||||||
archive(new Archive(jid))
|
archive(new Archive(jid)),
|
||||||
|
subscriptionState(Shared::unknown)
|
||||||
{
|
{
|
||||||
archive->open(account);
|
archive->open(account);
|
||||||
}
|
}
|
||||||
@ -36,7 +37,7 @@ Core::Contact::~Contact()
|
|||||||
|
|
||||||
Core::Contact::ArchiveState Core::Contact::getArchiveState() const
|
Core::Contact::ArchiveState Core::Contact::getArchiveState() const
|
||||||
{
|
{
|
||||||
return state;
|
return archiveState;
|
||||||
}
|
}
|
||||||
|
|
||||||
QSet<QString> Core::Contact::getGroups() const
|
QSet<QString> Core::Contact::getGroups() const
|
||||||
@ -53,5 +54,40 @@ void Core::Contact::setName(const QString& n)
|
|||||||
{
|
{
|
||||||
if (name != n) {
|
if (name != n) {
|
||||||
name = n;
|
name = n;
|
||||||
|
emit nameChanged(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Shared::SubscriptionState Core::Contact::getSubscriptionState() const
|
||||||
|
{
|
||||||
|
return subscriptionState;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Core::Contact::setGroups(const QSet<QString>& set)
|
||||||
|
{
|
||||||
|
QSet<QString> toRemove = groups - set;
|
||||||
|
QSet<QString> toAdd = set - groups;
|
||||||
|
|
||||||
|
groups = set;
|
||||||
|
|
||||||
|
for (QSet<QString>::iterator itr = toRemove.begin(), end = toRemove.end(); itr != end; ++itr) {
|
||||||
|
emit groupRemoved(*itr);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (QSet<QString>::iterator itr = toAdd.begin(), end = toAdd.end(); itr != end; ++itr) {
|
||||||
|
emit groupAdded(*itr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Core::Contact::setSubscriptionState(Shared::SubscriptionState state)
|
||||||
|
{
|
||||||
|
if (subscriptionState != state) {
|
||||||
|
subscriptionState = state;
|
||||||
|
emit subscriptionStateChanged(subscriptionState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int Core::Contact::groupsCount() const
|
||||||
|
{
|
||||||
|
return groups.size();
|
||||||
|
}
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
#include "archive.h"
|
#include "archive.h"
|
||||||
|
#include "../global.h"
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
|
||||||
@ -43,6 +44,16 @@ public:
|
|||||||
QString getName() const;
|
QString getName() const;
|
||||||
void setName(const QString& n);
|
void setName(const QString& n);
|
||||||
QSet<QString> getGroups() const;
|
QSet<QString> getGroups() const;
|
||||||
|
void setGroups(const QSet<QString>& set);
|
||||||
|
void setSubscriptionState(Shared::SubscriptionState state);
|
||||||
|
Shared::SubscriptionState getSubscriptionState() const;
|
||||||
|
unsigned int groupsCount() const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void groupAdded(const QString& name);
|
||||||
|
void groupRemoved(const QString& name);
|
||||||
|
void nameChanged(const QString& name);
|
||||||
|
void subscriptionStateChanged(Shared::SubscriptionState state);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const QString jid;
|
const QString jid;
|
||||||
@ -50,8 +61,9 @@ public:
|
|||||||
private:
|
private:
|
||||||
QString name;
|
QString name;
|
||||||
QSet<QString> groups;
|
QSet<QString> groups;
|
||||||
ArchiveState state;
|
ArchiveState archiveState;
|
||||||
Archive* archive;
|
Archive* archive;
|
||||||
|
Shared::SubscriptionState subscriptionState;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user