Lots of additions again. Working on implementing commands and prettifying the output.
authorManuel Nickschas <sputnick@quassel-irc.org>
Wed, 25 Oct 2006 01:14:22 +0000 (01:14 +0000)
committerManuel Nickschas <sputnick@quassel-irc.org>
Wed, 25 Oct 2006 01:14:22 +0000 (01:14 +0000)
Still work in progress, of course. At least we have a sorta working nick list now,
even though only joins are handled by now.
Oh, and timestamps and stuff.

15 files changed:
core/core.cpp
core/core.h
core/coreproxy.h
gui/channelwidget.cpp
gui/channelwidget.h
gui/channelwidget.ui
gui/guiproxy.cpp
gui/guiproxy.h
main/message.cpp
main/message.h
main/proxy_common.h
network/builtin_cmds.cpp
network/cmdcodes.h
network/server.cpp
network/server.h

index 6270527..44c925a 100644 (file)
@@ -30,8 +30,8 @@ Core::Core() {
 
   connect(coreProxy, SIGNAL(gsRequestConnect(QStringList)), this, SLOT(connectToIrc(QStringList)));
   connect(coreProxy, SIGNAL(gsUserInput(QString, QString, QString)), this, SIGNAL(msgFromGUI(QString, QString, QString)));
 
   connect(coreProxy, SIGNAL(gsRequestConnect(QStringList)), this, SLOT(connectToIrc(QStringList)));
   connect(coreProxy, SIGNAL(gsUserInput(QString, QString, QString)), this, SIGNAL(msgFromGUI(QString, QString, QString)));
-  connect(this, SIGNAL(sendMessage(QString, QString, Message)), coreProxy, SLOT(csSendMessage(QString, QString, Message)));
-  connect(this, SIGNAL(sendStatusMsg(QString, QString)), coreProxy, SLOT(csSendStatusMsg(QString, QString)));
+  connect(this, SIGNAL(displayMsg(QString, QString, Message)), coreProxy, SLOT(csDisplayMsg(QString, QString, Message)));
+  connect(this, SIGNAL(displayStatusMsg(QString, QString)), coreProxy, SLOT(csDisplayStatusMsg(QString, QString)));
 
   // Read global settings from config file
   QSettings s;
 
   // Read global settings from config file
   QSettings s;
@@ -63,10 +63,15 @@ void Core::connectToIrc(QStringList networks) {
       connect(this, SIGNAL(connectToIrc(QString)), server, SLOT(connectToIrc(QString)));
       connect(this, SIGNAL(disconnectFromIrc(QString)), server, SLOT(disconnectFromIrc(QString)));
       connect(this, SIGNAL(msgFromGUI(QString, QString, QString)), server, SLOT(userInput(QString, QString, QString)));
       connect(this, SIGNAL(connectToIrc(QString)), server, SLOT(connectToIrc(QString)));
       connect(this, SIGNAL(disconnectFromIrc(QString)), server, SLOT(disconnectFromIrc(QString)));
       connect(this, SIGNAL(msgFromGUI(QString, QString, QString)), server, SLOT(userInput(QString, QString, QString)));
-      connect(server, SIGNAL(sendMessage(QString, Message)), this, SLOT(recvMessageFromServer(QString, Message)));
-      connect(server, SIGNAL(sendStatusMsg(QString)), this, SLOT(recvStatusMsgFromServer(QString)));
-      connect(server, SIGNAL(setTopic(QString, QString, QString)), coreProxy, SLOT(csSetTopic(QString, QString, QString)));
+      connect(server, SIGNAL(displayMsg(QString, Message)), this, SLOT(recvMessageFromServer(QString, Message)));
+      connect(server, SIGNAL(displayStatusMsg(QString)), this, SLOT(recvStatusMsgFromServer(QString)));
+      connect(server, SIGNAL(modeSet(QString, QString, QString)), coreProxy, SLOT(csModeSet(QString, QString, QString)));
+      connect(server, SIGNAL(topicSet(QString, QString, QString)), coreProxy, SLOT(csTopicSet(QString, QString, QString)));
       connect(server, SIGNAL(setNicks(QString, QString, QStringList)), coreProxy, SLOT(csSetNicks(QString, QString, QStringList)));
       connect(server, SIGNAL(setNicks(QString, QString, QStringList)), coreProxy, SLOT(csSetNicks(QString, QString, QStringList)));
+      connect(server, SIGNAL(nickAdded(QString, QString, VarMap)), coreProxy, SLOT(csNickAdded(QString, QString, VarMap)));
+      connect(server, SIGNAL(nickRemoved(QString, QString)), coreProxy, SLOT(csNickRemoved(QString, QString)));
+      connect(server, SIGNAL(nickUpdated(QString, QString, VarMap)), coreProxy, SLOT(csNickUpdated(QString, QString, VarMap)));
+      connect(server, SIGNAL(ownNickSet(QString, QString)), coreProxy, SLOT(csOwnNickSet(QString, QString)));
       // add error handling
 
       server->start();
       // add error handling
 
       server->start();
@@ -76,16 +81,18 @@ void Core::connectToIrc(QStringList networks) {
   }
 }
 
   }
 }
 
+// ALL messages coming pass through these functions before going to the GUI.
+// So this is the perfect place for storing the backlog and log stuff.
 void Core::recvMessageFromServer(QString buf, Message msg) {
   Q_ASSERT(sender());
   QString net = qobject_cast<Server*>(sender())->getNetwork();
 void Core::recvMessageFromServer(QString buf, Message msg) {
   Q_ASSERT(sender());
   QString net = qobject_cast<Server*>(sender())->getNetwork();
-  emit sendMessage(net, buf, msg);
+  emit displayMsg(net, buf, msg);
 }
 
 void Core::recvStatusMsgFromServer(QString msg) {
   Q_ASSERT(sender());
   QString net = qobject_cast<Server*>(sender())->getNetwork();
 }
 
 void Core::recvStatusMsgFromServer(QString msg) {
   Q_ASSERT(sender());
   QString net = qobject_cast<Server*>(sender())->getNetwork();
-  emit sendStatusMsg(net, msg);
+  emit displayStatusMsg(net, msg);
 }
 
 
 }
 
 
index b87bc23..6b7a0ae 100644 (file)
@@ -40,8 +40,8 @@ class Core : public QObject {
 
   signals:
     void msgFromGUI(QString network, QString channel, QString message);
 
   signals:
     void msgFromGUI(QString network, QString channel, QString message);
-    void sendMessage(QString network, QString channel, Message message);
-    void sendStatusMsg(QString, QString);
+    void displayMsg(QString network, QString channel, Message message);
+    void displayStatusMsg(QString, QString);
 
     void connectToIrc(QString net);
     void disconnectFromIrc(QString net);
 
     void connectToIrc(QString net);
     void disconnectFromIrc(QString net);
index d1fd9c7..8cdea83 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "proxy_common.h"
 #include "message.h"
 
 #include "proxy_common.h"
 #include "message.h"
+#include "global.h"
 
 #include <QtCore>
 #include <QTcpSocket>
 
 #include <QtCore>
 #include <QTcpSocket>
@@ -40,10 +41,15 @@ class CoreProxy : public QObject {
 
   public slots:
     inline void csUpdateGlobalData(QString key, QVariant data)          { send(CS_UPDATE_GLOBAL_DATA, key, data); }
 
   public slots:
     inline void csUpdateGlobalData(QString key, QVariant data)          { send(CS_UPDATE_GLOBAL_DATA, key, data); }
-    inline void csSendMessage(QString net, QString buf, Message msg)    { send(CS_SEND_MESSAGE, net, buf, QVariant::fromValue(msg)); }
-    inline void csSendStatusMsg(QString net, QString msg)               { send(CS_SEND_STATUS_MSG, net, msg); }
-    inline void csSetTopic(QString net, QString buf, QString topic)     { send(CS_SET_TOPIC, net, buf, topic); }
+    inline void csDisplayMsg(QString net, QString buf, Message msg)     { send(CS_DISPLAY_MSG, net, buf, QVariant::fromValue(msg)); }
+    inline void csDisplayStatusMsg(QString net, QString msg)            { send(CS_DISPLAY_STATUS_MSG, net, msg); }
+    inline void csModeSet(QString net, QString target, QString mode)    { send(CS_MODE_SET, net, target, mode); }
+    inline void csTopicSet(QString net, QString buf, QString topic)     { send(CS_TOPIC_SET, net, buf, topic); }
     inline void csSetNicks(QString net, QString buf, QStringList nicks) { send(CS_SET_NICKS, net, buf, nicks); }
     inline void csSetNicks(QString net, QString buf, QStringList nicks) { send(CS_SET_NICKS, net, buf, nicks); }
+    inline void csNickAdded(QString net, QString nick, VarMap props)    { send(CS_NICK_ADDED, net, nick, props); }
+    inline void csNickRemoved(QString net, QString nick)                { send(CS_NICK_REMOVED, net, nick); }
+    inline void csNickUpdated(QString net, QString nick, VarMap props)  { send(CS_NICK_UPDATED, net, nick, props); }
+    inline void csOwnNickSet(QString net, QString nick)                 { send(CS_OWN_NICK_SET, net, nick); }
 
   signals:
     void gsPutGlobalData(QString, QVariant);
 
   signals:
     void gsPutGlobalData(QString, QVariant);
index f5024b2..5053654 100644 (file)
 #include <QtGui>
 #include <iostream>
 
 #include <QtGui>
 #include <iostream>
 
-ChannelWidget::ChannelWidget(QString netname, QString bufname, QWidget *parent) : QWidget(parent) {
+ChannelWidget::ChannelWidget(QString netname, QString bufname, QString own, QWidget *parent) : QWidget(parent) {
   ui.setupUi(this);
   _networkName = netname;
   _bufferName = bufname;
   ui.setupUi(this);
   _networkName = netname;
   _bufferName = bufname;
+  ui.ownNick->clear();
+  ui.ownNick->addItem(own);
+  if(bufname.isEmpty()) {
+    // Server Buffer
+    ui.nickTree->hide();
+    ui.topicEdit->hide();
+    ui.chanSettingsButton->hide();
+  }
   connect(ui.inputEdit, SIGNAL(returnPressed()), this, SLOT(enterPressed()));
   //ui.inputEdit->setFocus();
 
   connect(ui.inputEdit, SIGNAL(returnPressed()), this, SLOT(enterPressed()));
   //ui.inputEdit->setFocus();
 
@@ -43,7 +51,7 @@ ChannelWidget::ChannelWidget(QString netname, QString bufname, QWidget *parent)
 }
 
 void ChannelWidget::enterPressed() {
 }
 
 void ChannelWidget::enterPressed() {
-  emit sendMessage(networkName(), bufferName(), ui.inputEdit->text());
+  emit sendInput(networkName(), bufferName(), ui.inputEdit->text());
   ui.inputEdit->clear();
 }
 
   ui.inputEdit->clear();
 }
 
@@ -51,18 +59,29 @@ void ChannelWidget::recvMessage(Message msg) {
   QString s;
   QColor c = stdCol;
   switch(msg.type) {
   QString s;
   QColor c = stdCol;
   switch(msg.type) {
+    case Message::Msg:
+      c = stdCol; s = QString("<%1> %2").arg(msg.sender).arg(msg.msg);
+      break;
     case Message::Server:
       c = serverCol; s = msg.msg;
       break;
     case Message::Error:
       c = errorCol; s = msg.msg;
       break;
     case Message::Server:
       c = serverCol; s = msg.msg;
       break;
     case Message::Error:
       c = errorCol; s = msg.msg;
       break;
+    case Message::Join:
+      c = joinCol; s = msg.msg;
+      break;
     default:
       c = stdCol; s = QString("[%1] %2").arg(msg.sender).arg(msg.msg);
       break;
   }
   ui.chatWidget->setTextColor(c);
     default:
       c = stdCol; s = QString("[%1] %2").arg(msg.sender).arg(msg.msg);
       break;
   }
   ui.chatWidget->setTextColor(c);
-  ui.chatWidget->insertPlainText(QString("%1\n").arg(s));
+  ui.chatWidget->insertPlainText(QString("[%2] %1\n").arg(s).arg(msg.timeStamp.toLocalTime().toString("hh:mm:ss")));
+  //ui.chatWidget->insertHtml(QString("<table><tr><td>[12:13]</td><td width=20><div align=right>[nickname]</div></td><td>This is the Message!</td></tr>"
+  //    "<tr><td>[12:13]</td><td><div align=right>[nick]</div></td><td>This is the Message!</td></tr>"
+  //    "<tr><td>[12:13]</td><td><div align=right>[looongnickname]</div></td><td>This is the Message!</td></tr>"
+  //    "<tr><td>[12:13]</td><td><div align=right>[nickname]</div></td><td>This is the Message!</td></tr></table>"
+  //                                 ));
   ui.chatWidget->ensureCursorVisible();
 }
 
   ui.chatWidget->ensureCursorVisible();
 }
 
@@ -80,6 +99,59 @@ void ChannelWidget::setNicks(QStringList nicks) {
 
 }
 
 
 }
 
+void ChannelWidget::addNick(QString nick, VarMap props) {
+  nicks[nick] = props;
+  updateNickList();
+}
+
+void ChannelWidget::updateNick(QString nick, VarMap props) {
+  nicks[nick] = props;
+  updateNickList();
+}
+
+void ChannelWidget::removeNick(QString nick) {
+  nicks[nick].toMap().remove(nick);
+  updateNickList();
+}
+
+void ChannelWidget::setOwnNick(QString nick) {
+  ui.ownNick->clear();
+  ui.ownNick->addItem(nick);
+}
+
+void ChannelWidget::updateNickList() {
+  ui.nickTree->clear();
+  if(nicks.count() != 1) ui.nickTree->setHeaderLabel(tr("%1 Users").arg(nicks.count()));
+  else ui.nickTree->setHeaderLabel(tr("1 User"));
+  QTreeWidgetItem *ops = new QTreeWidgetItem();
+  QTreeWidgetItem *voiced = new QTreeWidgetItem();
+  QTreeWidgetItem *users = new QTreeWidgetItem();
+  // To sort case-insensitive, we have to put all nicks in a map which is sorted by (lowercase) key...
+  QMap<QString, QString> sorted;
+  foreach(QString n, nicks.keys()) { sorted[n.toLower()] = n; }
+  foreach(QString n, sorted.keys()) {
+    QString nick = sorted[n];
+    QString mode = nicks[nick].toMap()["Channels"].toMap()[bufferName()].toMap()["Mode"].toString();
+    if(mode.contains('o')) { new QTreeWidgetItem(ops, QStringList(QString("@%1").arg(nick))); }
+    else if(mode.contains('v')) { new QTreeWidgetItem(voiced, QStringList(QString("+%1").arg(nick))); }
+    else new QTreeWidgetItem(users, QStringList(nick));
+  }
+  if(ops->childCount()) {
+    ops->setText(0, tr("%1 Operators").arg(ops->childCount()));
+   ui.nickTree->addTopLevelItem(ops);
+    ops->setExpanded(true);
+  } else delete ops;
+  if(voiced->childCount()) {
+    voiced->setText(0, tr("%1 Voiced").arg(voiced->childCount()));
+    ui.nickTree->addTopLevelItem(voiced);
+    voiced->setExpanded(true);
+  } else delete voiced;
+  if(users->childCount()) {
+    users->setText(0, tr("%1 Users").arg(users->childCount()));
+    ui.nickTree->addTopLevelItem(users);
+    users->setExpanded(true);
+  } else delete users;
+}
 /**********************************************************************************************/
 
 
 /**********************************************************************************************/
 
 
@@ -87,18 +159,22 @@ IrcWidget::IrcWidget(QWidget *parent) : QWidget(parent) {
   ui.setupUi(this);
   ui.tabWidget->removeTab(0);
 
   ui.setupUi(this);
   ui.tabWidget->removeTab(0);
 
-  connect(guiProxy, SIGNAL(csSendMessage(QString, QString, Message)), this, SLOT(recvMessage(QString, QString, Message)));
-  connect(guiProxy, SIGNAL(csSendStatusMsg(QString, QString)), this, SLOT(recvStatusMsg(QString, QString)));
-  connect(guiProxy, SIGNAL(csSetTopic(QString, QString, QString)), this, SLOT(setTopic(QString, QString, QString)));
+  connect(guiProxy, SIGNAL(csDisplayMsg(QString, QString, Message)), this, SLOT(recvMessage(QString, QString, Message)));
+  connect(guiProxy, SIGNAL(csDisplayStatusMsg(QString, QString)), this, SLOT(recvStatusMsg(QString, QString)));
+  connect(guiProxy, SIGNAL(csTopicSet(QString, QString, QString)), this, SLOT(setTopic(QString, QString, QString)));
   connect(guiProxy, SIGNAL(csSetNicks(QString, QString, QStringList)), this, SLOT(setNicks(QString, QString, QStringList)));
   connect(guiProxy, SIGNAL(csSetNicks(QString, QString, QStringList)), this, SLOT(setNicks(QString, QString, QStringList)));
-  connect(this, SIGNAL(sendMessage( QString, QString, QString )), guiProxy, SLOT(gsUserInput(QString, QString, QString)));
+  connect(guiProxy, SIGNAL(csNickAdded(QString, QString, VarMap)), this, SLOT(addNick(QString, QString, VarMap)));
+  connect(guiProxy, SIGNAL(csNickRemoved(QString, QString)), this, SLOT(removeNick(QString, QString)));
+  connect(guiProxy, SIGNAL(csNickUpdated(QString, QString, VarMap)), this, SLOT(updateNick(QString, QString, VarMap)));
+  connect(guiProxy, SIGNAL(csOwnNickSet(QString, QString)), this, SLOT(setOwnNick(QString, QString)));
+  connect(this, SIGNAL(sendInput( QString, QString, QString )), guiProxy, SLOT(gsUserInput(QString, QString, QString)));
 }
 
 ChannelWidget * IrcWidget::getBuffer(QString net, QString buf) {
   QString key = net + buf;
   if(!buffers.contains(key)) {
 }
 
 ChannelWidget * IrcWidget::getBuffer(QString net, QString buf) {
   QString key = net + buf;
   if(!buffers.contains(key)) {
-    ChannelWidget *cw = new ChannelWidget(net, buf);
-    connect(cw, SIGNAL(sendMessage(QString, QString, QString)), this, SLOT(userInput(QString, QString, QString)));
+    ChannelWidget *cw = new ChannelWidget(net, buf, ownNick);
+    connect(cw, SIGNAL(sendInput(QString, QString, QString)), this, SLOT(userInput(QString, QString, QString)));
     ui.tabWidget->addTab(cw, net+buf);
     ui.tabWidget->setCurrentWidget(cw);
     //cw->setFocus();
     ui.tabWidget->addTab(cw, net+buf);
     ui.tabWidget->setCurrentWidget(cw);
     //cw->setFocus();
@@ -119,7 +195,7 @@ void IrcWidget::recvStatusMsg(QString net, QString msg) {
 }
 
 void IrcWidget::userInput(QString net, QString buf, QString msg) {
 }
 
 void IrcWidget::userInput(QString net, QString buf, QString msg) {
-  emit sendMessage(net, buf, msg);
+  emit sendInput(net, buf, msg);
 }
 
 void IrcWidget::setTopic(QString net, QString buf, QString topic) {
 }
 
 void IrcWidget::setTopic(QString net, QString buf, QString topic) {
@@ -132,3 +208,42 @@ void IrcWidget::setNicks(QString net, QString buf, QStringList nicks) {
   cw->setNicks(nicks);
 }
 
   cw->setNicks(nicks);
 }
 
+void IrcWidget::addNick(QString net, QString nick, VarMap props) {
+  nicks[net].toMap()[nick] = props;
+  VarMap chans = props["Channels"].toMap();
+  QStringList c = chans.keys();
+  foreach(QString bufname, c) {
+    getBuffer(net, bufname)->addNick(nick, props);
+  }
+}
+
+void IrcWidget::updateNick(QString net, QString nick, VarMap props) {
+  QStringList oldchans = nicks[net].toMap()[nick].toMap()["Channels"].toMap().keys();
+  QStringList newchans = props["Channels"].toMap().keys();
+  foreach(QString c, newchans) {
+    if(oldchans.contains(c)) getBuffer(net, c)->updateNick(nick, props);
+    else getBuffer(net, c)->addNick(nick, props);
+  }
+  foreach(QString c, oldchans) {
+    if(!newchans.contains(c)) getBuffer(net, c)->removeNick(nick);
+  }
+  nicks[net].toMap()[nick] = props;
+}
+
+void IrcWidget::removeNick(QString net, QString nick) {
+  VarMap chans = nicks[net].toMap()[nick].toMap()["Channels"].toMap();
+  foreach(QString bufname, chans.keys()) {
+    getBuffer(net, bufname)->removeNick(nick);
+  }
+  qDebug() << nicks;
+  nicks[net].toMap().remove(nick);
+  qDebug() << nicks;
+}
+
+void IrcWidget::setOwnNick(QString net, QString nick) {
+  ownNick = nick;
+  foreach(ChannelWidget *cw, buffers.values()) {
+    if(cw->networkName() == net) cw->setOwnNick(nick);
+  }
+}
+
index 7338ecd..e1d2f2e 100644 (file)
 #include "ui_channelwidget.h"
 #include "ui_ircwidget.h"
 
 #include "ui_channelwidget.h"
 #include "ui_ircwidget.h"
 
+#include "global.h"
 #include "message.h"
 
 class ChannelWidget : public QWidget {
   Q_OBJECT
 
   public:
 #include "message.h"
 
 class ChannelWidget : public QWidget {
   Q_OBJECT
 
   public:
-    ChannelWidget(QString netname, QString bufname, QWidget *parent = 0);
+    ChannelWidget(QString netname, QString bufname, QString ownNick, QWidget *parent = 0);
 
     QString bufferName() { return _bufferName; }
     QString networkName() { return _networkName; }
   signals:
 
     QString bufferName() { return _bufferName; }
     QString networkName() { return _networkName; }
   signals:
-    void sendMessage(QString, QString, QString);
+    void sendInput(QString, QString, QString);
 
   public slots:
     void recvMessage(Message);
     void recvStatusMsg(QString msg);
     void setTopic(QString);
     void setNicks(QStringList);
 
   public slots:
     void recvMessage(Message);
     void recvStatusMsg(QString msg);
     void setTopic(QString);
     void setNicks(QStringList);
+    void addNick(QString nick, VarMap props);
+    void removeNick(QString nick);
+    void updateNick(QString nick, VarMap props);
+    void setOwnNick(QString nick);
+
 
   private slots:
     void enterPressed();
 
   private slots:
     void enterPressed();
+    void updateNickList();
 
   private:
     Ui::ChannelWidget ui;
 
   private:
     Ui::ChannelWidget ui;
@@ -52,6 +59,7 @@ class ChannelWidget : public QWidget {
     QColor stdCol, errorCol, noticeCol, joinCol, quitCol, partCol, serverCol;
     QString _networkName;
     QString _bufferName;
     QColor stdCol, errorCol, noticeCol, joinCol, quitCol, partCol, serverCol;
     QString _networkName;
     QString _bufferName;
+    VarMap nicks;
 };
 
 /** Temporary widget for displaying a set of ChannelWidgets. */
 };
 
 /** Temporary widget for displaying a set of ChannelWidgets. */
@@ -66,9 +74,13 @@ class IrcWidget : public QWidget {
     void recvStatusMsg(QString network, QString message);
     void setTopic(QString, QString, QString);
     void setNicks(QString, QString, QStringList);
     void recvStatusMsg(QString network, QString message);
     void setTopic(QString, QString, QString);
     void setNicks(QString, QString, QStringList);
+    void addNick(QString net, QString nick, VarMap props);
+    void removeNick(QString net, QString nick);
+    void updateNick(QString net, QString nick, VarMap props);
+    void setOwnNick(QString net, QString nick);
 
   signals:
 
   signals:
-    void sendMessage(QString network, QString buffer, QString message);
+    void sendInput(QString network, QString buffer, QString message);
 
   private slots:
     void userInput(QString, QString, QString);
 
   private slots:
     void userInput(QString, QString, QString);
@@ -76,6 +88,8 @@ class IrcWidget : public QWidget {
   private:
     Ui::IrcWidget ui;
     QHash<QString, ChannelWidget *> buffers;
   private:
     Ui::IrcWidget ui;
     QHash<QString, ChannelWidget *> buffers;
+    VarMap nicks;
+    QString ownNick;
 
     ChannelWidget * getBuffer(QString net, QString buf);
 };
 
     ChannelWidget * getBuffer(QString net, QString buf);
 };
index a821979..3bc85eb 100644 (file)
       <property name="textElideMode" >
        <enum>Qt::ElideRight</enum>
       </property>
       <property name="textElideMode" >
        <enum>Qt::ElideRight</enum>
       </property>
+      <property name="rootIsDecorated" >
+       <bool>true</bool>
+      </property>
       <property name="sortingEnabled" >
        <bool>false</bool>
       </property>
       <property name="sortingEnabled" >
        <bool>false</bool>
       </property>
      </property>
      <item>
       <widget class="QComboBox" name="ownNick" >
      </property>
      <item>
       <widget class="QComboBox" name="ownNick" >
-       <item>
-        <property name="text" >
-         <string>mainNick</string>
-        </property>
-       </item>
-       <item>
-        <property name="text" >
-         <string>altNick</string>
-        </property>
-       </item>
+       <property name="sizeAdjustPolicy" >
+        <enum>QComboBox::AdjustToContents</enum>
+       </property>
       </widget>
      </item>
      <item>
       </widget>
      </item>
      <item>
index e9da5b0..9848ff3 100644 (file)
@@ -30,10 +30,15 @@ void GUIProxy::recv(CoreSignal sig, QVariant arg1, QVariant arg2, QVariant arg3)
     case CS_CORE_STATE: emit csCoreState(arg1); break;
     case CS_UPDATE_GLOBAL_DATA: emit csUpdateGlobalData(arg1.toString(), arg2); break;
     //case CS_GLOBAL_DATA_CHANGED: emit csGlobalDataChanged(arg1.toString()); break;
     case CS_CORE_STATE: emit csCoreState(arg1); break;
     case CS_UPDATE_GLOBAL_DATA: emit csUpdateGlobalData(arg1.toString(), arg2); break;
     //case CS_GLOBAL_DATA_CHANGED: emit csGlobalDataChanged(arg1.toString()); break;
-    case CS_SEND_MESSAGE: emit csSendMessage(arg1.toString(), arg2.toString(), arg3.value<Message>()); break;
-    case CS_SEND_STATUS_MSG: emit csSendStatusMsg(arg1.toString(), arg2.toString()); break;
-    case CS_SET_TOPIC: emit csSetTopic(arg1.toString(), arg2.toString(), arg3.toString()); break;
+    case CS_DISPLAY_MSG: emit csDisplayMsg(arg1.toString(), arg2.toString(), arg3.value<Message>()); break;
+    case CS_DISPLAY_STATUS_MSG: emit csDisplayStatusMsg(arg1.toString(), arg2.toString()); break;
+    case CS_MODE_SET: emit csModeSet(arg1.toString(), arg2.toString(), arg3.toString()); break;
+    case CS_TOPIC_SET: emit csTopicSet(arg1.toString(), arg2.toString(), arg3.toString()); break;
     case CS_SET_NICKS: emit csSetNicks(arg1.toString(), arg2.toString(), arg3.toStringList()); break;
     case CS_SET_NICKS: emit csSetNicks(arg1.toString(), arg2.toString(), arg3.toStringList()); break;
+    case CS_NICK_ADDED: emit csNickAdded(arg1.toString(), arg2.toString(), arg3.toMap()); break;
+    case CS_NICK_REMOVED: emit csNickRemoved(arg1.toString(), arg2.toString()); break;
+    case CS_NICK_UPDATED: emit csNickUpdated(arg1.toString(), arg2.toString(), arg3.toMap()); break;
+    case CS_OWN_NICK_SET: emit csOwnNickSet(arg1.toString(), arg2.toString()); break;
 
     default: qWarning() << "Unknown signal in GUIProxy::recv: " << sig;
   }
 
     default: qWarning() << "Unknown signal in GUIProxy::recv: " << sig;
   }
index df788d7..a068b6d 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "proxy_common.h"
 #include "message.h"
 
 #include "proxy_common.h"
 #include "message.h"
+#include "global.h"
 
 #include <QObject>
 #include <QVariant>
 
 #include <QObject>
 #include <QVariant>
@@ -48,12 +49,17 @@ class GUIProxy : public QObject {
 
   signals:
     void csCoreState(QVariant);
 
   signals:
     void csCoreState(QVariant);
-    void csSendMessage(QString, QString, Message);
-    void csSendStatusMsg(QString, QString);
+    void csDisplayMsg(QString, QString, Message);
+    void csDisplayStatusMsg(QString, QString);
     void csUpdateGlobalData(QString key, QVariant data);
     void csGlobalDataChanged(QString key);
     void csUpdateGlobalData(QString key, QVariant data);
     void csGlobalDataChanged(QString key);
-    void csSetTopic(QString, QString, QString);
+    void csModeSet(QString, QString, QString);
+    void csTopicSet(QString, QString, QString);
     void csSetNicks(QString, QString, QStringList);
     void csSetNicks(QString, QString, QStringList);
+    void csNickAdded(QString, QString, VarMap);
+    void csNickRemoved(QString, QString);
+    void csNickUpdated(QString, QString, VarMap);
+    void csOwnNickSet(QString, QString);
 
     void coreConnected();
     void coreDisconnected();
 
     void coreConnected();
     void coreDisconnected();
index 3739822..e89d1a1 100644 (file)
 #include <QDataStream>
 
 QDataStream &operator<<(QDataStream &out, const Message &msg) {
 #include <QDataStream>
 
 QDataStream &operator<<(QDataStream &out, const Message &msg) {
-  out << (quint8)msg.type << (quint8)msg.flags << msg.sender << msg.msg;
+  out << (quint8)msg.type << (quint8)msg.flags << msg.sender << msg.msg << (quint32)msg.timeStamp.toTime_t();
   return out;
 }
 
 QDataStream &operator>>(QDataStream &in, Message &msg) {
   quint8 t, f;
   return out;
 }
 
 QDataStream &operator>>(QDataStream &in, Message &msg) {
   quint8 t, f;
-  in >> t >> f >> msg.sender >> msg.msg;
+  quint32 ts;
+  in >> t >> f >> msg.sender >> msg.msg >> ts;
   msg.type = (Message::Type)t;
   msg.flags = (Message::Flags)f;
   msg.type = (Message::Type)t;
   msg.flags = (Message::Flags)f;
+  msg.timeStamp = QDateTime::fromTime_t(ts);
   return in;
 }
   return in;
 }
index 9eb182a..c1954f5 100644 (file)
@@ -33,9 +33,10 @@ struct Message {
   Flags flags;
   QString sender;
   QString msg;
   Flags flags;
   QString sender;
   QString msg;
+  QDateTime timeStamp;
 
   Message(QString _msg = "", QString _sender = "", Type _type = Msg, Flags _flags = None)
 
   Message(QString _msg = "", QString _sender = "", Type _type = Msg, Flags _flags = None)
-  : msg(_msg), sender(_sender), type(_type), flags(_flags) {};
+  : msg(_msg), sender(_sender), type(_type), flags(_flags) { timeStamp = QDateTime::currentDateTime().toUTC(); };
 
 };
 
 
 };
 
index f7b5594..64dd228 100644 (file)
@@ -25,8 +25,9 @@ enum GUISignal { GS_CLIENT_INIT, GS_USER_INPUT, GS_REQUEST_CONNECT, GS_UPDATE_GL
 
 };
 
 
 };
 
-enum CoreSignal { CS_CORE_STATE, CS_SEND_MESSAGE, CS_SEND_STATUS_MSG, CS_UPDATE_GLOBAL_DATA,
-  CS_SET_TOPIC, CS_SET_NICKS,
+enum CoreSignal { CS_CORE_STATE, CS_DISPLAY_MSG, CS_DISPLAY_STATUS_MSG, CS_UPDATE_GLOBAL_DATA,
+  CS_MODE_SET, CS_TOPIC_SET, CS_SET_NICKS, CS_NICK_ADDED, CS_NICK_REMOVED, CS_NICK_UPDATED,
+  CS_OWN_NICK_SET,
 
 };
 
 
 };
 
index 2e72c9d..5927469 100644 (file)
@@ -18,6 +18,8 @@
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 
+/* THIS CODE IS OBSOLETE! */
+
 #include <QtGlobal>
 //#include "message.h"
 #include "cmdcodes.h"
 #include <QtGlobal>
 //#include "message.h"
 #include "cmdcodes.h"
index 787a673..7f9625f 100644 (file)
@@ -18,6 +18,8 @@
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 
+/* THIS CODE IS OBSOLETE! */
+
 #ifndef _CMDCODES_H_
 #define _CMDCODES_H_
 
 #ifndef _CMDCODES_H_
 #define _CMDCODES_H_
 
index d9e0a5b..e4d37a6 100644 (file)
@@ -24,6 +24,7 @@
 #include "message.h"
 
 #include <QMetaObject>
 #include "message.h"
 
 #include <QMetaObject>
+#include <QDateTime>
 
 Server::Server(QString net) : network(net) {
 
 
 Server::Server(QString net) : network(net) {
 
@@ -45,11 +46,12 @@ void Server::run() {
 
 void Server::connectToIrc(QString net) {
   if(net != network) return; // not me!
 
 void Server::connectToIrc(QString net) {
   if(net != network) return; // not me!
-  QList<QVariant> servers = global->getData("Networks").toMap()[net].toMap()["Servers"].toList();
-  qDebug() << "Connecting to"<< servers[0].toMap();
+  networkSettings = global->getData("Networks").toMap()[net].toMap();
+  identity = global->getData("Identities").toMap()[networkSettings["Identity"].toString()].toMap();
+  QList<QVariant> servers = networkSettings["Servers"].toList();
   QString host = servers[0].toMap()["Address"].toString();
   quint16 port = servers[0].toMap()["Port"].toUInt();
   QString host = servers[0].toMap()["Address"].toString();
   quint16 port = servers[0].toMap()["Port"].toUInt();
-  sendStatusMsg(QString("Connecting to %1:%2...").arg(host).arg(port));
+  displayStatusMsg(QString("Connecting to %1:%2...").arg(host).arg(port));
   socket.connectToHost(host, port);
 }
 
   socket.connectToHost(host, port);
 }
 
@@ -74,9 +76,8 @@ void Server::socketError( QAbstractSocket::SocketError err ) {
 }
 
 void Server::socketConnected( ) {
 }
 
 void Server::socketConnected( ) {
-  qDebug() << "Socket connected!";
-  putRawLine("NICK :QuasselDev");
-  putRawLine("USER Sputnick 8 * :Using Quassel IRC (WiP Version)");
+  putRawLine(QString("NICK :%1").arg(identity["NickList"].toStringList()[0]));
+  putRawLine(QString("USER %1 8 * :%2").arg(identity["Ident"].toString()).arg(identity["RealName"].toString()));
 }
 
 void Server::socketDisconnected( ) {
 }
 
 void Server::socketDisconnected( ) {
@@ -88,6 +89,22 @@ void Server::socketStateChanged(QAbstractSocket::SocketState state) {
   //qDebug() << "Socket state changed: " << state;
 }
 
   //qDebug() << "Socket state changed: " << state;
 }
 
+QString Server::nickFromMask(QString mask) {
+  return mask.section('!', 0, 0);
+}
+
+QString Server::userFromMask(QString mask) {
+  QString userhost = mask.section('!', 1);
+  if(userhost.isEmpty()) return QString();
+  return userhost.section('@', 0, 0);
+}
+
+QString Server::hostFromMask(QString mask) {
+  QString userhost = mask.section('!', 1);
+  if(userhost.isEmpty()) return QString();
+  return userhost.section('@', 1);
+}
+
 void Server::userInput(QString net, QString buf, QString msg) {
   if(net != network) return; // not me!
   msg = msg.trimmed(); // remove whitespace from start and end
 void Server::userInput(QString net, QString buf, QString msg) {
   if(net != network) return; // not me!
   msg = msg.trimmed(); // remove whitespace from start and end
@@ -143,6 +160,13 @@ void Server::handleServerMsg(QString msg) {
     if(!trailing.isEmpty()) {
       params << trailing;
     }
     if(!trailing.isEmpty()) {
       params << trailing;
     }
+    // numeric replies usually have our own nick as first param. Remove this!
+    // BTW, this behavior is not in the RFC.
+    uint num = cmd.toUInt();
+    if(num > 1 && params.count() > 0) {  // 001 sets our nick, so we shouldn't remove anything
+      if(params[0] == currentNick) params.removeFirst();
+      else qWarning((QString("First param NOT nick: %1:%2 %3").arg(prefix).arg(cmd).arg(params.join(" "))).toAscii());
+    }
     // Now we try to find a handler for this message. BTW, I do love the Trolltech guys ;-)
     QString hname = cmd.toLower();
     hname[0] = hname[0].toUpper();
     // Now we try to find a handler for this message. BTW, I do love the Trolltech guys ;-)
     QString hname = cmd.toLower();
     hname[0] = hname[0].toUpper();
@@ -152,35 +176,31 @@ void Server::handleServerMsg(QString msg) {
       defaultServerHandler(cmd, prefix, params);
     }
   } catch(Exception e) {
       defaultServerHandler(cmd, prefix, params);
     }
   } catch(Exception e) {
-    emit sendMessage("", Message(e.msg(), "", Message::Error));
+    emit displayMsg("", Message(e.msg(), "", Message::Error));
   }
 }
 
 void Server::defaultServerHandler(QString cmd, QString prefix, QStringList params) {
   uint num = cmd.toUInt();
   if(num) {
   }
 }
 
 void Server::defaultServerHandler(QString cmd, QString prefix, QStringList params) {
   uint num = cmd.toUInt();
   if(num) {
-    if(params.count() > 0) {
-      if(params[0] == currentNick) params.removeFirst();  // remove nick if it is first arg
-      else qWarning((QString("First param NOT nick: %1:%2 %3").arg(prefix).arg(cmd).arg(params.join(" "))).toAscii());
-    }
     // A lot of server messages don't really need their own handler because they don't do much.
     // Catch and handle these here.
     switch(num) {
       // Welcome, status, info messages. Just display these.
       case 2: case 3: case 4: case 5: case 251: case 252: case 253: case 254: case 255: case 372: case 375:
     // A lot of server messages don't really need their own handler because they don't do much.
     // Catch and handle these here.
     switch(num) {
       // Welcome, status, info messages. Just display these.
       case 2: case 3: case 4: case 5: case 251: case 252: case 253: case 254: case 255: case 372: case 375:
-        emit sendMessage("", Message(params.join(" "), prefix, Message::Server));
+        emit displayMsg("", Message(params.join(" "), prefix, Message::Server));
         break;
       // Ignore these commands.
         break;
       // Ignore these commands.
-      case 376:
+      case 366: case 376:
         break;
 
       // Everything else will be marked in red, so we can add them somewhere.
       default:
         break;
 
       // Everything else will be marked in red, so we can add them somewhere.
       default:
-        emit sendMessage("", Message(cmd + " " + params.join(" "), prefix, Message::Error));
+        emit displayMsg("", Message(cmd + " " + params.join(" "), prefix, Message::Error));
     }
     //qDebug() << prefix <<":"<<cmd<<params;
   } else {
     }
     //qDebug() << prefix <<":"<<cmd<<params;
   } else {
-    emit sendMessage("", Message(QString("Unknown: ") + cmd + " " + params.join(" "), prefix, Message::Error));
+    emit displayMsg("", Message(QString("Unknown: ") + cmd + " " + params.join(" "), prefix, Message::Error));
     //qDebug() << prefix <<":"<<cmd<<params;
   }
 }
     //qDebug() << prefix <<":"<<cmd<<params;
   }
 }
@@ -202,12 +222,12 @@ void Server::handleUserMsg(QString bufname, QString usrMsg) {
       defaultUserHandler(cmd, msg, buffer);
     }
   } catch(Exception e) {
       defaultUserHandler(cmd, msg, buffer);
     }
   } catch(Exception e) {
-    emit sendMessage("", Message(e.msg(), "", Message::Error));
+    emit displayMsg("", Message(e.msg(), "", Message::Error));
   }
 }
 
 void Server::defaultUserHandler(QString cmd, QString msg, Buffer *buf) {
   }
 }
 
 void Server::defaultUserHandler(QString cmd, QString msg, Buffer *buf) {
-  emit sendMessage("", Message(QString("Error: %1 %2").arg(cmd).arg(msg), "", Message::Error));
+  emit displayMsg("", Message(QString("Error: %1 %2").arg(cmd).arg(msg), "", Message::Error));
 
 }
 
 
 }
 
@@ -234,24 +254,50 @@ void Server::handleUserSay(QString msg, Buffer *buf) {
   QStringList params;
   params << buf->name() << msg;
   putCmd("PRIVMSG", params);
   QStringList params;
   params << buf->name() << msg;
   putCmd("PRIVMSG", params);
+  emit displayMsg(params[0], Message(msg, currentNick, Message::Msg, Message::Self));
 }
 
 /**********************************************************************************/
 
 void Server::handleServerJoin(QString prefix, QStringList params) {
   Q_ASSERT(params.count() == 1);
 }
 
 /**********************************************************************************/
 
 void Server::handleServerJoin(QString prefix, QStringList params) {
   Q_ASSERT(params.count() == 1);
-  QString bufname = params[0];
-  if(!buffers.contains(bufname)) {
-    Buffer *buf = new Buffer(bufname);
-    buffers[bufname] = buf;
+  QString nick = nickFromMask(prefix);
+  if(nick == currentNick) {
+    Q_ASSERT(!buffers.contains(params[0]));  // cannot join a buffer twice!
+    Buffer *buf = new Buffer(params[0]);
+    buffers[params[0]] = buf;
+  } else {
+    VarMap n;
+    if(nicks.contains(nick)) {
+      n = nicks[nick].toMap();
+      VarMap chans = n["Channels"].toMap();
+      // Q_ASSERT(!chans.keys().contains(params[0])); TODO uncomment
+      chans[params[0]] = VarMap();
+      n["Channels"] = chans;
+      nicks[nick] = n;
+      emit nickUpdated(network, nick, n);
+    } else {
+      VarMap chans;
+      chans[params[0]] = VarMap();
+      n["Channels"] = chans;
+      n["Nick"] = nick;
+      n["User"] = userFromMask(prefix);
+      n["Host"] = hostFromMask(prefix);
+      nicks[nick] = n;
+      emit nickAdded(network, nick, n);
+    }
+    QString user = n["User"].toString(); QString host = n["Host"].toString();
+    if(user.isEmpty() || host.isEmpty()) emit displayMsg(params[0], Message(tr("%1 has joined %2").arg(nick).arg(params[0]), "", Message::Join));
+    else emit displayMsg(params[0], Message(tr("%1 (%2@%3) has joined %4").arg(nick).arg(user).arg(host).arg(params[0]), "", Message::Join));
   }
   }
-  // handle user joins!
 }
 
 }
 
+
+
 void Server::handleServerNotice(QString prefix, QStringList params) {
   Message msg(params[1], prefix, Message::Notice);
 void Server::handleServerNotice(QString prefix, QStringList params) {
   Message msg(params[1], prefix, Message::Notice);
-  if(prefix == currentServer) emit sendMessage("", Message(params[1], prefix, Message::Server));
-  else emit sendMessage("", Message(params[1], prefix, Message::Notice));
+  if(prefix == currentServer) emit displayMsg("", Message(params[1], prefix, Message::Server));
+  else emit displayMsg("", Message(params[1], prefix, Message::Notice));
 }
 
 void Server::handleServerPing(QString prefix, QStringList params) {
 }
 
 void Server::handleServerPing(QString prefix, QStringList params) {
@@ -259,7 +305,7 @@ void Server::handleServerPing(QString prefix, QStringList params) {
 }
 
 void Server::handleServerPrivmsg(QString prefix, QStringList params) {
 }
 
 void Server::handleServerPrivmsg(QString prefix, QStringList params) {
-  emit sendMessage(params[0], Message(params[1], prefix, Message::Msg));
+  emit displayMsg(params[0], Message(params[1], nickFromMask(prefix), Message::Msg));
 
 }
 
 
 }
 
@@ -267,21 +313,54 @@ void Server::handleServerPrivmsg(QString prefix, QStringList params) {
 void Server::handleServer001(QString prefix, QStringList params) {
   currentServer = prefix;
   currentNick = params[0];
 void Server::handleServer001(QString prefix, QStringList params) {
   currentServer = prefix;
   currentNick = params[0];
-  emit sendMessage("", Message(params[1], prefix, Message::Server));
+  emit ownNickSet(network, currentNick);
+  emit displayMsg("", Message(params[1], prefix, Message::Server));
 }
 
 /* RPL_NOTOPIC */
 void Server::handleServer331(QString prefix, QStringList params) {
 }
 
 /* RPL_NOTOPIC */
 void Server::handleServer331(QString prefix, QStringList params) {
-  if(params[0] == currentNick) params.removeFirst();
-  emit setTopic(network, params[0], "");
+  emit topicSet(network, params[0], "");
 }
 
 /* RPL_TOPIC */
 void Server::handleServer332(QString prefix, QStringList params) {
 }
 
 /* RPL_TOPIC */
 void Server::handleServer332(QString prefix, QStringList params) {
-  if(params[0] == currentNick) params.removeFirst();
-  emit setTopic(network, params[0], params[1]);
+  emit topicSet(network, params[0], params[1]);
+  emit displayMsg(params[0], Message(tr("Topic for %1 is \"%2\"").arg(params[0]).arg(params[1]), "", Message::Server));
 }
 
 }
 
+/* Topic set by... */
+void Server::handleServer333(QString prefix, QStringList params) {
+  emit displayMsg(params[0], Message(tr("Topic set by %1 on %2").arg(params[1]).arg(QDateTime::fromTime_t(params[2].toUInt()).toString()), "", Message::Server));
+}
+
+/* RPL_NAMREPLY */
+void Server::handleServer353(QString prefix, QStringList params) {
+  params.removeFirst(); // = or *
+  QString buf = params.takeFirst();
+  foreach(QString nick, params[0].split(' ')) {
+    // TODO: parse more prefix characters! use 005?
+    QString mode = "";
+    if(nick.startsWith('@')) { mode = "o"; nick.remove(0,1); }
+    else if(nick.startsWith('+')) { mode = "v"; nick.remove(0,1); }
+    VarMap c; c["Mode"] = mode;
+    if(nicks.contains(nick)) {
+      VarMap n = nicks[nick].toMap();
+      VarMap chans = n["Channels"].toMap();
+      chans[buf] = c;
+      n["Channels"] = chans;
+      nicks[nick] = n;
+      emit nickUpdated(network, nick, n);
+    } else {
+      VarMap n; VarMap c; VarMap chans;
+      c["Mode"] = mode;
+      chans[buf] = c;
+      n["Channels"] = chans;
+      n["Nick"] = nick;
+      nicks[nick] = n;
+      emit nickAdded(network, nick, n);
+    }
+  }
+}
 /***********************************************************************************/
 
 /* Exception classes for message handling */
 /***********************************************************************************/
 
 /* Exception classes for message handling */
index 6fde53f..c5a3daa 100644 (file)
@@ -62,12 +62,17 @@ class Server : public QThread {
 
   signals:
     void recvRawServerMsg(QString);
 
   signals:
     void recvRawServerMsg(QString);
-    void sendStatusMsg(QString);
-    void sendMessage(QString buffer, Message msg);
+    void displayStatusMsg(QString);
+    void displayMsg(QString buffer, Message msg);
     void disconnected();
 
     void disconnected();
 
-    void setTopic(QString network, QString buffer, QString topic);
+    void nickAdded(QString network, QString nick, VarMap props);
+    void nickRemoved(QString network, QString nick);
+    void nickUpdated(QString network, QString nick, VarMap props);
+    void modeSet(QString network, QString target, QString mode);
+    void topicSet(QString network, QString buffer, QString topic);
     void setNicks(QString network, QString buffer, QStringList nicks);
     void setNicks(QString network, QString buffer, QStringList nicks);
+    void ownNickSet(QString network, QString newNick);
 
 
   private slots:
 
 
   private slots:
@@ -95,6 +100,8 @@ class Server : public QThread {
     void handleServer001(QString, QStringList);   // RPL_WELCOME
     void handleServer331(QString, QStringList);   // RPL_NOTOPIC
     void handleServer332(QString, QStringList);   // RPL_TOPIC
     void handleServer001(QString, QStringList);   // RPL_WELCOME
     void handleServer331(QString, QStringList);   // RPL_NOTOPIC
     void handleServer332(QString, QStringList);   // RPL_TOPIC
+    void handleServer333(QString, QStringList);   // Topic set by...
+    void handleServer353(QString, QStringList);   // RPL_NAMREPLY
 
     void defaultServerHandler(QString cmd, QString prefix, QStringList params);
     void defaultUserHandler(QString cmd, QString msg, Buffer *buf);
 
     void defaultServerHandler(QString cmd, QString prefix, QStringList params);
     void defaultUserHandler(QString cmd, QString msg, Buffer *buf);
@@ -106,10 +113,17 @@ class Server : public QThread {
 
     QString currentNick;
     QString currentServer;
 
     QString currentNick;
     QString currentServer;
+    VarMap networkSettings;
+    VarMap identity;
+    VarMap nicks;  // stores all known nicks for the server
 
     void handleServerMsg(QString rawMsg);
     void handleUserMsg(QString buffer, QString usrMsg);
 
 
     void handleServerMsg(QString rawMsg);
     void handleUserMsg(QString buffer, QString usrMsg);
 
+    QString nickFromMask(QString mask);
+    QString userFromMask(QString mask);
+    QString hostFromMask(QString mask);
+
     class ParseError : public Exception {
       public:
         ParseError(QString cmd, QString prefix, QStringList params);
     class ParseError : public Exception {
       public:
         ParseError(QString cmd, QString prefix, QStringList params);