X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fcommon%2Fircuser.cpp;h=ec1ecb1c93c903c93b3386fbf30a4c9da29b3b92;hp=b9f359e1da8c00593b7de937b82923b0a749694b;hb=7298446b3e86140c4bbbfe7aeeb959c16c53363c;hpb=4a5065255e652dd0c301bac0db41b7afb777ef49 diff --git a/src/common/ircuser.cpp b/src/common/ircuser.cpp index b9f359e1..ec1ecb1c 100644 --- a/src/common/ircuser.cpp +++ b/src/common/ircuser.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005-2013 by the Quassel Project * + * Copyright (C) 2005-2020 by the Quassel Project * * devel@quassel-irc.org * * * * This program is free software; you can redistribute it and/or modify * @@ -19,42 +19,40 @@ ***************************************************************************/ #include "ircuser.h" -#include "util.h" +#include +#include + +#include "ircchannel.h" #include "network.h" #include "signalproxy.h" -#include "ircchannel.h" - -#include -#include +#include "util.h" -INIT_SYNCABLE_OBJECT(IrcUser) -IrcUser::IrcUser(const QString &hostmask, Network *network) : SyncableObject(network), - _initialized(false), - _nick(nickFromMask(hostmask)), - _user(userFromMask(hostmask)), - _host(hostFromMask(hostmask)), - _realName(), - _awayMessage(), - _away(false), - _server(), +IrcUser::IrcUser(const QString& hostmask, Network* network) + : SyncableObject(network) + , _initialized(false) + , _nick(nickFromMask(hostmask)) + , _user(userFromMask(hostmask)) + , _host(hostFromMask(hostmask)) + , _realName() + , _awayMessage() + , _away(false) + , _server() + , // _idleTime(QDateTime::currentDateTime()), - _ircOperator(), - _lastAwayMessage(0), - _whoisServiceReply(), - _network(network), - _codecForEncoding(0), - _codecForDecoding(0) + _ircOperator() + , _lastAwayMessageTime() + , _whoisServiceReply() + , _encrypted(false) + , _network(network) + , _codecForEncoding(nullptr) + , _codecForDecoding(nullptr) { updateObjectName(); + _lastAwayMessageTime.setTimeSpec(Qt::UTC); + _lastAwayMessageTime.setMSecsSinceEpoch(0); } - -IrcUser::~IrcUser() -{ -} - - // ==================== // PUBLIC: // ==================== @@ -64,58 +62,54 @@ QString IrcUser::hostmask() const return QString("%1!%2@%3").arg(nick()).arg(user()).arg(host()); } - QDateTime IrcUser::idleTime() { - if (QDateTime::currentDateTime().toTime_t() - _idleTimeSet.toTime_t() > 1200) + if ((QDateTime::currentDateTime().toMSecsSinceEpoch() - _idleTimeSet.toMSecsSinceEpoch()) > 1200000) { + // 20 * 60 * 1000 = 1200000 + // 20 minutes have elapsed, clear the known idle time as it's likely inaccurate by now _idleTime = QDateTime(); + } return _idleTime; } - QStringList IrcUser::channels() const { QStringList chanList; - IrcChannel *channel; - foreach(channel, _channels) { + IrcChannel* channel; + foreach (channel, _channels) { chanList << channel->name(); } return chanList; } - -void IrcUser::setCodecForEncoding(const QString &name) +void IrcUser::setCodecForEncoding(const QString& name) { - setCodecForEncoding(QTextCodec::codecForName(name.toAscii())); + setCodecForEncoding(QTextCodec::codecForName(name.toLatin1())); } - -void IrcUser::setCodecForEncoding(QTextCodec *codec) +void IrcUser::setCodecForEncoding(QTextCodec* codec) { _codecForEncoding = codec; } - -void IrcUser::setCodecForDecoding(const QString &name) +void IrcUser::setCodecForDecoding(const QString& name) { - setCodecForDecoding(QTextCodec::codecForName(name.toAscii())); + setCodecForDecoding(QTextCodec::codecForName(name.toLatin1())); } - -void IrcUser::setCodecForDecoding(QTextCodec *codec) +void IrcUser::setCodecForDecoding(QTextCodec* codec) { _codecForDecoding = codec; } - -QString IrcUser::decodeString(const QByteArray &text) const +QString IrcUser::decodeString(const QByteArray& text) const { - if (!codecForDecoding()) return network()->decodeString(text); + if (!codecForDecoding()) + return network()->decodeString(text); return ::decodeString(text, codecForDecoding()); } - -QByteArray IrcUser::encodeString(const QString &string) const +QByteArray IrcUser::encodeString(const QString& string) const { if (codecForEncoding()) { return codecForEncoding()->fromUnicode(string); @@ -123,11 +117,10 @@ QByteArray IrcUser::encodeString(const QString &string) const return network()->encodeString(string); } - // ==================== // PUBLIC SLOTS: // ==================== -void IrcUser::setUser(const QString &user) +void IrcUser::setUser(const QString& user) { if (!user.isEmpty() && _user != user) { _user = user; @@ -135,8 +128,7 @@ void IrcUser::setUser(const QString &user) } } - -void IrcUser::setRealName(const QString &realName) +void IrcUser::setRealName(const QString& realName) { if (!realName.isEmpty() && _realName != realName) { _realName = realName; @@ -144,27 +136,34 @@ void IrcUser::setRealName(const QString &realName) } } +void IrcUser::setAccount(const QString& account) +{ + if (_account != account) { + _account = account; + SYNC(ARG(account)) + } +} -void IrcUser::setAway(const bool &away) +void IrcUser::setAway(bool away) { if (away != _away) { _away = away; + markAwayChanged(); SYNC(ARG(away)) emit awaySet(away); } } - -void IrcUser::setAwayMessage(const QString &awayMessage) +void IrcUser::setAwayMessage(const QString& awayMessage) { if (!awayMessage.isEmpty() && _awayMessage != awayMessage) { _awayMessage = awayMessage; + markAwayChanged(); SYNC(ARG(awayMessage)) } } - -void IrcUser::setIdleTime(const QDateTime &idleTime) +void IrcUser::setIdleTime(const QDateTime& idleTime) { if (idleTime.isValid() && _idleTime != idleTime) { _idleTime = idleTime; @@ -173,8 +172,7 @@ void IrcUser::setIdleTime(const QDateTime &idleTime) } } - -void IrcUser::setLoginTime(const QDateTime &loginTime) +void IrcUser::setLoginTime(const QDateTime& loginTime) { if (loginTime.isValid() && _loginTime != loginTime) { _loginTime = loginTime; @@ -182,8 +180,7 @@ void IrcUser::setLoginTime(const QDateTime &loginTime) } } - -void IrcUser::setServer(const QString &server) +void IrcUser::setServer(const QString& server) { if (!server.isEmpty() && _server != server) { _server = server; @@ -191,8 +188,7 @@ void IrcUser::setServer(const QString &server) } } - -void IrcUser::setIrcOperator(const QString &ircOperator) +void IrcUser::setIrcOperator(const QString& ircOperator) { if (!ircOperator.isEmpty() && _ircOperator != ircOperator) { _ircOperator = ircOperator; @@ -200,17 +196,30 @@ void IrcUser::setIrcOperator(const QString &ircOperator) } } +// This function is only ever called by SYNC calls from legacy cores (pre-0.13). +// Therefore, no SYNC call is needed here. +void IrcUser::setLastAwayMessage(int lastAwayMessage) +{ +#if QT_VERSION >= 0x050800 + QDateTime lastAwayMessageTime = QDateTime::fromSecsSinceEpoch(lastAwayMessage); +#else + // toSecsSinceEpoch() was added in Qt 5.8. Manually downconvert to seconds for now. + // See https://doc.qt.io/qt-5/qdatetime.html#toMSecsSinceEpoch + QDateTime lastAwayMessageTime = QDateTime::fromMSecsSinceEpoch(lastAwayMessage * 1000); +#endif + lastAwayMessageTime.setTimeSpec(Qt::UTC); + setLastAwayMessageTime(lastAwayMessageTime); +} -void IrcUser::setLastAwayMessage(const int &lastAwayMessage) +void IrcUser::setLastAwayMessageTime(const QDateTime& lastAwayMessageTime) { - if (lastAwayMessage > _lastAwayMessage) { - _lastAwayMessage = lastAwayMessage; - SYNC(ARG(lastAwayMessage)) + if (lastAwayMessageTime > _lastAwayMessageTime) { + _lastAwayMessageTime = lastAwayMessageTime; + SYNC(ARG(lastAwayMessageTime)) } } - -void IrcUser::setHost(const QString &host) +void IrcUser::setHost(const QString& host) { if (!host.isEmpty() && _host != host) { _host = host; @@ -218,8 +227,7 @@ void IrcUser::setHost(const QString &host) } } - -void IrcUser::setNick(const QString &nick) +void IrcUser::setNick(const QString& nick) { if (!nick.isEmpty() && nick != _nick) { _nick = nick; @@ -229,8 +237,7 @@ void IrcUser::setNick(const QString &nick) } } - -void IrcUser::setWhoisServiceReply(const QString &whoisServiceReply) +void IrcUser::setWhoisServiceReply(const QString& whoisServiceReply) { if (!whoisServiceReply.isEmpty() && whoisServiceReply != _whoisServiceReply) { _whoisServiceReply = whoisServiceReply; @@ -238,8 +245,7 @@ void IrcUser::setWhoisServiceReply(const QString &whoisServiceReply) } } - -void IrcUser::setSuserHost(const QString &suserHost) +void IrcUser::setSuserHost(const QString& suserHost) { if (!suserHost.isEmpty() && suserHost != _suserHost) { _suserHost = suserHost; @@ -247,14 +253,19 @@ void IrcUser::setSuserHost(const QString &suserHost) } } +void IrcUser::setEncrypted(bool encrypted) +{ + _encrypted = encrypted; + emit encryptedSet(encrypted); + SYNC(ARG(encrypted)) +} void IrcUser::updateObjectName() { - renameObject(QString::number(network()->networkId().toInt()) + "/" + _nick); + setObjectName(QString::number(network()->networkId().toInt()) + "/" + _nick); } - -void IrcUser::updateHostmask(const QString &mask) +void IrcUser::updateHostmask(const QString& mask) { if (mask == hostmask()) return; @@ -265,41 +276,30 @@ void IrcUser::updateHostmask(const QString &mask) setHost(host); } - -void IrcUser::joinChannel(IrcChannel *channel) +void IrcUser::joinChannel(IrcChannel* channel, bool skip_channel_join) { Q_ASSERT(channel); if (!_channels.contains(channel)) { _channels.insert(channel); - channel->joinIrcUser(this); + if (!skip_channel_join) + channel->joinIrcUser(this); } } - -void IrcUser::joinChannel(const QString &channelname) +void IrcUser::joinChannel(const QString& channelname) { joinChannel(network()->newIrcChannel(channelname)); } - -void IrcUser::partChannel(IrcChannel *channel) +void IrcUser::partChannel(IrcChannel* channel) { - if (_channels.contains(channel)) { - _channels.remove(channel); - disconnect(channel, 0, this, 0); - channel->part(this); - QString channelName = channel->name(); - SYNC_OTHER(partChannel, ARG(channelName)) - if (_channels.isEmpty() && !network()->isMe(this)) - quit(); - } + partChannelInternal(channel, false); } - -void IrcUser::partChannel(const QString &channelname) +void IrcUser::partChannel(const QString& channelname) { - IrcChannel *channel = network()->ircChannel(channelname); - if (channel == 0) { + IrcChannel* channel = network()->ircChannel(channelname); + if (channel == nullptr) { qWarning() << "IrcUser::partChannel(): received part for unknown Channel" << channelname; } else { @@ -307,25 +307,41 @@ void IrcUser::partChannel(const QString &channelname) } } +void IrcUser::partChannelInternal(IrcChannel* channel, bool skip_sync) +{ + if (_channels.contains(channel)) { + _channels.remove(channel); + disconnect(channel, nullptr, this, nullptr); + channel->part(this); + QString channelName = channel->name(); + if (!skip_sync) SYNC_OTHER(partChannel, ARG(channelName)) + if (_channels.isEmpty() && !network()->isMe(this)) + quitInternal(skip_sync); + } +} void IrcUser::quit() { - QList channels = _channels.toList(); + quitInternal(false); +} + +void IrcUser::quitInternal(bool skip_sync) +{ + QList channels = _channels.values(); _channels.clear(); - foreach(IrcChannel *channel, channels) { - disconnect(channel, 0, this, 0); + foreach (IrcChannel* channel, channels) { + disconnect(channel, nullptr, this, nullptr); channel->part(this); } network()->removeIrcUser(this); - SYNC(NO_ARG) + if (!skip_sync) SYNC(NO_ARG) emit quited(); } - void IrcUser::channelDestroyed() { // private slot! - IrcChannel *channel = static_cast(sender()); + auto* channel = static_cast(sender()); if (_channels.contains(channel)) { _channels.remove(channel); if (_channels.isEmpty() && !network()->isMe(this)) @@ -333,31 +349,36 @@ void IrcUser::channelDestroyed() } } - -void IrcUser::setUserModes(const QString &modes) +void IrcUser::setUserModes(const QString& modes) { - _userModes = modes; - SYNC(ARG(modes)) - emit userModesSet(modes); + if (_userModes != modes) { + _userModes = modes; + SYNC(ARG(modes)) + emit userModesSet(modes); + } } - -void IrcUser::addUserModes(const QString &modes) +void IrcUser::addUserModes(const QString& modes) { if (modes.isEmpty()) return; + // Don't needlessly sync when no changes are made + bool changesMade = false; for (int i = 0; i < modes.count(); i++) { - if (!_userModes.contains(modes[i])) + if (!_userModes.contains(modes[i])) { _userModes += modes[i]; + changesMade = true; + } } - SYNC(ARG(modes)) - emit userModesAdded(modes); + if (changesMade) { + SYNC(ARG(modes)) + emit userModesAdded(modes); + } } - -void IrcUser::removeUserModes(const QString &modes) +void IrcUser::removeUserModes(const QString& modes) { if (modes.isEmpty()) return; @@ -369,15 +390,13 @@ void IrcUser::removeUserModes(const QString &modes) emit userModesRemoved(modes); } - -void IrcUser::setLastChannelActivity(BufferId buffer, const QDateTime &time) +void IrcUser::setLastChannelActivity(BufferId buffer, const QDateTime& time) { _lastActivity[buffer] = time; emit lastChannelActivityUpdated(buffer, time); } - -void IrcUser::setLastSpokenTo(BufferId buffer, const QDateTime &time) +void IrcUser::setLastSpokenTo(BufferId buffer, const QDateTime& time) { _lastSpokenTo[buffer] = time; emit lastSpokenToUpdated(buffer, time);