Refactoring, account destruction fix, some thoughts about where to store contact settings (omemo enable status for instance)

This commit is contained in:
Blue 2023-03-16 22:38:05 +03:00
parent 283e9ebc4d
commit fffef9876a
Signed by: blue
GPG Key ID: 9B203B252A63EE38
15 changed files with 352 additions and 380 deletions

View File

@ -44,6 +44,7 @@ Account::Account(const QString& p_login, const QString& p_server, const QString&
#endif #endif
#if (QXMPP_VERSION) >= QT_VERSION_CHECK(1, 5, 0) #if (QXMPP_VERSION) >= QT_VERSION_CHECK(1, 5, 0)
cm(new QXmppCarbonManagerV2()), cm(new QXmppCarbonManagerV2()),
psm(new QXmppPubSubManager()),
#else #else
cm(new QXmppCarbonManager()), cm(new QXmppCarbonManager()),
#endif #endif
@ -55,7 +56,6 @@ Account::Account(const QString& p_login, const QString& p_server, const QString&
um(new QXmppUploadRequestManager()), um(new QXmppUploadRequestManager()),
dm(client.findExtension<QXmppDiscoveryManager>()), dm(client.findExtension<QXmppDiscoveryManager>()),
rcpm(new QXmppMessageReceiptManager()), rcpm(new QXmppMessageReceiptManager()),
psm(new QXmppPubSubManager()),
reconnectScheduled(false), reconnectScheduled(false),
reconnectTimer(new QTimer), reconnectTimer(new QTimer),
network(p_net), network(p_net),
@ -167,22 +167,34 @@ Account::~Account() {
QObject::disconnect(network, &NetworkAccess::downloadFileComplete, mh, &MessageHandler::onDownloadFileComplete); QObject::disconnect(network, &NetworkAccess::downloadFileComplete, mh, &MessageHandler::onDownloadFileComplete);
QObject::disconnect(network, &NetworkAccess::loadFileError, mh, &MessageHandler::onLoadFileError); QObject::disconnect(network, &NetworkAccess::loadFileError, mh, &MessageHandler::onLoadFileError);
delete vh; rh->clear(); //conferenses inside of roster handler hold QXmppMuc objects.
delete mh; //If we destroy QXmppMucManager, then when we will be destroying RosterHandler
delete rh; //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; delete reconnectTimer;
#ifdef WITH_OMEMO
delete om;
#endif
delete rcpm; delete rcpm;
delete dm;
delete um; delete um;
delete bm; delete bm;
delete mm; delete mm;
delete am; delete am;
delete cm; 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 { Shared::ConnectionState Core::Account::getState() const {
@ -345,7 +357,7 @@ void Core::Account::onPresenceReceived(const QXmppPresence& p_presence) {
vh->handlePresenceOfMyAccountChange(p_presence); vh->handlePresenceOfMyAccountChange(p_presence);
} else { } else {
RosterItem* item = rh->getRosterItem(jid); RosterItem* item = rh->getRosterItem(jid);
if (item != 0) if (item != nullptr)
item->handlePresence(p_presence); 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; qDebug() << "An archive request for " << jid << ", before " << before;
RosterItem* contact = rh->getRosterItem(jid); 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"; 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<Shared::Message>(), true); emit responseArchive(jid, std::list<Shared::Message>(), true);
return; return;
@ -483,7 +495,7 @@ void Core::Account::onMamResultsReceived(const QString& queryId, const QXmppResu
RosterItem* ri = rh->getRosterItem(jid); RosterItem* ri = rh->getRosterItem(jid);
if (ri != 0) { if (ri != nullptr) {
qDebug() << "Flushing messages for" << jid << ", complete:" << complete; qDebug() << "Flushing messages for" << jid << ", complete:" << complete;
ri->flushMessagesToArchive(complete, resultSetReply.first(), resultSetReply.last()); ri->flushMessagesToArchive(complete, resultSetReply.first(), resultSetReply.last());
} }

View File

@ -200,6 +200,7 @@ private:
#endif #endif
#if (QXMPP_VERSION) >= QT_VERSION_CHECK(1, 5, 0) #if (QXMPP_VERSION) >= QT_VERSION_CHECK(1, 5, 0)
QXmppCarbonManagerV2* cm; QXmppCarbonManagerV2* cm;
QXmppPubSubManager* psm;
#else #else
QXmppCarbonManager* cm; QXmppCarbonManager* cm;
#endif #endif
@ -211,7 +212,6 @@ private:
QXmppUploadRequestManager* um; QXmppUploadRequestManager* um;
QXmppDiscoveryManager* dm; QXmppDiscoveryManager* dm;
QXmppMessageReceiptManager* rcpm; QXmppMessageReceiptManager* rcpm;
QXmppPubSubManager* psm;
bool reconnectScheduled; bool reconnectScheduled;
QTimer* reconnectTimer; QTimer* reconnectTimer;

View File

@ -42,57 +42,48 @@ Core::Conference::Conference(const QString& p_jid, const QString& p_account, boo
connect(room, &QXmppMucRoom::error, this, &Conference::onRoomError); connect(room, &QXmppMucRoom::error, this, &Conference::onRoomError);
room->setNickName(nick); room->setNickName(nick);
if (autoJoin) { if (autoJoin)
room->join(); room->join();
}
archive->readAllResourcesAvatars(exParticipants); archive->readAllResourcesAvatars(exParticipants);
} }
Core::Conference::~Conference() Core::Conference::~Conference(){
{ if (joined)
if (joined) {
room->leave(); room->leave();
}
room->deleteLater(); room->deleteLater();
} }
QString Core::Conference::getNick() const QString Core::Conference::getNick() const {
{
return nick; return nick;
} }
bool Core::Conference::getAutoJoin() bool Core::Conference::getAutoJoin() const {
{
return autoJoin; return autoJoin;
} }
bool Core::Conference::getJoined() const bool Core::Conference::getJoined() const {
{
return joined; return joined;
} }
void Core::Conference::setJoined(bool p_joined) void Core::Conference::setJoined(bool p_joined) {
{
if (joined != p_joined) { if (joined != p_joined) {
if (p_joined) { if (p_joined)
room->join(); room->join();
} else { else
room->leave(); room->leave();
}
} }
} }
void Core::Conference::setAutoJoin(bool p_autoJoin) void Core::Conference::setAutoJoin(bool p_autoJoin) {
{
if (autoJoin != p_autoJoin) { if (autoJoin != p_autoJoin) {
autoJoin = p_autoJoin; autoJoin = p_autoJoin;
emit autoJoinChanged(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 (nick != p_nick) {
if (joined) { if (joined) {
room->setNickName(p_nick); 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; joined = true;
emit joinedChanged(joined); emit joinedChanged(joined);
} }
void Core::Conference::onRoomLeft() void Core::Conference::onRoomLeft() {
{
joined = false; joined = false;
emit joinedChanged(joined); emit joinedChanged(joined);
} }
void Core::Conference::onRoomNameChanged(const QString& p_name) void Core::Conference::onRoomNameChanged(const QString& p_name) {
{
setName(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) { if (p_nick != nick) {
nick = p_nick; nick = p_nick;
emit nickChanged(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(); 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("/"); QStringList comps = p_name.split("/");
QString resource = comps.back(); QString resource = comps.back();
QXmppPresence pres = room->participantPresence(p_name); QXmppPresence pres = room->participantPresence(p_name);
QXmppMucItem mi = pres.mucItem(); QXmppMucItem mi = pres.mucItem();
if (resource == jid) { if (resource == jid)
resource = ""; resource = "";
}
std::map<QString, Archive::AvatarInfo>::const_iterator itr = exParticipants.find(resource); std::map<QString, Archive::AvatarInfo>::const_iterator itr = exParticipants.find(resource);
bool hasAvatar = itr != exParticipants.end(); bool hasAvatar = itr != exParticipants.end();
@ -166,19 +150,7 @@ void Core::Conference::onRoomParticipantAdded(const QString& p_name)
) )
} }
}; };
careAboutAvatar(hasAvatar, itr->second, cData, resource, p_name);
if (hasAvatar) {
if (itr->second.autogenerated) {
cData.insert("avatarState", static_cast<uint>(Shared::Avatar::valid));
} else {
cData.insert("avatarState", static_cast<uint>(Shared::Avatar::autocreated));
}
cData.insert("avatarPath", avatarPath(resource) + "." + itr->second.type);
} else {
cData.insert("avatarState", static_cast<uint>(Shared::Avatar::empty));
cData.insert("avatarPath", "");
emit requestVCard(p_name);
}
emit addParticipant(resource, cData); emit addParticipant(resource, cData);
} }
@ -196,9 +168,9 @@ void Core::Conference::onRoomParticipantAdded(const QString& p_name)
break; break;
case QXmppPresence::VCardUpdateValidPhoto:{ //there is a photo, need to load case QXmppPresence::VCardUpdateValidPhoto:{ //there is a photo, need to load
if (hasAvatar) { if (hasAvatar) {
if (itr->second.autogenerated || itr->second.hash != pres.photoHash()) { if (itr->second.autogenerated || itr->second.hash != pres.photoHash())
emit requestVCard(p_name); emit requestVCard(p_name);
}
} else { } else {
emit requestVCard(p_name); 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("/"); QStringList comps = p_name.split("/");
QString resource = comps.back(); QString resource = comps.back();
QXmppPresence pres = room->participantPresence(p_name); QXmppPresence pres = room->participantPresence(p_name);
@ -216,9 +187,8 @@ void Core::Conference::onRoomParticipantChanged(const QString& p_name)
handlePresence(pres); handlePresence(pres);
if (resource != jid) { if (resource != jid) {
QDateTime lastInteraction = pres.lastUserInteraction(); QDateTime lastInteraction = pres.lastUserInteraction();
if (!lastInteraction.isValid()) { if (!lastInteraction.isValid())
lastInteraction = QDateTime::currentDateTimeUtc(); lastInteraction = QDateTime::currentDateTimeUtc();
}
emit changeParticipant(resource, { emit changeParticipant(resource, {
{"lastActivity", lastInteraction}, {"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("/"); QStringList comps = p_name.split("/");
QString resource = comps.back(); QString resource = comps.back();
if (resource == jid) { if (resource == jid) {
@ -248,29 +217,24 @@ void Core::Conference::onRoomParticipantRemoved(const QString& p_name)
} }
} }
QString Core::Conference::getSubject() const QString Core::Conference::getSubject() const {
{ if (joined)
if (joined) {
return room->subject(); return room->subject();
} else { else
return ""; return "";
}
} }
void Core::Conference::onRoomSubjectChanged(const QString& p_name) void Core::Conference::onRoomSubjectChanged(const QString& p_name) {
{
emit subjectChanged(p_name); emit subjectChanged(p_name);
} }
void Core::Conference::handlePresence(const QXmppPresence& pres) void Core::Conference::handlePresence(const QXmppPresence& pres) {
{
QString id = pres.from(); QString id = pres.from();
QStringList comps = id.split("/"); QStringList comps = id.split("/");
QString jid = comps.front(); QString jid = comps.front();
QString resource(""); QString resource("");
if (comps.size() > 1) { if (comps.size() > 1)
resource = comps.back(); resource = comps.back();
}
switch (pres.vCardUpdateType()) { switch (pres.vCardUpdateType()) {
case QXmppPresence::VCardUpdateNone: //this presence has nothing to do with photo case QXmppPresence::VCardUpdateNone: //this presence has nothing to do with photo
@ -284,14 +248,13 @@ void Core::Conference::handlePresence(const QXmppPresence& pres)
setAutoGeneratedAvatar(resource); setAutoGeneratedAvatar(resource);
} }
} }
break; break;
case QXmppPresence::VCardUpdateValidPhoto:{ //there is a photo, need to load case QXmppPresence::VCardUpdateValidPhoto:{ //there is a photo, need to load
Archive::AvatarInfo info; Archive::AvatarInfo info;
bool hasAvatar = readAvatarInfo(info, resource); bool hasAvatar = readAvatarInfo(info, resource);
if (hasAvatar) { if (hasAvatar) {
if (info.autogenerated || info.hash != pres.photoHash()) { if (info.autogenerated || info.hash != pres.photoHash())
emit requestVCard(id); emit requestVCard(id);
}
} else { } else {
emit requestVCard(id); 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; Archive::AvatarInfo newInfo;
bool result = RosterItem::setAutoGeneratedAvatar(newInfo, resource); bool result = RosterItem::setAutoGeneratedAvatar(newInfo, resource);
if (result && resource.size() != 0) { if (result && resource.size() != 0) {
std::map<QString, Archive::AvatarInfo>::iterator itr = exParticipants.find(resource); std::map<QString, Archive::AvatarInfo>::iterator itr = exParticipants.find(resource);
if (itr == exParticipants.end()) { if (itr == exParticipants.end())
exParticipants.insert(std::make_pair(resource, newInfo)); exParticipants.insert(std::make_pair(resource, newInfo));
} else { else
itr->second = newInfo; itr->second = newInfo;
}
emit changeParticipant(resource, { emit changeParticipant(resource, {
{"avatarState", static_cast<uint>(Shared::Avatar::autocreated)}, {"avatarState", static_cast<uint>(Shared::Avatar::autocreated)},
{"avatarPath", avatarPath(resource) + "." + newInfo.type} {"avatarPath", avatarPath(resource) + "." + newInfo.type}
@ -320,17 +281,15 @@ bool Core::Conference::setAutoGeneratedAvatar(const QString& resource)
return result; 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); bool result = RosterItem::setAvatar(data, info, resource);
if (result && resource.size() != 0) { if (result && resource.size() != 0) {
if (data.size() > 0) { if (data.size() > 0) {
std::map<QString, Archive::AvatarInfo>::iterator itr = exParticipants.find(resource); std::map<QString, Archive::AvatarInfo>::iterator itr = exParticipants.find(resource);
if (itr == exParticipants.end()) { if (itr == exParticipants.end())
exParticipants.insert(std::make_pair(resource, info)); exParticipants.insert(std::make_pair(resource, info));
} else { else
itr->second = info; itr->second = info;
}
emit changeParticipant(resource, { emit changeParticipant(resource, {
{"avatarState", static_cast<uint>(Shared::Avatar::autocreated)}, {"avatarState", static_cast<uint>(Shared::Avatar::autocreated)},
@ -338,9 +297,8 @@ bool Core::Conference::setAvatar(const QByteArray& data, Archive::AvatarInfo& in
}); });
} else { } else {
std::map<QString, Archive::AvatarInfo>::iterator itr = exParticipants.find(resource); std::map<QString, Archive::AvatarInfo>::iterator itr = exParticipants.find(resource);
if (itr != exParticipants.end()) { if (itr != exParticipants.end())
exParticipants.erase(itr); exParticipants.erase(itr);
}
emit changeParticipant(resource, { emit changeParticipant(resource, {
{"avatarState", static_cast<uint>(Shared::Avatar::empty)}, {"avatarState", static_cast<uint>(Shared::Avatar::empty)},
@ -353,10 +311,8 @@ bool Core::Conference::setAvatar(const QByteArray& data, Archive::AvatarInfo& in
return result; 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); RosterItem::handleResponseVCard(card, resource, out);
if (resource.size() > 0) { if (resource.size() > 0) {
emit changeParticipant(resource, { emit changeParticipant(resource, {
{"avatarState", static_cast<uint>(out.getAvatarType())}, {"avatarState", static_cast<uint>(out.getAvatarType())},
@ -365,11 +321,21 @@ void Core::Conference::handleResponseVCard(const QXmppVCardIq& card, const QStri
} }
} }
QMap<QString, QVariant> Core::Conference::getAllAvatars() const QMap<QString, QVariant> Core::Conference::getAllAvatars() const {
{
QMap<QString, QVariant> result; QMap<QString, QVariant> result;
for (const std::pair<const QString, Archive::AvatarInfo>& pair : exParticipants) { for (const std::pair<const QString, Archive::AvatarInfo>& pair : exParticipants)
result.insert(pair.first, avatarPath(pair.first) + "." + pair.second.type); result.insert(pair.first, avatarPath(pair.first) + "." + pair.second.type);
}
return result; return result;
} }
QMap<QString, QVariant> Core::Conference::getInfo() const {
QMap<QString, QVariant> data = RosterItem::getInfo();
data.insert("autoJoin", getAutoJoin());
data.insert("joined", getJoined());
data.insert("nick", getNick());
data.insert("avatars", getAllAvatars());
return data;
}

View File

@ -49,12 +49,13 @@ public:
bool getJoined() const; bool getJoined() const;
void setJoined(bool p_joined); void setJoined(bool p_joined);
bool getAutoJoin(); bool getAutoJoin() const;
void setAutoJoin(bool p_autoJoin); void setAutoJoin(bool p_autoJoin);
void handlePresence(const QXmppPresence & pres) override; void handlePresence(const QXmppPresence & pres) override;
bool setAutoGeneratedAvatar(const QString& resource = "") override; bool setAutoGeneratedAvatar(const QString& resource = "") override;
void handleResponseVCard(const QXmppVCardIq & card, const QString &resource, Shared::VCard& out) override; void handleResponseVCard(const QXmppVCardIq & card, const QString &resource, Shared::VCard& out) override;
QMap<QString, QVariant> getAllAvatars() const; QMap<QString, QVariant> getAllAvatars() const;
QMap<QString, QVariant> getInfo() const override;
signals: signals:
void nickChanged(const QString& nick); void nickChanged(const QString& nick);

View File

@ -24,54 +24,43 @@ Core::Contact::Contact(const QString& pJid, const QString& account, QObject* par
groups(), groups(),
subscriptionState(Shared::SubscriptionState::unknown), subscriptionState(Shared::SubscriptionState::unknown),
pep(Shared::Support::unknown) pep(Shared::Support::unknown)
{ {}
}
Core::Contact::~Contact() Core::Contact::~Contact() {}
{
}
QSet<QString> Core::Contact::getGroups() const QSet<QString> Core::Contact::getGroups() const {
{
return groups; return groups;
} }
unsigned int Core::Contact::groupsCount() const unsigned int Core::Contact::groupsCount() const {
{
return groups.size(); return groups.size();
} }
void Core::Contact::setGroups(const QSet<QString>& set) void Core::Contact::setGroups(const QSet<QString>& set) {
{
QSet<QString> toRemove = groups - set; QSet<QString> toRemove = groups - set;
QSet<QString> toAdd = set - groups; QSet<QString> toAdd = set - groups;
groups = set; groups = set;
for (QSet<QString>::iterator itr = toRemove.begin(), end = toRemove.end(); itr != end; ++itr) { for (const QString& group : toRemove)
emit groupRemoved(*itr); emit groupRemoved(group);
}
for (QSet<QString>::iterator itr = toAdd.begin(), end = toAdd.end(); itr != end; ++itr) { for (const QString& group : toAdd)
emit groupAdded(*itr); emit groupAdded(group);
}
} }
Shared::SubscriptionState Core::Contact::getSubscriptionState() const Shared::SubscriptionState Core::Contact::getSubscriptionState() const {
{
return subscriptionState; return subscriptionState;
} }
void Core::Contact::setSubscriptionState(Shared::SubscriptionState state) void Core::Contact::setSubscriptionState(Shared::SubscriptionState state) {
{
if (subscriptionState != state) { if (subscriptionState != state) {
subscriptionState = state; subscriptionState = state;
emit subscriptionStateChanged(subscriptionState); emit subscriptionStateChanged(subscriptionState);
} }
} }
void Core::Contact::handlePresence(const QXmppPresence& pres) void Core::Contact::handlePresence(const QXmppPresence& pres) {
{
switch (pres.vCardUpdateType()) { switch (pres.vCardUpdateType()) {
case QXmppPresence::VCardUpdateNone: //this presence has nothing to do with photo case QXmppPresence::VCardUpdateNone: //this presence has nothing to do with photo
break; break;
@ -101,13 +90,21 @@ void Core::Contact::handlePresence(const QXmppPresence& pres)
} }
void Core::Contact::setPepSupport(Shared::Support support) { void Core::Contact::setPepSupport(Shared::Support support) {
if (pep != support) { if (pep != support)
pep = support; pep = support;
}
} }
Shared::Support Core::Contact::getPepSupport() const { Shared::Support Core::Contact::getPepSupport() const {
return pep;} return pep;
}
QMap<QString, QVariant> Core::Contact::getInfo() const {
QMap<QString, QVariant> data = RosterItem::getInfo();
data.insert("state", QVariant::fromValue(subscriptionState));
return data;
}

View File

@ -45,6 +45,7 @@ public:
Shared::Support getPepSupport() const; Shared::Support getPepSupport() const;
void handlePresence(const QXmppPresence & pres) override; void handlePresence(const QXmppPresence & pres) override;
QMap<QString, QVariant> getInfo() const override;
signals: signals:
void groupAdded(const QString& name); void groupAdded(const QString& name);

View File

@ -83,7 +83,7 @@ void Core::MessageHandler::onMessageReceived(const QXmppMessage& msg)
{"state", static_cast<uint>(Shared::Message::State::error)}, {"state", static_cast<uint>(Shared::Message::State::error)},
{"errorText", msg.error().text()} {"errorText", msg.error().text()}
}; };
if (cnt != 0) { if (cnt != nullptr) {
cnt->changeMessage(id, cData); cnt->changeMessage(id, cData);
} }
emit acc->changeMessage(jid, id, cData); emit acc->changeMessage(jid, id, cData);
@ -291,7 +291,7 @@ void Core::MessageHandler::onReceiptReceived(const QString& jid, const QString&
QMap<QString, QVariant> cData = {{"state", static_cast<uint>(Shared::Message::State::delivered)}}; QMap<QString, QVariant> cData = {{"state", static_cast<uint>(Shared::Message::State::delivered)}};
RosterItem* ri = acc->rh->getRosterItem(std::get<2>(ids)); RosterItem* ri = acc->rh->getRosterItem(std::get<2>(ids));
if (ri != 0) { if (ri != nullptr) {
ri->changeMessage(std::get<1>(ids), cData); ri->changeMessage(std::get<1>(ids), cData);
} }
emit acc->changeMessage(std::get<2>(ids), 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 { } else {
realId = id; realId = id;
} }
if (ri != 0) { if (ri != nullptr) {
if (newMessage) { if (newMessage) {
ri->appendMessageToArchive(data); ri->appendMessageToArchive(data);
} else { } else {
@ -429,7 +429,7 @@ void Core::MessageHandler::prepareUpload(const Shared::Message& data, bool newMe
QString jid = data.getPenPalJid(); QString jid = data.getPenPalJid();
QString id = data.getId(); QString id = data.getId();
RosterItem* ri = acc->rh->getRosterItem(jid); 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"; 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; return;
} }
@ -517,7 +517,7 @@ void Core::MessageHandler::onDownloadFileComplete(const std::list<Shared::Messag
for (const Shared::MessageInfo& info : msgs) { for (const Shared::MessageInfo& info : msgs) {
if (info.account == acc->getName()) { if (info.account == acc->getName()) {
RosterItem* cnt = acc->rh->getRosterItem(info.jid); RosterItem* cnt = acc->rh->getRosterItem(info.jid);
if (cnt != 0) { if (cnt != nullptr) {
if (cnt->changeMessage(info.messageId, cData)) { if (cnt->changeMessage(info.messageId, cData)) {
emit acc->changeMessage(info.jid, info.messageId, cData); emit acc->changeMessage(info.jid, info.messageId, cData);
} }
@ -553,7 +553,7 @@ void Core::MessageHandler::onUploadFileComplete(const std::list<Shared::MessageI
for (const Shared::MessageInfo& info : msgs) { for (const Shared::MessageInfo& info : msgs) {
if (info.account == acc->getName()) { if (info.account == acc->getName()) {
RosterItem* ri = acc->rh->getRosterItem(info.jid); RosterItem* ri = acc->rh->getRosterItem(info.jid);
if (ri != 0) { if (ri != nullptr) {
Shared::Message msg = ri->getMessage(info.messageId); Shared::Message msg = ri->getMessage(info.messageId);
msg.setAttachPath(path); msg.setAttachPath(path);
sendMessageWithLocalUploadedFile(msg, url, false); sendMessageWithLocalUploadedFile(msg, url, false);
@ -584,7 +584,7 @@ static const std::set<QString> allowedToChangeKeys({
void Core::MessageHandler::requestChangeMessage(const QString& jid, const QString& messageId, const QMap<QString, QVariant>& data) void Core::MessageHandler::requestChangeMessage(const QString& jid, const QString& messageId, const QMap<QString, QVariant>& data)
{ {
RosterItem* cnt = acc->rh->getRosterItem(jid); RosterItem* cnt = acc->rh->getRosterItem(jid);
if (cnt != 0) { if (cnt != nullptr) {
bool allSupported = true; bool allSupported = true;
QString unsupportedString; QString unsupportedString;
for (QMap<QString, QVariant>::const_iterator itr = data.begin(); itr != data.end(); ++itr) { //I need all this madness for (QMap<QString, QVariant>::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) void Core::MessageHandler::resendMessage(const QString& jid, const QString& id)
{ {
RosterItem* cnt = acc->rh->getRosterItem(jid); RosterItem* cnt = acc->rh->getRosterItem(jid);
if (cnt != 0) { if (cnt != nullptr) {
try { try {
Shared::Message msg = cnt->getMessage(id); Shared::Message msg = cnt->getMessage(id);
if (msg.getState() == Shared::Message::State::error) { if (msg.getState() == Shared::Message::State::error) {

View File

@ -41,19 +41,23 @@ void Core::RosterHandler::initialize() {
connect(acc, &Account::pepSupportChanged, this, &RosterHandler::onPepSupportedChanged); connect(acc, &Account::pepSupportChanged, this, &RosterHandler::onPepSupportedChanged);
} }
Core::RosterHandler::~RosterHandler() Core::RosterHandler::~RosterHandler() {
{ clear();
for (std::map<QString, Contact*>::const_iterator itr = contacts.begin(), end = contacts.end(); itr != end; ++itr) {
delete itr->second;
}
for (std::map<QString, Conference*>::const_iterator itr = conferences.begin(), end = conferences.end(); itr != end; ++itr) {
delete itr->second;
}
} }
void Core::RosterHandler::onRosterReceived() void Core::RosterHandler::clear() {
{ for (const std::pair<const QString, Contact*>& pair : contacts)
delete pair.second;
for (const std::pair<const QString, Conference*>& pair : conferences)
delete pair.second;
contacts.clear();
conferences.clear();
}
void Core::RosterHandler::onRosterReceived() {
QStringList bj = acc->rm->getRosterBareJids(); QStringList bj = acc->rm->getRosterBareJids();
for (int i = 0; i < bj.size(); ++i) { for (int i = 0; i < bj.size(); ++i) {
const QString& jid = bj[i]; const QString& jid = bj[i];
@ -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(); QString lcJid = bareJid.toLower();
addedAccount(lcJid); addedAccount(lcJid);
std::map<QString, QString>::const_iterator itr = queuedContacts.find(lcJid); std::map<QString, QString>::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<QString, Contact*>::const_iterator itr = contacts.find(jid); std::map<QString, Contact*>::const_iterator itr = contacts.find(jid);
QXmppRosterIq::Item re = acc->rm->getRosterEntry(jid); QXmppRosterIq::Item re = acc->rm->getRosterEntry(jid);
Contact* contact; Contact* contact;
@ -82,7 +84,6 @@ void Core::RosterHandler::addedAccount(const QString& jid)
newContact = true; newContact = true;
contact = new Contact(jid, acc->name); contact = new Contact(jid, acc->name);
contacts.insert(std::make_pair(jid, contact)); contacts.insert(std::make_pair(jid, contact));
} else { } else {
contact = itr->second; contact = itr->second;
} }
@ -94,12 +95,7 @@ void Core::RosterHandler::addedAccount(const QString& jid)
contact->setName(re.name()); contact->setName(re.name());
if (newContact) { if (newContact) {
QMap<QString, QVariant> cData({ QMap<QString, QVariant> cData = contact->getInfo();
{"name", re.name()},
{"state", QVariant::fromValue(state)}
});
careAboutAvatar(contact, cData);
int grCount = 0; int grCount = 0;
for (QSet<QString>::const_iterator itr = gr.begin(), end = gr.end(); itr != end; ++itr) { for (QSet<QString>::const_iterator itr = gr.begin(), end = gr.end(); itr != end; ++itr) {
const QString& groupName = *itr; const QString& groupName = *itr;
@ -108,9 +104,9 @@ void Core::RosterHandler::addedAccount(const QString& jid)
grCount++; grCount++;
} }
if (grCount == 0) { if (grCount == 0)
emit acc->addContact(jid, "", cData); emit acc->addContact(jid, "", cData);
}
if (acc->pepSupport == Shared::Support::supported) { if (acc->pepSupport == Shared::Support::supported) {
acc->dm->requestInfo(jid); acc->dm->requestInfo(jid);
//acc->dm->requestItems(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); QXmppMucRoom* room = acc->mm->addRoom(jid);
QString lNick = nick; QString lNick = nick;
if (lNick.size() == 0) { if (lNick.size() == 0)
lNick = acc->getName(); lNick = acc->getName();
}
Conference* conf = new Conference(jid, acc->getName(), autoJoin, roomName, lNick, room); Conference* conf = new Conference(jid, acc->getName(), autoJoin, roomName, lNick, room);
conferences.insert(std::make_pair(jid, conf)); conferences.insert(std::make_pair(jid, conf));
handleNewConference(conf); handleNewConference(conf);
QMap<QString, QVariant> cData = { QMap<QString, QVariant> cData = conf->getInfo();
{"autoJoin", conf->getAutoJoin()},
{"joined", conf->getJoined()},
{"nick", conf->getNick()},
{"name", conf->getName()},
{"avatars", conf->getAllAvatars()}
};
careAboutAvatar(conf, cData);
emit acc->addRoom(jid, cData); emit acc->addRoom(jid, cData);
} }
void Core::RosterHandler::careAboutAvatar(Core::RosterItem* item, QMap<QString, QVariant>& data) void Core::RosterHandler::addContactRequest(const QString& jid, const QString& name, const QSet<QString>& groups) {
{
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<QString>& groups)
{
if (acc->state == Shared::ConnectionState::connected) { if (acc->state == Shared::ConnectionState::connected) {
std::map<QString, QString>::const_iterator itr = queuedContacts.find(jid); std::map<QString, QString>::const_iterator itr = queuedContacts.find(jid);
if (itr != queuedContacts.end()) { 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(); QString lcJid = jid.toLower();
if (acc->state == Shared::ConnectionState::connected) { if (acc->state == Shared::ConnectionState::connected) {
std::set<QString>::const_iterator itr = outOfRosterContacts.find(lcJid); std::set<QString>::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::needHistory, this->acc, &Account::onContactNeedHistory);
connect(contact, &RosterItem::historyResponse, this->acc, &Account::onContactHistoryResponse); connect(contact, &RosterItem::historyResponse, this->acc, &Account::onContactHistoryResponse);
connect(contact, &RosterItem::nameChanged, this, &RosterHandler::onContactNameChanged); connect(contact, &RosterItem::nameChanged, this, &RosterHandler::onContactNameChanged);
connect(contact, &RosterItem::avatarChanged, this, &RosterHandler::onContactAvatarChanged); connect(contact, &RosterItem::avatarChanged, this, &RosterHandler::onContactAvatarChanged);
connect(contact, &RosterItem::encryptionChanged, this, &RosterHandler::onContactEncryptionChanged);
connect(contact, &RosterItem::requestVCard, acc->delay, &DelayManager::Manager::getVCard); 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); handleNewRosterItem(contact);
connect(contact, &Contact::groupAdded, this, &RosterHandler::onContactGroupAdded); connect(contact, &Contact::groupAdded, this, &RosterHandler::onContactGroupAdded);
connect(contact, &Contact::groupRemoved, this, &RosterHandler::onContactGroupRemoved); connect(contact, &Contact::groupRemoved, this, &RosterHandler::onContactGroupRemoved);
connect(contact, &Contact::subscriptionStateChanged, this, &RosterHandler::onContactSubscriptionStateChanged); connect(contact, &Contact::subscriptionStateChanged, this, &RosterHandler::onContactSubscriptionStateChanged);
} }
void Core::RosterHandler::handleNewConference(Core::Conference* contact) void Core::RosterHandler::handleNewConference(Core::Conference* contact) {
{
handleNewRosterItem(contact); handleNewRosterItem(contact);
connect(contact, &Conference::nickChanged, this, &RosterHandler::onMucNickNameChanged); connect(contact, &Conference::nickChanged, this, &RosterHandler::onMucNickNameChanged);
connect(contact, &Conference::subjectChanged, this, &RosterHandler::onMucSubjectChanged); 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); connect(contact, &Conference::removeParticipant, this, &RosterHandler::onMucRemoveParticipant);
} }
void Core::RosterHandler::onMucAddParticipant(const QString& nickName, const QMap<QString, QVariant>& data) void Core::RosterHandler::onMucAddParticipant(const QString& nickName, const QMap<QString, QVariant>& data) {
{
Conference* room = static_cast<Conference*>(sender()); Conference* room = static_cast<Conference*>(sender());
emit acc->addRoomParticipant(room->jid, nickName, data); emit acc->addRoomParticipant(room->jid, nickName, data);
} }
void Core::RosterHandler::onMucChangeParticipant(const QString& nickName, const QMap<QString, QVariant>& data) void Core::RosterHandler::onMucChangeParticipant(const QString& nickName, const QMap<QString, QVariant>& data) {
{
Conference* room = static_cast<Conference*>(sender()); Conference* room = static_cast<Conference*>(sender());
emit acc->changeRoomParticipant(room->jid, nickName, data); 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<Conference*>(sender()); Conference* room = static_cast<Conference*>(sender());
emit acc->removeRoomParticipant(room->jid, nickName); emit acc->removeRoomParticipant(room->jid, nickName);
} }
void Core::RosterHandler::onMucSubjectChanged(const QString& subject) void Core::RosterHandler::onMucSubjectChanged(const QString& subject) {
{
Conference* room = static_cast<Conference*>(sender()); Conference* room = static_cast<Conference*>(sender());
emit acc->changeRoom(room->jid, { emit acc->changeRoom(room->jid, {{"subject", subject}});
{"subject", subject}
});
} }
void Core::RosterHandler::onContactGroupAdded(const QString& group) void Core::RosterHandler::onContactGroupAdded(const QString& group) {
{
Contact* contact = static_cast<Contact*>(sender()); Contact* contact = static_cast<Contact*>(sender());
if (contact->groupsCount() == 1) { if (contact->groupsCount() == 1) {
// not sure i need to handle it here, the situation with grouped and ungrouped contacts handled on the client anyway // 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<QString, QVariant> cData({ QMap<QString, QVariant> cData({
{"name", contact->getName()}, {"name", contact->getName()},
{"state", QVariant::fromValue(contact->getSubscriptionState())} {"state", QVariant::fromValue(contact->getSubscriptionState())},
{"encryption", contact->isEncryptionEnabled()}
}); });
addToGroup(contact->jid, group); addToGroup(contact->jid, group);
emit acc->addContact(contact->jid, group, cData); 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<Contact*>(sender()); Contact* contact = static_cast<Contact*>(sender());
if (contact->groupsCount() == 0) { if (contact->groupsCount() == 0) {
// not sure i need to handle it here, the situation with grouped and ungrouped contacts handled on the client anyway // 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); removeFromGroup(contact->jid, group);
} }
void Core::RosterHandler::onContactNameChanged(const QString& cname) void Core::RosterHandler::onContactNameChanged(const QString& cname) {
{ RosterItem* contact = static_cast<RosterItem*>(sender());
Contact* contact = static_cast<Contact*>(sender()); emit acc->changeContact(contact->jid, {{"name", cname}});
QMap<QString, QVariant> cData({
{"name", cname},
});
emit acc->changeContact(contact->jid, cData);
} }
void Core::RosterHandler::onContactSubscriptionStateChanged(Shared::SubscriptionState cstate) void Core::RosterHandler::onContactEncryptionChanged(bool value) {
{ RosterItem* contact = static_cast<RosterItem*>(sender());
emit acc->changeContact(contact->jid, {{"encryption", value}});
}
void Core::RosterHandler::onContactSubscriptionStateChanged(Shared::SubscriptionState cstate) {
Contact* contact = static_cast<Contact*>(sender()); Contact* contact = static_cast<Contact*>(sender());
QMap<QString, QVariant> cData({ QMap<QString, QVariant> cData({
{"state", QVariant::fromValue(cstate)}, {"state", QVariant::fromValue(cstate)},
@ -290,8 +249,7 @@ void Core::RosterHandler::onContactSubscriptionStateChanged(Shared::Subscription
emit acc->changeContact(contact->jid, cData); 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<QString, std::set<QString>>::iterator gItr = groups.find(group); std::map<QString, std::set<QString>>::iterator gItr = groups.find(group);
if (gItr == groups.end()) { if (gItr == groups.end()) {
gItr = groups.insert(std::make_pair(group, std::set<QString>())).first; gItr = groups.insert(std::make_pair(group, std::set<QString>())).first;
@ -300,8 +258,7 @@ void Core::RosterHandler::addToGroup(const QString& jid, const QString& group)
gItr->second.insert(jid.toLower()); 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<QString> toRemove; QSet<QString> toRemove;
std::map<QString, std::set<QString>>::iterator itr = groups.find(group); std::map<QString, std::set<QString>>::iterator itr = groups.find(group);
if (itr == groups.end()) { 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) Core::RosterItem * Core::RosterHandler::getRosterItem(const QString& jid) {
{ RosterItem* item = nullptr;
RosterItem* item = 0;
QString lcJid = jid.toLower(); QString lcJid = jid.toLower();
std::map<QString, Contact*>::const_iterator citr = contacts.find(lcJid); std::map<QString, Contact*>::const_iterator citr = contacts.find(lcJid);
if (citr != contacts.end()) { if (citr != contacts.end()) {
item = citr->second; item = citr->second;
} else { } else {
std::map<QString, Conference*>::const_iterator coitr = conferences.find(lcJid); std::map<QString, Conference*>::const_iterator coitr = conferences.find(lcJid);
if (coitr != conferences.end()) { if (coitr != conferences.end())
item = coitr->second; item = coitr->second;
}
} }
return item; return item;
} }
Core::Conference * Core::RosterHandler::getConference(const QString& jid) Core::Conference * Core::RosterHandler::getConference(const QString& jid) {
{
Conference* item = 0; Conference* item = 0;
std::map<QString, Conference*>::const_iterator coitr = conferences.find(jid.toLower()); std::map<QString, Conference*>::const_iterator coitr = conferences.find(jid.toLower());
if (coitr != conferences.end()) { if (coitr != conferences.end()) {
@ -345,8 +299,7 @@ Core::Conference * Core::RosterHandler::getConference(const QString& jid)
return item; return item;
} }
Core::Contact * Core::RosterHandler::getContact(const QString& jid) Core::Contact * Core::RosterHandler::getContact(const QString& jid) {
{
Contact* item = 0; Contact* item = 0;
std::map<QString, Contact*>::const_iterator citr = contacts.find(jid.toLower()); std::map<QString, Contact*>::const_iterator citr = contacts.find(jid.toLower());
if (citr != contacts.end()) { if (citr != contacts.end()) {
@ -355,22 +308,21 @@ Core::Contact * Core::RosterHandler::getContact(const QString& jid)
return item; return item;
} }
Core::Contact * Core::RosterHandler::addOutOfRosterContact(const QString& jid) Core::Contact * Core::RosterHandler::addOutOfRosterContact(const QString& jid) {
{
QString lcJid = jid.toLower(); QString lcJid = jid.toLower();
Contact* cnt = new Contact(lcJid, acc->name); Contact* cnt = new Contact(lcJid, acc->name);
contacts.insert(std::make_pair(lcJid, cnt)); contacts.insert(std::make_pair(lcJid, cnt));
outOfRosterContacts.insert(lcJid); outOfRosterContacts.insert(lcJid);
cnt->setSubscriptionState(Shared::SubscriptionState::unknown); cnt->setSubscriptionState(Shared::SubscriptionState::unknown);
emit acc->addContact(lcJid, "", QMap<QString, QVariant>({ emit acc->addContact(lcJid, "", QMap<QString, QVariant>({
{"state", QVariant::fromValue(Shared::SubscriptionState::unknown)} {"state", QVariant::fromValue(Shared::SubscriptionState::unknown)},
{"encryption", false}
})); }));
handleNewContact(cnt); handleNewContact(cnt);
return cnt; return cnt;
} }
void Core::RosterHandler::onRosterItemChanged(const QString& bareJid) void Core::RosterHandler::onRosterItemChanged(const QString& bareJid) {
{
QString lcJid = bareJid.toLower(); QString lcJid = bareJid.toLower();
std::map<QString, Contact*>::const_iterator itr = contacts.find(lcJid); std::map<QString, Contact*>::const_iterator itr = contacts.find(lcJid);
if (itr == contacts.end()) { if (itr == contacts.end()) {
@ -387,8 +339,7 @@ void Core::RosterHandler::onRosterItemChanged(const QString& bareJid)
contact->setName(re.name()); contact->setName(re.name());
} }
void Core::RosterHandler::onRosterItemRemoved(const QString& bareJid) void Core::RosterHandler::onRosterItemRemoved(const QString& bareJid) {
{
QString lcJid = bareJid.toLower(); QString lcJid = bareJid.toLower();
std::map<QString, Contact*>::const_iterator itr = contacts.find(lcJid); std::map<QString, Contact*>::const_iterator itr = contacts.find(lcJid);
if (itr == contacts.end()) { if (itr == contacts.end()) {
@ -406,14 +357,12 @@ void Core::RosterHandler::onRosterItemRemoved(const QString& bareJid)
contact->deleteLater(); contact->deleteLater();
} }
void Core::RosterHandler::onMucRoomAdded(QXmppMucRoom* room) void Core::RosterHandler::onMucRoomAdded(QXmppMucRoom* room) {
{
qDebug() << "room" << room->jid() << "added with name" << room->name() qDebug() << "room" << room->jid() << "added with name" << room->name()
<< ", account" << acc->getName() << "joined:" << room->isJoined(); << ", account" << acc->getName() << "joined:" << room->isJoined();
} }
void Core::RosterHandler::bookmarksReceived(const QXmppBookmarkSet& bookmarks) void Core::RosterHandler::bookmarksReceived(const QXmppBookmarkSet& bookmarks) {
{
QList<QXmppBookmarkConference> confs = bookmarks.conferences(); QList<QXmppBookmarkConference> confs = bookmarks.conferences();
for (QList<QXmppBookmarkConference>::const_iterator itr = confs.begin(), end = confs.end(); itr != end; ++itr) { for (QList<QXmppBookmarkConference>::const_iterator itr = confs.begin(), end = confs.end(); itr != end; ++itr) {
const QXmppBookmarkConference& c = *itr; const QXmppBookmarkConference& c = *itr;
@ -423,54 +372,42 @@ void Core::RosterHandler::bookmarksReceived(const QXmppBookmarkSet& bookmarks)
if (cItr == conferences.end()) { if (cItr == conferences.end()) {
addNewRoom(jid, c.nickName(), c.name(), c.autoJoin()); addNewRoom(jid, c.nickName(), c.name(), c.autoJoin());
} else { } else {
if (c.autoJoin()) { if (c.autoJoin())
cItr->second->setJoined(true); cItr->second->setJoined(true);
} else { else
cItr->second->setAutoJoin(false); cItr->second->setAutoJoin(false);
}
} }
} }
} }
void Core::RosterHandler::onMucJoinedChanged(bool joined) void Core::RosterHandler::onMucJoinedChanged(bool joined){
{
Conference* room = static_cast<Conference*>(sender()); Conference* room = static_cast<Conference*>(sender());
emit acc->changeRoom(room->jid, { emit acc->changeRoom(room->jid, {{"joined", joined}});
{"joined", joined}
});
} }
void Core::RosterHandler::onMucAutoJoinChanged(bool autoJoin) void Core::RosterHandler::onMucAutoJoinChanged(bool autoJoin) {
{
storeConferences(); storeConferences();
Conference* room = static_cast<Conference*>(sender()); Conference* room = static_cast<Conference*>(sender());
emit acc->changeRoom(room->jid, { emit acc->changeRoom(room->jid, {{"autoJoin", autoJoin}});
{"autoJoin", autoJoin}
});
} }
void Core::RosterHandler::onMucNickNameChanged(const QString& nickName) void Core::RosterHandler::onMucNickNameChanged(const QString& nickName){
{
storeConferences(); storeConferences();
Conference* room = static_cast<Conference*>(sender()); Conference* room = static_cast<Conference*>(sender());
emit acc->changeRoom(room->jid, { emit acc->changeRoom(room->jid, {{"nick", nickName}});
{"nick", nickName}
});
} }
Shared::SubscriptionState Core::RosterHandler::castSubscriptionState(QXmppRosterIq::Item::SubscriptionType qs) Shared::SubscriptionState Core::RosterHandler::castSubscriptionState(QXmppRosterIq::Item::SubscriptionType qs){
{
Shared::SubscriptionState state; Shared::SubscriptionState state;
if (qs == QXmppRosterIq::Item::NotSet) { if (qs == QXmppRosterIq::Item::NotSet)
state = Shared::SubscriptionState::unknown; state = Shared::SubscriptionState::unknown;
} else { else
state = static_cast<Shared::SubscriptionState>(qs); state = static_cast<Shared::SubscriptionState>(qs);
}
return state; return state;
} }
void Core::RosterHandler::storeConferences() void Core::RosterHandler::storeConferences() {
{
QXmppBookmarkSet bms = acc->bm->bookmarks(); QXmppBookmarkSet bms = acc->bm->bookmarks();
QList<QXmppBookmarkConference> confs; QList<QXmppBookmarkConference> confs;
for (std::map<QString, Conference*>::const_iterator itr = conferences.begin(), end = conferences.end(); itr != end; ++itr) { for (std::map<QString, Conference*>::const_iterator itr = conferences.begin(), end = conferences.end(); itr != end; ++itr) {
@ -486,8 +423,7 @@ void Core::RosterHandler::storeConferences()
acc->bm->setBookmarks(bms); acc->bm->setBookmarks(bms);
} }
void Core::RosterHandler::clearConferences() void Core::RosterHandler::clearConferences() {
{
for (std::map<QString, Conference*>::const_iterator itr = conferences.begin(), end = conferences.end(); itr != end; itr++) { for (std::map<QString, Conference*>::const_iterator itr = conferences.begin(), end = conferences.end(); itr != end; itr++) {
itr->second->deleteLater(); itr->second->deleteLater();
emit acc->removeRoom(itr->first); emit acc->removeRoom(itr->first);
@ -495,8 +431,7 @@ void Core::RosterHandler::clearConferences()
conferences.clear(); conferences.clear();
} }
void Core::RosterHandler::removeRoomRequest(const QString& jid) void Core::RosterHandler::removeRoomRequest(const QString& jid) {
{
QString lcJid = jid.toLower(); QString lcJid = jid.toLower();
std::map<QString, Conference*>::const_iterator itr = conferences.find(lcJid); std::map<QString, Conference*>::const_iterator itr = conferences.find(lcJid);
if (itr == conferences.end()) { if (itr == conferences.end()) {
@ -508,8 +443,7 @@ void Core::RosterHandler::removeRoomRequest(const QString& jid)
storeConferences(); 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(); QString lcJid = jid.toLower();
std::map<QString, Conference*>::const_iterator cItr = conferences.find(lcJid); std::map<QString, Conference*>::const_iterator cItr = conferences.find(lcJid);
if (cItr == conferences.end()) { 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(); QString lcJid = jid.toLower();
std::map<QString, Contact*>::const_iterator itr = contacts.find(lcJid); std::map<QString, Contact*>::const_iterator itr = contacts.find(lcJid);
if (itr == contacts.end()) { 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(); QString lcJid = jid.toLower();
std::map<QString, Contact*>::const_iterator itr = contacts.find(lcJid); std::map<QString, Contact*>::const_iterator itr = contacts.find(lcJid);
if (itr == contacts.end()) { 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<RosterItem*>(sender()); RosterItem* item = static_cast<RosterItem*>(sender());
QMap<QString, QVariant> cData({ QMap<QString, QVariant> cData({
{"avatarState", static_cast<uint>(type)}, {"avatarState", QVariant::fromValue(type)},
{"avatarPath", path} {"avatarPath", path}
}); });
emit acc->changeContact(item->jid, cData); emit acc->changeContact(item->jid, cData);
} }
void Core::RosterHandler::handleOffline() void Core::RosterHandler::handleOffline() {
{
for (const std::pair<const QString, Conference*>& pair : conferences) { for (const std::pair<const QString, Conference*>& pair : conferences) {
pair.second->clearArchiveRequests(); pair.second->clearArchiveRequests();
pair.second->downgradeDatabaseState(); 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) { if (support == Shared::Support::supported) {
for (const std::pair<const QString, Contact*>& pair : contacts) { for (const std::pair<const QString, Contact*>& pair : contacts) {
if (pair.second->getPepSupport() == Shared::Support::unknown) { if (pair.second->getPepSupport() == Shared::Support::unknown)
acc->dm->requestInfo(pair.first); acc->dm->requestInfo(pair.first);
}
} }
} }
} }

View File

@ -68,6 +68,7 @@ public:
void clearConferences(); void clearConferences();
void initialize(); void initialize();
void clear();
private slots: private slots:
void onRosterReceived(); void onRosterReceived();
@ -91,6 +92,7 @@ private slots:
void onContactNameChanged(const QString& name); void onContactNameChanged(const QString& name);
void onContactSubscriptionStateChanged(Shared::SubscriptionState state); void onContactSubscriptionStateChanged(Shared::SubscriptionState state);
void onContactAvatarChanged(Shared::Avatar, const QString& path); void onContactAvatarChanged(Shared::Avatar, const QString& path);
void onContactEncryptionChanged(bool value);
void onPepSupportedChanged(Shared::Support support); void onPepSupportedChanged(Shared::Support support);
private: private:
@ -101,7 +103,6 @@ private:
void handleNewRosterItem(Core::RosterItem* contact); void handleNewRosterItem(Core::RosterItem* contact);
void handleNewContact(Core::Contact* contact); void handleNewContact(Core::Contact* contact);
void handleNewConference(Core::Conference* contact); void handleNewConference(Core::Conference* contact);
void careAboutAvatar(Core::RosterItem* item, QMap<QString, QVariant>& data);
static Shared::SubscriptionState castSubscriptionState(QXmppRosterIq::Item::SubscriptionType qs); static Shared::SubscriptionState castSubscriptionState(QXmppRosterIq::Item::SubscriptionType qs);

View File

@ -88,7 +88,7 @@ void Core::VCardHandler::onVCardReceived(const QXmppVCardIq& card) {
} }
RosterItem* item = acc->rh->getRosterItem(jid); RosterItem* item = acc->rh->getRosterItem(jid);
if (item == 0) { if (item == nullptr) {
if (jid == acc->getBareJid()) if (jid == acc->getBareJid())
onOwnVCardReceived(card); onOwnVCardReceived(card);
else else

View File

@ -41,39 +41,33 @@ Core::RosterItem::RosterItem(const QString& pJid, const QString& pAccount, QObje
archive->open(account); archive->open(account);
if (archive->size() != 0) { if (archive->size() != 0) {
if (archive->isFromTheBeginning()) { if (archive->isFromTheBeginning())
archiveState = beginning; archiveState = beginning;
} else { else
archiveState = chunk; archiveState = chunk;
}
} }
} }
Core::RosterItem::~RosterItem() Core::RosterItem::~RosterItem() {
{
delete archive; delete archive;
} }
Core::RosterItem::ArchiveState Core::RosterItem::getArchiveState() const Core::RosterItem::ArchiveState Core::RosterItem::getArchiveState() const {
{
return archiveState; return archiveState;
} }
QString Core::RosterItem::getName() const QString Core::RosterItem::getName() const {
{
return name; return name;
} }
void Core::RosterItem::setName(const QString& n) void Core::RosterItem::setName(const QString& n) {
{
if (name != n) { if (name != n) {
name = n; name = n;
emit nameChanged(name); emit nameChanged(name);
} }
} }
void Core::RosterItem::addMessageToArchive(const Shared::Message& msg) void Core::RosterItem::addMessageToArchive(const Shared::Message& msg) {
{
if (msg.storable()) { if (msg.storable()) {
hisoryCache.push_back(msg); hisoryCache.push_back(msg);
std::map<QString, Shared::Message>::iterator itr = toCorrect.find(msg.getId()); std::map<QString, Shared::Message>::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()) { if (msg.storable()) {
QDateTime thisTime = msg.getTime(); QDateTime thisTime = msg.getTime();
std::map<QString, Shared::Message>::iterator itr = toCorrect.find(originalId); std::map<QString, Shared::Message>::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) { if (syncronizing) {
requestCache.emplace_back(count, before); requestCache.emplace_back(count, before);
} else { } 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 (syncronizing) {
if (requestedCount != -1) { if (requestedCount != -1) {
bool last = false; 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; syncronizing = true;
requestedCount = count; requestedCount = count;
requestedBefore = before; 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; QString id;
if (muc) { if (muc) {
id = msg.getStanzaId(); id = msg.getStanzaId();
@ -257,8 +246,7 @@ QString Core::RosterItem::getId(const Shared::Message& msg)
return id; 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.getId().size() > 0) {
if (msg.storable()) { if (msg.storable()) {
switch (archiveState) { switch (archiveState) {
@ -299,8 +287,7 @@ void Core::RosterItem::appendMessageToArchive(const Shared::Message& msg)
} }
} }
bool Core::RosterItem::changeMessage(const QString& id, const QMap<QString, QVariant>& data) bool Core::RosterItem::changeMessage(const QString& id, const QMap<QString, QVariant>& data) {
{
bool found = false; bool found = false;
for (Shared::Message& msg : appendCache) { for (Shared::Message& msg : appendCache) {
if (msg.getId() == id) { if (msg.getId() == id) {
@ -341,8 +328,7 @@ bool Core::RosterItem::changeMessage(const QString& id, const QMap<QString, QVar
return found; return found;
} }
void Core::RosterItem::flushMessagesToArchive(bool finished, const QString& firstId, const QString& lastId) void Core::RosterItem::flushMessagesToArchive(bool finished, const QString& firstId, const QString& lastId) {
{
unsigned int added(0); unsigned int added(0);
if (hisoryCache.size() > 0) { if (hisoryCache.size() > 0) {
added = archive->addElements(hisoryCache); 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("@"); QStringList lst = jid.split("@");
return lst.back(); return lst.back();
} }
bool Core::RosterItem::isMuc() const bool Core::RosterItem::isMuc() const {
{
return muc; 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); QString path = folderPath() + "/" + (resource.size() == 0 ? jid : resource);
return path; return path;
} }
QString Core::RosterItem::folderPath() const QString Core::RosterItem::folderPath() const {
{
QString path(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)); QString path(QStandardPaths::writableLocation(QStandardPaths::CacheLocation));
path += "/" + account + "/" + jid; path += "/" + account + "/" + jid;
return path; 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); bool result = archive->setAvatar(data, info, false, resource);
if (resource.size() == 0 && result) { if (resource.size() == 0 && result) {
if (data.size() == 0) { if (data.size() == 0)
emit avatarChanged(Shared::Avatar::empty, ""); emit avatarChanged(Shared::Avatar::empty, "");
} else { else
emit avatarChanged(Shared::Avatar::valid, avatarPath(resource) + "." + info.type); emit avatarChanged(Shared::Avatar::valid, avatarPath(resource) + "." + info.type);
}
} }
return result; return result;
} }
bool Core::RosterItem::setAutoGeneratedAvatar(const QString& resource) bool Core::RosterItem::setAutoGeneratedAvatar(const QString& resource) {
{
Archive::AvatarInfo info; Archive::AvatarInfo info;
return setAutoGeneratedAvatar(info, resource); 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); QImage image(96, 96, QImage::Format_ARGB32_Premultiplied);
QPainter painter(&image); QPainter painter(&image);
quint8 colorIndex = rand() % Shared::colorPalette.size(); quint8 colorIndex = rand() % Shared::colorPalette.size();
@ -483,11 +461,11 @@ bool Core::RosterItem::setAutoGeneratedAvatar(Archive::AvatarInfo& info, const Q
f.setBold(true); f.setBold(true);
f.setPixelSize(72); f.setPixelSize(72);
painter.setFont(f); painter.setFont(f);
if (bg.lightnessF() > 0.5) { if (bg.lightnessF() > 0.5)
painter.setPen(Qt::black); painter.setPen(Qt::black);
} else { else
painter.setPen(Qt::white); painter.setPen(Qt::white);
}
painter.drawText(image.rect(), Qt::AlignCenter | Qt::AlignVCenter, resource.size() == 0 ? jid.at(0).toUpper() : resource.at(0).toUpper()); painter.drawText(image.rect(), Qt::AlignCenter | Qt::AlignVCenter, resource.size() == 0 ? jid.at(0).toUpper() : resource.at(0).toUpper());
QByteArray arr; QByteArray arr;
QBuffer stream(&arr); QBuffer stream(&arr);
@ -495,19 +473,17 @@ bool Core::RosterItem::setAutoGeneratedAvatar(Archive::AvatarInfo& info, const Q
image.save(&stream, "PNG"); image.save(&stream, "PNG");
stream.close(); stream.close();
bool result = archive->setAvatar(arr, info, true, resource); 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"); emit avatarChanged(Shared::Avatar::autocreated, avatarPath(resource) + ".png");
}
return result; 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); 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 info;
Archive::AvatarInfo newInfo; Archive::AvatarInfo newInfo;
bool hasAvatar = readAvatarInfo(info, resource); bool hasAvatar = readAvatarInfo(info, resource);
@ -532,9 +508,9 @@ void Core::RosterItem::handleResponseVCard(const QXmppVCardIq& card, const QStri
} }
} }
} else { } else {
if (!hasAvatar || !info.autogenerated) { if (!hasAvatar || !info.autogenerated)
setAutoGeneratedAvatar(resource); setAutoGeneratedAvatar(resource);
}
type = Shared::Avatar::autocreated; type = Shared::Avatar::autocreated;
path = avatarPath(resource) + ".png"; path = avatarPath(resource) + ".png";
} }
@ -542,13 +518,11 @@ void Core::RosterItem::handleResponseVCard(const QXmppVCardIq& card, const QStri
vCard.setAvatarType(type); vCard.setAvatarType(type);
vCard.setAvatarPath(path); vCard.setAvatarPath(path);
if (resource.size() == 0) { if (resource.size() == 0)
emit avatarChanged(vCard.getAvatarType(), vCard.getAvatarPath()); emit avatarChanged(vCard.getAvatarType(), vCard.getAvatarPath());
}
} }
void Core::RosterItem::clearArchiveRequests() void Core::RosterItem::clearArchiveRequests() {
{
syncronizing = false; syncronizing = false;
requestedCount = 0; requestedCount = 0;
requestedBefore = ""; requestedBefore = "";
@ -564,30 +538,72 @@ void Core::RosterItem::clearArchiveRequests()
requestCache.clear(); requestCache.clear();
} }
void Core::RosterItem::downgradeDatabaseState() void Core::RosterItem::downgradeDatabaseState() {
{ if (archiveState == ArchiveState::complete)
if (archiveState == ArchiveState::complete) {
archiveState = ArchiveState::beginning; archiveState = ArchiveState::beginning;
}
if (archiveState == ArchiveState::end) {
if (archiveState == ArchiveState::end)
archiveState = ArchiveState::chunk; 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) { for (const Shared::Message& msg : appendCache) {
if (msg.getId() == id) { if (msg.getId() == id)
return msg; return msg;
}
} }
for (Shared::Message& msg : hisoryCache) { for (Shared::Message& msg : hisoryCache) {
if (msg.getId() == id) { if (msg.getId() == id)
return msg; return msg;
}
} }
return archive->getElement(id); 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<QString, QVariant> Core::RosterItem::getInfo() const {
QMap<QString, QVariant> 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<QString, QVariant>& 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);
}
}

View File

@ -62,6 +62,8 @@ public:
void setName(const QString& n); void setName(const QString& n);
QString getServer() const; QString getServer() const;
bool isMuc() const; bool isMuc() const;
bool isEncryptionEnabled() const;
void enableEncryption(bool value = true);
void addMessageToArchive(const Shared::Message& msg); void addMessageToArchive(const Shared::Message& msg);
void correctMessageInArchive(const QString& originalId, 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<QString, QVariant>& data); bool changeMessage(const QString& id, const QMap<QString, QVariant>& data);
void clearArchiveRequests(); void clearArchiveRequests();
void downgradeDatabaseState(); void downgradeDatabaseState();
virtual QMap<QString, QVariant> getInfo() const;
Shared::Message getMessage(const QString& id); Shared::Message getMessage(const QString& id);
signals: signals:
void nameChanged(const QString& name); void nameChanged(const QString& name) const;
void subscriptionStateChanged(Shared::SubscriptionState state); void subscriptionStateChanged(Shared::SubscriptionState state) const;
void historyResponse(const std::list<Shared::Message>& messages, bool last); void historyResponse(const std::list<Shared::Message>& messages, bool last) const;
void needHistory(const QString& before, const QString& after, const QDateTime& afterTime = QDateTime()); void needHistory(const QString& before, const QString& after, const QDateTime& afterTime = QDateTime()) const;
void avatarChanged(Shared::Avatar, const QString& path); void avatarChanged(Shared::Avatar, const QString& path) const;
void requestVCard(const QString& jid); void requestVCard(const QString& jid) const;
void encryptionChanged(bool value) const;
public: public:
const QString jid; const QString jid;
@ -96,6 +100,13 @@ public:
protected: protected:
virtual bool setAvatar(const QByteArray& data, Archive::AvatarInfo& info, const QString& resource = ""); virtual bool setAvatar(const QByteArray& data, Archive::AvatarInfo& info, const QString& resource = "");
virtual bool setAutoGeneratedAvatar(Archive::AvatarInfo& info, const QString& resource = ""); virtual bool setAutoGeneratedAvatar(Archive::AvatarInfo& info, const QString& resource = "");
void careAboutAvatar(
bool hasAvatar,
const Archive::AvatarInfo& info,
QMap<QString, QVariant>& output,
const QString& resource = "",
const QString& subject = ""
) const;
protected: protected:
QString name; QString name;

View File

@ -29,6 +29,7 @@ Core::Archive::Archive(const QString& p_jid, QObject* parent):
jid(p_jid), jid(p_jid),
opened(false), opened(false),
fromTheBeginning(false), fromTheBeginning(false),
encryptionEnabled(false),
environment(), environment(),
main(), main(),
order(), order(),
@ -85,6 +86,12 @@ void Core::Archive::open(const QString& account)
fromTheBeginning = false; fromTheBeginning = false;
} }
try {
encryptionEnabled = getStatBoolValue("encryptionEnabled", txn);
} catch (const NotFound& e) {
encryptionEnabled = false;
}
std::string sJid = jid.toStdString(); std::string sJid = jid.toStdString();
AvatarInfo info; AvatarInfo info;
bool hasAvatar = readAvatarInfo(info, sJid, txn); bool hasAvatar = readAvatarInfo(info, sJid, txn);
@ -603,7 +610,7 @@ std::list<Shared::Message> Core::Archive::getBefore(int count, const QString& id
return res; return res;
} }
bool Core::Archive::isFromTheBeginning() bool Core::Archive::isFromTheBeginning() const
{ {
if (!opened) { if (!opened) {
throw Closed("isFromTheBeginning", jid.toStdString()); 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 QString Core::Archive::idByStanzaId(const QString& stanzaId) const
{ {
if (!opened) { if (!opened) {

View File

@ -55,8 +55,10 @@ public:
void clear(); void clear();
long unsigned int size() const; long unsigned int size() const;
std::list<Shared::Message> getBefore(int count, const QString& id); std::list<Shared::Message> getBefore(int count, const QString& id);
bool isFromTheBeginning(); bool isFromTheBeginning() const;
void setFromTheBeginning(bool is); 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 = ""); bool setAvatar(const QByteArray& data, AvatarInfo& info, bool generated = false, const QString& resource = "");
AvatarInfo getAvatarInfo(const QString& resource = "") const; AvatarInfo getAvatarInfo(const QString& resource = "") const;
bool readAvatarInfo(AvatarInfo& target, const QString& resource = "") const; bool readAvatarInfo(AvatarInfo& target, const QString& resource = "") const;
@ -171,6 +173,7 @@ public:
private: private:
bool opened; bool opened;
bool fromTheBeginning; bool fromTheBeginning;
bool encryptionEnabled;
MDB_env* environment; MDB_env* environment;
MDB_dbi main; //id to message MDB_dbi main; //id to message
MDB_dbi order; //time to id MDB_dbi order; //time to id

View File

@ -1,11 +1,11 @@
find_package(Qt5LinguistTools) find_package(Qt${QT_VERSION_MAJOR}LinguistTools)
set(TS_FILES set(TS_FILES
squawk.en.ts squawk.en.ts
squawk.ru.ts squawk.ru.ts
squawk.pt_BR.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}) add_custom_target(translations ALL DEPENDS ${QM_FILES})
install(FILES ${QM_FILES} DESTINATION ${CMAKE_INSTALL_DATADIR}/macaw.me/squawk/l10n) install(FILES ${QM_FILES} DESTINATION ${CMAKE_INSTALL_DATADIR}/macaw.me/squawk/l10n)