SignalProxy now only allows syncing for classes derived from the new
[quassel.git] / src / common / networkinfo.cpp
index f79ef5c..19f4233 100644 (file)
@@ -1,11 +1,11 @@
 /***************************************************************************
- *   Copyright (C) 2005-07 by The Quassel Team                             *
+ *   Copyright (C) 2005-08 by the Quassel Project                          *
  *   devel@quassel-irc.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
  *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
+ *   (at your option) version 3.                                           *
  *                                                                         *
  *   This program is distributed in the hope that it will be useful,       *
  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 #include "networkinfo.h"
 
 #include "signalproxy.h"
-#include "synchronizer.h"
 #include "ircuser.h"
 #include "ircchannel.h"
 
 #include <QDebug>
+#include <QTextCodec>
 
 #include "util.h"
 
 // ====================
 //  Public:
 // ====================
-NetworkInfo::NetworkInfo(const uint &networkid, SignalProxy *proxy, QObject *parent)
-  : QObject(parent),
+NetworkInfo::NetworkInfo(const uint &networkid, QObject *parent)
+  : SyncableObject(parent),
     _networkId(networkid),
     _initialized(false),
     _myNick(QString()),
     _networkName(QString()),
     _currentServer(QString()),
     _prefixes(QString()),
-    _prefixModes(QString())
+    _prefixModes(QString()),
+    _proxy(0),
+    _codecForEncoding(0),
+    _codecForDecoding(0)
 {
   setObjectName(QString::number(networkid));
-  _synchronizer = new Synchronizer(this, proxy);
 }
 
 // I think this is unnecessary since IrcUsers have us as their daddy :)
-// NetworkInfo::~NetworkInfo() {
+//NetworkInfo::~NetworkInfo() {
 //   QHashIterator<QString, IrcUser *> ircuser(_ircUsers);
 //   while (ircuser.hasNext()) {
 //     ircuser.next();
 //     delete ircuser.value();
 //   }
-// }
+//}
 
 uint NetworkInfo::networkId() const {
   return _networkId;
@@ -62,8 +64,13 @@ bool NetworkInfo::initialized() const {
   return _initialized;
 }
 
-Synchronizer *NetworkInfo::synchronizer() {
-  return _synchronizer;
+SignalProxy *NetworkInfo::proxy() const {
+  return _proxy;
+}
+
+void NetworkInfo::setProxy(SignalProxy *proxy) {
+  _proxy = proxy;
+  proxy->synchronize(this);
 }
 
 bool NetworkInfo::isMyNick(const QString &nick) const {
@@ -71,7 +78,7 @@ bool NetworkInfo::isMyNick(const QString &nick) const {
 }
 
 bool NetworkInfo::isMyNick(IrcUser *ircuser) const {
-  return (ircuser->nick().toLower() == myNick());
+  return (ircuser->nick().toLower() == myNick().toLower());
 }
 
 bool NetworkInfo::isChannelName(const QString &channelname) const {
@@ -159,54 +166,138 @@ QString NetworkInfo::support(const QString &param) const {
 }
 
 IrcUser *NetworkInfo::newIrcUser(const QString &hostmask) {
-  QString nick(nickFromMask(hostmask));
+  QString nick(nickFromMask(hostmask).toLower());
   if(!_ircUsers.contains(nick)) {
     IrcUser *ircuser = new IrcUser(hostmask, this);
-    new Synchronizer(ircuser, synchronizer()->proxy());
+    // mark IrcUser as already initialized to keep the SignalProxy from requesting initData
+    if(initialized())
+      ircuser->setInitialized();
+    if(proxy())
+      proxy()->synchronize(ircuser);
+    else
+      qWarning() << "unable to synchronize new IrcUser" << hostmask << "forgot to call NetworkInfo::setProxy(SignalProxy *)?";
+    
     connect(ircuser, SIGNAL(nickSet(QString)), this, SLOT(ircUserNickChanged(QString)));
     connect(ircuser, SIGNAL(initDone()), this, SIGNAL(ircUserInitDone()));
     connect(ircuser, SIGNAL(destroyed()), this, SLOT(ircUserDestroyed()));
     _ircUsers[nick] = ircuser;
     emit ircUserAdded(hostmask);
   }
-  return  _ircUsers[nick];
+  return _ircUsers[nick];
+}
+
+IrcUser *NetworkInfo::newIrcUser(const QByteArray &hostmask) {
+  return newIrcUser(decodeString(hostmask));
+}
+
+void NetworkInfo::removeIrcUser(IrcUser *ircuser) {
+  QString nick = _ircUsers.key(ircuser);
+  if(nick.isNull())
+    return;
+
+  _ircUsers.remove(nick);
+  ircuser->deleteLater();
+  emit ircUserRemoved(nick);
+}
+
+void NetworkInfo::removeIrcUser(QString nick) {
+  IrcUser *ircuser;
+  if((ircuser = ircUser(nick)) != 0)
+    removeIrcUser(ircuser);
 }
 
-IrcUser *NetworkInfo::ircUser(const QString &nickname) const {
+IrcUser *NetworkInfo::ircUser(QString nickname) const {
+  nickname = nickname.toLower();
   if(_ircUsers.contains(nickname))
     return _ircUsers[nickname];
   else
     return 0;
 }
 
+IrcUser *NetworkInfo::ircUser(const QByteArray &nickname) const {
+  return ircUser(decodeString(nickname));
+}
+
 QList<IrcUser *> NetworkInfo::ircUsers() const {
   return _ircUsers.values();
 }
 
 IrcChannel *NetworkInfo::newIrcChannel(const QString &channelname) {
-  if(!_ircChannels.contains(channelname)) {
+  if(!_ircChannels.contains(channelname.toLower())) {
     IrcChannel *channel = new IrcChannel(channelname, this);
-    new Synchronizer(channel, synchronizer()->proxy());
+    // mark IrcUser as already initialized to keep the SignalProxy from requesting initData
+    if(initialized())
+      channel->setInitialized();
+
+    if(proxy())
+      proxy()->synchronize(channel);
+    else
+      qWarning() << "unable to synchronize new IrcChannel" << channelname << "forgot to call NetworkInfo::setProxy(SignalProxy *)?";
+
     connect(channel, SIGNAL(initDone()), this, SIGNAL(ircChannelInitDone()));
     connect(channel, SIGNAL(destroyed()), this, SLOT(channelDestroyed()));
-    _ircChannels[channelname] = channel;
+    _ircChannels[channelname.toLower()] = channel;
     emit ircChannelAdded(channelname);
   }
-  return _ircChannels[channelname];
+  return _ircChannels[channelname.toLower()];
 }
 
+IrcChannel *NetworkInfo::newIrcChannel(const QByteArray &channelname) {
+  return newIrcChannel(decodeString(channelname));
+}
 
-IrcChannel *NetworkInfo::ircChannel(const QString &channelname) {
+IrcChannel *NetworkInfo::ircChannel(QString channelname) {
+  channelname = channelname.toLower();
   if(_ircChannels.contains(channelname))
     return _ircChannels[channelname];
   else
     return 0;
 }
 
+IrcChannel *NetworkInfo::ircChannel(const QByteArray &channelname) {
+  return ircChannel(decodeString(channelname));
+}
+
+
 QList<IrcChannel *> NetworkInfo::ircChannels() const {
   return _ircChannels.values();
 }
 
+QTextCodec *NetworkInfo::codecForEncoding() const {
+  return _codecForEncoding;
+}
+
+void NetworkInfo::setCodecForEncoding(const QString &name) {
+  setCodecForEncoding(QTextCodec::codecForName(name.toAscii()));
+}
+
+void NetworkInfo::setCodecForEncoding(QTextCodec *codec) {
+  _codecForEncoding = codec;
+}
+
+QTextCodec *NetworkInfo::codecForDecoding() const {
+  return _codecForDecoding;
+}
+
+void NetworkInfo::setCodecForDecoding(const QString &name) {
+  setCodecForDecoding(QTextCodec::codecForName(name.toAscii()));
+}
+
+void NetworkInfo::setCodecForDecoding(QTextCodec *codec) {
+  _codecForDecoding = codec;
+}
+
+QString NetworkInfo::decodeString(const QByteArray &text) const {
+  return ::decodeString(text, _codecForDecoding);
+}
+
+QByteArray NetworkInfo::encodeString(const QString string) const {
+  if(_codecForEncoding) {
+    return _codecForEncoding->fromUnicode(string);
+  }
+  return string.toAscii();
+}
+
 // ====================
 //  Public Slots:
 // ====================
@@ -285,7 +376,7 @@ void NetworkInfo::initSetChannels(const QStringList &channels) {
 }
 
 IrcUser *NetworkInfo::updateNickFromMask(const QString &mask) {
-  QString nick(nickFromMask(mask));
+  QString nick(nickFromMask(mask).toLower());
   IrcUser *ircuser;
   
   if(_ircUsers.contains(nick)) {
@@ -302,25 +393,21 @@ void NetworkInfo::ircUserNickChanged(QString newnick) {
 
   if(oldnick.isNull())
     return;
+
+  if(newnick.toLower() != oldnick) _ircUsers[newnick.toLower()] = _ircUsers.take(oldnick);
   
-  _ircUsers[newnick] = _ircUsers.take(oldnick);
-  
-  if(myNick() == oldnick)
+  if(myNick().toLower() == oldnick)
     setMyNick(newnick);
 }
 
 void NetworkInfo::ircUserDestroyed() {
-  IrcUser *ircuser = qobject_cast<IrcUser *>(sender());
-  // in case this assert triggers we probably need a static_cast
-  // dynamic_casts seem to screw things up when using the destroyed signal
+  IrcUser *ircuser = static_cast<IrcUser *>(sender());
   Q_ASSERT(ircuser);
-  _ircUsers.remove(_ircUsers.key(ircuser));
+  removeIrcUser(ircuser);
 }
 
 void NetworkInfo::channelDestroyed() {
-  IrcChannel *channel = qobject_cast<IrcChannel *>(sender());
-  // in case this assert triggers we probably need a static_cast
-  // dynamic_casts seem to screw things up when using the destroyed signal
+  IrcChannel *channel = static_cast<IrcChannel *>(sender());
   Q_ASSERT(channel);
   _ircChannels.remove(_ircChannels.key(channel));
 }
@@ -341,8 +428,8 @@ void NetworkInfo::determinePrefixes() {
     _prefixes = PREFIX.section(")", 1);
     _prefixModes = PREFIX.mid(1).section(")", 0, 0);
   } else {
-    QString defaultPrefixes("@%+");
-    QString defaultPrefixModes("ohv");
+    QString defaultPrefixes("~&@%+");
+    QString defaultPrefixModes("qaohv");
 
     // we just assume that in PREFIX are only prefix chars stored
     for(int i = 0; i < defaultPrefixes.size(); i++) {