sometimes I hate git... forgot stupid -a for git commit
authorMarcus Eggenberger <egs@quassel-irc.org>
Mon, 9 Jun 2008 20:56:36 +0000 (22:56 +0200)
committerMarcus Eggenberger <egs@quassel-irc.org>
Mon, 9 Jun 2008 20:57:20 +0000 (22:57 +0200)
src/client/networkmodel.cpp
src/common/ircchannel.cpp
src/common/ircchannel.h
src/common/network.cpp
src/common/network.h
src/core/core.pri
src/core/coresession.cpp
src/core/coresession.h
src/core/ircserverhandler.cpp
src/core/ircserverhandler.h

index 940feb7..bd2d8a5 100644 (file)
@@ -313,6 +313,11 @@ QString BufferItem::toolTip(int column) const {
             toolTip.append(tr("<b>Topic:</b> %1").arg(_topic));
           }
         }
+       if(_ircChannel) {
+         QString channelMode = _ircChannel->channelModeString(); // channelModeString is compiled on the fly -> thus cache the result
+         if(!channelMode.isEmpty())
+           toolTip.append(tr("<b>Mode:</b> %1").arg(channelMode));
+       }
       } else {
         toolTip.append(tr("Not active <br /> Double-click to join"));
       }
index 57be4e7..976375d 100644 (file)
@@ -21,8 +21,6 @@
 #include "ircchannel.h"
 
 #include "network.h"
-//#include "nicktreemodel.h"
-#include "signalproxy.h"
 #include "ircuser.h"
 #include "util.h"
 
@@ -33,7 +31,8 @@
 #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()),
@@ -44,9 +43,6 @@ IrcChannel::IrcChannel(const QString &channelname, Network *network) : SyncableO
   setObjectName(QString::number(network->networkId().toInt()) + "/" +  channelname);
 }
 
-IrcChannel::~IrcChannel() {
-}
-
 // ====================
 //  PUBLIC:
 // ====================
@@ -241,7 +237,6 @@ void IrcChannel::removeUserMode(IrcUser *ircuser, const QString &mode) {
     emit userModeRemoved(ircuser->nick(), mode);
     emit ircUserModeRemoved(ircuser, mode);
   }
-
 }
 
 void IrcChannel::removeUserMode(const QString &nick, const QString &mode) {
@@ -271,6 +266,73 @@ void IrcChannel::initSetUserModes(const QVariantMap &usermodes) {
   joinIrcUsers(users, modes);
 }
 
+QVariantMap IrcChannel::initChanModes() const {
+  QVariantMap channelModes;
+
+  QVariantMap A_modes;
+  QHash<QChar, QStringList>::const_iterator A_iter = _A_channelModes.constBegin();
+  while(A_iter != _A_channelModes.constEnd()) {
+    A_modes[A_iter.key()] = A_iter.value();
+    A_iter++;
+  }
+  channelModes["A"] = A_modes;
+  
+  QVariantMap B_modes;
+  QHash<QChar, QString>::const_iterator B_iter = _B_channelModes.constBegin();
+  while(B_iter != _B_channelModes.constEnd()) {
+    B_modes[B_iter.key()] = B_iter.value();
+    B_iter++;
+  }
+  channelModes["B"] = B_modes;
+  
+  QVariantMap C_modes;
+  QHash<QChar, QString>::const_iterator C_iter = _C_channelModes.constBegin();
+  while(C_iter != _C_channelModes.constEnd()) {
+    C_modes[C_iter.key()] = C_iter.value();
+    C_iter++;
+  }
+  channelModes["C"] = C_modes;
+  
+  QString D_modes;
+  QSet<QChar>::const_iterator D_iter = _D_channelModes.constBegin();
+  while(D_iter != _D_channelModes.constEnd()) {
+    D_modes += *D_iter;
+    D_iter++;
+  }
+  channelModes["D"] = D_modes;
+
+  return channelModes;
+}
+
+void IrcChannel::initSetChanModes(const QVariantMap &channelModes) {
+  QVariantMap::const_iterator iter = channelModes["A"].toMap().constBegin();
+  QVariantMap::const_iterator iterEnd = channelModes["A"].toMap().constEnd();
+  while(iter != iterEnd) {
+    _A_channelModes[iter.key()[0]] = iter.value().toStringList();
+    iter++;
+  }
+
+  iter = channelModes["B"].toMap().constBegin();
+  iterEnd = channelModes["B"].toMap().constEnd();
+  while(iter != iterEnd) {
+    _B_channelModes[iter.key()[0]] = iter.value().toString();
+    iter++;
+  }
+  
+  iter = channelModes["C"].toMap().constBegin();
+  iterEnd = channelModes["C"].toMap().constEnd();
+  while(iter != iterEnd) {
+    _C_channelModes[iter.key()[0]] = iter.value().toString();
+    iter++;
+  }
+
+  QString D_modes = channelModes["D"].toString();
+  for(int i = 0; i < D_modes.count(); i++) {
+    _D_channelModes << D_modes[i];
+  }
+
+}
+
 void IrcChannel::ircUserDestroyed() {
   IrcUser *ircUser = static_cast<IrcUser *>(sender());
   Q_ASSERT(ircUser);
@@ -285,3 +347,182 @@ void IrcChannel::ircUserNickSet(QString nick) {
   emit ircUserNickSet(ircUser, nick);
 }
 
+/*******************************************************************************
+ *
+ * 3.3 CHANMODES
+ * 
+ *    o  CHANMODES=A,B,C,D
+ * 
+ *    The CHANMODES token specifies the modes that may be set on a channel.
+ *    These modes are split into four categories, as follows:
+ * 
+ *    o  Type A: Modes that add or remove an address to or from a list.
+ *       These modes always take a parameter when sent by the server to a
+ *       client; when sent by a client, they may be specified without a
+ *       parameter, which requests the server to display the current
+ *       contents of the corresponding list on the channel to the client.
+ *    o  Type B: Modes that change a setting on the channel.  These modes
+ *       always take a parameter.
+ *    o  Type C: Modes that change a setting on the channel. These modes
+ *       take a parameter only when set; the parameter is absent when the
+ *       mode is removed both in the client's and server's MODE command.
+ *    o  Type D: Modes that change a setting on the channel. These modes
+ *       never take a parameter.
+ * 
+ *    If the server sends any additional types after these 4, the client
+ *    MUST ignore them; this is intended to allow future extension of this
+ *    token.
+ * 
+ *    The IRC server MUST NOT list modes in CHANMODES which are also
+ *    present in the PREFIX parameter; however, for completeness, modes
+ *    described in PREFIX may be treated as type B modes.
+ *
+ ******************************************************************************/
+
+
+/*******************************************************************************
+ * Short Version:
+ * A --> add/remove from List
+ * B --> set value or remove
+ * C --> set value or remove
+ * D --> on/off
+ *
+ * B and C behave very similar... we store the data in different datastructes
+ * for future compatibility
+ ******************************************************************************/
+
+// NOTE: the behavior of addChannelMode and removeChannelMode depends on the type of mode
+// see list above for chanmode types
+void IrcChannel::addChannelMode(const QChar &mode, const QString &value) {
+  Network::ChannelModeType modeType = network->channelModeType(mode);
+
+  switch(modeType) {
+  case Network::NOT_A_CHANMODE:
+    return;
+  case Network::A_CHANMODE:
+    if(!_A_channelModes.contains(mode))
+      _A_channelModes[mode] = QStringList(value);
+    else if(!_A_channelModes[mode].contains(value))
+      _A_channelModes[mode] << value;
+    break;
+    
+  case Network::B_CHANMODE:
+    _B_channelModes[mode] = value;
+    break;
+
+  case Network::C_CHANMODE:
+    _C_channelModes[mode] = value;
+    break;
+
+  case Network::D_CHANMODE:
+    _D_channelModes << mode;
+    break;
+  }
+  emit channelModeAdded(mode, value);
+}
+
+void IrcChannel::removeChannelMode(const QChar &mode, const QString &value) {
+  Network::ChannelModeType modeType = network->channelModeType(mode);
+
+  switch(modeType) {
+  case Network::NOT_A_CHANMODE:
+    return;
+  case Network::A_CHANMODE:
+    if(_A_channelModes.contains(mode))
+      _A_channelModes[mode].removeOne(value);
+    break;
+    
+  case Network::B_CHANMODE:
+    _B_channelModes.remove(mode);
+    break;
+
+  case Network::C_CHANMODE:
+    _C_channelModes.remove(mode);
+    break;
+
+  case Network::D_CHANMODE:
+    _D_channelModes.remove(mode);
+    break;
+  }
+  emit channelModeRemoved(mode, value);
+}
+
+bool IrcChannel::hasMode(const QChar &mode) const {
+  Network::ChannelModeType modeType = network->channelModeType(mode);
+
+  switch(modeType) {
+  case Network::NOT_A_CHANMODE:
+    return false;
+  case Network::A_CHANMODE:
+    return _A_channelModes.contains(mode);
+  case Network::B_CHANMODE:
+    return _B_channelModes.contains(mode);
+  case Network::C_CHANMODE:
+    return _C_channelModes.contains(mode);
+  case Network::D_CHANMODE:
+    return _D_channelModes.contains(mode);
+  default:
+    return false;
+  }
+}
+
+QString IrcChannel::modeValue(const QChar &mode) const {
+  Network::ChannelModeType modeType = network->channelModeType(mode);
+
+  switch(modeType) {
+  case Network::B_CHANMODE:
+    if(_B_channelModes.contains(mode))
+      return _B_channelModes[mode];
+    else
+      return QString();
+  case Network::C_CHANMODE:
+    if(_C_channelModes.contains(mode))
+      return _C_channelModes[mode];
+    else
+      return QString();
+  default:
+    return QString();
+  }
+  
+}
+
+QStringList IrcChannel::modeValueList(const QChar &mode) const {
+  Network::ChannelModeType modeType = network->channelModeType(mode);
+
+  switch(modeType) {
+  case Network::A_CHANMODE:
+    if(_A_channelModes.contains(mode))
+      return _A_channelModes[mode];
+  default:
+    return QStringList();
+  }
+}
+
+QString IrcChannel::channelModeString() const {
+  QStringList params;
+  QString modeString;
+
+  QSet<QChar>::const_iterator D_iter = _D_channelModes.constBegin();
+  while(D_iter != _D_channelModes.constEnd()) {
+    modeString += *D_iter;
+    D_iter++;
+  }
+
+  QHash<QChar, QString>::const_iterator BC_iter = _C_channelModes.constBegin();
+  while(BC_iter != _C_channelModes.constEnd()) {
+    modeString += BC_iter.key();
+    params << BC_iter.value();
+    BC_iter++;
+  }
+
+  BC_iter = _B_channelModes.constBegin();
+  while(BC_iter != _B_channelModes.constEnd()) {
+    modeString += BC_iter.key();
+    params << BC_iter.value();
+    BC_iter++;
+  }
+  if(modeString.isEmpty())
+    return modeString;
+  else
+    return QString("+%1 %2").arg(modeString).arg(params.join(" "));
+}
index 26340ce..24347a8 100644 (file)
@@ -22,6 +22,7 @@
 #define _IRCCHANNEL_H_
 
 #include <QHash>
+#include <QSet>
 #include <QString>
 #include <QStringList>
 #include <QVariantMap>
@@ -30,7 +31,6 @@
 
 class IrcUser;
 class Network;
-class SignalProxy;
 
 class IrcChannel : public SyncableObject {
   Q_OBJECT
@@ -41,7 +41,6 @@ class IrcChannel : public SyncableObject {
 
 public:
   IrcChannel(const QString &channelname, Network *network);
-  ~IrcChannel();
 
   bool isKnownUser(IrcUser *ircuser) const;
   bool isValidChannelUserMode(const QString &mode) const;
@@ -55,6 +54,11 @@ public:
   QString userModes(IrcUser *ircuser) const;
   QString userModes(const QString &nick) const;
 
+  bool hasMode(const QChar &mode) const;
+  QString modeValue(const QChar &mode) const;
+  QStringList modeValueList(const QChar &mode) const;
+  QString channelModeString() const;
+  
   inline QTextCodec *codecForEncoding() const { return _codecForEncoding; }
   inline QTextCodec *codecForDecoding() const { return _codecForDecoding; }
   void setCodecForEncoding(const QString &codecName);
@@ -86,22 +90,26 @@ public slots:
   void removeUserMode(IrcUser *ircuser, const QString &mode);
   void removeUserMode(const QString &nick, const QString &mode);
 
+  void addChannelMode(const QChar &mode, const QString &value);
+  void removeChannelMode(const QChar &mode, const QString &value);
+
   // init geters
   QVariantMap initUserModes() const;
+  QVariantMap initChanModes() const;
 
   // init seters
   void initSetUserModes(const QVariantMap &usermodes);
+  void initSetChanModes(const QVariantMap &chanModes);
 
 signals:
   void topicSet(const QString &topic);
   void passwordSet(const QString &password);
   void userModesSet(QString nick, QString modes);
-  //void userModesSet(IrcUser *ircuser, QString modes);
   void userModeAdded(QString nick, QString mode);
-  //void userModeAdded(IrcUser *ircuser, QString mode);
   void userModeRemoved(QString nick, QString mode);
-  //void userModeRemoved(IrcUser *ircuser, QString mode);
-
+  void channelModeAdded(const QChar &mode, const QString &value);
+  void channelModeRemoved(const QChar &mode, const QString &value);
+  
   void ircUsersJoined(QList<IrcUser *> ircusers);
   void ircUsersJoined(QStringList nicks, QStringList modes);
   void ircUserParted(IrcUser *ircuser);
@@ -126,6 +134,12 @@ private:
 
   QTextCodec *_codecForEncoding;
   QTextCodec *_codecForDecoding;
+
+  QHash<QChar, QStringList> _A_channelModes;
+  QHash<QChar, QString> _B_channelModes;
+  QHash<QChar, QString> _C_channelModes;
+  QSet<QChar> _D_channelModes;
+
 };
 
 #endif
index db15d25..4a1d6c8 100644 (file)
  ***************************************************************************/
 #include "network.h"
 
-#include "signalproxy.h"
-#include "ircuser.h"
-#include "ircchannel.h"
-
 #include <QDebug>
 #include <QTextCodec>
 
 QTextCodec *Network::_defaultCodecForServer = 0;
 QTextCodec *Network::_defaultCodecForEncoding = 0;
 QTextCodec *Network::_defaultCodecForDecoding = 0;
-
 // ====================
 //  Public:
 // ====================
-Network::Network(const NetworkId &networkid, QObject *parent) : SyncableObject(parent),
+Network::Network(const NetworkId &networkid, QObject *parent)
+  : SyncableObject(parent),
     _proxy(0),
     _networkId(networkid),
     _identity(0),
@@ -59,38 +55,8 @@ Network::Network(const NetworkId &networkid, QObject *parent) : SyncableObject(p
   setObjectName(QString::number(networkid.toInt()));
 }
 
-// I think this is unnecessary since IrcUsers have us as their daddy :)
-
 Network::~Network() {
   emit aboutToBeDestroyed();
-//  QHashIterator<QString, IrcUser *> ircuser(_ircUsers);
-//  while (ircuser.hasNext()) {
-//    ircuser.next();
-//    delete ircuser.value();
-//  }
-//  qDebug() << "Destroying net" << networkName() << networkId();
-}
-
-
-NetworkId Network::networkId() const {
-  return _networkId;
-}
-
-SignalProxy *Network::proxy() const {
-  return _proxy;
-}
-
-void Network::setProxy(SignalProxy *proxy) {
-  _proxy = proxy;
-  //proxy->synchronize(this);  // we should to this explicitly from the outside!
-}
-
-bool Network::isMyNick(const QString &nick) const {
-  return (myNick().toLower() == nick.toLower());
-}
-
-bool Network::isMe(IrcUser *ircuser) const {
-  return (ircuser->nick().toLower() == myNick().toLower());
 }
 
 bool Network::isChannelName(const QString &channelname) const {
@@ -103,15 +69,6 @@ bool Network::isChannelName(const QString &channelname) const {
     return QString("#&!+").contains(channelname[0]);
 }
 
-bool Network::isConnected() const {
-  return _connected;
-}
-
-//Network::ConnectionState Network::connectionState() const {
-int Network::connectionState() const {
-  return _connectionState;
-}
-
 NetworkInfo Network::networkInfo() const {
   NetworkInfo info;
   info.networkName = networkName();
@@ -161,10 +118,6 @@ QString Network::prefixToMode(const QString &prefix) {
     return QString();
 }
 
-QString Network::prefixToMode(const QCharRef &prefix) {
-  return prefixToMode(QString(prefix));
-}
-
 QString Network::modeToPrefix(const QString &mode) {
   if(prefixModes().contains(mode))
     return QString(prefixes()[prefixModes().indexOf(mode)]);
@@ -172,26 +125,6 @@ QString Network::modeToPrefix(const QString &mode) {
     return QString();
 }
 
-QString Network::modeToPrefix(const QCharRef &mode) {
-  return modeToPrefix(QString(mode));
-}
-  
-QString Network::networkName() const {
-  return _networkName;
-}
-
-QString Network::currentServer() const {
-  return _currentServer;
-}
-
-QString Network::myNick() const {
-  return _myNick;
-}
-
-IdentityId Network::identity() const {
-  return _identity;
-}
-
 QStringList Network::nicks() const {
   // we don't use _ircUsers.keys() since the keys may be
   // not up to date after a nick change
@@ -202,54 +135,6 @@ QStringList Network::nicks() const {
   return nicks;
 }
 
-QStringList Network::channels() const {
-  return _ircChannels.keys();
-}
-
-QVariantList Network::serverList() const {
-  return _serverList;
-}
-
-bool Network::useRandomServer() const {
-  return _useRandomServer;
-}
-
-QStringList Network::perform() const {
-  return _perform;
-}
-
-bool Network::useAutoIdentify() const {
-  return _useAutoIdentify;
-}
-
-QString Network::autoIdentifyService() const {
-  return _autoIdentifyService;
-}
-
-QString Network::autoIdentifyPassword() const {
-  return _autoIdentifyPassword;
-}
-
-bool Network::useAutoReconnect() const {
-  return _useAutoReconnect;
-}
-
-quint32 Network::autoReconnectInterval() const {
-  return _autoReconnectInterval;
-}
-
-quint16 Network::autoReconnectRetries() const {
-  return _autoReconnectRetries;
-}
-
-bool Network::unlimitedReconnectRetries() const {
-  return _unlimitedReconnectRetries;
-}
-
-bool Network::rejoinChannels() const {
-  return _rejoinChannels;
-}
-
 QString Network::prefixes() {
   if(_prefixes.isNull())
     determinePrefixes();
@@ -264,8 +149,27 @@ QString Network::prefixModes() {
   return _prefixModes;
 }
 
-bool Network::supports(const QString &param) const {
-  return _supports.contains(param);
+// example Unreal IRCD: CHANMODES=beI,kfL,lj,psmntirRcOAQKVCuzNSMTG 
+Network::ChannelModeType Network::channelModeType(const QString &mode) {
+  if(mode.isEmpty())
+    return NOT_A_CHANMODE;
+
+  QString chanmodes = support("CHANMODES");
+  if(chanmodes.isEmpty())
+    return NOT_A_CHANMODE;
+
+  ChannelModeType modeType = A_CHANMODE;
+  for(int i = 0; i < chanmodes.count(); i++) {
+    if(chanmodes[i] == mode[0])
+      break;
+    else if(chanmodes[i] == ',')
+      modeType = (ChannelModeType)(modeType << 1);
+  }
+  if(modeType > D_CHANMODE) {
+    qWarning() << "Network" << networkId() << "supplied invalid CHANMODES:" << chanmodes;
+    modeType = NOT_A_CHANMODE;
+  }
+  return modeType;
 }
 
 QString Network::support(const QString &param) const {
@@ -296,10 +200,6 @@ IrcUser *Network::newIrcUser(const QString &hostmask) {
   return _ircUsers[nick];
 }
 
-IrcUser *Network::newIrcUser(const QByteArray &hostmask) {
-  return newIrcUser(decodeServerString(hostmask));
-}
-
 void Network::ircUserDestroyed() {
   IrcUser *ircUser = static_cast<IrcUser *>(sender());
   if(!ircUser)
@@ -352,18 +252,6 @@ IrcUser *Network::ircUser(QString nickname) const {
     return 0;
 }
 
-IrcUser *Network::ircUser(const QByteArray &nickname) const {
-  return ircUser(decodeServerString(nickname));
-}
-
-QList<IrcUser *> Network::ircUsers() const {
-  return _ircUsers.values();
-}
-
-quint32 Network::ircUserCount() const {
-  return _ircUsers.count();
-}
-
 IrcChannel *Network::newIrcChannel(const QString &channelname) {
   if(!_ircChannels.contains(channelname.toLower())) {
     IrcChannel *channel = new IrcChannel(channelname, this);
@@ -382,10 +270,6 @@ IrcChannel *Network::newIrcChannel(const QString &channelname) {
   return _ircChannels[channelname.toLower()];
 }
 
-IrcChannel *Network::newIrcChannel(const QByteArray &channelname) {
-  return newIrcChannel(decodeServerString(channelname));
-}
-
 IrcChannel *Network::ircChannel(QString channelname) const {
   channelname = channelname.toLower();
   if(_ircChannels.contains(channelname))
@@ -394,21 +278,9 @@ IrcChannel *Network::ircChannel(QString channelname) const {
     return 0;
 }
 
-IrcChannel *Network::ircChannel(const QByteArray &channelname) const {
-  return ircChannel(decodeServerString(channelname));
-}
-
-
-QList<IrcChannel *> Network::ircChannels() const {
-  return _ircChannels.values();
-}
-
-quint32 Network::ircChannelCount() const {
-  return _ircChannels.count();
-}
-
 QByteArray Network::defaultCodecForServer() {
-  if(_defaultCodecForServer) return _defaultCodecForServer->name();
+  if(_defaultCodecForServer)
+    return _defaultCodecForServer->name();
   return QByteArray();
 }
 
@@ -417,7 +289,8 @@ void Network::setDefaultCodecForServer(const QByteArray &name) {
 }
 
 QByteArray Network::defaultCodecForEncoding() {
-  if(_defaultCodecForEncoding) return _defaultCodecForEncoding->name();
+  if(_defaultCodecForEncoding)
+    return _defaultCodecForEncoding->name();
   return QByteArray();
 }
 
@@ -426,7 +299,8 @@ void Network::setDefaultCodecForEncoding(const QByteArray &name) {
 }
 
 QByteArray Network::defaultCodecForDecoding() {
-  if(_defaultCodecForDecoding) return _defaultCodecForDecoding->name();
+  if(_defaultCodecForDecoding)
+    return _defaultCodecForDecoding->name();
   return QByteArray();
 }
 
@@ -435,7 +309,8 @@ void Network::setDefaultCodecForDecoding(const QByteArray &name) {
 }
 
 QByteArray Network::codecForServer() const {
-  if(_codecForServer) return _codecForServer->name();
+  if(_codecForServer)
+    return _codecForServer->name();
   return QByteArray();
 }
 
@@ -449,7 +324,8 @@ void Network::setCodecForServer(QTextCodec *codec) {
 }
 
 QByteArray Network::codecForEncoding() const {
-  if(_codecForEncoding) return _codecForEncoding->name();
+  if(_codecForEncoding)
+    return _codecForEncoding->name();
   return QByteArray();
 }
 
@@ -463,7 +339,8 @@ void Network::setCodecForEncoding(QTextCodec *codec) {
 }
 
 QByteArray Network::codecForDecoding() const {
-  if(_codecForDecoding) return _codecForDecoding->name();
+  if(_codecForDecoding)
+    return _codecForDecoding->name();
   else return QByteArray();
 }
 
@@ -478,7 +355,8 @@ void Network::setCodecForDecoding(QTextCodec *codec) {
 
 // FIXME use server encoding if appropriate
 QString Network::decodeString(const QByteArray &text) const {
-  if(_codecForDecoding) return ::decodeString(text, _codecForDecoding);
+  if(_codecForDecoding)
+    return ::decodeString(text, _codecForDecoding);
   else return ::decodeString(text, _defaultCodecForDecoding);
 }
 
@@ -493,8 +371,10 @@ QByteArray Network::encodeString(const QString &string) const {
 }
 
 QString Network::decodeServerString(const QByteArray &text) const {
-  if(_codecForServer) return ::decodeString(text, _codecForServer);
-  else return ::decodeString(text, _defaultCodecForServer);
+  if(_codecForServer)
+    return ::decodeString(text, _codecForServer);
+  else
+    return ::decodeString(text, _defaultCodecForServer);
 }
 
 QByteArray Network::encodeServerString(const QString &string) const {
@@ -521,6 +401,9 @@ void Network::setCurrentServer(const QString &currentServer) {
 }
 
 void Network::setConnected(bool connected) {
+  if(_connected == connected)
+    return;
+  
   _connected = connected;
   if(!connected) {
     removeChansAndUsers();
@@ -626,10 +509,6 @@ QVariantMap Network::initSupports() const {
   return supports;
 }
 
-QVariantList Network::initServerList() const {
-  return serverList();
-}
-
 QStringList Network::initIrcUsers() const {
   QStringList hostmasks;
   foreach(IrcUser *ircuser, ircUsers()) {
@@ -656,10 +535,6 @@ void Network::initSetSupports(const QVariantMap &supports) {
   }
 }
 
-void Network::initSetServerList(const QVariantList & serverList) {
-  setServerList(serverList);
-}
-
 void Network::initSetIrcUsers(const QStringList &hostmasks) {
   if(!_ircUsers.empty())
     return;
@@ -737,30 +612,6 @@ void Network::channelDestroyed() {
   emit ircChannelRemoved(channel);
 }
 
-void Network::requestConnect() const {
-  if(!proxy()) return;
-  if(proxy()->proxyMode() == SignalProxy::Client) emit connectRequested(); // on the client this triggers calling this slot on the core
-  else {
-    if(connectionState() != Disconnected) {
-      qWarning() << "Requesting connect while already being connected!";
-      return;
-    }
-    emit connectRequested(networkId());  // and this is for CoreSession :)
-  }
-}
-
-void Network::requestDisconnect() const {
-  if(!proxy()) return;
-  if(proxy()->proxyMode() == SignalProxy::Client) emit disconnectRequested(); // on the client this triggers calling this slot on the core
-  else {
-    if(connectionState() == Disconnected) {
-      qWarning() << "Requesting disconnect while not being connected!";
-      return;
-    }
-    emit disconnectRequested(networkId());  // and this is for CoreSession :)
-  }
-}
-
 void Network::emitConnectionError(const QString &errorMsg) {
   emit connectionError(errorMsg);
 }
@@ -887,7 +738,3 @@ QDebug operator<<(QDebug dbg, const NetworkInfo &i) {
       << " rejoinChannels = " << i.rejoinChannels << ")";
   return dbg.space();
 }
-
-
-
-
index bf430f8..3759e56 100644 (file)
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 
-#ifndef _NETWORK_H_
-#define _NETWORK_H_
+#ifndef NETWORK_H_
+#define NETWORK_H_
 
-#include <QDebug>
 #include <QString>
 #include <QStringList>
 #include <QList>
@@ -33,9 +32,9 @@
 #include "types.h"
 #include "syncableobject.h"
 
-class SignalProxy;
-class IrcUser;
-class IrcChannel;
+#include "signalproxy.h"
+#include "ircuser.h"
+#include "ircchannel.h"
 
 // defined below!
 struct NetworkInfo;
@@ -68,48 +67,70 @@ class Network : public SyncableObject {
   Q_PROPERTY(bool rejoinChannels READ rejoinChannels WRITE setRejoinChannels STORED false)
 
 public:
-  enum ConnectionState { Disconnected, Connecting, Initializing, Initialized, Reconnecting, Disconnecting };
+  enum ConnectionState {
+    Disconnected,
+    Connecting,
+    Initializing,
+    Initialized,
+    Reconnecting,
+    Disconnecting
+  };
+
+  // see:
+  //  http://www.irc.org/tech_docs/005.html
+  //  http://www.irc.org/tech_docs/draft-brocklesby-irc-isupport-03.txt
+  enum ChannelModeType {
+    NOT_A_CHANMODE = 0x00,
+    A_CHANMODE = 0x01,
+    B_CHANMODE = 0x02,
+    C_CHANMODE = 0x04,
+    D_CHANMODE = 0x08
+  };
 
+  
   Network(const NetworkId &networkid, QObject *parent = 0);
   ~Network();
 
-  NetworkId networkId() const;
+  inline NetworkId networkId() const { return _networkId; }
 
-  SignalProxy *proxy() const;
-  void setProxy(SignalProxy *proxy);
+  inline SignalProxy *proxy() const { return _proxy; }
+  inline void setProxy(SignalProxy *proxy) { _proxy = proxy; }
 
-  bool isMyNick(const QString &nick) const;
-  bool isMe(IrcUser *ircuser) const;
+  inline bool isMyNick(const QString &nick) const { return (myNick().toLower() == nick.toLower()); }
+  inline bool isMe(IrcUser *ircuser) const { return (ircuser->nick().toLower() == myNick().toLower()); }
 
   bool isChannelName(const QString &channelname) const;
 
-  bool isConnected() const;
+  inline bool isConnected() const { return _connected; }
   //Network::ConnectionState connectionState() const;
-  int connectionState() const;
+  inline int connectionState() const { return _connectionState; }
 
   QString prefixToMode(const QString &prefix);
-  QString prefixToMode(const QCharRef &prefix);
+  inline QString prefixToMode(const QCharRef &prefix) { return prefixToMode(QString(prefix)); }
   QString modeToPrefix(const QString &mode);
-  QString modeToPrefix(const QCharRef &mode);
+  inline QString modeToPrefix(const QCharRef &mode) { return modeToPrefix(QString(mode)); }
 
-  QString networkName() const;
-  QString currentServer() const;
-  QString myNick() const;
+  ChannelModeType channelModeType(const QString &mode);
+  inline ChannelModeType channelModeType(const QCharRef &mode) { return channelModeType(QString(mode)); }
+  
+  inline const QString &networkName() const { return _networkName; }
+  inline const QString &currentServer() const { return _currentServer; }
+  inline const QString &myNick() const { return _myNick; }
   inline IrcUser *me() const { return ircUser(myNick()); }
-  IdentityId identity() const;
+  inline IdentityId identity() const { return _identity; }
   QStringList nicks() const;
-  QStringList channels() const;
-  QVariantList serverList() const;
-  bool useRandomServer() const;
-  QStringList perform() const;
-  bool useAutoIdentify() const;
-  QString autoIdentifyService() const;
-  QString autoIdentifyPassword() const;
-  bool useAutoReconnect() const;
-  quint32 autoReconnectInterval() const;
-  quint16 autoReconnectRetries() const;
-  bool unlimitedReconnectRetries() const;
-  bool rejoinChannels() const;
+  inline QStringList channels() const { return _ircChannels.keys(); }
+  inline const QVariantList &serverList() const { return _serverList; }
+  inline bool useRandomServer() const { return _useRandomServer; }
+  inline const QStringList &perform() const { return _perform; }
+  inline bool useAutoIdentify() const { return _useAutoIdentify; }
+  inline const QString &autoIdentifyService() const { return _autoIdentifyService; }
+  inline const QString &autoIdentifyPassword() const { return _autoIdentifyPassword; }
+  inline bool useAutoReconnect() const { return _useAutoReconnect; }
+  inline quint32 autoReconnectInterval() const { return _autoReconnectInterval; }
+  inline quint16 autoReconnectRetries() const { return _autoReconnectRetries; }
+  inline bool unlimitedReconnectRetries() const { return _unlimitedReconnectRetries; }
+  inline bool rejoinChannels() const { return _rejoinChannels; }
 
   NetworkInfo networkInfo() const;
   void setNetworkInfo(const NetworkInfo &);
@@ -117,22 +138,22 @@ public:
   QString prefixes();
   QString prefixModes();
 
-  bool supports(const QString &param) const;
+  bool supports(const QString &param) const { return _supports.contains(param); }
   QString support(const QString &param) const;
 
   IrcUser *newIrcUser(const QString &hostmask);
-  IrcUser *newIrcUser(const QByteArray &hostmask);
+  inline IrcUser *newIrcUser(const QByteArray &hostmask) { return newIrcUser(decodeServerString(hostmask)); }
   IrcUser *ircUser(QString nickname) const;
-  IrcUser *ircUser(const QByteArray &nickname) const;
-  QList<IrcUser *> ircUsers() const;
-  quint32 ircUserCount() const;
+  inline IrcUser *ircUser(const QByteArray &nickname) const { return ircUser(decodeServerString(nickname)); }
+  inline QList<IrcUser *> ircUsers() const { return _ircUsers.values(); }
+  inline quint32 ircUserCount() const { return _ircUsers.count(); }
 
   IrcChannel *newIrcChannel(const QString &channelname);
-  IrcChannel *newIrcChannel(const QByteArray &channelname);
+  inline IrcChannel *newIrcChannel(const QByteArray &channelname) { return newIrcChannel(decodeServerString(channelname)); }
   IrcChannel *ircChannel(QString channelname) const;
-  IrcChannel *ircChannel(const QByteArray &channelname) const;
-  QList<IrcChannel *> ircChannels() const;
-  quint32 ircChannelCount() const;
+  inline IrcChannel *ircChannel(const QByteArray &channelname) const { return ircChannel(decodeServerString(channelname)); }
+  inline QList<IrcChannel *> ircChannels() const { return _ircChannels.values(); }
+  inline quint32 ircChannelCount() const { return _ircChannels.count(); }
 
   QByteArray codecForServer() const;
   QByteArray codecForEncoding() const;
@@ -188,13 +209,13 @@ public slots:
 
   //init geters
   QVariantMap initSupports() const;
-  QVariantList initServerList() const;
+  inline QVariantList initServerList() const { return serverList(); }
   QStringList initIrcUsers() const;
   QStringList initIrcChannels() const;
   
   //init seters
   void initSetSupports(const QVariantMap &supports);
-  void initSetServerList(const QVariantList &serverList);
+  inline void initSetServerList(const QVariantList &serverList) { setServerList(serverList); }
   void initSetIrcUsers(const QStringList &hostmasks);
   void initSetIrcChannels(const QStringList &channels);
   
@@ -204,8 +225,8 @@ public slots:
   // channel lists up to date
   void ircUserNickChanged(QString newnick);
 
-  void requestConnect() const;
-  void requestDisconnect() const;
+  virtual inline void requestConnect() const { emit connectRequested(); }
+  virtual inline void requestDisconnect() const { emit disconnectRequested(); }
 
   void emitConnectionError(const QString &);
 
index 333c09d..8c0f01a 100644 (file)
@@ -1,9 +1,9 @@
 DEPMOD = common
 QT_MOD = core network sql script
 
-SRCS = core.cpp corebacklogmanager.cpp corebufferviewconfig.cpp corebufferviewmanager.cpp coresession.cpp coresettings.cpp networkconnection.cpp sqlitestorage.cpp abstractsqlstorage.cpp storage.cpp basichandler.cpp \
+SRCS = core.cpp corebacklogmanager.cpp corebufferviewconfig.cpp corebufferviewmanager.cpp corenetwork.cpp coresession.cpp coresettings.cpp networkconnection.cpp sqlitestorage.cpp abstractsqlstorage.cpp storage.cpp basichandler.cpp \
        ircserverhandler.cpp userinputhandler.cpp ctcphandler.cpp coreusersettings.cpp sessionthread.cpp
-HDRS = core.h corebacklogmanager.h corebufferviewconfig.h corebufferviewmanager.h coresession.h coresettings.h networkconnection.h sqlitestorage.h abstractsqlstorage.h storage.h basichandler.h \
+HDRS = core.h corebacklogmanager.h corebufferviewconfig.h corebufferviewmanager.h corenetwork.h coresession.h coresettings.h networkconnection.h sqlitestorage.h abstractsqlstorage.h storage.h basichandler.h \
        ircserverhandler.h userinputhandler.h ctcphandler.h coreusersettings.h sessionthread.h
 
 contains(QT_CONFIG, openssl) | contains(QT_CONFIG, openssl-linked) {
index 4b47121..f868379 100644 (file)
@@ -31,7 +31,7 @@
 #include "corebufferviewmanager.h"
 #include "storage.h"
 
-#include "network.h"
+#include "corenetwork.h"
 #include "ircuser.h"
 #include "ircchannel.h"
 #include "identity.h"
@@ -99,7 +99,7 @@ CoreSession::~CoreSession() {
   foreach(NetworkConnection *conn, _connections.values()) {
     delete conn;
   }
-  foreach(Network *net, _networks.values()) {
+  foreach(CoreNetwork *net, _networks.values()) {
     delete net;
   }
 }
@@ -108,7 +108,7 @@ UserId CoreSession::user() const {
   return _user;
 }
 
-Network *CoreSession::network(NetworkId id) const {
+CoreNetwork *CoreSession::network(NetworkId id) const {
   if(_networks.contains(id)) return _networks[id];
   return 0;
 }
@@ -170,7 +170,7 @@ void CoreSession::updateBufferInfo(UserId uid, const BufferInfo &bufinfo) {
 }
 
 void CoreSession::connectToNetwork(NetworkId id) {
-  Network *net = network(id);
+  CoreNetwork *net = network(id);
   if(!net) {
     qWarning() << "Connect to unknown network requested! net:" << id << "user:" << user();
     return;
@@ -408,7 +408,7 @@ void CoreSession::createNetwork(const NetworkInfo &info_) {
 
   id = info.networkId.toInt();
   if(!_networks.contains(id)) {
-    Network *net = new Network(id, this);
+    CoreNetwork *net = new CoreNetwork(id, this);
     connect(net, SIGNAL(connectRequested(NetworkId)), this, SLOT(connectToNetwork(NetworkId)));
     connect(net, SIGNAL(disconnectRequested(NetworkId)), this, SLOT(disconnectFromNetwork(NetworkId)));
     net->setNetworkInfo(info);
@@ -422,6 +422,7 @@ void CoreSession::createNetwork(const NetworkInfo &info_) {
   }
 }
 
+// FIXME: move to CoreNetwork
 void CoreSession::updateNetwork(const NetworkInfo &info) {
   if(!_networks.contains(info.networkId)) {
     qWarning() << "Update request for unknown network received!";
@@ -472,7 +473,7 @@ void CoreSession::removeBufferRequested(BufferId bufferId) {
   }
   
   if(bufferInfo.type() == BufferInfo::ChannelBuffer) {
-    Network *net = network(bufferInfo.networkId());
+    CoreNetwork *net = network(bufferInfo.networkId());
     if(!net) {
       qWarning() << "CoreSession::removeBufferRequested(): Received BufferInfo with unknown networkId!";
       return;
index 1403c74..913f630 100644 (file)
@@ -31,7 +31,7 @@ class CoreBacklogManager;
 class CoreBufferViewManager;
 class Identity;
 class NetworkConnection;
-class Network;
+class CoreNetwork;
 struct NetworkInfo;
 class SignalProxy;
 
@@ -46,7 +46,7 @@ public:
 
   QList<BufferInfo> buffers() const;
   UserId user() const;
-  Network *network(NetworkId) const;
+  CoreNetwork *network(NetworkId) const;
   NetworkConnection *networkConnection(NetworkId) const;
   Identity *identity(IdentityId) const;
 
@@ -178,8 +178,8 @@ private:
 
   SignalProxy *_signalProxy;
   QHash<NetworkId, NetworkConnection *> _connections;
-  QHash<NetworkId, Network *> _networks;
-  QHash<NetworkId, Network *> _networksToRemove;
+  QHash<NetworkId, CoreNetwork *> _networks;
+  //  QHash<NetworkId, CoreNetwork *> _networksToRemove;
   QHash<IdentityId, Identity *> _identities;
 
   BufferSyncer *_bufferSyncer;
index 9bb6e1d..5034a71 100644 (file)
@@ -170,7 +170,10 @@ void IrcServerHandler::handleJoin(const QString &prefix, const QList<QByteArray>
   emit displayMsg(Message::Join, BufferInfo::ChannelBuffer, channel, channel, prefix);
   //qDebug() << "IrcServerHandler::handleJoin()" << prefix << params;
   ircuser->joinChannel(channel);
-  if(network()->isMe(ircuser)) networkConnection()->setChannelJoined(channel);
+  if(network()->isMe(ircuser)) {
+    networkConnection()->setChannelJoined(channel);
+    putCmd("MODE", params[0]); // we want to know the modes of the channel we just joined, so we ask politely
+  }
 }
 
 void IrcServerHandler::handleKick(const QString &prefix, const QList<QByteArray> &params) {
@@ -204,11 +207,9 @@ void IrcServerHandler::handleMode(const QString &prefix, const QList<QByteArray>
     emit displayMsg(Message::Mode, BufferInfo::ChannelBuffer, serverDecode(params[0]), serverDecode(params).join(" "), prefix);
 
     IrcChannel *channel = network()->ircChannel(params[0]);
-    // FIXME: currently the IrcChannels only support PREFIX-Modes for users
-    // This cannot be fixed unless the SignalProxy() doesn't rely on methodIds anymore
     QString modes = params[1];
     bool add = true;
-    int modeIndex = 2;
+    int paramOffset = 2;
     for(int c = 0; c < modes.length(); c++) {
       if(modes[c] == '+') {
        add = true;
@@ -219,15 +220,36 @@ void IrcServerHandler::handleMode(const QString &prefix, const QList<QByteArray>
        continue;
       }
 
-      // this is the part where we restrict the mode changes to PREFIXES:
-      if(network()->prefixModes().contains(modes[c]) && modeIndex < params.count()) {
-       IrcUser *ircUser = network()->ircUser(params[modeIndex]);
+      if(network()->prefixModes().contains(modes[c])) {
+       // user channel modes (op, voice, etc...)
+       if(paramOffset < params.count()) {
+         IrcUser *ircUser = network()->ircUser(params[paramOffset]);
+         if(add)
+           channel->addUserMode(ircUser, QString(modes[c]));
+         else
+           channel->removeUserMode(ircUser, QString(modes[c]));
+       } else {
+         qWarning() << "Received MODE with too few parameters:" << serverDecode(params);
+       }
+       paramOffset++;
+      } else {
+       // regular channel modes
+       QString value;
+       Network::ChannelModeType modeType = network()->channelModeType(modes[c]);
+       if(modeType == Network::A_CHANMODE || modeType == Network::B_CHANMODE || (modeType == Network::C_CHANMODE && add)) {
+           if(paramOffset < params.count()) {
+             value = params[paramOffset];
+           } else {
+             qWarning() << "Received MODE with too few parameters:" << serverDecode(params);
+           }
+           paramOffset++;
+       }
+       
        if(add)
-         channel->addUserMode(ircUser, QString(modes[c]));
+         channel->addChannelMode(modes[c], value);
        else
-         channel->removeUserMode(ircUser, QString(modes[c]));
+         channel->removeChannelMode(modes[c], value);
       }
-      modeIndex++;
     }
     
   } else {
@@ -701,6 +723,18 @@ void IrcServerHandler::handle320(const QString &prefix, const QList<QByteArray>
   emit displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("[Whois] %1").arg(serverDecode(params).join(" ")));
 }
 
+/* RPL_CHANNELMODEIS - "<channel> <mode> <mode params>" */
+void IrcServerHandler::handle324(const QString &prefix, const QList<QByteArray> &params) {
+  Q_UNUSED(prefix);
+  handleMode(prefix, params);
+}
+
+/* RPL_??? - "<channel> <creation time (unix)>" */
+void IrcServerHandler::handle329(const QString &prefix, const QList<QByteArray> &params) {
+  Q_UNUSED(prefix);
+  // FIXME implement this... 
+}
+
 /* RPL_NOTOPIC */
 void IrcServerHandler::handle331(const QString &prefix, const QList<QByteArray> &params) {
   Q_UNUSED(prefix);
index f58b2ea..953c3b4 100644 (file)
@@ -64,6 +64,8 @@ public slots:
   void handle318(const QString &prefix, const QList<QByteArray> &params);   // RPL_ENDOFWHOIS
   void handle319(const QString &prefix, const QList<QByteArray> &params);   // RPL_WHOISCHANNELS
   void handle320(const QString &prefix, const QList<QByteArray> &params);   // RPL_WHOISVIRT (is identified to services)
+  void handle324(const QString &prefix, const QList<QByteArray> &params);   // RPL_CHANNELMODEIS
+  void handle329(const QString &prefix, const QList<QByteArray> &params);   // RPL_??? (channel creation time)
   void handle331(const QString &prefix, const QList<QByteArray> &params);   // RPL_NOTOPIC
   void handle332(const QString &prefix, const QList<QByteArray> &params);   // RPL_TOPIC
   void handle333(const QString &prefix, const QList<QByteArray> &params);   // Topic set by...