From: Janne Koschinski Date: Wed, 20 Dec 2017 02:22:31 +0000 (+0100) Subject: Implement UI and serialization logic for sender modes X-Git-Tag: travis-deploy-test~200 X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=commitdiff_plain;h=53861faa5551606eea31588b65ba501b24fb2e1a;hp=30fa961d1aca319b52071ad9d6e4527ea2638fb7 Implement UI and serialization logic for sender modes --- diff --git a/src/client/clientauthhandler.cpp b/src/client/clientauthhandler.cpp index 4a99890d..ce7c58d9 100644 --- a/src/client/clientauthhandler.cpp +++ b/src/client/clientauthhandler.cpp @@ -288,7 +288,7 @@ void ClientAuthHandler::startRegistration() useSsl = _account.useSsl(); #endif - _peer->dispatch(RegisterClient(Quassel::buildInfo().fancyVersionString, Quassel::buildInfo().commitDate, useSsl)); + _peer->dispatch(RegisterClient(Quassel::buildInfo().fancyVersionString, Quassel::buildInfo().commitDate, useSsl, Quassel::features())); } @@ -305,7 +305,8 @@ void ClientAuthHandler::handle(const ClientRegistered &msg) _backendInfo = msg.backendInfo; _authenticatorInfo = msg.authenticatorInfo; - Client::setCoreFeatures(static_cast(msg.coreFeatures)); + Client::setCoreFeatures(Quassel::Features(msg.coreFeatures)); + SignalProxy::current()->sourcePeer()->setFeatures(Quassel::Features(msg.coreFeatures)); // The legacy protocol enables SSL at this point if(_legacy && _account.useSsl()) diff --git a/src/common/message.cpp b/src/common/message.cpp index 25ea45c0..a0e480a1 100644 --- a/src/common/message.cpp +++ b/src/common/message.cpp @@ -21,6 +21,8 @@ #include "message.h" #include "util.h" +#include "signalproxy.h" +#include "peer.h" #include @@ -51,28 +53,52 @@ Message::Message(const QDateTime &ts, const BufferInfo &bufferInfo, Type type, c QDataStream &operator<<(QDataStream &out, const Message &msg) { // We do not serialize the sender prefixes until we have a new protocol or client-features implemented - out << msg.msgId() << (quint32)msg.timestamp().toTime_t() << (quint32)msg.type() << (quint8)msg.flags() - << msg.bufferInfo() << msg.sender().toUtf8() << msg.contents().toUtf8(); + out << msg.msgId() + << (quint32) msg.timestamp().toTime_t() + << (quint32) msg.type() + << (quint8) msg.flags() + << msg.bufferInfo() + << msg.sender().toUtf8(); + + if (SignalProxy::current()->targetPeer()->features().testFlag(Quassel::Feature::SenderPrefixes)) + out << msg.senderPrefixes().toUtf8(); + + out << msg.contents().toUtf8(); return out; } QDataStream &operator>>(QDataStream &in, Message &msg) { - quint8 f; - quint32 t; - quint32 ts; - QByteArray s, m; - BufferInfo buf; - in >> msg._msgId >> ts >> t >> f >> buf >> s >> m; - msg._type = (Message::Type)t; - msg._flags = (Message::Flags)f; - msg._bufferInfo = buf; - msg._timestamp = QDateTime::fromTime_t(ts); - msg._sender = QString::fromUtf8(s); - // We do not serialize the sender prefixes until we have a new protocol or client-features implemented - msg._senderPrefixes = QString(""); - msg._contents = QString::fromUtf8(m); + in >> msg._msgId; + + quint32 timeStamp; + in >> timeStamp; + msg._timestamp = QDateTime::fromTime_t(timeStamp); + + quint32 type; + in >> type; + msg._type = Message::Type(type); + + quint8 flags; + in >> flags; + msg._flags = Message::Flags(flags); + + in >> msg._bufferInfo; + + QByteArray sender; + in >> sender; + msg._sender = QString::fromUtf8(sender); + + QByteArray senderPrefixes; + if (SignalProxy::current()->sourcePeer()->features().testFlag(Quassel::Feature::SenderPrefixes)) + in >> senderPrefixes; + msg._senderPrefixes = QString::fromUtf8(senderPrefixes); + + QByteArray contents; + in >> contents; + msg._contents = QString::fromUtf8(contents); + return in; } diff --git a/src/common/peer.cpp b/src/common/peer.cpp index b0eee444..9a9e3f58 100644 --- a/src/common/peer.cpp +++ b/src/common/peer.cpp @@ -57,6 +57,14 @@ void Peer::setClientVersion(const QString &clientVersion) { _clientVersion = clientVersion; } +Quassel::Features Peer::features() const { + return _features; +} + +void Peer::setFeatures(Quassel::Features features) { + _features = features; +} + int Peer::id() const { return _id; } diff --git a/src/common/peer.h b/src/common/peer.h index 6f17ed66..34a56619 100644 --- a/src/common/peer.h +++ b/src/common/peer.h @@ -28,6 +28,7 @@ #include "authhandler.h" #include "protocol.h" #include "signalproxy.h" +#include "quassel.h" class Peer : public QObject { @@ -51,6 +52,9 @@ public: QString clientVersion() const; void setClientVersion(const QString &clientVersion); + Quassel::Features features() const; + void setFeatures(Quassel::Features features); + int id() const; void setId(int id); @@ -102,6 +106,7 @@ private: QString _buildDate; QString _clientVersion; + Quassel::Features _features; int _id = -1; }; diff --git a/src/common/protocol.h b/src/common/protocol.h index bf6c401e..45760801 100644 --- a/src/common/protocol.h +++ b/src/common/protocol.h @@ -57,16 +57,18 @@ struct HandshakeMessage { struct RegisterClient : public HandshakeMessage { - inline RegisterClient(const QString &clientVersion, const QString &buildDate, bool sslSupported = false) + inline RegisterClient(const QString &clientVersion, const QString &buildDate, bool sslSupported = false, int32_t features = 0) : clientVersion(clientVersion) , buildDate(buildDate) - , sslSupported(sslSupported) {} + , sslSupported(sslSupported) + , clientFeatures(features) {} QString clientVersion; QString buildDate; // this is only used by the LegacyProtocol in compat mode bool sslSupported; + int32_t clientFeatures; }; diff --git a/src/common/protocols/datastream/datastreampeer.cpp b/src/common/protocols/datastream/datastreampeer.cpp index 6a21a169..e91c9775 100644 --- a/src/common/protocols/datastream/datastreampeer.cpp +++ b/src/common/protocols/datastream/datastreampeer.cpp @@ -116,7 +116,7 @@ void DataStreamPeer::handleHandshakeMessage(const QVariantList &mapData) } if (msgType == "ClientInit") { - handle(RegisterClient(m["ClientVersion"].toString(), m["ClientDate"].toString(), false)); // UseSsl obsolete + handle(RegisterClient(m["ClientVersion"].toString(), m["ClientDate"].toString(), false, m["Features"].toInt())); // UseSsl obsolete } else if (msgType == "ClientInitReject") { @@ -168,6 +168,7 @@ void DataStreamPeer::dispatch(const RegisterClient &msg) { m["MsgType"] = "ClientInit"; m["ClientVersion"] = msg.clientVersion; m["ClientDate"] = msg.buildDate; + m["Features"] = msg.clientFeatures; writeMessage(m); } diff --git a/src/common/protocols/legacy/legacypeer.cpp b/src/common/protocols/legacy/legacypeer.cpp index f59dffa6..ebbd164e 100644 --- a/src/common/protocols/legacy/legacypeer.cpp +++ b/src/common/protocols/legacy/legacypeer.cpp @@ -151,7 +151,7 @@ void LegacyPeer::handleHandshakeMessage(const QVariant &msg) socket()->setProperty("UseCompression", true); } #endif - handle(RegisterClient(m["ClientVersion"].toString(), m["ClientDate"].toString(), m["UseSsl"].toBool())); + handle(RegisterClient(m["ClientVersion"].toString(), m["ClientDate"].toString(), m["UseSsl"].toBool(), m["Features"].toInt())); } else if (msgType == "ClientInitReject") { @@ -214,6 +214,7 @@ void LegacyPeer::dispatch(const RegisterClient &msg) { m["MsgType"] = "ClientInit"; m["ClientVersion"] = msg.clientVersion; m["ClientDate"] = msg.buildDate; + m["Features"] = msg.clientFeatures; // FIXME only in compat mode m["ProtocolVersion"] = protocolVersion; diff --git a/src/common/quassel.h b/src/common/quassel.h index d20fdc23..b30872da 100644 --- a/src/common/quassel.h +++ b/src/common/quassel.h @@ -79,8 +79,9 @@ public: Authenticators = 0x0400, /// Whether or not the core supports auth backends. BufferActivitySync = 0x0800, /// Sync buffer activity status CoreSideHighlights = 0x1000, /// Core-Side highlight configuration and matching + SenderPrefixes = 0x2000, /// Show prefixes for senders in backlog - NumFeatures = 0x1000 + NumFeatures = 0x2000 }; Q_DECLARE_FLAGS(Features, Feature) diff --git a/src/common/remotepeer.cpp b/src/common/remotepeer.cpp index 60c8b63d..e25cbb3f 100644 --- a/src/common/remotepeer.cpp +++ b/src/common/remotepeer.cpp @@ -208,8 +208,16 @@ void RemotePeer::close(const QString &reason) void RemotePeer::onReadyRead() { QByteArray msg; - while (readMessage(msg)) + while (readMessage(msg)) { + if (SignalProxy::current()) + SignalProxy::current()->setSourcePeer(this); + processMessage(msg); + + + if (SignalProxy::current()) + SignalProxy::current()->setSourcePeer(nullptr); + } } diff --git a/src/common/signalproxy.cpp b/src/common/signalproxy.cpp index db4a6758..bcc639fa 100644 --- a/src/common/signalproxy.cpp +++ b/src/common/signalproxy.cpp @@ -221,6 +221,8 @@ void SignalProxy::setProxyMode(ProxyMode mode) initClient(); } +thread_local SignalProxy *SignalProxy::_current; + void SignalProxy::init() { @@ -230,6 +232,7 @@ void SignalProxy::init() setHeartBeatInterval(30); setMaxHeartBeatCount(2); _secure = false; + _current = this; updateSecureState(); } @@ -514,21 +517,28 @@ template void SignalProxy::dispatch(const T &protoMessage) { for (auto peer : _peerMap.values()) { + _targetPeer = peer; + if (peer->isOpen()) peer->dispatch(protoMessage); else QCoreApplication::postEvent(this, new ::RemovePeerEvent(peer)); } + _targetPeer = nullptr; } template void SignalProxy::dispatch(Peer *peer, const T &protoMessage) { + _targetPeer = peer; + if (peer && peer->isOpen()) peer->dispatch(protoMessage); else QCoreApplication::postEvent(this, new ::RemovePeerEvent(peer)); + + _targetPeer = nullptr; } @@ -571,7 +581,9 @@ void SignalProxy::handle(Peer *peer, const SyncMessage &syncMessage) if (eMeta->argTypes(receiverId).count() > 1) returnParams << syncMessage.params; returnParams << returnValue; + _targetPeer = peer; peer->dispatch(SyncMessage(syncMessage.className, syncMessage.objectName, eMeta->methodName(receiverId), returnParams)); + _targetPeer = nullptr; } // send emit update signal @@ -594,7 +606,9 @@ void SignalProxy::handle(Peer *peer, const InitRequest &initRequest) } SyncableObject *obj = _syncSlave[initRequest.className][initRequest.objectName]; + _targetPeer = peer; peer->dispatch(InitData(initRequest.className, initRequest.objectName, initData(obj))); + _targetPeer = nullptr; } @@ -851,6 +865,22 @@ void SignalProxy::restrictTargetPeers(QSet peers, std::function c _restrictedTargets = previousRestrictedTargets; } +Peer *SignalProxy::sourcePeer() { + return _sourcePeer; +} + +void SignalProxy::setSourcePeer(Peer *sourcePeer) { + _sourcePeer = sourcePeer; +} + +Peer *SignalProxy::targetPeer() { + return _targetPeer; +} + +void SignalProxy::setTargetPeer(Peer *targetPeer) { + _targetPeer = targetPeer; +} + // ================================================== // ExtendedMetaObject // ================================================== diff --git a/src/common/signalproxy.h b/src/common/signalproxy.h index 63d3438a..77ef3a46 100644 --- a/src/common/signalproxy.h +++ b/src/common/signalproxy.h @@ -23,8 +23,10 @@ #include #include +#include #include +#include #include "protocol.h" @@ -80,6 +82,10 @@ public: void dumpProxyStats(); void dumpSyncMap(SyncableObject *object); + static SignalProxy *current() { + return _current; + } + /**@{*/ /** * This method allows to send a signal only to a limited set of peers @@ -111,7 +117,14 @@ public: /** * @return If handling a signal, the Peer from which the current signal originates */ - Peer *sourcePeer() { return _sourcePeer; } + Peer *sourcePeer(); + void setSourcePeer(Peer *sourcePeer); + + /** + * @return If sending a signal, the Peer to which the current signal is directed + */ + Peer *targetPeer(); + void setTargetPeer(Peer *targetPeer); public slots: void detachObject(QObject *obj); @@ -206,6 +219,9 @@ private: bool _restrictMessageTarget = false; Peer *_sourcePeer = nullptr; + Peer *_targetPeer = nullptr; + + thread_local static SignalProxy *_current; friend class SignalRelay; friend class SyncableObject; diff --git a/src/core/coreauthhandler.cpp b/src/core/coreauthhandler.cpp index a2367c37..c01115f4 100644 --- a/src/core/coreauthhandler.cpp +++ b/src/core/coreauthhandler.cpp @@ -185,6 +185,7 @@ void CoreAuthHandler::handle(const RegisterClient &msg) _peer->setBuildDate(msg.buildDate); _peer->setClientVersion(msg.clientVersion); + _peer->setFeatures(Quassel::Features(msg.clientFeatures)); if (_legacy && useSsl) startSsl(); diff --git a/src/qtui/chatviewsettings.h b/src/qtui/chatviewsettings.h index b727ab8a..a0f70f9d 100644 --- a/src/qtui/chatviewsettings.h +++ b/src/qtui/chatviewsettings.h @@ -73,6 +73,13 @@ public: */ inline void setTimestampFormatString(const QString &format) { setLocalValue("TimestampFormat", format); } + /** + * Gets if prefixmodes are shown before sender names + * + * @returns True if sender prefixmodes enabled, otherwise false + */ + inline bool showSenderPrefixes() { return localValue("ShowSenderPrefixes", false).toBool(); } + /** * Gets if brackets are shown around sender names * diff --git a/src/qtui/qtuistyle.cpp b/src/qtui/qtuistyle.cpp index d167b2eb..60d858ae 100644 --- a/src/qtui/qtuistyle.cpp +++ b/src/qtui/qtuistyle.cpp @@ -32,6 +32,8 @@ QtUiStyle::QtUiStyle(QObject *parent) : UiStyle(parent) updateUseCustomTimestampFormat(); s.notify("TimestampFormat", this, SLOT(updateTimestampFormatString())); updateTimestampFormatString(); + s.notify("ShowSenderPrefixes", this, SLOT(updateShowSenderPrefixes())); + updateShowSenderPrefixes(); s.notify("ShowSenderBrackets", this, SLOT(updateShowSenderBrackets())); updateShowSenderBrackets(); @@ -54,6 +56,12 @@ void QtUiStyle::updateTimestampFormatString() setTimestampFormatString(s.timestampFormatString()); } +void QtUiStyle::updateShowSenderPrefixes() +{ + ChatViewSettings s; + enableSenderPrefixes(s.showSenderPrefixes()); +} + void QtUiStyle::updateShowSenderBrackets() { ChatViewSettings s; diff --git a/src/qtui/qtuistyle.h b/src/qtui/qtuistyle.h index 733e73e5..8b9b17c3 100644 --- a/src/qtui/qtuistyle.h +++ b/src/qtui/qtuistyle.h @@ -59,6 +59,11 @@ private slots: * Updates knowledge of the current timestamp format */ void updateTimestampFormatString(); + + /** + * Updates knowledge of whether or not to show sender prefixmodes + */ + void updateShowSenderPrefixes(); /** * Updates knowledge of whether or not to show sender brackets diff --git a/src/qtui/settingspages/chatviewsettingspage.ui b/src/qtui/settingspages/chatviewsettingspage.ui index 80c6cff3..55fbc08e 100644 --- a/src/qtui/settingspages/chatviewsettingspage.ui +++ b/src/qtui/settingspages/chatviewsettingspage.ui @@ -92,6 +92,25 @@ + + + + Shows the modes of senders before their name (e.g. @, +) + + + Show sendermodes in front of nicknames: + + + true + + + true + + + ShowSenderPrefixes + + + diff --git a/src/uisupport/uistyle.cpp b/src/uisupport/uistyle.cpp index f35543de..3b9e079b 100644 --- a/src/uisupport/uistyle.cpp +++ b/src/uisupport/uistyle.cpp @@ -32,6 +32,7 @@ QHash UiStyle::_formatCodes; bool UiStyle::_useCustomTimestampFormat; /// If true, use the custom timestamp format QString UiStyle::_timestampFormatString; /// Timestamp format QString UiStyle::_systemTimestampFormatString; /// Cached copy of system locale timestamp format +bool UiStyle::_showSenderPrefixes; /// If true, show prefixmodes before sender names bool UiStyle::_showSenderBrackets; /// If true, show brackets around sender names UiStyle::UiStyle(QObject *parent) @@ -74,6 +75,7 @@ UiStyle::UiStyle(QObject *parent) // in there. setUseCustomTimestampFormat(false); setTimestampFormatString(" hh:mm:ss"); + enableSenderPrefixes(false); enableSenderBrackets(true); // BufferView / NickView settings @@ -224,6 +226,13 @@ void UiStyle::setTimestampFormatString(const QString &format) } } +void UiStyle::enableSenderPrefixes(bool enabled) +{ + if (_showSenderPrefixes != enabled) { + _showSenderPrefixes = enabled; + } +} + void UiStyle::enableSenderBrackets(bool enabled) { if (_showSenderBrackets != enabled) { @@ -908,15 +917,20 @@ QString UiStyle::StyledMessage::plainSender() const QString UiStyle::StyledMessage::decoratedSender() const { + QString _senderPrefixes; + if (_showSenderPrefixes) { + _senderPrefixes = senderPrefixes(); + } + switch (type()) { case Message::Plain: if (_showSenderBrackets) - return QString("<%1>").arg(plainSender()); + return QString("<%1%2>").arg(_senderPrefixes, plainSender()); else - return QString("%1").arg(plainSender()); + return QString("%1%2").arg(_senderPrefixes, plainSender()); break; case Message::Notice: - return QString("[%1]").arg(plainSender()); break; + return QString("[%1%2]").arg(_senderPrefixes, plainSender()); break; case Message::Action: return "-*-"; break; case Message::Nick: @@ -950,7 +964,7 @@ QString UiStyle::StyledMessage::decoratedSender() const case Message::Invite: return "->"; break; default: - return QString("%1").arg(plainSender()); + return QString("%1%2").arg(_senderPrefixes, plainSender()); } } diff --git a/src/uisupport/uistyle.h b/src/uisupport/uistyle.h index 030c1ac1..d565e5b8 100644 --- a/src/uisupport/uistyle.h +++ b/src/uisupport/uistyle.h @@ -284,6 +284,12 @@ protected: * @param[in] format Timestamp format string */ static void setTimestampFormatString(const QString &format); + /** + * Updates the local setting cache of whether or not to show sender prefixmodes + * + * @param[in] enabled If true, sender prefixmodes are enabled, otherwise false. + */ + static void enableSenderPrefixes(bool enabled); /** * Updates the local setting cache of whether or not to show sender brackets @@ -309,6 +315,7 @@ private: static bool _useCustomTimestampFormat; /// If true, use the custom timestamp format static QString _systemTimestampFormatString; /// Cached copy of system locale timestamp format static QString _timestampFormatString; /// Timestamp format string + static bool _showSenderPrefixes; /// If true, show prefixmodes before sender names static bool _showSenderBrackets; /// If true, show brackets around sender names QIcon _channelJoinedIcon;