From 21b40a9ccbf6a89bc41ed143780359103b996a85 Mon Sep 17 00:00:00 2001 From: blue Date: Tue, 14 Mar 2023 22:49:58 +0300 Subject: [PATCH] Client node now displays in all participants and presences, some additional checkups before querying empty clients, refactoring --- core/account.cpp | 10 +- core/account.h | 1 + core/components/clientcache.cpp | 10 +- core/components/clientcache.h | 3 +- core/conference.cpp | 18 ++- core/conference.h | 3 +- core/handlers/trusthandler.cpp | 8 +- core/squawk.cpp | 232 +++++++++++------------------- shared/clientid.cpp | 115 +++++++++++++++ shared/clientid.h | 13 ++ shared/clientinfo.cpp | 13 +- shared/clientinfo.h | 2 + ui/models/CMakeLists.txt | 58 ++++---- ui/models/abstractparticipant.cpp | 83 ++++++----- ui/models/abstractparticipant.h | 12 +- ui/models/participant.cpp | 127 ++++++++-------- ui/models/presence.cpp | 10 +- ui/models/presence.h | 2 - ui/models/roster.cpp | 4 +- 19 files changed, 407 insertions(+), 317 deletions(-) diff --git a/core/account.cpp b/core/account.cpp index a0b7311..9740029 100644 --- a/core/account.cpp +++ b/core/account.cpp @@ -360,9 +360,13 @@ void Core::Account::onPresenceReceived(const QXmppPresence& p_presence) { {"lastActivity", lastInteraction}, {"availability", p_presence.availableStatusType()}, //TODO check and handle invisible {"status", p_presence.statusText()}, - {"capabilityNode", p_presence.capabilityNode()}, - {"capabilityVer", p_presence.capabilityVer().toBase64()}, - {"capabilityHash", p_presence.capabilityHash()} + {"client", QVariant::fromValue( + Shared::ClientId( + p_presence.capabilityNode(), + p_presence.capabilityVer().toBase64(), + p_presence.capabilityHash()) + ) + } }); } break; diff --git a/core/account.h b/core/account.h index 58ff9b5..b257d2b 100644 --- a/core/account.h +++ b/core/account.h @@ -51,6 +51,7 @@ #include #include #include +#include #include "contact.h" #include "conference.h" #include diff --git a/core/components/clientcache.cpp b/core/components/clientcache.cpp index dfd9680..fe1fa64 100644 --- a/core/components/clientcache.cpp +++ b/core/components/clientcache.cpp @@ -37,14 +37,10 @@ void Core::ClientCache::open() { void Core::ClientCache::close() { db.close();} - -bool Core::ClientCache::checkClient(const QString& node, const QString& ver, const QString& hash) { - QString id = node + "/" + ver; +bool Core::ClientCache::checkClient(const Shared::ClientId& p_id) { + QString id = p_id.getId(); if (requested.count(id) == 0 && !cache->checkRecord(id)) { - Shared::ClientInfo& info = requested.insert(std::make_pair(id, Shared::ClientInfo())).first->second; - info.id.node = node; - info.id.verification = ver; - info.id.hash = hash; + requested.emplace(id, p_id); emit requestClientInfo(id); return false; } diff --git a/core/components/clientcache.h b/core/components/clientcache.h index 640def3..6202af5 100644 --- a/core/components/clientcache.h +++ b/core/components/clientcache.h @@ -25,6 +25,7 @@ #include +#include #include #include @@ -43,7 +44,7 @@ signals: void requestClientInfo(const QString& id); public slots: - bool checkClient(const QString& node, const QString& ver, const QString& hash); + bool checkClient(const Shared::ClientId& id); bool registerClientInfo(const QString& sourceFullJid, const QString& id, const std::set& identities, const std::set& features); private: diff --git a/core/conference.cpp b/core/conference.cpp index 065490c..2e49625 100644 --- a/core/conference.cpp +++ b/core/conference.cpp @@ -157,7 +157,14 @@ void Core::Conference::onRoomParticipantAdded(const QString& p_name) {"availability", pres.availableStatusType()}, {"status", pres.statusText()}, {"affiliation", mi.affiliation()}, - {"role", mi.role()} + {"role", mi.role()}, + {"client", QVariant::fromValue( + Shared::ClientId( + pres.capabilityNode(), + pres.capabilityVer().toBase64(), + pres.capabilityHash()) + ) + } }; if (hasAvatar) { @@ -218,7 +225,14 @@ void Core::Conference::onRoomParticipantChanged(const QString& p_name) {"availability", pres.availableStatusType()}, {"status", pres.statusText()}, {"affiliation", mi.affiliation()}, - {"role", mi.role()} + {"role", mi.role()}, + {"client", QVariant::fromValue( + Shared::ClientId( + pres.capabilityNode(), + pres.capabilityVer().toBase64(), + pres.capabilityHash()) + ) + } }); } } diff --git a/core/conference.h b/core/conference.h index 41141ad..00ade47 100644 --- a/core/conference.h +++ b/core/conference.h @@ -26,7 +26,8 @@ #include #include "rosteritem.h" -#include "shared/global.h" +#include +#include namespace Core { diff --git a/core/handlers/trusthandler.cpp b/core/handlers/trusthandler.cpp index 647d568..cc97e57 100644 --- a/core/handlers/trusthandler.cpp +++ b/core/handlers/trusthandler.cpp @@ -347,8 +347,7 @@ Core::TrustHandler::Keys Core::TrustHandler::getKeys(const QString& protocol, co } } -Shared::TrustLevel Core::TrustHandler::convert(Core::TrustHandler::TL level) -{ +Shared::TrustLevel Core::TrustHandler::convert(Core::TrustHandler::TL level) { switch (level) { case QXmpp::TrustLevel::Undecided: return Shared::TrustLevel::undecided; case QXmpp::TrustLevel::AutomaticallyDistrusted: return Shared::TrustLevel::automaticallyDistrusted; @@ -356,11 +355,11 @@ Shared::TrustLevel Core::TrustHandler::convert(Core::TrustHandler::TL level) case QXmpp::TrustLevel::AutomaticallyTrusted: return Shared::TrustLevel::automaticallyTrusted; case QXmpp::TrustLevel::ManuallyTrusted: return Shared::TrustLevel::manuallyTrusted; case QXmpp::TrustLevel::Authenticated: return Shared::TrustLevel::authenticated; + default: throw 2413; //never supposed to get here, switch case if complete, this line is just to suppress a warning } } -Core::TrustHandler::TL Core::TrustHandler::convert(Shared::TrustLevel level) -{ +Core::TrustHandler::TL Core::TrustHandler::convert(Shared::TrustLevel level) { switch (level) { case Shared::TrustLevel::undecided: return QXmpp::TrustLevel::Undecided; case Shared::TrustLevel::automaticallyDistrusted: return QXmpp::TrustLevel::AutomaticallyDistrusted; @@ -368,5 +367,6 @@ Core::TrustHandler::TL Core::TrustHandler::convert(Shared::TrustLevel level) case Shared::TrustLevel::automaticallyTrusted: return QXmpp::TrustLevel::AutomaticallyTrusted; case Shared::TrustLevel::manuallyTrusted: return QXmpp::TrustLevel::ManuallyTrusted; case Shared::TrustLevel::authenticated: return QXmpp::TrustLevel::Authenticated; + default: throw 2413; //never supposed to get here, switch case if complete, this line is just to suppress a warning } } diff --git a/core/squawk.cpp b/core/squawk.cpp index 33f2bf5..b7a0aad 100644 --- a/core/squawk.cpp +++ b/core/squawk.cpp @@ -50,8 +50,7 @@ Core::Squawk::Squawk(QObject* parent): #endif } -Core::Squawk::~Squawk() -{ +Core::Squawk::~Squawk() { Accounts::const_iterator itr = accounts.begin(); Accounts::const_iterator end = accounts.end(); for (; itr != end; ++itr) { @@ -59,13 +58,11 @@ Core::Squawk::~Squawk() } } -void Core::Squawk::onWalletOpened(bool success) -{ +void Core::Squawk::onWalletOpened(bool success) { qDebug() << "KWallet opened: " << success; } -void Core::Squawk::stop() -{ +void Core::Squawk::stop() { qDebug("Stopping squawk core.."); network.stop(); clientCache.close(); @@ -110,8 +107,7 @@ void Core::Squawk::stop() emit quit(); } -void Core::Squawk::start() -{ +void Core::Squawk::start() { qDebug("Starting squawk core.."); readSettings(); @@ -120,8 +116,7 @@ void Core::Squawk::start() clientCache.open(); } -void Core::Squawk::newAccountRequest(const QMap& map) -{ +void Core::Squawk::newAccountRequest(const QMap& map) { QString name = map.value("name").toString(); QString login = map.value("login").toString(); QString server = map.value("server").toString(); @@ -205,31 +200,28 @@ void Core::Squawk::addAccount( switch (passwordType) { case Shared::AccountPassword::alwaysAsk: case Shared::AccountPassword::kwallet: - if (password == "") { + if (password == "") acc->invalidatePassword(); - break; - } + + break; default: break; } if (state != Shared::Availability::offline) { acc->setAvailability(state); - if (acc->getActive()) { + if (acc->getActive()) acc->connect(); - } } } -void Core::Squawk::changeState(Shared::Availability p_state) -{ +void Core::Squawk::changeState(Shared::Availability p_state) { if (state != p_state) { for (std::deque::iterator itr = accounts.begin(), end = accounts.end(); itr != end; ++itr) { Account* acc = *itr; acc->setAvailability(p_state); - if (state == Shared::Availability::offline && acc->getActive()) { + if (state == Shared::Availability::offline && acc->getActive()) acc->connect(); - } } state = p_state; @@ -237,21 +229,18 @@ void Core::Squawk::changeState(Shared::Availability p_state) } } -void Core::Squawk::connectAccount(const QString& account) -{ +void Core::Squawk::connectAccount(const QString& account) { AccountsMap::const_iterator itr = amap.find(account); if (itr == amap.end()) { qDebug("An attempt to connect non existing account, skipping"); return; } itr->second->setActive(true); - if (state != Shared::Availability::offline) { + if (state != Shared::Availability::offline) itr->second->connect(); - } } -void Core::Squawk::disconnectAccount(const QString& account) -{ +void Core::Squawk::disconnectAccount(const QString& account) { AccountsMap::const_iterator itr = amap.find(account); if (itr == amap.end()) { qDebug("An attempt to connect non existing account, skipping"); @@ -262,15 +251,14 @@ void Core::Squawk::disconnectAccount(const QString& account) itr->second->disconnect(); } -void Core::Squawk::onAccountConnectionStateChanged(Shared::ConnectionState p_state) -{ +void Core::Squawk::onAccountConnectionStateChanged(Shared::ConnectionState p_state) { Account* acc = static_cast(sender()); QMap changes = { {"state", QVariant::fromValue(p_state)} }; - if (acc->getLastError() == Account::Error::none) { + if (acc->getLastError() == Account::Error::none) changes.insert("error", ""); - } + emit changeAccount(acc->getName(), changes); #ifdef WITH_KWALLET @@ -282,55 +270,48 @@ void Core::Squawk::onAccountConnectionStateChanged(Shared::ConnectionState p_sta #endif } -void Core::Squawk::onAccountAddContact(const QString& jid, const QString& group, const QMap& data) -{ +void Core::Squawk::onAccountAddContact(const QString& jid, const QString& group, const QMap& data) { Account* acc = static_cast(sender()); emit addContact(acc->getName(), jid, group, data); } -void Core::Squawk::onAccountAddGroup(const QString& name) -{ +void Core::Squawk::onAccountAddGroup(const QString& name) { Account* acc = static_cast(sender()); emit addGroup(acc->getName(), name); } -void Core::Squawk::onAccountRemoveGroup(const QString& name) -{ +void Core::Squawk::onAccountRemoveGroup(const QString& name) { Account* acc = static_cast(sender()); emit removeGroup(acc->getName(), name); } -void Core::Squawk::onAccountChangeContact(const QString& jid, const QMap& data) -{ +void Core::Squawk::onAccountChangeContact(const QString& jid, const QMap& data) { Account* acc = static_cast(sender()); emit changeContact(acc->getName(), jid, data); } -void Core::Squawk::onAccountRemoveContact(const QString& jid) -{ +void Core::Squawk::onAccountRemoveContact(const QString& jid) { Account* acc = static_cast(sender()); emit removeContact(acc->getName(), jid); } -void Core::Squawk::onAccountRemoveContact(const QString& jid, const QString& group) -{ +void Core::Squawk::onAccountRemoveContact(const QString& jid, const QString& group) { Account* acc = static_cast(sender()); emit removeContact(acc->getName(), jid, group); } -void Core::Squawk::onAccountAddPresence(const QString& jid, const QString& name, const QMap& data) -{ +void Core::Squawk::onAccountAddPresence(const QString& jid, const QString& name, const QMap& data) { Account* acc = static_cast(sender()); emit addPresence(acc->getName(), jid, name, data); //it's equal if a MUC sends its status with presence of the same jid (ex: muc@srv.im/muc@srv.im), it's not a client, so, no need to request if (jid != name) { - QString node = data["capabilityNode"].toString(); - QString ver = data["capabilityVer"].toString(); - QString hash = data["capabilityHash"].toString(); - if (!clientCache.checkClient(node, ver, hash)) { - acc->discoverInfo(jid + "/" + name, node + "/" + ver); - } + const Shared::ClientId& id = data["client"].value(); + if (!id.valid()) + return; + + if (!clientCache.checkClient(id)) + acc->discoverInfo(jid + "/" + name, id.getId()); } } @@ -347,32 +328,27 @@ void Core::Squawk::onAccountInfoDiscovered( } } -void Core::Squawk::onAccountRemovePresence(const QString& jid, const QString& name) -{ +void Core::Squawk::onAccountRemovePresence(const QString& jid, const QString& name) { Account* acc = static_cast(sender()); emit removePresence(acc->getName(), jid, name); } -void Core::Squawk::onAccountAvailabilityChanged(Shared::Availability state) -{ +void Core::Squawk::onAccountAvailabilityChanged(Shared::Availability state) { Account* acc = static_cast(sender()); emit changeAccount(acc->getName(), {{"availability", QVariant::fromValue(state)}}); } -void Core::Squawk::onAccountChanged(const QMap& data) -{ +void Core::Squawk::onAccountChanged(const QMap& data) { Account* acc = static_cast(sender()); emit changeAccount(acc->getName(), data); } -void Core::Squawk::onAccountMessage(const Shared::Message& data) -{ +void Core::Squawk::onAccountMessage(const Shared::Message& data) { Account* acc = static_cast(sender()); emit accountMessage(acc->getName(), data); } -void Core::Squawk::sendMessage(const QString& account, const Shared::Message& data) -{ +void Core::Squawk::sendMessage(const QString& account, const Shared::Message& data) { AccountsMap::const_iterator itr = amap.find(account); if (itr == amap.end()) { qDebug() << "An attempt to send a message with non existing account" << account << ", skipping"; @@ -382,8 +358,7 @@ void Core::Squawk::sendMessage(const QString& account, const Shared::Message& da itr->second->sendMessage(data); } -void Core::Squawk::replaceMessage(const QString& account, const QString& originalId, const Shared::Message& data) -{ +void Core::Squawk::replaceMessage(const QString& account, const QString& originalId, const Shared::Message& data) { AccountsMap::const_iterator itr = amap.find(account); if (itr == amap.end()) { qDebug() << "An attempt to replace a message with non existing account" << account << ", skipping"; @@ -393,8 +368,7 @@ void Core::Squawk::replaceMessage(const QString& account, const QString& origina itr->second->replaceMessage(originalId, data); } -void Core::Squawk::resendMessage(const QString& account, const QString& jid, const QString& id) -{ +void Core::Squawk::resendMessage(const QString& account, const QString& jid, const QString& id) { AccountsMap::const_iterator itr = amap.find(account); if (itr == amap.end()) { qDebug() << "An attempt to resend a message with non existing account" << account << ", skipping"; @@ -404,8 +378,7 @@ void Core::Squawk::resendMessage(const QString& account, const QString& jid, con itr->second->resendMessage(jid, id); } -void Core::Squawk::requestArchive(const QString& account, const QString& jid, int count, const QString& before) -{ +void Core::Squawk::requestArchive(const QString& account, const QString& jid, int count, const QString& before) { AccountsMap::const_iterator itr = amap.find(account); if (itr == amap.end()) { qDebug("An attempt to request an archive of non existing account, skipping"); @@ -414,14 +387,12 @@ void Core::Squawk::requestArchive(const QString& account, const QString& jid, in itr->second->requestArchive(jid, count, before); } -void Core::Squawk::onAccountResponseArchive(const QString& jid, const std::list& list, bool last) -{ +void Core::Squawk::onAccountResponseArchive(const QString& jid, const std::list& list, bool last) { Account* acc = static_cast(sender()); emit responseArchive(acc->getName(), jid, list, last); } -void Core::Squawk::modifyAccountRequest(const QString& name, const QMap& map) -{ +void Core::Squawk::modifyAccountRequest(const QString& name, const QMap& map) { AccountsMap::const_iterator itr = amap.find(name); if (itr == amap.end()) { qDebug("An attempt to modify non existing account, skipping"); @@ -471,29 +442,24 @@ void Core::Squawk::modifyAccountRequest(const QString& name, const QMapsetLogin(mItr->toString()); - } mItr = map.find("password"); - if (mItr != map.end()) { + if (mItr != map.end()) acc->setPassword(mItr->toString()); - } mItr = map.find("resource"); - if (mItr != map.end()) { + if (mItr != map.end()) acc->setResource(mItr->toString()); - } mItr = map.find("server"); - if (mItr != map.end()) { + if (mItr != map.end()) acc->setServer(mItr->toString()); - } mItr = map.find("passwordType"); - if (mItr != map.end()) { + if (mItr != map.end()) acc->setPasswordType(Shared::Global::fromInt(mItr->toInt())); - } #ifdef WITH_KWALLET if (acc->getPasswordType() == Shared::AccountPassword::kwallet @@ -505,28 +471,24 @@ void Core::Squawk::modifyAccountRequest(const QString& name, const QMapgetActive()) { + if (activeChanged && acc->getActive()) acc->connect(); - } else if (!wentReconnecting && acc->getActive() && acc->getLastError() == Account::Error::authentication) { + else if (!wentReconnecting && acc->getActive() && acc->getLastError() == Account::Error::authentication) acc->connect(); - } } emit changeAccount(name, map); } -void Core::Squawk::onAccountError(const QString& text) -{ +void Core::Squawk::onAccountError(const QString& text) { Account* acc = static_cast(sender()); emit changeAccount(acc->getName(), {{"error", text}}); - if (acc->getLastError() == Account::Error::authentication) { + if (acc->getLastError() == Account::Error::authentication) emit requestPassword(acc->getName(), true); - } } -void Core::Squawk::removeAccountRequest(const QString& name) -{ +void Core::Squawk::removeAccountRequest(const QString& name) { AccountsMap::const_iterator itr = amap.find(name); if (itr == amap.end()) { qDebug() << "An attempt to remove non existing account " << name << " from core, skipping"; @@ -534,9 +496,8 @@ void Core::Squawk::removeAccountRequest(const QString& name) } Account* acc = itr->second; - if (acc->getState() != Shared::ConnectionState::disconnected) { + if (acc->getState() != Shared::ConnectionState::disconnected) acc->disconnect(); - } for (Accounts::const_iterator aItr = accounts.begin(); aItr != accounts.end(); ++aItr) { if (*aItr == acc) { @@ -556,8 +517,7 @@ void Core::Squawk::removeAccountRequest(const QString& name) acc->deleteLater(); } -void Core::Squawk::subscribeContact(const QString& account, const QString& jid, const QString& reason) -{ +void Core::Squawk::subscribeContact(const QString& account, const QString& jid, const QString& reason) { AccountsMap::const_iterator itr = amap.find(account); if (itr == amap.end()) { qDebug("An attempt to subscribe to the contact with non existing account, skipping"); @@ -567,8 +527,7 @@ void Core::Squawk::subscribeContact(const QString& account, const QString& jid, itr->second->subscribeToContact(jid, reason); } -void Core::Squawk::unsubscribeContact(const QString& account, const QString& jid, const QString& reason) -{ +void Core::Squawk::unsubscribeContact(const QString& account, const QString& jid, const QString& reason) { AccountsMap::const_iterator itr = amap.find(account); if (itr == amap.end()) { qDebug("An attempt to subscribe to the contact with non existing account, skipping"); @@ -578,8 +537,7 @@ void Core::Squawk::unsubscribeContact(const QString& account, const QString& jid itr->second->unsubscribeFromContact(jid, reason); } -void Core::Squawk::removeContactRequest(const QString& account, const QString& jid) -{ +void Core::Squawk::removeContactRequest(const QString& account, const QString& jid) { AccountsMap::const_iterator itr = amap.find(account); if (itr == amap.end()) { qDebug("An attempt to remove contact from non existing account, skipping"); @@ -589,8 +547,7 @@ void Core::Squawk::removeContactRequest(const QString& account, const QString& j itr->second->removeContactRequest(jid); } -void Core::Squawk::addContactRequest(const QString& account, const QString& jid, const QString& name, const QSet& groups) -{ +void Core::Squawk::addContactRequest(const QString& account, const QString& jid, const QString& name, const QSet& groups) { AccountsMap::const_iterator itr = amap.find(account); if (itr == amap.end()) { qDebug("An attempt to add contact to a non existing account, skipping"); @@ -600,26 +557,22 @@ void Core::Squawk::addContactRequest(const QString& account, const QString& jid, itr->second->addContactRequest(jid, name, groups); } -void Core::Squawk::onAccountAddRoom(const QString jid, const QMap& data) -{ +void Core::Squawk::onAccountAddRoom(const QString jid, const QMap& data) { Account* acc = static_cast(sender()); emit addRoom(acc->getName(), jid, data); } -void Core::Squawk::onAccountChangeRoom(const QString jid, const QMap& data) -{ +void Core::Squawk::onAccountChangeRoom(const QString jid, const QMap& data) { Account* acc = static_cast(sender()); emit changeRoom(acc->getName(), jid, data); } -void Core::Squawk::onAccountRemoveRoom(const QString jid) -{ +void Core::Squawk::onAccountRemoveRoom(const QString jid) { Account* acc = static_cast(sender()); emit removeRoom(acc->getName(), jid); } -void Core::Squawk::setRoomJoined(const QString& account, const QString& jid, bool joined) -{ +void Core::Squawk::setRoomJoined(const QString& account, const QString& jid, bool joined) { AccountsMap::const_iterator itr = amap.find(account); if (itr == amap.end()) { qDebug() << "An attempt to set jouned to the room" << jid << "of non existing account" << account << ", skipping"; @@ -628,8 +581,7 @@ void Core::Squawk::setRoomJoined(const QString& account, const QString& jid, boo itr->second->setRoomJoined(jid, joined); } -void Core::Squawk::setRoomAutoJoin(const QString& account, const QString& jid, bool joined) -{ +void Core::Squawk::setRoomAutoJoin(const QString& account, const QString& jid, bool joined) { AccountsMap::const_iterator itr = amap.find(account); if (itr == amap.end()) { qDebug() << "An attempt to set autoJoin to the room" << jid << "of non existing account" << account << ", skipping"; @@ -638,32 +590,27 @@ void Core::Squawk::setRoomAutoJoin(const QString& account, const QString& jid, b itr->second->setRoomAutoJoin(jid, joined); } -void Core::Squawk::onAccountAddRoomPresence(const QString& jid, const QString& nick, const QMap& data) -{ +void Core::Squawk::onAccountAddRoomPresence(const QString& jid, const QString& nick, const QMap& data) { Account* acc = static_cast(sender()); emit addRoomParticipant(acc->getName(), jid, nick, data); } -void Core::Squawk::onAccountChangeRoomPresence(const QString& jid, const QString& nick, const QMap& data) -{ +void Core::Squawk::onAccountChangeRoomPresence(const QString& jid, const QString& nick, const QMap& data) { Account* acc = static_cast(sender()); emit changeRoomParticipant(acc->getName(), jid, nick, data); } -void Core::Squawk::onAccountRemoveRoomPresence(const QString& jid, const QString& nick) -{ +void Core::Squawk::onAccountRemoveRoomPresence(const QString& jid, const QString& nick) { Account* acc = static_cast(sender()); emit removeRoomParticipant(acc->getName(), jid, nick); } -void Core::Squawk::onAccountChangeMessage(const QString& jid, const QString& id, const QMap& data) -{ +void Core::Squawk::onAccountChangeMessage(const QString& jid, const QString& id, const QMap& data) { Account* acc = static_cast(sender()); emit changeMessage(acc->getName(), jid, id, data); } -void Core::Squawk::removeRoomRequest(const QString& account, const QString& jid) -{ +void Core::Squawk::removeRoomRequest(const QString& account, const QString& jid) { AccountsMap::const_iterator itr = amap.find(account); if (itr == amap.end()) { qDebug() << "An attempt to remove the room" << jid << "of non existing account" << account << ", skipping"; @@ -672,8 +619,7 @@ void Core::Squawk::removeRoomRequest(const QString& account, const QString& jid) itr->second->removeRoomRequest(jid); } -void Core::Squawk::addRoomRequest(const QString& account, const QString& jid, const QString& nick, const QString& password, bool autoJoin) -{ +void Core::Squawk::addRoomRequest(const QString& account, const QString& jid, const QString& nick, const QString& password, bool autoJoin) { AccountsMap::const_iterator itr = amap.find(account); if (itr == amap.end()) { qDebug() << "An attempt to add the room" << jid << "to non existing account" << account << ", skipping"; @@ -682,13 +628,11 @@ void Core::Squawk::addRoomRequest(const QString& account, const QString& jid, co itr->second->addRoomRequest(jid, nick, password, autoJoin); } -void Core::Squawk::fileDownloadRequest(const QString& url) -{ +void Core::Squawk::fileDownloadRequest(const QString& url) { network.downladFile(url); } -void Core::Squawk::addContactToGroupRequest(const QString& account, const QString& jid, const QString& groupName) -{ +void Core::Squawk::addContactToGroupRequest(const QString& account, const QString& jid, const QString& groupName) { AccountsMap::const_iterator itr = amap.find(account); if (itr == amap.end()) { qDebug() << "An attempt to add contact" << jid << "of non existing account" << account << "to the group" << groupName << ", skipping"; @@ -697,8 +641,7 @@ void Core::Squawk::addContactToGroupRequest(const QString& account, const QStrin itr->second->addContactToGroupRequest(jid, groupName); } -void Core::Squawk::removeContactFromGroupRequest(const QString& account, const QString& jid, const QString& groupName) -{ +void Core::Squawk::removeContactFromGroupRequest(const QString& account, const QString& jid, const QString& groupName) { AccountsMap::const_iterator itr = amap.find(account); if (itr == amap.end()) { qDebug() << "An attempt to add contact" << jid << "of non existing account" << account << "to the group" << groupName << ", skipping"; @@ -707,8 +650,7 @@ void Core::Squawk::removeContactFromGroupRequest(const QString& account, const Q itr->second->removeContactFromGroupRequest(jid, groupName); } -void Core::Squawk::renameContactRequest(const QString& account, const QString& jid, const QString& newName) -{ +void Core::Squawk::renameContactRequest(const QString& account, const QString& jid, const QString& newName) { AccountsMap::const_iterator itr = amap.find(account); if (itr == amap.end()) { qDebug() << "An attempt to rename contact" << jid << "of non existing account" << account << ", skipping"; @@ -717,8 +659,7 @@ void Core::Squawk::renameContactRequest(const QString& account, const QString& j itr->second->renameContactRequest(jid, newName); } -void Core::Squawk::requestInfo(const QString& account, const QString& jid) -{ +void Core::Squawk::requestInfo(const QString& account, const QString& jid) { AccountsMap::const_iterator itr = amap.find(account); if (itr == amap.end()) { qDebug() << "An attempt to request info about" << jid << "of non existing account" << account << ", skipping"; @@ -727,8 +668,7 @@ void Core::Squawk::requestInfo(const QString& account, const QString& jid) itr->second->requestInfo(jid); } -void Core::Squawk::updateInfo(const QString& account, const Shared::Info& info) -{ +void Core::Squawk::updateInfo(const QString& account, const Shared::Info& info) { AccountsMap::const_iterator itr = amap.find(account); if (itr == amap.end()) { qDebug() << "An attempt to update info to non existing account" << account << ", skipping"; @@ -737,8 +677,7 @@ void Core::Squawk::updateInfo(const QString& account, const Shared::Info& info) itr->second->updateInfo(info); } -void Core::Squawk::readSettings() -{ +void Core::Squawk::readSettings() { QSettings settings; settings.beginGroup("core"); int size = settings.beginReadArray("accounts"); @@ -772,8 +711,7 @@ void Core::Squawk::readSettings() emit ready(); } -void Core::Squawk::onAccountNeedPassword() -{ +void Core::Squawk::onAccountNeedPassword() { Account* acc = static_cast(sender()); switch (acc->getPasswordType()) { case Shared::AccountPassword::alwaysAsk: @@ -796,13 +734,11 @@ void Core::Squawk::onAccountNeedPassword() } } -void Core::Squawk::onWalletRejectPassword(const QString& login) -{ +void Core::Squawk::onWalletRejectPassword(const QString& login) { emit requestPassword(login, false); } -void Core::Squawk::responsePassword(const QString& account, const QString& password) -{ +void Core::Squawk::responsePassword(const QString& account, const QString& password) { AccountsMap::const_iterator itr = amap.find(account); if (itr == amap.end()) { qDebug() << "An attempt to set password to non existing account" << account << ", skipping"; @@ -811,24 +747,19 @@ void Core::Squawk::responsePassword(const QString& account, const QString& passw Account* acc = itr->second; acc->setPassword(password); emit changeAccount(account, {{"password", password}}); - if (state != Shared::Availability::offline && acc->getActive()) { + if (state != Shared::Availability::offline && acc->getActive()) acc->connect(); - } } -void Core::Squawk::onAccountUploadFileError(const QString& jid, const QString id, const QString& errorText) -{ +void Core::Squawk::onAccountUploadFileError(const QString& jid, const QString id, const QString& errorText) { Account* acc = static_cast(sender()); emit fileError({{acc->getName(), jid, id}}, errorText, true); } -void Core::Squawk::onLocalPathInvalid(const QString& path) -{ +void Core::Squawk::onLocalPathInvalid(const QString& path) { std::list list = network.reportPathInvalid(path); - QMap data({ - {"attachPath", ""} - }); + QMap data({{"attachPath", ""}}); for (const Shared::MessageInfo& info : list) { AccountsMap::const_iterator itr = amap.find(info.account); if (itr != amap.end()) { @@ -839,8 +770,7 @@ void Core::Squawk::onLocalPathInvalid(const QString& path) } } -void Core::Squawk::changeDownloadsPath(const QString& path) -{ +void Core::Squawk::changeDownloadsPath(const QString& path) { network.moveFilesDirectory(path); } diff --git a/shared/clientid.cpp b/shared/clientid.cpp index f16736c..b050df6 100644 --- a/shared/clientid.cpp +++ b/shared/clientid.cpp @@ -22,10 +22,125 @@ Shared::ClientId::ClientId(): hash() {} +Shared::ClientId::ClientId(const QString& p_node, const QString& p_ver, const QString& p_hash): + node(p_node), + verification(p_ver), + hash(p_hash) +{} + + +Shared::ClientId::ClientId(const Shared::ClientId& other): + node(other.node), + verification(other.verification), + hash(other.hash) +{} + +Shared::ClientId & Shared::ClientId::operator=(const Shared::ClientId& other) { + node = other.node; + verification = other.verification; + hash = other.hash; + + return *this; +} + +bool Shared::ClientId::operator==(const Shared::ClientId& other) const { + return hash == other.hash && verification == other.verification && node == other.node; +} + +bool Shared::ClientId::operator!=(const Shared::ClientId& other) const { + return hash != other.hash && verification != other.verification && node != other.node; +} + +bool Shared::ClientId::operator<(const Shared::ClientId& other) const { + if (hash < other.hash) + return true; + + if (hash > other.hash) + return false; + + if (verification < other.verification) + return true; + + if (verification > other.verification) + return false; + + if (node < other.node) + return true; + + return false; +} + +bool Shared::ClientId::operator>(const Shared::ClientId& other) const { + if (hash > other.hash) + return true; + + if (hash < other.hash) + return false; + + if (verification > other.verification) + return true; + + if (verification < other.verification) + return false; + + if (node > other.node) + return true; + + return false; +} + +bool Shared::ClientId::operator<=(const Shared::ClientId& other) const { + if (hash < other.hash) + return true; + + if (hash > other.hash) + return false; + + if (verification < other.verification) + return true; + + if (verification > other.verification) + return false; + + if (node < other.node) + return true; + + if (node > other.node) + return false; + + return true; +} + +bool Shared::ClientId::operator>=(const Shared::ClientId& other) const { + if (hash > other.hash) + return true; + + if (hash < other.hash) + return false; + + if (verification > other.verification) + return true; + + if (verification < other.verification) + return false; + + if (node > other.node) + return true; + + if (node < other.node) + return false; + + return true; +} + QString Shared::ClientId::getId() const { return node + "/" + verification; } +bool Shared::ClientId::valid() const { + return node.size() > 0 && verification.size() > 0 && hash.size() > 0; +} + QDataStream & Shared::ClientId::operator<<(QDataStream& stream) { stream >> node; stream >> verification; diff --git a/shared/clientid.h b/shared/clientid.h index defe909..5188b1c 100644 --- a/shared/clientid.h +++ b/shared/clientid.h @@ -25,7 +25,18 @@ namespace Shared { class ClientId { public: ClientId(); + ClientId(const QString& node, const QString& verification, const QString& hash); + ClientId(const ClientId& other); + ClientId& operator = (const ClientId& other); + bool operator == (const ClientId& other) const; + bool operator != (const ClientId& other) const; + bool operator < (const ClientId& other) const; + bool operator > (const ClientId& other) const; + bool operator <= (const ClientId& other) const; + bool operator >= (const ClientId& other) const; + + bool valid() const; QString getId() const; QDataStream& operator << (QDataStream& stream); @@ -39,6 +50,8 @@ public: } +Q_DECLARE_METATYPE(Shared::ClientId) + QDataStream& operator << (QDataStream& stream, const Shared::ClientId& info); QDataStream& operator >> (QDataStream& stream, Shared::ClientId& info); diff --git a/shared/clientinfo.cpp b/shared/clientinfo.cpp index 9a3fdac..9b84755 100644 --- a/shared/clientinfo.cpp +++ b/shared/clientinfo.cpp @@ -35,11 +35,22 @@ Shared::ClientInfo::ClientInfo(): id(), specificPresence() {} +Shared::ClientInfo::ClientInfo(const QString& p_node, const QString& p_ver, const QString& p_hash) : + identities(), + extensions(), + id(p_node, p_ver, p_hash), + specificPresence() {} + +Shared::ClientInfo::ClientInfo(const Shared::ClientId& p_id) : + identities(), + extensions(), + id(p_id), + specificPresence() {} + QString Shared::ClientInfo::getId() const { return id.getId(); } - QDataStream & Shared::ClientInfo::operator >> (QDataStream& stream) const { stream << id; stream << (quint8)identities.size(); diff --git a/shared/clientinfo.h b/shared/clientinfo.h index 8e95180..288e9fa 100644 --- a/shared/clientinfo.h +++ b/shared/clientinfo.h @@ -31,6 +31,8 @@ namespace Shared { class ClientInfo { public: ClientInfo(); + ClientInfo(const ClientId& id); + ClientInfo(const QString& node, const QString& verification, const QString& hash); QString getId() const; bool valid() const; diff --git a/ui/models/CMakeLists.txt b/ui/models/CMakeLists.txt index 84aba66..0e6d8ab 100644 --- a/ui/models/CMakeLists.txt +++ b/ui/models/CMakeLists.txt @@ -1,28 +1,36 @@ +set(SOURCE_FILES + abstractparticipant.cpp + account.cpp + accounts.cpp + contact.cpp + element.cpp + group.cpp + item.cpp + participant.cpp + presence.cpp + reference.cpp + room.cpp + roster.cpp +) + +set(HEADER_FILES + abstractparticipant.h + account.h + accounts.h + contact.h + element.h + group.h + item.h + participant.h + presence.h + reference.h + room.h + roster.h +) + target_sources(squawk PRIVATE - abstractparticipant.cpp - abstractparticipant.h - account.cpp - account.h - accounts.cpp - accounts.h - contact.cpp - contact.h - element.cpp - element.h - group.cpp - group.h - item.cpp - item.h - participant.cpp - participant.h - presence.cpp - presence.h - reference.cpp - reference.h - room.cpp - room.h - roster.cpp - roster.h - ) + ${SOURCE_FILES} + ${HEADER_FILES} +) add_subdirectory(info) diff --git a/ui/models/abstractparticipant.cpp b/ui/models/abstractparticipant.cpp index 029527d..240e5ba 100644 --- a/ui/models/abstractparticipant.cpp +++ b/ui/models/abstractparticipant.cpp @@ -18,40 +18,38 @@ #include "abstractparticipant.h" -using namespace Models; - Models::AbstractParticipant::AbstractParticipant(Models::Item::Type p_type, const QMap& data, Models::Item* parentItem): Item(p_type, data, parentItem), availability(Shared::Availability::offline), lastActivity(data.value("lastActivity").toDateTime()), - status(data.value("status").toString()) + status(data.value("status").toString()), + client() { QMap::const_iterator itr = data.find("availability"); - if (itr != data.end()) { + if (itr != data.end()) setAvailability(itr.value().toUInt()); - } + + itr = data.find("client"); + if (itr != data.end()) + setClient(itr.value().value()); } Models::AbstractParticipant::AbstractParticipant(const Models::AbstractParticipant& other): Item(other), availability(other.availability), lastActivity(other.lastActivity), - status(other.status) -{ + status(other.status), + client(other.client) +{} + + +Models::AbstractParticipant::~AbstractParticipant() {} + +int Models::AbstractParticipant::columnCount() const { + return 5; } - -Models::AbstractParticipant::~AbstractParticipant() -{ -} - -int Models::AbstractParticipant::columnCount() const -{ - return 4; -} - -QVariant Models::AbstractParticipant::data(int column) const -{ +QVariant Models::AbstractParticipant::data(int column) const { switch (column) { case 0: return Item::data(column); @@ -61,62 +59,71 @@ QVariant Models::AbstractParticipant::data(int column) const return QVariant::fromValue(availability); case 3: return status; + case 4: + return QVariant::fromValue(client); default: return QVariant(); } } -Shared::Availability Models::AbstractParticipant::getAvailability() const -{ +Shared::Availability Models::AbstractParticipant::getAvailability() const { return availability; } -QDateTime Models::AbstractParticipant::getLastActivity() const -{ +QDateTime Models::AbstractParticipant::getLastActivity() const { return lastActivity; } -QString Models::AbstractParticipant::getStatus() const -{ +QString Models::AbstractParticipant::getStatus() const { return status; } -void Models::AbstractParticipant::setAvailability(Shared::Availability p_avail) -{ +void Models::AbstractParticipant::setAvailability(Shared::Availability p_avail) { if (availability != p_avail) { availability = p_avail; changed(2); } } -void Models::AbstractParticipant::setAvailability(unsigned int avail) -{ +void Models::AbstractParticipant::setAvailability(unsigned int avail) { setAvailability(Shared::Global::fromInt(avail)); } -void Models::AbstractParticipant::setLastActivity(const QDateTime& p_time) -{ +void Models::AbstractParticipant::setLastActivity(const QDateTime& p_time) { if (lastActivity != p_time) { lastActivity = p_time; changed(1); } } -void Models::AbstractParticipant::setStatus(const QString& p_state) -{ +void Models::AbstractParticipant::setStatus(const QString& p_state) { if (status != p_state) { status = p_state; changed(3); } } -QIcon Models::AbstractParticipant::getStatusIcon(bool big) const -{ +Shared::ClientId Models::AbstractParticipant::getClient() const { + return client; +} + +QString Models::AbstractParticipant::getClientNode() const { + return client.node; +} + +void Models::AbstractParticipant::setClient(const Shared::ClientId& id) { + if (client != id) { + client = id; + changed(4); + } +} + + +QIcon Models::AbstractParticipant::getStatusIcon(bool big) const { return Shared::availabilityIcon(availability, big); } -void Models::AbstractParticipant::update(const QString& key, const QVariant& value) -{ +void Models::AbstractParticipant::update(const QString& key, const QVariant& value) { if (key == "name") { setName(value.toString()); } else if (key == "status") { @@ -125,5 +132,7 @@ void Models::AbstractParticipant::update(const QString& key, const QVariant& val setAvailability(value.toUInt()); } else if (key == "lastActivity") { setLastActivity(value.toDateTime()); + } else if (key == "client") { + setClient(value.value()); } } diff --git a/ui/models/abstractparticipant.h b/ui/models/abstractparticipant.h index cb20788..fe2f0b5 100644 --- a/ui/models/abstractparticipant.h +++ b/ui/models/abstractparticipant.h @@ -21,9 +21,10 @@ #include "item.h" -#include "shared/enums.h" -#include "shared/icons.h" -#include "shared/global.h" +#include +#include +#include +#include #include #include @@ -51,6 +52,10 @@ public: QString getStatus() const; void setStatus(const QString& p_state); virtual QIcon getStatusIcon(bool big = false) const; + + Shared::ClientId getClient() const; + void setClient(const Shared::ClientId& id); + QString getClientNode() const; virtual void update(const QString& key, const QVariant& value); @@ -58,6 +63,7 @@ protected: Shared::Availability availability; QDateTime lastActivity; QString status; + Shared::ClientId client; }; } diff --git a/ui/models/participant.cpp b/ui/models/participant.cpp index dc42c07..7201acb 100644 --- a/ui/models/participant.cpp +++ b/ui/models/participant.cpp @@ -26,52 +26,46 @@ Models::Participant::Participant(const QMap& data, Models::It role(Shared::Role::unspecified) { QMap::const_iterator itr = data.find("affiliation"); - if (itr != data.end()) { + if (itr != data.end()) setAffiliation(itr.value().toUInt()); - } - + itr = data.find("role"); - if (itr != data.end()) { + if (itr != data.end()) setRole(itr.value().toUInt()); - } - + itr = data.find("avatarState"); - if (itr != data.end()) { + if (itr != data.end()) setAvatarState(itr.value().toUInt()); - } + itr = data.find("avatarPath"); - if (itr != data.end()) { + if (itr != data.end()) setAvatarPath(itr.value().toString()); - } + } Models::Participant::~Participant() -{ +{} + +int Models::Participant::columnCount() const { + return 9; } -int Models::Participant::columnCount() const -{ - return 8; -} - -QVariant Models::Participant::data(int column) const -{ +QVariant Models::Participant::data(int column) const { switch (column) { - case 4: - return QVariant::fromValue(affiliation); case 5: - return QVariant::fromValue(role); + return QVariant::fromValue(affiliation); case 6: - return QVariant::fromValue(getAvatarState()); + return QVariant::fromValue(role); case 7: + return QVariant::fromValue(getAvatarState()); + case 8: return getAvatarPath(); default: return AbstractParticipant::data(column); } } -void Models::Participant::update(const QString& key, const QVariant& value) -{ +void Models::Participant::update(const QString& key, const QVariant& value) { if (key == "affiliation") { setAffiliation(value.toUInt()); } else if (key == "role") { @@ -85,67 +79,58 @@ void Models::Participant::update(const QString& key, const QVariant& value) } } -Shared::Affiliation Models::Participant::getAffiliation() const -{ +Shared::Affiliation Models::Participant::getAffiliation() const { return affiliation; } -void Models::Participant::setAffiliation(Shared::Affiliation p_aff) -{ +void Models::Participant::setAffiliation(Shared::Affiliation p_aff) { if (p_aff != affiliation) { affiliation = p_aff; - changed(4); - } -} - -void Models::Participant::setAffiliation(unsigned int aff) -{ - setAffiliation(Shared::Global::fromInt(aff)); -} - -Shared::Role Models::Participant::getRole() const -{ - return role; -} - -void Models::Participant::setRole(Shared::Role p_role) -{ - if (p_role != role) { - role = p_role; changed(5); } } -void Models::Participant::setRole(unsigned int p_role) -{ - setRole(Shared::Global::fromInt(p_role)); +void Models::Participant::setAffiliation(unsigned int aff) { + setAffiliation(Shared::Global::fromInt(aff)); } -QString Models::Participant::getAvatarPath() const -{ - return avatarPath; +Shared::Role Models::Participant::getRole() const { + return role; } -Shared::Avatar Models::Participant::getAvatarState() const -{ - return avatarState; -} - -void Models::Participant::setAvatarPath(const QString& path) -{ - if (avatarPath != path) { - avatarPath = path; - changed(7); - } -} - -void Models::Participant::setAvatarState(Shared::Avatar p_state) -{ - if (avatarState != p_state) { - avatarState = p_state; +void Models::Participant::setRole(Shared::Role p_role) { + if (p_role != role) { + role = p_role; changed(6); } } -void Models::Participant::setAvatarState(unsigned int p_state) -{setAvatarState(Shared::Global::fromInt(p_state));} +void Models::Participant::setRole(unsigned int p_role) { + setRole(Shared::Global::fromInt(p_role)); +} + +QString Models::Participant::getAvatarPath() const { + return avatarPath; +} + +Shared::Avatar Models::Participant::getAvatarState() const { + return avatarState; +} + +void Models::Participant::setAvatarPath(const QString& path) { + if (avatarPath != path) { + avatarPath = path; + changed(8); + } +} + +void Models::Participant::setAvatarState(Shared::Avatar p_state) { + if (avatarState != p_state) { + avatarState = p_state; + changed(7); + } +} + +void Models::Participant::setAvatarState(unsigned int p_state) { + setAvatarState(Shared::Global::fromInt(p_state)); +} diff --git a/ui/models/presence.cpp b/ui/models/presence.cpp index 8ba7c47..a867243 100644 --- a/ui/models/presence.cpp +++ b/ui/models/presence.cpp @@ -21,14 +21,8 @@ Models::Presence::Presence(const QMap& data, Item* parentItem): AbstractParticipant(Item::presence, data, parentItem) -{ -} +{} Models::Presence::~Presence() -{ -} +{} -int Models::Presence::columnCount() const -{ - return 4; -} diff --git a/ui/models/presence.h b/ui/models/presence.h index fb1a31c..4df662a 100644 --- a/ui/models/presence.h +++ b/ui/models/presence.h @@ -34,8 +34,6 @@ class Presence : public Models::AbstractParticipant public: explicit Presence(const QMap &data, Item *parentItem = 0); ~Presence(); - - int columnCount() const override; }; } diff --git a/ui/models/roster.cpp b/ui/models/roster.cpp index 8ce3464..43717f8 100644 --- a/ui/models/roster.cpp +++ b/ui/models/roster.cpp @@ -225,6 +225,7 @@ QVariant Models::Roster::data (const QModelIndex& index, int role) const if (s.size() > 0) { str += "\n" + tr("Status: ") + s; } + str += "\n" + tr("Client: ") + contact->getClientNode(); result = str; } @@ -240,7 +241,8 @@ QVariant Models::Roster::data (const QModelIndex& index, int role) const } str += tr("Affiliation: ") + Shared::Global::getName(p->getAffiliation()) + "\n"; - str += tr("Role: ") + Shared::Global::getName(p->getRole()); + str += tr("Role: ") + Shared::Global::getName(p->getRole()) + "\n"; + str += tr("Client: ") + p->getClientNode(); result = str; }