diff --git a/core/account.cpp b/core/account.cpp index 98cbec0..ebcfd38 100644 --- a/core/account.cpp +++ b/core/account.cpp @@ -1,4 +1,5 @@ #include "account.h" +#include using namespace Core; @@ -9,15 +10,19 @@ Account::Account(const QString& p_login, const QString& p_server, const QString& server(p_server), password(p_password), client(), - state(Shared::disconnected) + state(Shared::disconnected), + groups() { QObject::connect(&client, SIGNAL(connected()), this, SLOT(onClientConnected())); QObject::connect(&client, SIGNAL(disconnected()), this, SLOT(onClientDisconnected())); + + + QXmppRosterManager& rm = client.rosterManager(); + QObject::connect(&rm, SIGNAL(rosterReceived()), this, SLOT(onRosterReceived())); } Account::~Account() { - } Shared::ConnectionState Core::Account::getState() const @@ -85,3 +90,31 @@ QString Core::Account::getServer() const { return server; } + +void Core::Account::onRosterReceived() +{ + QXmppRosterManager& rm = client.rosterManager(); + QStringList bj = rm.getRosterBareJids(); + for (int i = 0; i < bj.size(); ++i) { + const QString& jid = bj[i]; + QXmppRosterIq::Item re = rm.getRosterEntry(jid); + QSet gr = re.groups(); + int grCount = 0; + for (QSet::const_iterator itr = gr.begin(), end = gr.end(); itr != end; ++itr) { + const QString& groupName = *itr; + std::map::iterator gItr = groups.find(groupName); + if (gItr == groups.end()) { + gItr = groups.insert(std::make_pair(groupName, 0)).first; + emit addGroup(groupName); + } + gItr->second++; + emit addContact(jid, re.name(), groupName); + grCount++; + } + + if (grCount == 0) { + emit addContact(jid, re.name(), ""); + } + } +} + diff --git a/core/account.h b/core/account.h index a68c423..13d4ec4 100644 --- a/core/account.h +++ b/core/account.h @@ -2,6 +2,7 @@ #define CORE_ACCOUNT_H #include +#include #include #include "../global.h" @@ -27,6 +28,9 @@ public: signals: void connectionStateChanged(int); + void addGroup(const QString& name); + void removeGroup(const QString& name); + void addContact(const QString& jid, const QString& name, const QString& group); private: QString name; @@ -35,10 +39,12 @@ private: QString password; QXmppClient client; Shared::ConnectionState state; + std::map groups; private slots: void onClientConnected(); void onClientDisconnected(); + void onRosterReceived(); }; diff --git a/core/squawk.cpp b/core/squawk.cpp index 896fca3..a1644ad 100644 --- a/core/squawk.cpp +++ b/core/squawk.cpp @@ -74,6 +74,9 @@ void Core::Squawk::addAccount(const QString& login, const QString& server, const amap.insert(std::make_pair(name, acc)); connect(acc, SIGNAL(connectionStateChanged(int)), this, SLOT(onAccountConnectionStateChanged(int))); + 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(removeGroup(const QString&)), this, SLOT(onAccountRemoveGroup(const QString&))); QMap map = { {"login", login}, @@ -112,3 +115,20 @@ void Core::Squawk::onAccountConnectionStateChanged(int state) emit accountConnectionStateChanged(acc->getName(), state); } +void Core::Squawk::onAccountAddContact(const QString& jid, const QString& name, const QString& group) +{ + Account* acc = static_cast(sender()); + emit addContact(acc->getName(), jid, name, group); +} + +void Core::Squawk::onAccountAddGroup(const QString& name) +{ + Account* acc = static_cast(sender()); + emit addGroup(acc->getName(), name); +} + +void Core::Squawk::onAccountRemoveGroup(const QString& name) +{ + Account* acc = static_cast(sender()); + emit removeGroup(acc->getName(), name); +} diff --git a/core/squawk.h b/core/squawk.h index 49fb2fd..fb37985 100644 --- a/core/squawk.h +++ b/core/squawk.h @@ -25,6 +25,9 @@ signals: void quit(); void newAccount(const QMap&); void accountConnectionStateChanged(const QString&, int); + void addGroup(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); public slots: void start(); @@ -45,6 +48,9 @@ private: private slots: void onAccountConnectionStateChanged(int state); + void onAccountAddGroup(const QString& name); + void onAccountRemoveGroup(const QString& name); + void onAccountAddContact(const QString& jid, const QString& name, const QString& group); }; } diff --git a/main.cpp b/main.cpp index d22aa02..c5e8d0b 100644 --- a/main.cpp +++ b/main.cpp @@ -34,6 +34,10 @@ int main(int argc, char *argv[]) QObject::connect(squawk, SIGNAL(newAccount(const QMap&)), &w, SLOT(newAccount(const QMap&))); QObject::connect(squawk, SIGNAL(accountConnectionStateChanged(const QString&, int)), &w, SLOT(accountConnectionStateChanged(const QString&, int))); + QObject::connect(squawk, SIGNAL(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(removeGroup(const QString&, const QString&)), &w, SLOT(removeGroup(const QString&, const QString&))); coreThread->start(); diff --git a/ui/models/item.h b/ui/models/item.h index edc2216..388fdfb 100644 --- a/ui/models/item.h +++ b/ui/models/item.h @@ -15,7 +15,7 @@ class Item : public QObject{ enum Type { account, group, - contect, + contact, conversation, root }; diff --git a/ui/models/roster.cpp b/ui/models/roster.cpp index 91b0be2..f3f9cda 100644 --- a/ui/models/roster.cpp +++ b/ui/models/roster.cpp @@ -1,4 +1,5 @@ #include "roster.h" +#include #include using namespace Models; @@ -8,6 +9,8 @@ Models::Roster::Roster(QObject* parent): accountsModel(new Accounts()), root(new Item(Item::root, {{"name", "root"}})), accounts(), + groups(), + contacts(), elements() { connect(accountsModel, @@ -193,4 +196,54 @@ void Models::Roster::onAccountDataChanged(const QModelIndex& tl, const QModelInd } } +void Models::Roster::addGroup(const QString& account, const QString& name) +{ + std::map::iterator itr = accounts.find(account); + if (itr != accounts.end()) { + Account* acc = itr->second; + Item* group = new Item(Item::group, {{"name", name}}, acc); + beginInsertRows(createIndex(acc->row(), 0, acc), acc->childCount(), acc->childCount()); + acc->appendChild(group); + groups.insert(std::make_pair(name, group)); + elements.insert({{account, name}, group}); + endInsertRows(); + } else { + qDebug() << "An attempt to add group " << name << " to non existing account " << account << ", skipping"; + } +} + +void Models::Roster::addContact(const QString& account, const QString& jid, const QString& name, const QString& group) +{ + Item* parent; + if (group == "") { + std::map::iterator itr = accounts.find(account); + if (itr == accounts.end()) { + qDebug() << "An attempt to add a contact " << name << " to non existing account " << account << ", skipping"; + return; + } + parent = itr->second; + } else { + std::map::iterator itr = groups.find(group); + if (itr == groups.end()) { + qDebug() << "An attempt to add a contact " << name << " to non existing group " << group << ", skipping"; + return; + } + parent = itr->second; + } + + QString sName = name; + if (sName == "") { + sName = jid; + } + Item* contact = new Item(Item::contact, {{"name", sName}}, parent); + beginInsertRows(createIndex(parent->row(), 0, parent), parent->childCount(), parent->childCount()); + parent->appendChild(contact); + contacts.insert(std::make_pair(jid, contact)); + elements.insert({{account, jid}, contact}); + endInsertRows(); +} + +void Models::Roster::removeGroup(const QString& account, const QString& name) +{ +} diff --git a/ui/models/roster.h b/ui/models/roster.h index d1ba136..2d38a7b 100644 --- a/ui/models/roster.h +++ b/ui/models/roster.h @@ -23,6 +23,9 @@ public: void addAccount(const QMap &data); void updateAccount(const QString& account, const QString& field, const QVariant& value); + void addGroup(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); QVariant data ( const QModelIndex& index, int role ) const override; Qt::ItemFlags flags(const QModelIndex &index) const override; @@ -37,6 +40,8 @@ public: private: Item* root; std::map accounts; + std::map groups; + std::map contacts; std::map elements; private slots: diff --git a/ui/squawk.cpp b/ui/squawk.cpp index d9509ba..21048fd 100644 --- a/ui/squawk.cpp +++ b/ui/squawk.cpp @@ -85,3 +85,21 @@ void Squawk::accountConnectionStateChanged(const QString& account, int state) { rosterModel.updateAccount(account, "state", state); } + +void Squawk::addContact(const QString& account, const QString& jid, const QString& name, const QString& group) +{ + rosterModel.addContact(account, jid, name, group); +} + +void Squawk::addGroup(const QString& account, const QString& name) +{ + rosterModel.addGroup(account, name); +} + +void Squawk::removeGroup(const QString& account, const QString& name) +{ +} + + + + diff --git a/ui/squawk.h b/ui/squawk.h index 3c3e09a..481c0b5 100644 --- a/ui/squawk.h +++ b/ui/squawk.h @@ -32,6 +32,9 @@ signals: public slots: void newAccount(const QMap& account); void accountConnectionStateChanged(const QString& account, int state); + void addGroup(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); private: QScopedPointer m_ui;