From fffef9876a87a949142688b0bfc6f1bee7783dd2 Mon Sep 17 00:00:00 2001 From: blue Date: Thu, 16 Mar 2023 22:38:05 +0300 Subject: [PATCH] Refactoring, account destruction fix, some thoughts about where to store contact settings (omemo enable status for instance) --- core/account.cpp | 38 +++-- core/account.h | 2 +- core/conference.cpp | 144 +++++++----------- core/conference.h | 3 +- core/contact.cpp | 49 +++---- core/contact.h | 1 + core/handlers/messagehandler.cpp | 16 +- core/handlers/rosterhandler.cpp | 242 +++++++++++-------------------- core/handlers/rosterhandler.h | 3 +- core/handlers/vcardhandler.cpp | 2 +- core/rosteritem.cpp | 162 +++++++++++---------- core/rosteritem.h | 23 ++- core/storage/archive.cpp | 38 ++++- core/storage/archive.h | 5 +- translations/CMakeLists.txt | 4 +- 15 files changed, 352 insertions(+), 380 deletions(-) diff --git a/core/account.cpp b/core/account.cpp index 165dfd8..3e713c4 100644 --- a/core/account.cpp +++ b/core/account.cpp @@ -44,6 +44,7 @@ Account::Account(const QString& p_login, const QString& p_server, const QString& #endif #if (QXMPP_VERSION) >= QT_VERSION_CHECK(1, 5, 0) cm(new QXmppCarbonManagerV2()), + psm(new QXmppPubSubManager()), #else cm(new QXmppCarbonManager()), #endif @@ -55,7 +56,6 @@ Account::Account(const QString& p_login, const QString& p_server, const QString& um(new QXmppUploadRequestManager()), dm(client.findExtension()), rcpm(new QXmppMessageReceiptManager()), - psm(new QXmppPubSubManager()), reconnectScheduled(false), reconnectTimer(new QTimer), network(p_net), @@ -167,22 +167,34 @@ Account::~Account() { QObject::disconnect(network, &NetworkAccess::downloadFileComplete, mh, &MessageHandler::onDownloadFileComplete); QObject::disconnect(network, &NetworkAccess::loadFileError, mh, &MessageHandler::onLoadFileError); - delete vh; - delete mh; - delete rh; - + rh->clear(); //conferenses inside of roster handler hold QXmppMuc objects. + //If we destroy QXmppMucManager, then when we will be destroying RosterHandler + //it will try to destory Core::Conference objects + //and inside of those QXmppMuc objects will already be destroyed. + //So, clear will start the destruction from Core::Conference and this way it's not gonna crash + + delete delay; delete reconnectTimer; -#ifdef WITH_OMEMO - delete om; -#endif delete rcpm; - delete dm; delete um; delete bm; delete mm; delete am; delete cm; - delete delay; +#if (QXMPP_VERSION) >= QT_VERSION_CHECK(1, 5, 0) + delete psm; +#endif +#ifdef WITH_OMEMO + delete om; + delete tm; + delete oh; + delete th; +#endif + + delete dh; + delete vh; + delete rh; + delete mh; } Shared::ConnectionState Core::Account::getState() const { @@ -345,7 +357,7 @@ void Core::Account::onPresenceReceived(const QXmppPresence& p_presence) { vh->handlePresenceOfMyAccountChange(p_presence); } else { RosterItem* item = rh->getRosterItem(jid); - if (item != 0) + if (item != nullptr) item->handlePresence(p_presence); } @@ -417,7 +429,7 @@ void Core::Account::requestArchive(const QString& jid, int count, const QString& qDebug() << "An archive request for " << jid << ", before " << before; RosterItem* contact = rh->getRosterItem(jid); - if (contact == 0) { + if (contact == nullptr) { qDebug() << "An attempt to request archive for" << jid << "in account" << name << ", but the contact with such id wasn't found, skipping"; emit responseArchive(jid, std::list(), true); return; @@ -483,7 +495,7 @@ void Core::Account::onMamResultsReceived(const QString& queryId, const QXmppResu RosterItem* ri = rh->getRosterItem(jid); - if (ri != 0) { + if (ri != nullptr) { qDebug() << "Flushing messages for" << jid << ", complete:" << complete; ri->flushMessagesToArchive(complete, resultSetReply.first(), resultSetReply.last()); } diff --git a/core/account.h b/core/account.h index b257d2b..26365c1 100644 --- a/core/account.h +++ b/core/account.h @@ -200,6 +200,7 @@ private: #endif #if (QXMPP_VERSION) >= QT_VERSION_CHECK(1, 5, 0) QXmppCarbonManagerV2* cm; + QXmppPubSubManager* psm; #else QXmppCarbonManager* cm; #endif @@ -211,7 +212,6 @@ private: QXmppUploadRequestManager* um; QXmppDiscoveryManager* dm; QXmppMessageReceiptManager* rcpm; - QXmppPubSubManager* psm; bool reconnectScheduled; QTimer* reconnectTimer; diff --git a/core/conference.cpp b/core/conference.cpp index 2e49625..3904675 100644 --- a/core/conference.cpp +++ b/core/conference.cpp @@ -42,57 +42,48 @@ Core::Conference::Conference(const QString& p_jid, const QString& p_account, boo connect(room, &QXmppMucRoom::error, this, &Conference::onRoomError); room->setNickName(nick); - if (autoJoin) { + if (autoJoin) room->join(); - } archive->readAllResourcesAvatars(exParticipants); } -Core::Conference::~Conference() -{ - if (joined) { +Core::Conference::~Conference(){ + if (joined) room->leave(); - } + room->deleteLater(); } -QString Core::Conference::getNick() const -{ +QString Core::Conference::getNick() const { return nick; } -bool Core::Conference::getAutoJoin() -{ +bool Core::Conference::getAutoJoin() const { return autoJoin; } -bool Core::Conference::getJoined() const -{ +bool Core::Conference::getJoined() const { return joined; } -void Core::Conference::setJoined(bool p_joined) -{ +void Core::Conference::setJoined(bool p_joined) { if (joined != p_joined) { - if (p_joined) { + if (p_joined) room->join(); - } else { + else room->leave(); - } } } -void Core::Conference::setAutoJoin(bool p_autoJoin) -{ +void Core::Conference::setAutoJoin(bool p_autoJoin) { if (autoJoin != p_autoJoin) { autoJoin = p_autoJoin; emit autoJoinChanged(autoJoin); } } -void Core::Conference::setNick(const QString& p_nick) -{ +void Core::Conference::setNick(const QString& p_nick) { if (nick != p_nick) { if (joined) { room->setNickName(p_nick); @@ -103,45 +94,38 @@ void Core::Conference::setNick(const QString& p_nick) } } -void Core::Conference::onRoomJoined() -{ +void Core::Conference::onRoomJoined() { joined = true; emit joinedChanged(joined); } -void Core::Conference::onRoomLeft() -{ +void Core::Conference::onRoomLeft() { joined = false; emit joinedChanged(joined); } -void Core::Conference::onRoomNameChanged(const QString& p_name) -{ +void Core::Conference::onRoomNameChanged(const QString& p_name) { setName(p_name); } -void Core::Conference::onRoomNickNameChanged(const QString& p_nick) -{ +void Core::Conference::onRoomNickNameChanged(const QString& p_nick) { if (p_nick != nick) { nick = p_nick; emit nickChanged(nick); } } -void Core::Conference::onRoomError(const QXmppStanza::Error& err) -{ +void Core::Conference::onRoomError(const QXmppStanza::Error& err) { qDebug() << "MUC" << jid << "error:" << err.text(); } -void Core::Conference::onRoomParticipantAdded(const QString& p_name) -{ +void Core::Conference::onRoomParticipantAdded(const QString& p_name) { QStringList comps = p_name.split("/"); QString resource = comps.back(); QXmppPresence pres = room->participantPresence(p_name); QXmppMucItem mi = pres.mucItem(); - if (resource == jid) { + if (resource == jid) resource = ""; - } std::map::const_iterator itr = exParticipants.find(resource); bool hasAvatar = itr != exParticipants.end(); @@ -166,19 +150,7 @@ void Core::Conference::onRoomParticipantAdded(const QString& p_name) ) } }; - - if (hasAvatar) { - if (itr->second.autogenerated) { - cData.insert("avatarState", static_cast(Shared::Avatar::valid)); - } else { - cData.insert("avatarState", static_cast(Shared::Avatar::autocreated)); - } - cData.insert("avatarPath", avatarPath(resource) + "." + itr->second.type); - } else { - cData.insert("avatarState", static_cast(Shared::Avatar::empty)); - cData.insert("avatarPath", ""); - emit requestVCard(p_name); - } + careAboutAvatar(hasAvatar, itr->second, cData, resource, p_name); emit addParticipant(resource, cData); } @@ -196,9 +168,9 @@ void Core::Conference::onRoomParticipantAdded(const QString& p_name) break; case QXmppPresence::VCardUpdateValidPhoto:{ //there is a photo, need to load if (hasAvatar) { - if (itr->second.autogenerated || itr->second.hash != pres.photoHash()) { + if (itr->second.autogenerated || itr->second.hash != pres.photoHash()) emit requestVCard(p_name); - } + } else { emit requestVCard(p_name); } @@ -207,8 +179,7 @@ void Core::Conference::onRoomParticipantAdded(const QString& p_name) } } -void Core::Conference::onRoomParticipantChanged(const QString& p_name) -{ +void Core::Conference::onRoomParticipantChanged(const QString& p_name) { QStringList comps = p_name.split("/"); QString resource = comps.back(); QXmppPresence pres = room->participantPresence(p_name); @@ -216,9 +187,8 @@ void Core::Conference::onRoomParticipantChanged(const QString& p_name) handlePresence(pres); if (resource != jid) { QDateTime lastInteraction = pres.lastUserInteraction(); - if (!lastInteraction.isValid()) { + if (!lastInteraction.isValid()) lastInteraction = QDateTime::currentDateTimeUtc(); - } emit changeParticipant(resource, { {"lastActivity", lastInteraction}, @@ -237,8 +207,7 @@ void Core::Conference::onRoomParticipantChanged(const QString& p_name) } } -void Core::Conference::onRoomParticipantRemoved(const QString& p_name) -{ +void Core::Conference::onRoomParticipantRemoved(const QString& p_name) { QStringList comps = p_name.split("/"); QString resource = comps.back(); if (resource == jid) { @@ -248,29 +217,24 @@ void Core::Conference::onRoomParticipantRemoved(const QString& p_name) } } -QString Core::Conference::getSubject() const -{ - if (joined) { +QString Core::Conference::getSubject() const { + if (joined) return room->subject(); - } else { + else return ""; - } } -void Core::Conference::onRoomSubjectChanged(const QString& p_name) -{ +void Core::Conference::onRoomSubjectChanged(const QString& p_name) { emit subjectChanged(p_name); } -void Core::Conference::handlePresence(const QXmppPresence& pres) -{ +void Core::Conference::handlePresence(const QXmppPresence& pres) { QString id = pres.from(); QStringList comps = id.split("/"); QString jid = comps.front(); QString resource(""); - if (comps.size() > 1) { + if (comps.size() > 1) resource = comps.back(); - } switch (pres.vCardUpdateType()) { case QXmppPresence::VCardUpdateNone: //this presence has nothing to do with photo @@ -284,14 +248,13 @@ void Core::Conference::handlePresence(const QXmppPresence& pres) setAutoGeneratedAvatar(resource); } } - break; + break; case QXmppPresence::VCardUpdateValidPhoto:{ //there is a photo, need to load Archive::AvatarInfo info; bool hasAvatar = readAvatarInfo(info, resource); if (hasAvatar) { - if (info.autogenerated || info.hash != pres.photoHash()) { + if (info.autogenerated || info.hash != pres.photoHash()) emit requestVCard(id); - } } else { emit requestVCard(id); } @@ -300,17 +263,15 @@ void Core::Conference::handlePresence(const QXmppPresence& pres) } } -bool Core::Conference::setAutoGeneratedAvatar(const QString& resource) -{ +bool Core::Conference::setAutoGeneratedAvatar(const QString& resource) { Archive::AvatarInfo newInfo; bool result = RosterItem::setAutoGeneratedAvatar(newInfo, resource); if (result && resource.size() != 0) { std::map::iterator itr = exParticipants.find(resource); - if (itr == exParticipants.end()) { + if (itr == exParticipants.end()) exParticipants.insert(std::make_pair(resource, newInfo)); - } else { + else itr->second = newInfo; - } emit changeParticipant(resource, { {"avatarState", static_cast(Shared::Avatar::autocreated)}, {"avatarPath", avatarPath(resource) + "." + newInfo.type} @@ -320,17 +281,15 @@ bool Core::Conference::setAutoGeneratedAvatar(const QString& resource) return result; } -bool Core::Conference::setAvatar(const QByteArray& data, Archive::AvatarInfo& info, const QString& resource) -{ +bool Core::Conference::setAvatar(const QByteArray& data, Archive::AvatarInfo& info, const QString& resource) { bool result = RosterItem::setAvatar(data, info, resource); if (result && resource.size() != 0) { if (data.size() > 0) { std::map::iterator itr = exParticipants.find(resource); - if (itr == exParticipants.end()) { + if (itr == exParticipants.end()) exParticipants.insert(std::make_pair(resource, info)); - } else { + else itr->second = info; - } emit changeParticipant(resource, { {"avatarState", static_cast(Shared::Avatar::autocreated)}, @@ -338,9 +297,8 @@ bool Core::Conference::setAvatar(const QByteArray& data, Archive::AvatarInfo& in }); } else { std::map::iterator itr = exParticipants.find(resource); - if (itr != exParticipants.end()) { + if (itr != exParticipants.end()) exParticipants.erase(itr); - } emit changeParticipant(resource, { {"avatarState", static_cast(Shared::Avatar::empty)}, @@ -353,10 +311,8 @@ bool Core::Conference::setAvatar(const QByteArray& data, Archive::AvatarInfo& in return result; } -void Core::Conference::handleResponseVCard(const QXmppVCardIq& card, const QString &resource, Shared::VCard& out) -{ +void Core::Conference::handleResponseVCard(const QXmppVCardIq& card, const QString &resource, Shared::VCard& out) { RosterItem::handleResponseVCard(card, resource, out); - if (resource.size() > 0) { emit changeParticipant(resource, { {"avatarState", static_cast(out.getAvatarType())}, @@ -365,11 +321,21 @@ void Core::Conference::handleResponseVCard(const QXmppVCardIq& card, const QStri } } -QMap Core::Conference::getAllAvatars() const -{ +QMap Core::Conference::getAllAvatars() const { QMap result; - for (const std::pair& pair : exParticipants) { + for (const std::pair& pair : exParticipants) result.insert(pair.first, avatarPath(pair.first) + "." + pair.second.type); - } return result; } + +QMap Core::Conference::getInfo() const { + QMap data = RosterItem::getInfo(); + + data.insert("autoJoin", getAutoJoin()); + data.insert("joined", getJoined()); + data.insert("nick", getNick()); + data.insert("avatars", getAllAvatars()); + + return data; +} + diff --git a/core/conference.h b/core/conference.h index 00ade47..3c077e3 100644 --- a/core/conference.h +++ b/core/conference.h @@ -49,12 +49,13 @@ public: bool getJoined() const; void setJoined(bool p_joined); - bool getAutoJoin(); + bool getAutoJoin() const; void setAutoJoin(bool p_autoJoin); void handlePresence(const QXmppPresence & pres) override; bool setAutoGeneratedAvatar(const QString& resource = "") override; void handleResponseVCard(const QXmppVCardIq & card, const QString &resource, Shared::VCard& out) override; QMap getAllAvatars() const; + QMap getInfo() const override; signals: void nickChanged(const QString& nick); diff --git a/core/contact.cpp b/core/contact.cpp index 3030f4d..93139ef 100644 --- a/core/contact.cpp +++ b/core/contact.cpp @@ -24,54 +24,43 @@ Core::Contact::Contact(const QString& pJid, const QString& account, QObject* par groups(), subscriptionState(Shared::SubscriptionState::unknown), pep(Shared::Support::unknown) -{ -} +{} -Core::Contact::~Contact() -{ -} +Core::Contact::~Contact() {} -QSet Core::Contact::getGroups() const -{ +QSet Core::Contact::getGroups() const { return groups; } -unsigned int Core::Contact::groupsCount() const -{ +unsigned int Core::Contact::groupsCount() const { return groups.size(); } -void Core::Contact::setGroups(const QSet& set) -{ +void Core::Contact::setGroups(const QSet& set) { QSet toRemove = groups - set; QSet toAdd = set - groups; groups = set; - for (QSet::iterator itr = toRemove.begin(), end = toRemove.end(); itr != end; ++itr) { - emit groupRemoved(*itr); - } + for (const QString& group : toRemove) + emit groupRemoved(group); - for (QSet::iterator itr = toAdd.begin(), end = toAdd.end(); itr != end; ++itr) { - emit groupAdded(*itr); - } + for (const QString& group : toAdd) + emit groupAdded(group); } -Shared::SubscriptionState Core::Contact::getSubscriptionState() const -{ +Shared::SubscriptionState Core::Contact::getSubscriptionState() const { return subscriptionState; } -void Core::Contact::setSubscriptionState(Shared::SubscriptionState state) -{ +void Core::Contact::setSubscriptionState(Shared::SubscriptionState state) { if (subscriptionState != state) { subscriptionState = state; emit subscriptionStateChanged(subscriptionState); } } -void Core::Contact::handlePresence(const QXmppPresence& pres) -{ +void Core::Contact::handlePresence(const QXmppPresence& pres) { switch (pres.vCardUpdateType()) { case QXmppPresence::VCardUpdateNone: //this presence has nothing to do with photo break; @@ -101,13 +90,21 @@ void Core::Contact::handlePresence(const QXmppPresence& pres) } void Core::Contact::setPepSupport(Shared::Support support) { - if (pep != support) { + if (pep != support) pep = support; - } } Shared::Support Core::Contact::getPepSupport() const { - return pep;} + return pep; +} + +QMap Core::Contact::getInfo() const { + QMap data = RosterItem::getInfo(); + + data.insert("state", QVariant::fromValue(subscriptionState)); + + return data; +} diff --git a/core/contact.h b/core/contact.h index 01c082f..bde95f2 100644 --- a/core/contact.h +++ b/core/contact.h @@ -45,6 +45,7 @@ public: Shared::Support getPepSupport() const; void handlePresence(const QXmppPresence & pres) override; + QMap getInfo() const override; signals: void groupAdded(const QString& name); diff --git a/core/handlers/messagehandler.cpp b/core/handlers/messagehandler.cpp index 2c5b16d..020ab6f 100644 --- a/core/handlers/messagehandler.cpp +++ b/core/handlers/messagehandler.cpp @@ -83,7 +83,7 @@ void Core::MessageHandler::onMessageReceived(const QXmppMessage& msg) {"state", static_cast(Shared::Message::State::error)}, {"errorText", msg.error().text()} }; - if (cnt != 0) { + if (cnt != nullptr) { cnt->changeMessage(id, cData); } emit acc->changeMessage(jid, id, cData); @@ -291,7 +291,7 @@ void Core::MessageHandler::onReceiptReceived(const QString& jid, const QString& QMap cData = {{"state", static_cast(Shared::Message::State::delivered)}}; RosterItem* ri = acc->rh->getRosterItem(std::get<2>(ids)); - if (ri != 0) { + if (ri != nullptr) { ri->changeMessage(std::get<1>(ids), cData); } emit acc->changeMessage(std::get<2>(ids), std::get<1>(ids), cData); @@ -346,7 +346,7 @@ void Core::MessageHandler::performSending(Shared::Message data, const QString& o } else { realId = id; } - if (ri != 0) { + if (ri != nullptr) { if (newMessage) { ri->appendMessageToArchive(data); } else { @@ -429,7 +429,7 @@ void Core::MessageHandler::prepareUpload(const Shared::Message& data, bool newMe QString jid = data.getPenPalJid(); QString id = data.getId(); RosterItem* ri = acc->rh->getRosterItem(jid); - if (!ri) { + if (ri == nullptr) { qDebug() << "An attempt to initialize upload in" << acc->name << "for pal" << jid << "but the object for this pal wasn't found, something went terrebly wrong, skipping send"; return; } @@ -517,7 +517,7 @@ void Core::MessageHandler::onDownloadFileComplete(const std::listgetName()) { RosterItem* cnt = acc->rh->getRosterItem(info.jid); - if (cnt != 0) { + if (cnt != nullptr) { if (cnt->changeMessage(info.messageId, cData)) { emit acc->changeMessage(info.jid, info.messageId, cData); } @@ -553,7 +553,7 @@ void Core::MessageHandler::onUploadFileComplete(const std::listgetName()) { RosterItem* ri = acc->rh->getRosterItem(info.jid); - if (ri != 0) { + if (ri != nullptr) { Shared::Message msg = ri->getMessage(info.messageId); msg.setAttachPath(path); sendMessageWithLocalUploadedFile(msg, url, false); @@ -584,7 +584,7 @@ static const std::set allowedToChangeKeys({ void Core::MessageHandler::requestChangeMessage(const QString& jid, const QString& messageId, const QMap& data) { RosterItem* cnt = acc->rh->getRosterItem(jid); - if (cnt != 0) { + if (cnt != nullptr) { bool allSupported = true; QString unsupportedString; for (QMap::const_iterator itr = data.begin(); itr != data.end(); ++itr) { //I need all this madness @@ -607,7 +607,7 @@ void Core::MessageHandler::requestChangeMessage(const QString& jid, const QStrin void Core::MessageHandler::resendMessage(const QString& jid, const QString& id) { RosterItem* cnt = acc->rh->getRosterItem(jid); - if (cnt != 0) { + if (cnt != nullptr) { try { Shared::Message msg = cnt->getMessage(id); if (msg.getState() == Shared::Message::State::error) { diff --git a/core/handlers/rosterhandler.cpp b/core/handlers/rosterhandler.cpp index cccd47d..3738d2c 100644 --- a/core/handlers/rosterhandler.cpp +++ b/core/handlers/rosterhandler.cpp @@ -41,19 +41,23 @@ void Core::RosterHandler::initialize() { connect(acc, &Account::pepSupportChanged, this, &RosterHandler::onPepSupportedChanged); } -Core::RosterHandler::~RosterHandler() -{ - for (std::map::const_iterator itr = contacts.begin(), end = contacts.end(); itr != end; ++itr) { - delete itr->second; - } - - for (std::map::const_iterator itr = conferences.begin(), end = conferences.end(); itr != end; ++itr) { - delete itr->second; - } +Core::RosterHandler::~RosterHandler() { + clear(); } -void Core::RosterHandler::onRosterReceived() -{ +void Core::RosterHandler::clear() { + for (const std::pair& pair : contacts) + delete pair.second; + + for (const std::pair& pair : conferences) + delete pair.second; + + contacts.clear(); + conferences.clear(); +} + + +void Core::RosterHandler::onRosterReceived() { QStringList bj = acc->rm->getRosterBareJids(); for (int i = 0; i < bj.size(); ++i) { const QString& jid = bj[i]; @@ -61,8 +65,7 @@ void Core::RosterHandler::onRosterReceived() } } -void Core::RosterHandler::onRosterItemAdded(const QString& bareJid) -{ +void Core::RosterHandler::onRosterItemAdded(const QString& bareJid) { QString lcJid = bareJid.toLower(); addedAccount(lcJid); std::map::const_iterator itr = queuedContacts.find(lcJid); @@ -72,8 +75,7 @@ void Core::RosterHandler::onRosterItemAdded(const QString& bareJid) } } -void Core::RosterHandler::addedAccount(const QString& jid) -{ +void Core::RosterHandler::addedAccount(const QString& jid) { std::map::const_iterator itr = contacts.find(jid); QXmppRosterIq::Item re = acc->rm->getRosterEntry(jid); Contact* contact; @@ -82,7 +84,6 @@ void Core::RosterHandler::addedAccount(const QString& jid) newContact = true; contact = new Contact(jid, acc->name); contacts.insert(std::make_pair(jid, contact)); - } else { contact = itr->second; } @@ -94,12 +95,7 @@ void Core::RosterHandler::addedAccount(const QString& jid) contact->setName(re.name()); if (newContact) { - QMap cData({ - {"name", re.name()}, - {"state", QVariant::fromValue(state)} - }); - - careAboutAvatar(contact, cData); + QMap cData = contact->getInfo(); int grCount = 0; for (QSet::const_iterator itr = gr.begin(), end = gr.end(); itr != end; ++itr) { const QString& groupName = *itr; @@ -108,9 +104,9 @@ void Core::RosterHandler::addedAccount(const QString& jid) grCount++; } - if (grCount == 0) { + if (grCount == 0) emit acc->addContact(jid, "", cData); - } + if (acc->pepSupport == Shared::Support::supported) { acc->dm->requestInfo(jid); //acc->dm->requestItems(jid); @@ -119,49 +115,22 @@ void Core::RosterHandler::addedAccount(const QString& jid) } } -void Core::RosterHandler::addNewRoom(const QString& jid, const QString& nick, const QString& roomName, bool autoJoin) -{ +void Core::RosterHandler::addNewRoom(const QString& jid, const QString& nick, const QString& roomName, bool autoJoin) { QXmppMucRoom* room = acc->mm->addRoom(jid); QString lNick = nick; - if (lNick.size() == 0) { + if (lNick.size() == 0) lNick = acc->getName(); - } + Conference* conf = new Conference(jid, acc->getName(), autoJoin, roomName, lNick, room); conferences.insert(std::make_pair(jid, conf)); handleNewConference(conf); - QMap cData = { - {"autoJoin", conf->getAutoJoin()}, - {"joined", conf->getJoined()}, - {"nick", conf->getNick()}, - {"name", conf->getName()}, - {"avatars", conf->getAllAvatars()} - }; - careAboutAvatar(conf, cData); + QMap cData = conf->getInfo(); emit acc->addRoom(jid, cData); } -void Core::RosterHandler::careAboutAvatar(Core::RosterItem* item, QMap& data) -{ - Archive::AvatarInfo info; - bool hasAvatar = item->readAvatarInfo(info); - if (hasAvatar) { - if (info.autogenerated) { - data.insert("avatarState", QVariant::fromValue(Shared::Avatar::autocreated)); - } else { - data.insert("avatarState", QVariant::fromValue(Shared::Avatar::valid)); - } - data.insert("avatarPath", item->avatarPath() + "." + info.type); - } else { - data.insert("avatarState", QVariant::fromValue(Shared::Avatar::empty)); - data.insert("avatarPath", ""); - acc->delay->requestVCard(item->jid); - } -} - -void Core::RosterHandler::addContactRequest(const QString& jid, const QString& name, const QSet& groups) -{ +void Core::RosterHandler::addContactRequest(const QString& jid, const QString& name, const QSet& groups) { if (acc->state == Shared::ConnectionState::connected) { std::map::const_iterator itr = queuedContacts.find(jid); if (itr != queuedContacts.end()) { @@ -175,8 +144,7 @@ void Core::RosterHandler::addContactRequest(const QString& jid, const QString& n } } -void Core::RosterHandler::removeContactRequest(const QString& jid) -{ +void Core::RosterHandler::removeContactRequest(const QString& jid) { QString lcJid = jid.toLower(); if (acc->state == Shared::ConnectionState::connected) { std::set::const_iterator itr = outOfRosterContacts.find(lcJid); @@ -191,25 +159,23 @@ void Core::RosterHandler::removeContactRequest(const QString& jid) } } -void Core::RosterHandler::handleNewRosterItem(Core::RosterItem* contact) -{ +void Core::RosterHandler::handleNewRosterItem(Core::RosterItem* contact) { connect(contact, &RosterItem::needHistory, this->acc, &Account::onContactNeedHistory); connect(contact, &RosterItem::historyResponse, this->acc, &Account::onContactHistoryResponse); connect(contact, &RosterItem::nameChanged, this, &RosterHandler::onContactNameChanged); connect(contact, &RosterItem::avatarChanged, this, &RosterHandler::onContactAvatarChanged); + connect(contact, &RosterItem::encryptionChanged, this, &RosterHandler::onContactEncryptionChanged); connect(contact, &RosterItem::requestVCard, acc->delay, &DelayManager::Manager::getVCard); } -void Core::RosterHandler::handleNewContact(Core::Contact* contact) -{ +void Core::RosterHandler::handleNewContact(Core::Contact* contact) { handleNewRosterItem(contact); connect(contact, &Contact::groupAdded, this, &RosterHandler::onContactGroupAdded); connect(contact, &Contact::groupRemoved, this, &RosterHandler::onContactGroupRemoved); connect(contact, &Contact::subscriptionStateChanged, this, &RosterHandler::onContactSubscriptionStateChanged); } -void Core::RosterHandler::handleNewConference(Core::Conference* contact) -{ +void Core::RosterHandler::handleNewConference(Core::Conference* contact) { handleNewRosterItem(contact); connect(contact, &Conference::nickChanged, this, &RosterHandler::onMucNickNameChanged); connect(contact, &Conference::subjectChanged, this, &RosterHandler::onMucSubjectChanged); @@ -220,34 +186,27 @@ void Core::RosterHandler::handleNewConference(Core::Conference* contact) connect(contact, &Conference::removeParticipant, this, &RosterHandler::onMucRemoveParticipant); } -void Core::RosterHandler::onMucAddParticipant(const QString& nickName, const QMap& data) -{ +void Core::RosterHandler::onMucAddParticipant(const QString& nickName, const QMap& data) { Conference* room = static_cast(sender()); emit acc->addRoomParticipant(room->jid, nickName, data); } -void Core::RosterHandler::onMucChangeParticipant(const QString& nickName, const QMap& data) -{ +void Core::RosterHandler::onMucChangeParticipant(const QString& nickName, const QMap& data) { Conference* room = static_cast(sender()); emit acc->changeRoomParticipant(room->jid, nickName, data); } -void Core::RosterHandler::onMucRemoveParticipant(const QString& nickName) -{ +void Core::RosterHandler::onMucRemoveParticipant(const QString& nickName) { Conference* room = static_cast(sender()); emit acc->removeRoomParticipant(room->jid, nickName); } -void Core::RosterHandler::onMucSubjectChanged(const QString& subject) -{ +void Core::RosterHandler::onMucSubjectChanged(const QString& subject) { Conference* room = static_cast(sender()); - emit acc->changeRoom(room->jid, { - {"subject", subject} - }); + emit acc->changeRoom(room->jid, {{"subject", subject}}); } -void Core::RosterHandler::onContactGroupAdded(const QString& group) -{ +void Core::RosterHandler::onContactGroupAdded(const QString& group) { Contact* contact = static_cast(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 @@ -255,14 +214,14 @@ void Core::RosterHandler::onContactGroupAdded(const QString& group) QMap cData({ {"name", contact->getName()}, - {"state", QVariant::fromValue(contact->getSubscriptionState())} + {"state", QVariant::fromValue(contact->getSubscriptionState())}, + {"encryption", contact->isEncryptionEnabled()} }); addToGroup(contact->jid, group); emit acc->addContact(contact->jid, group, cData); } -void Core::RosterHandler::onContactGroupRemoved(const QString& group) -{ +void Core::RosterHandler::onContactGroupRemoved(const QString& group) { Contact* contact = static_cast(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 @@ -272,17 +231,17 @@ void Core::RosterHandler::onContactGroupRemoved(const QString& group) removeFromGroup(contact->jid, group); } -void Core::RosterHandler::onContactNameChanged(const QString& cname) -{ - Contact* contact = static_cast(sender()); - QMap cData({ - {"name", cname}, - }); - emit acc->changeContact(contact->jid, cData); +void Core::RosterHandler::onContactNameChanged(const QString& cname) { + RosterItem* contact = static_cast(sender()); + emit acc->changeContact(contact->jid, {{"name", cname}}); } -void Core::RosterHandler::onContactSubscriptionStateChanged(Shared::SubscriptionState cstate) -{ +void Core::RosterHandler::onContactEncryptionChanged(bool value) { + RosterItem* contact = static_cast(sender()); + emit acc->changeContact(contact->jid, {{"encryption", value}}); +} + +void Core::RosterHandler::onContactSubscriptionStateChanged(Shared::SubscriptionState cstate) { Contact* contact = static_cast(sender()); QMap cData({ {"state", QVariant::fromValue(cstate)}, @@ -290,8 +249,7 @@ void Core::RosterHandler::onContactSubscriptionStateChanged(Shared::Subscription emit acc->changeContact(contact->jid, cData); } -void Core::RosterHandler::addToGroup(const QString& jid, const QString& group) -{ +void Core::RosterHandler::addToGroup(const QString& jid, const QString& group) { std::map>::iterator gItr = groups.find(group); if (gItr == groups.end()) { gItr = groups.insert(std::make_pair(group, std::set())).first; @@ -300,8 +258,7 @@ void Core::RosterHandler::addToGroup(const QString& jid, const QString& group) gItr->second.insert(jid.toLower()); } -void Core::RosterHandler::removeFromGroup(const QString& jid, const QString& group) -{ +void Core::RosterHandler::removeFromGroup(const QString& jid, const QString& group) { QSet toRemove; std::map>::iterator itr = groups.find(group); if (itr == groups.end()) { @@ -319,24 +276,21 @@ void Core::RosterHandler::removeFromGroup(const QString& jid, const QString& gro } } -Core::RosterItem * Core::RosterHandler::getRosterItem(const QString& jid) -{ - RosterItem* item = 0; +Core::RosterItem * Core::RosterHandler::getRosterItem(const QString& jid) { + RosterItem* item = nullptr; QString lcJid = jid.toLower(); std::map::const_iterator citr = contacts.find(lcJid); if (citr != contacts.end()) { item = citr->second; } else { std::map::const_iterator coitr = conferences.find(lcJid); - if (coitr != conferences.end()) { + if (coitr != conferences.end()) item = coitr->second; - } } return item; } -Core::Conference * Core::RosterHandler::getConference(const QString& jid) -{ +Core::Conference * Core::RosterHandler::getConference(const QString& jid) { Conference* item = 0; std::map::const_iterator coitr = conferences.find(jid.toLower()); if (coitr != conferences.end()) { @@ -345,8 +299,7 @@ Core::Conference * Core::RosterHandler::getConference(const QString& jid) return item; } -Core::Contact * Core::RosterHandler::getContact(const QString& jid) -{ +Core::Contact * Core::RosterHandler::getContact(const QString& jid) { Contact* item = 0; std::map::const_iterator citr = contacts.find(jid.toLower()); if (citr != contacts.end()) { @@ -355,22 +308,21 @@ Core::Contact * Core::RosterHandler::getContact(const QString& jid) return item; } -Core::Contact * Core::RosterHandler::addOutOfRosterContact(const QString& jid) -{ +Core::Contact * Core::RosterHandler::addOutOfRosterContact(const QString& jid) { QString lcJid = jid.toLower(); Contact* cnt = new Contact(lcJid, acc->name); contacts.insert(std::make_pair(lcJid, cnt)); outOfRosterContacts.insert(lcJid); cnt->setSubscriptionState(Shared::SubscriptionState::unknown); emit acc->addContact(lcJid, "", QMap({ - {"state", QVariant::fromValue(Shared::SubscriptionState::unknown)} + {"state", QVariant::fromValue(Shared::SubscriptionState::unknown)}, + {"encryption", false} })); handleNewContact(cnt); return cnt; } -void Core::RosterHandler::onRosterItemChanged(const QString& bareJid) -{ +void Core::RosterHandler::onRosterItemChanged(const QString& bareJid) { QString lcJid = bareJid.toLower(); std::map::const_iterator itr = contacts.find(lcJid); if (itr == contacts.end()) { @@ -387,8 +339,7 @@ void Core::RosterHandler::onRosterItemChanged(const QString& bareJid) contact->setName(re.name()); } -void Core::RosterHandler::onRosterItemRemoved(const QString& bareJid) -{ +void Core::RosterHandler::onRosterItemRemoved(const QString& bareJid) { QString lcJid = bareJid.toLower(); std::map::const_iterator itr = contacts.find(lcJid); if (itr == contacts.end()) { @@ -406,14 +357,12 @@ void Core::RosterHandler::onRosterItemRemoved(const QString& bareJid) contact->deleteLater(); } -void Core::RosterHandler::onMucRoomAdded(QXmppMucRoom* room) -{ +void Core::RosterHandler::onMucRoomAdded(QXmppMucRoom* room) { qDebug() << "room" << room->jid() << "added with name" << room->name() << ", account" << acc->getName() << "joined:" << room->isJoined(); } -void Core::RosterHandler::bookmarksReceived(const QXmppBookmarkSet& bookmarks) -{ +void Core::RosterHandler::bookmarksReceived(const QXmppBookmarkSet& bookmarks) { QList confs = bookmarks.conferences(); for (QList::const_iterator itr = confs.begin(), end = confs.end(); itr != end; ++itr) { const QXmppBookmarkConference& c = *itr; @@ -423,54 +372,42 @@ void Core::RosterHandler::bookmarksReceived(const QXmppBookmarkSet& bookmarks) if (cItr == conferences.end()) { addNewRoom(jid, c.nickName(), c.name(), c.autoJoin()); } else { - if (c.autoJoin()) { + if (c.autoJoin()) cItr->second->setJoined(true); - } else { + else cItr->second->setAutoJoin(false); - } } } } -void Core::RosterHandler::onMucJoinedChanged(bool joined) -{ +void Core::RosterHandler::onMucJoinedChanged(bool joined){ Conference* room = static_cast(sender()); - emit acc->changeRoom(room->jid, { - {"joined", joined} - }); + emit acc->changeRoom(room->jid, {{"joined", joined}}); } -void Core::RosterHandler::onMucAutoJoinChanged(bool autoJoin) -{ +void Core::RosterHandler::onMucAutoJoinChanged(bool autoJoin) { storeConferences(); Conference* room = static_cast(sender()); - emit acc->changeRoom(room->jid, { - {"autoJoin", autoJoin} - }); + emit acc->changeRoom(room->jid, {{"autoJoin", autoJoin}}); } -void Core::RosterHandler::onMucNickNameChanged(const QString& nickName) -{ +void Core::RosterHandler::onMucNickNameChanged(const QString& nickName){ storeConferences(); Conference* room = static_cast(sender()); - emit acc->changeRoom(room->jid, { - {"nick", nickName} - }); + emit acc->changeRoom(room->jid, {{"nick", nickName}}); } -Shared::SubscriptionState Core::RosterHandler::castSubscriptionState(QXmppRosterIq::Item::SubscriptionType qs) -{ +Shared::SubscriptionState Core::RosterHandler::castSubscriptionState(QXmppRosterIq::Item::SubscriptionType qs){ Shared::SubscriptionState state; - if (qs == QXmppRosterIq::Item::NotSet) { + if (qs == QXmppRosterIq::Item::NotSet) state = Shared::SubscriptionState::unknown; - } else { + else state = static_cast(qs); - } + return state; } -void Core::RosterHandler::storeConferences() -{ +void Core::RosterHandler::storeConferences() { QXmppBookmarkSet bms = acc->bm->bookmarks(); QList confs; for (std::map::const_iterator itr = conferences.begin(), end = conferences.end(); itr != end; ++itr) { @@ -486,8 +423,7 @@ void Core::RosterHandler::storeConferences() acc->bm->setBookmarks(bms); } -void Core::RosterHandler::clearConferences() -{ +void Core::RosterHandler::clearConferences() { for (std::map::const_iterator itr = conferences.begin(), end = conferences.end(); itr != end; itr++) { itr->second->deleteLater(); emit acc->removeRoom(itr->first); @@ -495,8 +431,7 @@ void Core::RosterHandler::clearConferences() conferences.clear(); } -void Core::RosterHandler::removeRoomRequest(const QString& jid) -{ +void Core::RosterHandler::removeRoomRequest(const QString& jid) { QString lcJid = jid.toLower(); std::map::const_iterator itr = conferences.find(lcJid); if (itr == conferences.end()) { @@ -508,8 +443,7 @@ void Core::RosterHandler::removeRoomRequest(const QString& jid) storeConferences(); } -void Core::RosterHandler::addRoomRequest(const QString& jid, const QString& nick, const QString& password, bool autoJoin) -{ +void Core::RosterHandler::addRoomRequest(const QString& jid, const QString& nick, const QString& password, bool autoJoin) { QString lcJid = jid.toLower(); std::map::const_iterator cItr = conferences.find(lcJid); if (cItr == conferences.end()) { @@ -520,8 +454,7 @@ void Core::RosterHandler::addRoomRequest(const QString& jid, const QString& nick } } -void Core::RosterHandler::addContactToGroupRequest(const QString& jid, const QString& groupName) -{ +void Core::RosterHandler::addContactToGroupRequest(const QString& jid, const QString& groupName) { QString lcJid = jid.toLower(); std::map::const_iterator itr = contacts.find(lcJid); if (itr == contacts.end()) { @@ -545,8 +478,7 @@ void Core::RosterHandler::addContactToGroupRequest(const QString& jid, const QSt } } -void Core::RosterHandler::removeContactFromGroupRequest(const QString& jid, const QString& groupName) -{ +void Core::RosterHandler::removeContactFromGroupRequest(const QString& jid, const QString& groupName) { QString lcJid = jid.toLower(); std::map::const_iterator itr = contacts.find(lcJid); if (itr == contacts.end()) { @@ -571,19 +503,17 @@ void Core::RosterHandler::removeContactFromGroupRequest(const QString& jid, cons } } -void Core::RosterHandler::onContactAvatarChanged(Shared::Avatar type, const QString& path) -{ +void Core::RosterHandler::onContactAvatarChanged(Shared::Avatar type, const QString& path) { RosterItem* item = static_cast(sender()); QMap cData({ - {"avatarState", static_cast(type)}, + {"avatarState", QVariant::fromValue(type)}, {"avatarPath", path} }); emit acc->changeContact(item->jid, cData); } -void Core::RosterHandler::handleOffline() -{ +void Core::RosterHandler::handleOffline() { for (const std::pair& pair : conferences) { pair.second->clearArchiveRequests(); pair.second->downgradeDatabaseState(); @@ -595,13 +525,11 @@ void Core::RosterHandler::handleOffline() } -void Core::RosterHandler::onPepSupportedChanged(Shared::Support support) -{ +void Core::RosterHandler::onPepSupportedChanged(Shared::Support support) { if (support == Shared::Support::supported) { for (const std::pair& pair : contacts) { - if (pair.second->getPepSupport() == Shared::Support::unknown) { + if (pair.second->getPepSupport() == Shared::Support::unknown) acc->dm->requestInfo(pair.first); - } } } } diff --git a/core/handlers/rosterhandler.h b/core/handlers/rosterhandler.h index 62a7b8b..63f291c 100644 --- a/core/handlers/rosterhandler.h +++ b/core/handlers/rosterhandler.h @@ -68,6 +68,7 @@ public: void clearConferences(); void initialize(); + void clear(); private slots: void onRosterReceived(); @@ -91,6 +92,7 @@ private slots: void onContactNameChanged(const QString& name); void onContactSubscriptionStateChanged(Shared::SubscriptionState state); void onContactAvatarChanged(Shared::Avatar, const QString& path); + void onContactEncryptionChanged(bool value); void onPepSupportedChanged(Shared::Support support); private: @@ -101,7 +103,6 @@ private: void handleNewRosterItem(Core::RosterItem* contact); void handleNewContact(Core::Contact* contact); void handleNewConference(Core::Conference* contact); - void careAboutAvatar(Core::RosterItem* item, QMap& data); static Shared::SubscriptionState castSubscriptionState(QXmppRosterIq::Item::SubscriptionType qs); diff --git a/core/handlers/vcardhandler.cpp b/core/handlers/vcardhandler.cpp index d4125e8..33b9c31 100644 --- a/core/handlers/vcardhandler.cpp +++ b/core/handlers/vcardhandler.cpp @@ -88,7 +88,7 @@ void Core::VCardHandler::onVCardReceived(const QXmppVCardIq& card) { } RosterItem* item = acc->rh->getRosterItem(jid); - if (item == 0) { + if (item == nullptr) { if (jid == acc->getBareJid()) onOwnVCardReceived(card); else diff --git a/core/rosteritem.cpp b/core/rosteritem.cpp index 0bac4a4..545e47f 100644 --- a/core/rosteritem.cpp +++ b/core/rosteritem.cpp @@ -41,39 +41,33 @@ Core::RosterItem::RosterItem(const QString& pJid, const QString& pAccount, QObje archive->open(account); if (archive->size() != 0) { - if (archive->isFromTheBeginning()) { + if (archive->isFromTheBeginning()) archiveState = beginning; - } else { + else archiveState = chunk; - } } } -Core::RosterItem::~RosterItem() -{ +Core::RosterItem::~RosterItem() { delete archive; } -Core::RosterItem::ArchiveState Core::RosterItem::getArchiveState() const -{ +Core::RosterItem::ArchiveState Core::RosterItem::getArchiveState() const { return archiveState; } -QString Core::RosterItem::getName() const -{ +QString Core::RosterItem::getName() const { return name; } -void Core::RosterItem::setName(const QString& n) -{ +void Core::RosterItem::setName(const QString& n) { if (name != n) { name = n; emit nameChanged(name); } } -void Core::RosterItem::addMessageToArchive(const Shared::Message& msg) -{ +void Core::RosterItem::addMessageToArchive(const Shared::Message& msg) { if (msg.storable()) { hisoryCache.push_back(msg); std::map::iterator itr = toCorrect.find(msg.getId()); @@ -87,8 +81,7 @@ void Core::RosterItem::addMessageToArchive(const Shared::Message& msg) } } -void Core::RosterItem::correctMessageInArchive(const QString& originalId, const Shared::Message& msg) -{ +void Core::RosterItem::correctMessageInArchive(const QString& originalId, const Shared::Message& msg) { if (msg.storable()) { QDateTime thisTime = msg.getTime(); std::map::iterator itr = toCorrect.find(originalId); @@ -109,8 +102,7 @@ void Core::RosterItem::correctMessageInArchive(const QString& originalId, const } } -void Core::RosterItem::requestHistory(int count, const QString& before) -{ +void Core::RosterItem::requestHistory(int count, const QString& before) { if (syncronizing) { requestCache.emplace_back(count, before); } else { @@ -118,8 +110,7 @@ void Core::RosterItem::requestHistory(int count, const QString& before) } } -void Core::RosterItem::nextRequest() -{ +void Core::RosterItem::nextRequest() { if (syncronizing) { if (requestedCount != -1) { bool last = false; @@ -157,8 +148,7 @@ void Core::RosterItem::nextRequest() } } -void Core::RosterItem::performRequest(int count, const QString& before) -{ +void Core::RosterItem::performRequest(int count, const QString& before) { syncronizing = true; requestedCount = count; requestedBefore = before; @@ -246,8 +236,7 @@ void Core::RosterItem::performRequest(int count, const QString& before) } } -QString Core::RosterItem::getId(const Shared::Message& msg) -{ +QString Core::RosterItem::getId(const Shared::Message& msg) { QString id; if (muc) { id = msg.getStanzaId(); @@ -257,8 +246,7 @@ QString Core::RosterItem::getId(const Shared::Message& msg) return id; } -void Core::RosterItem::appendMessageToArchive(const Shared::Message& msg) -{ +void Core::RosterItem::appendMessageToArchive(const Shared::Message& msg) { if (msg.getId().size() > 0) { if (msg.storable()) { switch (archiveState) { @@ -299,8 +287,7 @@ void Core::RosterItem::appendMessageToArchive(const Shared::Message& msg) } } -bool Core::RosterItem::changeMessage(const QString& id, const QMap& data) -{ +bool Core::RosterItem::changeMessage(const QString& id, const QMap& data) { bool found = false; for (Shared::Message& msg : appendCache) { if (msg.getId() == id) { @@ -341,8 +328,7 @@ bool Core::RosterItem::changeMessage(const QString& id, const QMap 0) { added = archive->addElements(hisoryCache); @@ -429,51 +415,43 @@ void Core::RosterItem::flushMessagesToArchive(bool finished, const QString& firs } } -QString Core::RosterItem::getServer() const -{ +QString Core::RosterItem::getServer() const { QStringList lst = jid.split("@"); return lst.back(); } -bool Core::RosterItem::isMuc() const -{ +bool Core::RosterItem::isMuc() const { return muc; } -QString Core::RosterItem::avatarPath(const QString& resource) const -{ +QString Core::RosterItem::avatarPath(const QString& resource) const { QString path = folderPath() + "/" + (resource.size() == 0 ? jid : resource); return path; } -QString Core::RosterItem::folderPath() const -{ +QString Core::RosterItem::folderPath() const { QString path(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)); path += "/" + account + "/" + jid; return path; } -bool Core::RosterItem::setAvatar(const QByteArray& data, Archive::AvatarInfo& info, const QString& resource) -{ +bool Core::RosterItem::setAvatar(const QByteArray& data, Archive::AvatarInfo& info, const QString& resource) { bool result = archive->setAvatar(data, info, false, resource); if (resource.size() == 0 && result) { - if (data.size() == 0) { + if (data.size() == 0) emit avatarChanged(Shared::Avatar::empty, ""); - } else { + else emit avatarChanged(Shared::Avatar::valid, avatarPath(resource) + "." + info.type); - } } return result; } -bool Core::RosterItem::setAutoGeneratedAvatar(const QString& resource) -{ +bool Core::RosterItem::setAutoGeneratedAvatar(const QString& resource) { Archive::AvatarInfo info; return setAutoGeneratedAvatar(info, resource); } -bool Core::RosterItem::setAutoGeneratedAvatar(Archive::AvatarInfo& info, const QString& resource) -{ +bool Core::RosterItem::setAutoGeneratedAvatar(Archive::AvatarInfo& info, const QString& resource) { QImage image(96, 96, QImage::Format_ARGB32_Premultiplied); QPainter painter(&image); quint8 colorIndex = rand() % Shared::colorPalette.size(); @@ -483,11 +461,11 @@ bool Core::RosterItem::setAutoGeneratedAvatar(Archive::AvatarInfo& info, const Q f.setBold(true); f.setPixelSize(72); painter.setFont(f); - if (bg.lightnessF() > 0.5) { + if (bg.lightnessF() > 0.5) painter.setPen(Qt::black); - } else { + else painter.setPen(Qt::white); - } + painter.drawText(image.rect(), Qt::AlignCenter | Qt::AlignVCenter, resource.size() == 0 ? jid.at(0).toUpper() : resource.at(0).toUpper()); QByteArray arr; QBuffer stream(&arr); @@ -495,19 +473,17 @@ bool Core::RosterItem::setAutoGeneratedAvatar(Archive::AvatarInfo& info, const Q image.save(&stream, "PNG"); stream.close(); bool result = archive->setAvatar(arr, info, true, resource); - if (resource.size() == 0 && result) { + if (resource.size() == 0 && result) emit avatarChanged(Shared::Avatar::autocreated, avatarPath(resource) + ".png"); - } + return result; } -bool Core::RosterItem::readAvatarInfo(Archive::AvatarInfo& target, const QString& resource) const -{ +bool Core::RosterItem::readAvatarInfo(Archive::AvatarInfo& target, const QString& resource) const { return archive->readAvatarInfo(target, resource); } -void Core::RosterItem::handleResponseVCard(const QXmppVCardIq& card, const QString& resource, Shared::VCard& vCard) -{ +void Core::RosterItem::handleResponseVCard(const QXmppVCardIq& card, const QString& resource, Shared::VCard& vCard) { Archive::AvatarInfo info; Archive::AvatarInfo newInfo; bool hasAvatar = readAvatarInfo(info, resource); @@ -532,9 +508,9 @@ void Core::RosterItem::handleResponseVCard(const QXmppVCardIq& card, const QStri } } } else { - if (!hasAvatar || !info.autogenerated) { + if (!hasAvatar || !info.autogenerated) setAutoGeneratedAvatar(resource); - } + type = Shared::Avatar::autocreated; path = avatarPath(resource) + ".png"; } @@ -542,13 +518,11 @@ void Core::RosterItem::handleResponseVCard(const QXmppVCardIq& card, const QStri vCard.setAvatarType(type); vCard.setAvatarPath(path); - if (resource.size() == 0) { + if (resource.size() == 0) emit avatarChanged(vCard.getAvatarType(), vCard.getAvatarPath()); - } } -void Core::RosterItem::clearArchiveRequests() -{ +void Core::RosterItem::clearArchiveRequests() { syncronizing = false; requestedCount = 0; requestedBefore = ""; @@ -564,30 +538,72 @@ void Core::RosterItem::clearArchiveRequests() requestCache.clear(); } -void Core::RosterItem::downgradeDatabaseState() -{ - if (archiveState == ArchiveState::complete) { +void Core::RosterItem::downgradeDatabaseState() { + if (archiveState == ArchiveState::complete) archiveState = ArchiveState::beginning; - } + - if (archiveState == ArchiveState::end) { + if (archiveState == ArchiveState::end) archiveState = ArchiveState::chunk; - } } -Shared::Message Core::RosterItem::getMessage(const QString& id) -{ +Shared::Message Core::RosterItem::getMessage(const QString& id) { for (const Shared::Message& msg : appendCache) { - if (msg.getId() == id) { + if (msg.getId() == id) return msg; - } } for (Shared::Message& msg : hisoryCache) { - if (msg.getId() == id) { + if (msg.getId() == id) return msg; - } } return archive->getElement(id); } + +bool Core::RosterItem::isEncryptionEnabled() const { + return archive->isEncryptionEnabled(); +} + +void Core::RosterItem::enableEncryption(bool value) { + bool changed = archive->setEncryptionEnabled(value); + if (changed) + emit encryptionChanged(value); +} + +QMap Core::RosterItem::getInfo() const { + QMap result({ + {"name", name}, + {"encryption", isEncryptionEnabled()}, + }); + Archive::AvatarInfo info; + bool hasAvatar = readAvatarInfo(info); + careAboutAvatar(hasAvatar, info, result); + + return result; +} + + +void Core::RosterItem::careAboutAvatar ( + bool hasAvatar, + const Archive::AvatarInfo& info, + QMap& output, + const QString& resource, + const QString& subject +) const { + if (hasAvatar) { + if (info.autogenerated) + output.insert("avatarState", QVariant::fromValue(Shared::Avatar::autocreated)); + else + output.insert("avatarState", QVariant::fromValue(Shared::Avatar::valid)); + + output.insert("avatarPath", avatarPath(resource) + "." + info.type); + } else { + output.insert("avatarState", QVariant::fromValue(Shared::Avatar::empty)); + output.insert("avatarPath", ""); + if (subject.size() == 0) + emit requestVCard(jid); + else + emit requestVCard(subject); + } +} diff --git a/core/rosteritem.h b/core/rosteritem.h index 7c82945..fa154c0 100644 --- a/core/rosteritem.h +++ b/core/rosteritem.h @@ -62,6 +62,8 @@ public: void setName(const QString& n); QString getServer() const; bool isMuc() const; + bool isEncryptionEnabled() const; + void enableEncryption(bool value = true); void addMessageToArchive(const Shared::Message& msg); void correctMessageInArchive(const QString& originalId, const Shared::Message& msg); @@ -78,16 +80,18 @@ public: bool changeMessage(const QString& id, const QMap& data); void clearArchiveRequests(); void downgradeDatabaseState(); + virtual QMap getInfo() const; Shared::Message getMessage(const QString& id); signals: - void nameChanged(const QString& name); - void subscriptionStateChanged(Shared::SubscriptionState state); - void historyResponse(const std::list& messages, bool last); - void needHistory(const QString& before, const QString& after, const QDateTime& afterTime = QDateTime()); - void avatarChanged(Shared::Avatar, const QString& path); - void requestVCard(const QString& jid); + void nameChanged(const QString& name) const; + void subscriptionStateChanged(Shared::SubscriptionState state) const; + void historyResponse(const std::list& messages, bool last) const; + void needHistory(const QString& before, const QString& after, const QDateTime& afterTime = QDateTime()) const; + void avatarChanged(Shared::Avatar, const QString& path) const; + void requestVCard(const QString& jid) const; + void encryptionChanged(bool value) const; public: const QString jid; @@ -96,6 +100,13 @@ public: protected: virtual bool setAvatar(const QByteArray& data, Archive::AvatarInfo& info, const QString& resource = ""); virtual bool setAutoGeneratedAvatar(Archive::AvatarInfo& info, const QString& resource = ""); + void careAboutAvatar( + bool hasAvatar, + const Archive::AvatarInfo& info, + QMap& output, + const QString& resource = "", + const QString& subject = "" + ) const; protected: QString name; diff --git a/core/storage/archive.cpp b/core/storage/archive.cpp index cb65a53..8330cff 100644 --- a/core/storage/archive.cpp +++ b/core/storage/archive.cpp @@ -29,6 +29,7 @@ Core::Archive::Archive(const QString& p_jid, QObject* parent): jid(p_jid), opened(false), fromTheBeginning(false), + encryptionEnabled(false), environment(), main(), order(), @@ -84,6 +85,12 @@ void Core::Archive::open(const QString& account) } catch (const NotFound& e) { fromTheBeginning = false; } + + try { + encryptionEnabled = getStatBoolValue("encryptionEnabled", txn); + } catch (const NotFound& e) { + encryptionEnabled = false; + } std::string sJid = jid.toStdString(); AvatarInfo info; @@ -603,7 +610,7 @@ std::list Core::Archive::getBefore(int count, const QString& id return res; } -bool Core::Archive::isFromTheBeginning() +bool Core::Archive::isFromTheBeginning() const { if (!opened) { throw Closed("isFromTheBeginning", jid.toStdString()); @@ -630,6 +637,35 @@ void Core::Archive::setFromTheBeginning(bool is) } } +bool Core::Archive::isEncryptionEnabled() const +{ + if (!opened) { + throw Closed("isEncryptionEnabled", jid.toStdString()); + } + return encryptionEnabled; +} + +bool Core::Archive::setEncryptionEnabled(bool is) +{ + if (!opened) { + throw Closed("setEncryptionEnabled", jid.toStdString()); + } + if (encryptionEnabled != is) { + encryptionEnabled = is; + + MDB_txn *txn; + mdb_txn_begin(environment, NULL, 0, &txn); + bool success = setStatValue("encryptionEnabled", is, txn); + if (success) { + mdb_txn_commit(txn); + return true; + } else { + mdb_txn_abort(txn); + } + } + return false; +} + QString Core::Archive::idByStanzaId(const QString& stanzaId) const { if (!opened) { diff --git a/core/storage/archive.h b/core/storage/archive.h index 47c62dc..ef10555 100644 --- a/core/storage/archive.h +++ b/core/storage/archive.h @@ -55,8 +55,10 @@ public: void clear(); long unsigned int size() const; std::list getBefore(int count, const QString& id); - bool isFromTheBeginning(); + bool isFromTheBeginning() const; void setFromTheBeginning(bool is); + bool isEncryptionEnabled() const; + bool setEncryptionEnabled(bool is); //returns true if changed, false otherwise bool setAvatar(const QByteArray& data, AvatarInfo& info, bool generated = false, const QString& resource = ""); AvatarInfo getAvatarInfo(const QString& resource = "") const; bool readAvatarInfo(AvatarInfo& target, const QString& resource = "") const; @@ -171,6 +173,7 @@ public: private: bool opened; bool fromTheBeginning; + bool encryptionEnabled; MDB_env* environment; MDB_dbi main; //id to message MDB_dbi order; //time to id diff --git a/translations/CMakeLists.txt b/translations/CMakeLists.txt index f70fe2b..6bdb6c9 100644 --- a/translations/CMakeLists.txt +++ b/translations/CMakeLists.txt @@ -1,11 +1,11 @@ -find_package(Qt5LinguistTools) +find_package(Qt${QT_VERSION_MAJOR}LinguistTools) set(TS_FILES squawk.en.ts squawk.ru.ts squawk.pt_BR.ts ) -qt5_add_translation(QM_FILES ${TS_FILES}) +qt_add_translation(QM_FILES ${TS_FILES}) add_custom_target(translations ALL DEPENDS ${QM_FILES}) install(FILES ${QM_FILES} DESTINATION ${CMAKE_INSTALL_DATADIR}/macaw.me/squawk/l10n)