More improvements to encoding handling. There is now a server encoding that
authorManuel Nickschas <sputnick@quassel-irc.org>
Wed, 13 Feb 2008 16:32:49 +0000 (16:32 +0000)
committerManuel Nickschas <sputnick@quassel-irc.org>
Wed, 13 Feb 2008 16:32:49 +0000 (16:32 +0000)
is independent from the message sending/receiving encodings, so you can have a
channelname encoded in ISO, for example, and still send messages in utf8 to that
chan.
No UI to configure this yet, the server encoding is hardcoded to Latin1 for now. The
rest can be edited in network settings.

13 files changed:
src/common/ircchannel.cpp
src/common/ircchannel.h
src/common/ircuser.cpp
src/common/ircuser.h
src/common/main.cpp
src/common/network.cpp
src/common/network.h
src/core/basichandler.cpp
src/core/basichandler.h
src/core/ircserverhandler.cpp
src/core/networkconnection.cpp
src/core/networkconnection.h
src/core/userinputhandler.cpp

index 0587697..f5710ba 100644 (file)
 #include <QDebug>
 
 
-IrcChannel::IrcChannel(const QString &channelname, Network *network) 
-  : SyncableObject(network),
+IrcChannel::IrcChannel(const QString &channelname, Network *network) : SyncableObject(network),
     _initialized(false),
     _name(channelname),
     _topic(QString()),
-    network(network)
+    network(network),
+    _codecForEncoding(0),
+    _codecForDecoding(0)
 {
   setObjectName(QString::number(network->networkId().toInt()) + "/" +  channelname);
 }
@@ -124,7 +125,7 @@ QString IrcChannel::decodeString(const QByteArray &text) const {
   return ::decodeString(text, _codecForDecoding);
 }
 
-QByteArray IrcChannel::encodeString(const QString string) const {
+QByteArray IrcChannel::encodeString(const QString &string) const {
   if(codecForEncoding()) {
     return _codecForEncoding->fromUnicode(string);
   }
index d970814..2bf5f64 100644 (file)
@@ -61,7 +61,7 @@ public:
   void setCodecForDecoding(QTextCodec *codec);
 
   QString decodeString(const QByteArray &text) const;
-  QByteArray encodeString(const QString string) const;
+  QByteArray encodeString(const QString &string) const;
 
 public slots:
   void setTopic(const QString &topic);
index 223a02f..c3c2d0c 100644 (file)
@@ -28,8 +28,7 @@
 #include <QTextCodec>
 #include <QDebug>
 
-IrcUser::IrcUser(const QString &hostmask, Network *network)
-  : SyncableObject(network),
+IrcUser::IrcUser(const QString &hostmask, Network *network) : SyncableObject(network),
     _initialized(false),
     _nick(nickFromMask(hostmask)),
     _user(userFromMask(hostmask)),
@@ -145,7 +144,7 @@ QString IrcUser::decodeString(const QByteArray &text) const {
   return ::decodeString(text, codecForDecoding());
 }
 
-QByteArray IrcUser::encodeString(const QString string) const {
+QByteArray IrcUser::encodeString(const QString &string) const {
   if(codecForEncoding()) {
     return codecForEncoding()->fromUnicode(string);
   }
index da96323..077cc6d 100644 (file)
@@ -80,7 +80,7 @@ public:
   void setCodecForDecoding(QTextCodec *codec);
 
   QString decodeString(const QByteArray &text) const;
-  QByteArray encodeString(const QString string) const;
+  QByteArray encodeString(const QString &string) const;
 
 public slots:
   void setUser(const QString &user);
index 378d8fe..0209647 100644 (file)
@@ -93,7 +93,7 @@ int main(int argc, char **argv) {
   quasselTranslator.load(QString(":i18n/quassel_%1").arg(locale.name()));
   app.installTranslator(&quasselTranslator);
 
-  Network::setDefaultCodecForServer("UTF-8");
+  Network::setDefaultCodecForServer("ISO-8859-15");
   Network::setDefaultCodecForEncoding("UTF-8");
   Network::setDefaultCodecForDecoding("ISO-8859-15");
 
index 99b647a..05efa9c 100644 (file)
@@ -36,6 +36,7 @@ QTextCodec *Network::_defaultCodecForDecoding = 0;
 //  Public:
 // ====================
 Network::Network(const NetworkId &networkid, QObject *parent) : SyncableObject(parent),
+    _proxy(0),
     _networkId(networkid),
     _identity(0),
     _myNick(QString()),
@@ -45,7 +46,6 @@ Network::Network(const NetworkId &networkid, QObject *parent) : SyncableObject(p
     _connectionState(Disconnected),
     _prefixes(QString()),
     _prefixModes(QString()),
-    _proxy(0),
     _useRandomServer(false),
     _useAutoIdentify(false),
     _useAutoReconnect(false),
@@ -296,7 +296,7 @@ IrcUser *Network::newIrcUser(const QString &hostmask) {
 }
 
 IrcUser *Network::newIrcUser(const QByteArray &hostmask) {
-  return newIrcUser(decodeString(hostmask));
+  return newIrcUser(decodeServerString(hostmask));
 }
 
 void Network::removeIrcUser(IrcUser *ircuser) {
@@ -337,7 +337,7 @@ IrcUser *Network::ircUser(QString nickname) const {
 }
 
 IrcUser *Network::ircUser(const QByteArray &nickname) const {
-  return ircUser(decodeString(nickname));
+  return ircUser(decodeServerString(nickname));
 }
 
 QList<IrcUser *> Network::ircUsers() const {
@@ -370,7 +370,7 @@ IrcChannel *Network::newIrcChannel(const QString &channelname) {
 }
 
 IrcChannel *Network::newIrcChannel(const QByteArray &channelname) {
-  return newIrcChannel(decodeString(channelname));
+  return newIrcChannel(decodeServerString(channelname));
 }
 
 IrcChannel *Network::ircChannel(QString channelname) const {
@@ -382,7 +382,7 @@ IrcChannel *Network::ircChannel(QString channelname) const {
 }
 
 IrcChannel *Network::ircChannel(const QByteArray &channelname) const {
-  return ircChannel(decodeString(channelname));
+  return ircChannel(decodeServerString(channelname));
 }
 
 
@@ -469,7 +469,7 @@ QString Network::decodeString(const QByteArray &text) const {
   else return ::decodeString(text, _defaultCodecForDecoding);
 }
 
-QByteArray Network::encodeString(const QString string) const {
+QByteArray Network::encodeString(const QString &string) const {
   if(_codecForEncoding) {
     return _codecForEncoding->fromUnicode(string);
   }
@@ -479,6 +479,21 @@ QByteArray Network::encodeString(const QString string) const {
   return string.toAscii();
 }
 
+QString Network::decodeServerString(const QByteArray &text) const {
+  if(_codecForServer) return ::decodeString(text, _codecForServer);
+  else return ::decodeString(text, _defaultCodecForServer);
+}
+
+QByteArray Network::encodeServerString(const QString &string) const {
+  if(_codecForServer) {
+    return _codecForServer->fromUnicode(string);
+  }
+  if(_defaultCodecForServer) {
+    return _defaultCodecForServer->fromUnicode(string);
+  }
+  return string.toAscii();
+}
+
 // ====================
 //  Public Slots:
 // ====================
index 6c2ff40..a64fb08 100644 (file)
@@ -141,7 +141,9 @@ public:
   void setCodecForDecoding(QTextCodec *codec);
 
   QString decodeString(const QByteArray &text) const;
-  QByteArray encodeString(const QString string) const;
+  QByteArray encodeString(const QString &string) const;
+  QString decodeServerString(const QByteArray &text) const;
+  QByteArray encodeServerString(const QString &string) const;
 
   static QByteArray defaultCodecForServer();
   static QByteArray defaultCodecForEncoding();
@@ -262,6 +264,8 @@ signals:
   void disconnectRequested(NetworkId id = 0) const;
 
 private:
+  QPointer<SignalProxy> _proxy;
+
   NetworkId _networkId;
   IdentityId _identity;
 
@@ -292,7 +296,6 @@ private:
   bool _unlimitedReconnectRetries;
   bool _rejoinChannels;
 
-  QPointer<SignalProxy> _proxy;
   void determinePrefixes();
 
   QTextCodec *_codecForServer;
index 3820578..8288e10 100644 (file)
@@ -102,13 +102,13 @@ QStringList BasicHandler::serverDecode(const QList<QByteArray> &stringlist) {
   return list;
 }
 
-QString BasicHandler::bufferDecode(const QString &bufferName, const QByteArray &string) {
-  return networkConnection()->bufferDecode(bufferName, string);
+QString BasicHandler::channelDecode(const QString &bufferName, const QByteArray &string) {
+  return networkConnection()->channelDecode(bufferName, string);
 }
 
-QStringList BasicHandler::bufferDecode(const QString &bufferName, const QList<QByteArray> &stringlist) {
+QStringList BasicHandler::channelDecode(const QString &bufferName, const QList<QByteArray> &stringlist) {
   QStringList list;
-  foreach(QByteArray s, stringlist) list << networkConnection()->bufferDecode(bufferName, s);
+  foreach(QByteArray s, stringlist) list << networkConnection()->channelDecode(bufferName, s);
   return list;
 }
 
@@ -134,13 +134,13 @@ QList<QByteArray> BasicHandler::serverEncode(const QStringList &stringlist) {
   return list;
 }
 
-QByteArray BasicHandler::bufferEncode(const QString &bufferName, const QString &string) {
-  return networkConnection()->bufferEncode(bufferName, string);
+QByteArray BasicHandler::channelEncode(const QString &bufferName, const QString &string) {
+  return networkConnection()->channelEncode(bufferName, string);
 }
 
-QList<QByteArray> BasicHandler::bufferEncode(const QString &bufferName, const QStringList &stringlist) {
+QList<QByteArray> BasicHandler::channelEncode(const QString &bufferName, const QStringList &stringlist) {
   QList<QByteArray> list;
-  foreach(QString s, stringlist) list << networkConnection()->bufferEncode(bufferName, s);
+  foreach(QString s, stringlist) list << networkConnection()->channelEncode(bufferName, s);
   return list;
 }
 
index a520087..7af3894 100644 (file)
@@ -42,15 +42,15 @@ public:
 
   QString serverDecode(const QByteArray &string);
   QStringList serverDecode(const QList<QByteArray> &stringlist);
-  QString bufferDecode(const QString &bufferName, const QByteArray &string);
-  QStringList bufferDecode(const QString &bufferName, const QList<QByteArray> &stringlist);
+  QString channelDecode(const QString &bufferName, const QByteArray &string);
+  QStringList channelDecode(const QString &bufferName, const QList<QByteArray> &stringlist);
   QString userDecode(const QString &userNick, const QByteArray &string);
   QStringList userDecode(const QString &userNick, const QList<QByteArray> &stringlist);
 
   QByteArray serverEncode(const QString &string);
   QList<QByteArray> serverEncode(const QStringList &stringlist);
-  QByteArray bufferEncode(const QString &bufferName, const QString &string);
-  QList<QByteArray> bufferEncode(const QString &bufferName, const QStringList &stringlist);
+  QByteArray channelEncode(const QString &bufferName, const QString &string);
+  QList<QByteArray> channelEncode(const QString &bufferName, const QStringList &stringlist);
   QByteArray userEncode(const QString &userNick, const QString &string);
   QList<QByteArray> userEncode(const QString &userNick, const QStringList &stringlist);
 
index 4b848bd..43c3126 100644 (file)
@@ -176,7 +176,7 @@ void IrcServerHandler::handleJoin(QString prefix, QList<QByteArray> params) {
 
 void IrcServerHandler::handleKick(QString prefix, QList<QByteArray> params) {
   network()->updateNickFromMask(prefix);
-  IrcUser *victim = network()->ircUser(serverDecode(params[1]));
+  IrcUser *victim = network()->ircUser(params[1]);
   QString channel = serverDecode(params[0]);
   Q_ASSERT(victim);
 
@@ -184,7 +184,7 @@ void IrcServerHandler::handleKick(QString prefix, QList<QByteArray> params) {
 
   QString msg;
   if(params.count() > 2) // someone got a reason!
-    msg = QString("%1 %2").arg(victim->nick()).arg(bufferDecode(channel, params[2]));
+    msg = QString("%1 %2").arg(victim->nick()).arg(channelDecode(channel, params[2]));
   else
     msg = victim->nick();
 
@@ -197,7 +197,7 @@ void IrcServerHandler::handleMode(QString prefix, QList<QByteArray> params) {
     return;
   }
 
-  if(network()->isChannelName(params[0])) {
+  if(network()->isChannelName(serverDecode(params[0]))) {
     // Channel Modes
     emit displayMsg(Message::Mode, BufferInfo::ChannelBuffer, serverDecode(params[0]), serverDecode(params).join(" "), prefix);
 
@@ -273,7 +273,7 @@ void IrcServerHandler::handleNotice(QString prefix, QList<QByteArray> params) {
     ? nickFromMask(prefix)
     : prefix;
 
-  networkConnection()->ctcpHandler()->parse(Message::Notice, sender, target, userDecode(prefix, params[1]));
+  networkConnection()->ctcpHandler()->parse(Message::Notice, sender, target, userDecode(sender, params[1]));
 }
 
 void IrcServerHandler::handlePart(QString prefix, QList<QByteArray> params) {
@@ -329,7 +329,7 @@ void IrcServerHandler::handleQuit(QString prefix, QList<QByteArray> params) {
 void IrcServerHandler::handleTopic(QString prefix, QList<QByteArray> params) {
   IrcUser *ircuser = network()->updateNickFromMask(prefix);
   QString channel = serverDecode(params[0]);
-  QString topic = bufferDecode(channel, params[1]);
+  QString topic = channelDecode(channel, params[1]);
   Q_ASSERT(ircuser);
 
   network()->ircChannel(channel)->setTopic(topic);
@@ -384,7 +384,7 @@ WHOWAS-Message:
 void IrcServerHandler::handle301(QString prefix, QList<QByteArray> params) {
   Q_UNUSED(prefix);
   QString nickName = serverDecode(params[0]);
-  QString awayMessage = serverDecode(params.last());
+  QString awayMessage = userDecode(nickName, params.last());
 
   IrcUser *ircuser = network()->ircUser(nickName);
   if(ircuser) {
@@ -463,8 +463,9 @@ void IrcServerHandler::handle315(QString prefix, QList<QByteArray> params) {
    (real life: "<nick> <integer> <integer> :seconds idle, signon time) */
    //TODO: parse real life message
 void IrcServerHandler::handle317(QString prefix, QList<QByteArray> params) {
-  Q_UNUSED(prefix)
-  IrcUser *ircuser = network()->ircUser(serverDecode(params[0]));
+  Q_UNUSED(prefix);
+  QString nick = serverDecode(params[0]);
+  IrcUser *ircuser = network()->ircUser(nick);
   if(ircuser) {
     QDateTime now = QDateTime::currentDateTime();
     int idleSecs = serverDecode(params[1]).toInt();
@@ -472,7 +473,7 @@ void IrcServerHandler::handle317(QString prefix, QList<QByteArray> params) {
     ircuser->setIdleTime(now.addSecs(idleSecs));
     emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("[Whois] %1 is idling for %2 seconds").arg(ircuser->nick()).arg(ircuser->idleTime().secsTo(now)));
   } else {
-    emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("[Whois] idle message: %1").arg(serverDecode(params).join(" ")));
+    emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("[Whois] idle message: %1").arg(userDecode(nick, params).join(" ")));
   }
 }
 
@@ -501,7 +502,7 @@ void IrcServerHandler::handle331(QString prefix, QList<QByteArray> params) {
 void IrcServerHandler::handle332(QString prefix, QList<QByteArray> params) {
   Q_UNUSED(prefix);
   QString channel = serverDecode(params[0]);
-  QString topic = bufferDecode(channel, params[1]);
+  QString topic = channelDecode(channel, params[1]);
   network()->ircChannel(channel)->setTopic(topic);
   emit displayMsg(Message::Server, BufferInfo::ChannelBuffer, channel, tr("Topic for %1 is \"%2\"").arg(channel, topic));
 }
@@ -510,7 +511,8 @@ void IrcServerHandler::handle332(QString prefix, QList<QByteArray> params) {
 void IrcServerHandler::handle333(QString prefix, QList<QByteArray> params) {
   Q_UNUSED(prefix);
   QString channel = serverDecode(params[0]);
-  emit displayMsg(Message::Server, BufferInfo::ChannelBuffer, channel, tr("Topic set by %1 on %2") .arg(bufferDecode(channel, params[1]), QDateTime::fromTime_t(bufferDecode(channel, params[2]).toUInt()).toString()));
+  emit displayMsg(Message::Server, BufferInfo::ChannelBuffer, channel,
+                  tr("Topic set by %1 on %2") .arg(serverDecode(params[1]), QDateTime::fromTime_t(channelDecode(channel, params[2]).toUInt()).toString()));
 }
 
 /*  RPL_WHOREPLY: "<channel> <user> <host> <server> <nick> 
index ed1a72b..381e99d 100644 (file)
@@ -27,6 +27,7 @@
 #include "core.h"
 #include "coresession.h"
 
+#include "ircchannel.h"
 #include "ircuser.h"
 #include "network.h"
 #include "identity.h"
@@ -109,12 +110,14 @@ CtcpHandler *NetworkConnection::ctcpHandler() const {
 }
 
 QString NetworkConnection::serverDecode(const QByteArray &string) const {
-  return network()->decodeString(string);
+  return network()->decodeServerString(string);
 }
 
-QString NetworkConnection::bufferDecode(const QString &bufferName, const QByteArray &string) const {
-  Q_UNUSED(bufferName);
-  // TODO: Implement buffer-specific encodings
+QString NetworkConnection::channelDecode(const QString &bufferName, const QByteArray &string) const {
+  if(!bufferName.isEmpty()) {
+    IrcChannel *channel = network()->ircChannel(bufferName);
+    if(channel) return channel->decodeString(string);
+  }
   return network()->decodeString(string);
 }
 
@@ -125,12 +128,14 @@ QString NetworkConnection::userDecode(const QString &userNick, const QByteArray
 }
 
 QByteArray NetworkConnection::serverEncode(const QString &string) const {
-  return network()->encodeString(string);
+  return network()->encodeServerString(string);
 }
 
-QByteArray NetworkConnection::bufferEncode(const QString &bufferName, const QString &string) const {
-  Q_UNUSED(bufferName);
-  // TODO: Implement buffer-specific encodings
+QByteArray NetworkConnection::channelEncode(const QString &bufferName, const QString &string) const {
+  if(!bufferName.isEmpty()) {
+    IrcChannel *channel = network()->ircChannel(bufferName);
+    if(channel) return channel->encodeString(string);
+  }
   return network()->encodeString(string);
 }
 
index a7aa1fd..745afc7 100644 (file)
@@ -65,19 +65,19 @@ public:
   //! Decode a string using the server (network) decoding.
   QString serverDecode(const QByteArray &string) const;
 
-  //! Decode a string using a buffer-specific encoding if one is set (and use the server encoding else).
-  QString bufferDecode(const QString &bufferName, const QByteArray &string) const;
+  //! Decode a string using a channel-specific encoding if one is set (and use the standard encoding else).
+  QString channelDecode(const QString &channelName, const QByteArray &string) const;
 
-  //! Decode a string using a IrcUser specific encoding, if one exists (using the server encoding else).
+  //! Decode a string using an IrcUser-specific encoding, if one exists (using the standaed encoding else).
   QString userDecode(const QString &userNick, const QByteArray &string) const;
 
   //! Encode a string using the server (network) encoding.
   QByteArray serverEncode(const QString &string) const;
 
-  //! Encode a string using the buffer-specific encoding, if set, and use the server encoding else.
-  QByteArray bufferEncode(const QString &bufferName, const QString &string) const;
+  //! Encode a string using the channel-specific encoding, if set, and use the standard encoding else.
+  QByteArray channelEncode(const QString &channelName, const QString &string) const;
 
-  //! Encode a string using the user-specific encoding, if set, and use the server encoding else.
+  //! Encode a string using the user-specific encoding, if set, and use the standard encoding else.
   QByteArray userEncode(const QString &userNick, const QString &string) const;
 
 public slots:
index a431f3d..956e352 100644 (file)
@@ -63,7 +63,7 @@ void UserInputHandler::handleBan(const BufferInfo &bufferInfo, const QString &ms
   
   //TODO: find suitable default hostmask if msg gives only nickname 
   // Example: MODE &oulu +b *!*@*
-  QByteArray banMsg = serverEncode(bufferInfo.bufferName()) + " +b " + bufferEncode(bufferInfo.bufferName(), msg);
+  QByteArray banMsg = serverEncode(bufferInfo.bufferName()) + " +b " + channelEncode(bufferInfo.bufferName(), msg);
   emit putCmd("MODE", banMsg);
 }
 
@@ -126,7 +126,7 @@ void UserInputHandler::handleKick(const BufferInfo &bufferInfo, const QString &m
   QString reason = msg.section(' ', 1, -1, QString::SectionSkipEmpty).trimmed();
   if(reason.isEmpty()) reason = networkConnection()->identity()->kickReason();
   QList<QByteArray> params;
-  params << serverEncode(bufferInfo.bufferName()) << serverEncode(nick) << bufferEncode(bufferInfo.bufferName(), reason);
+  params << serverEncode(bufferInfo.bufferName()) << serverEncode(nick) << channelEncode(bufferInfo.bufferName(), reason);
   emit putCmd("KICK", params);
 }
 
@@ -138,13 +138,13 @@ void UserInputHandler::handleList(const BufferInfo &bufferInfo, const QString &m
 
 void UserInputHandler::handleMe(const BufferInfo &bufferInfo, const QString &msg) {
   if(bufferInfo.bufferName().isEmpty()) return; // server buffer
-  networkConnection()->ctcpHandler()->query(bufferInfo.bufferName(), "ACTION", bufferEncode(bufferInfo.bufferName(), msg));
+  networkConnection()->ctcpHandler()->query(bufferInfo.bufferName(), "ACTION", channelEncode(bufferInfo.bufferName(), msg));
   emit displayMsg(Message::Action, bufferInfo.type(), bufferInfo.bufferName(), msg, network()->myNick());
 }
 
 void UserInputHandler::handleMode(const BufferInfo &bufferInfo, const QString &msg) {
   Q_UNUSED(bufferInfo)
-  // TODO handle correct encoding for buffer modes (bufferEncode())
+  // TODO handle correct encoding for buffer modes (channelEncode())
   emit putCmd("MODE", serverEncode(msg.split(' ', QString::SkipEmptyParts)));
 }
 
@@ -177,7 +177,7 @@ void UserInputHandler::handleOp(const BufferInfo &bufferInfo, const QString &msg
 
 void UserInputHandler::handlePart(const BufferInfo &bufferInfo, const QString &msg) {
   QList<QByteArray> params;
-  params << serverEncode(bufferInfo.bufferName()) << bufferEncode(bufferInfo.bufferName(), msg);
+  params << serverEncode(bufferInfo.bufferName()) << channelEncode(bufferInfo.bufferName(), msg);
   emit putCmd("PART", params);
 }
 
@@ -206,7 +206,7 @@ void UserInputHandler::handleQuote(const BufferInfo &bufferInfo, const QString &
 void UserInputHandler::handleSay(const BufferInfo &bufferInfo, const QString &msg) {
   if(bufferInfo.bufferName().isEmpty()) return;  // server buffer
   QList<QByteArray> params;
-  params << serverEncode(bufferInfo.bufferName()) << bufferEncode(bufferInfo.bufferName(), msg);
+  params << serverEncode(bufferInfo.bufferName()) << channelEncode(bufferInfo.bufferName(), msg);
   emit putCmd("PRIVMSG", params);
   emit displayMsg(Message::Plain, bufferInfo.type(), bufferInfo.bufferName(), msg, network()->myNick(), Message::Self);
 }
@@ -214,7 +214,7 @@ void UserInputHandler::handleSay(const BufferInfo &bufferInfo, const QString &ms
 void UserInputHandler::handleTopic(const BufferInfo &bufferInfo, const QString &msg) {
   if(bufferInfo.bufferName().isEmpty()) return;
   QList<QByteArray> params;
-  params << serverEncode(bufferInfo.bufferName()) << bufferEncode(bufferInfo.bufferName(), msg);
+  params << serverEncode(bufferInfo.bufferName()) << channelEncode(bufferInfo.bufferName(), msg);
   emit putCmd("TOPIC", params);
 }