changeset 13679:e272af3f252d

Renamed qirc to irc.
author Jacob Dawid <jacob.dawid@googlemail.com>
date Sun, 25 Sep 2011 21:13:59 +0200
parents 117ae3cb156e
children 3a2b09503fed
files gui/octave-gui.pro gui/src/irc/IRCClientImpl.cpp gui/src/irc/IRCClientImpl.h gui/src/irc/IRCClientInterface.h gui/src/irc/IRCCodes.h gui/src/irc/IRCWidget.cpp gui/src/irc/IRCWidget.h gui/src/irc/Makefile.am gui/src/qirc/IRCClientImpl.cpp gui/src/qirc/IRCClientImpl.h gui/src/qirc/IRCClientInterface.h gui/src/qirc/IRCCodes.h gui/src/qirc/IRCWidget.cpp gui/src/qirc/IRCWidget.h gui/src/qirc/Makefile.am
diffstat 15 files changed, 1898 insertions(+), 1898 deletions(-) [+]
line wrap: on
line diff
--- a/gui/octave-gui.pro	Sun Sep 25 21:12:47 2011 +0200
+++ b/gui/octave-gui.pro	Sun Sep 25 21:13:59 2011 +0200
@@ -65,7 +65,7 @@
     	  src/FileEditorMdiSubWindow.cpp \
     	  src/BrowserWidget.cpp \
     	  src/ImageViewerMdiSubWindow.cpp \
-    src/qirc/IRCWidget.cpp \
+    src/irc/IRCWidget.cpp \
     src/SettingsDialog.cpp \
     src/OctaveGUI.cpp \
     src/ResourceManager.cpp \
@@ -73,7 +73,7 @@
     src/backend/OctaveCallbackThread.cpp \
     src/backend/OctaveLink.cpp \
     src/backend/OctaveMainThread.cpp \
-    src/qirc/IRCClientImpl.cpp \
+    src/irc/IRCClientImpl.cpp \
     src/terminal/TerminalEmulation.cpp \
     src/terminal/LinuxTerminalEmulation.cpp \
     src/backend/ReadlineAdapter.cpp \
@@ -92,15 +92,15 @@
     	  src/FileEditorMdiSubWindow.h \
     	  src/BrowserWidget.h \
     	  src/ImageViewerMdiSubWindow.h \
-    src/qirc/IRCWidget.h \
+    src/irc/IRCWidget.h \
     src/SettingsDialog.h \
     src/ResourceManager.h \
     src/CommandLineParser.h \
     src/backend/OctaveCallbackThread.h \
     src/backend/OctaveLink.h \
     src/backend/OctaveMainThread.h \
-    src/qirc/IRCClientInterface.h \
-    src/qirc/IRCClientImpl.h \
+    src/irc/IRCClientInterface.h \
+    src/irc/IRCClientImpl.h \
     src/terminal/TerminalEmulation.h \
     src/terminal/LinuxTerminalEmulation.h \
     src/backend/ReadlineAdapter.h \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/src/irc/IRCClientImpl.cpp	Sun Sep 25 21:13:59 2011 +0200
@@ -0,0 +1,511 @@
+/* OctaveGUI - A graphical user interface for Octave
+ * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "IRCClientImpl.h"
+
+IRCServerMessage::IRCServerMessage (const QString& serverMessage)
+{
+  if (serverMessage.isEmpty ())
+    return;
+
+  int position = 0;
+  QString buffer;
+
+  m_nick = "";
+  m_user = "";
+  m_host = "";
+
+  // A server message starting with a prefix indicates
+  // a prefix. A prefix has the format:
+  // :nick!user@host
+  // followed by a space character.
+  if (serverMessage.startsWith (":"))
+    {
+      position++;
+      while ((position < serverMessage.size ())
+             &&(serverMessage.at (position) != '!')
+             && !serverMessage.at (position).isSpace ())
+        {
+          buffer.append (serverMessage.at (position));
+          position++;
+        }
+      m_nick = buffer, buffer.clear (), position++;
+
+      // If it belongs to the prefix, it must be concatenanted neatlessly without
+      // any spaces.
+      if (!serverMessage.at (position - 1).isSpace ())
+        {
+          while ((position < serverMessage.size ())
+                 && serverMessage.at (position) != '@')
+            {
+              buffer.append (serverMessage.at (position));
+              position++;
+            }
+          m_user = buffer, buffer.clear (), position++;
+        }
+
+      // If it belongs to the prefix, it must be concatenanted neatlessly without
+      // any spaces.
+      if (!serverMessage.at (position - 1).isSpace ())
+        {
+          while ((position < serverMessage.size ())
+                 && serverMessage.at (position) != ' ')
+            {
+              buffer.append (serverMessage.at (position));
+              position++;
+            }
+          m_host = buffer, buffer.clear (), position++;
+        }
+    }
+
+  // The next part is the command. The command can either be numeric
+  // or a written command.
+  while ((position < serverMessage.size ())
+         && !serverMessage.at (position).isSpace ())
+    {
+      buffer.append (serverMessage.at (position));
+      position++;
+    }
+  m_command = buffer.toUpper (), buffer.clear (), position++;
+  m_codeNumber = m_command.toInt (&m_isNumeric);
+
+  // Next: a list of parameters. If any of these parameters
+  // starts with a colon, we have to read everything that follows
+  // as a single parameter.
+  bool readUntilEnd = false;
+  while (position < serverMessage.size ())
+    {
+      if (buffer.isEmpty () && !readUntilEnd && (serverMessage.at (position) == ':'))
+        {
+          readUntilEnd = true;
+        }
+      else
+        {
+          if (readUntilEnd)
+            {
+              buffer.append (serverMessage.at (position));
+            }
+          else
+            {
+              if (serverMessage.at (position).isSpace ())
+                {
+                  if (!buffer.isEmpty ())
+                    {
+                      m_parameters.append (buffer);
+                      buffer.clear ();
+                    }
+                }
+              else
+                {
+                  buffer.append (serverMessage.at (position));
+                }
+            }
+        }
+      position++;
+    }
+
+  if (!buffer.isEmpty ())
+    {
+      // We need to chop off \r\n here.
+      buffer.chop (2);
+      m_parameters.append (buffer);
+    }
+}
+
+int
+IRCServerMessage::numericValue ()
+{
+  if (m_isNumeric)
+    return m_codeNumber;
+  return -1;
+}
+
+QString
+IRCServerMessage::parameter (int index)
+{
+  if (index >= 0 && index < m_parameters.size ())
+    return m_parameters.at (index);
+  return "";
+}
+
+
+IRCChannelProxyImpl::IRCChannelProxyImpl (IRCClientInterface *clientInterface, const QString& channelName, QObject *parent)
+  : IRCChannelProxyInterface (clientInterface, channelName, parent),
+    m_clientInterface (clientInterface)
+{
+  m_channelName = channelName;
+  connect (clientInterface, SIGNAL (nicknameChanged (QString,QString)),
+           this, SLOT (handleNickChange (QString,QString)));
+}
+
+QTextDocument *
+IRCChannelProxyImpl::conversationModel ()
+{
+  return &m_conversationModel;
+}
+
+QStringListModel *
+IRCChannelProxyImpl::userListModel ()
+{
+  return &m_userListModel;
+}
+
+QString
+IRCChannelProxyImpl::channelName ()
+{
+  return m_channelName;
+}
+
+void
+IRCChannelProxyImpl::setNickList (const QStringList &nickList)
+{
+  m_userList = nickList;
+  m_userListModel.setStringList (nickList);
+}
+
+void
+IRCChannelProxyImpl::sendMessage (const QString& message)
+{
+  QStringList arguments;
+  arguments << m_channelName;
+  arguments << message;
+  m_clientInterface->sendIRCCommand (IRCCommand::PrivateMessage, arguments);
+}
+
+void
+IRCChannelProxyImpl::sendJoinRequest ()
+{
+  m_clientInterface->sendIRCCommand (IRCCommand::Join, QStringList (m_channelName));
+}
+
+
+void
+IRCChannelProxyImpl::leave (const QString& reason)
+{
+  Q_UNUSED (reason);
+}
+
+void
+IRCChannelProxyImpl::handleNickChange (const QString &oldNick, const QString &newNick)
+{
+  m_userList = m_userListModel.stringList ();
+  m_userList.removeAll (oldNick);
+  m_userList.append (newNick);
+  m_userListModel.setStringList (m_userList);
+}
+
+void
+IRCChannelProxyImpl::handleJoin (const QString &nick)
+{
+  m_userList = m_userListModel.stringList ();
+  m_userList.append (nick);
+  m_userListModel.setStringList (m_userList);
+}
+
+IRCClientImpl::IRCClientImpl (QObject *parent)
+  : IRCClientInterface (parent)
+{
+  m_loggedIn = false;
+  connect (&m_tcpSocket, SIGNAL (connected ()), this, SLOT (handleConnected ()));
+  connect (&m_tcpSocket, SIGNAL (disconnected ()), this, SLOT (handleDisconnected ()));
+  connect (&m_tcpSocket, SIGNAL (readyRead ()), this, SLOT (handleReadyRead ()));
+}
+
+IRCClientImpl::~IRCClientImpl ()
+{
+  foreach (IRCChannelProxyInterface *ircChannelProxy, m_channels)
+    {
+      delete ircChannelProxy;
+    }
+}
+
+void
+IRCClientImpl::connectToHost (const QHostAddress& host, int port, const QString& initialNick)
+{
+  m_host = host;
+  m_nickname = initialNick;
+  m_tcpSocket.connectToHost(host, port);
+}
+
+void
+IRCClientImpl::disconnect ()
+{
+  m_tcpSocket.disconnect ();
+}
+
+void
+IRCClientImpl::reconnect ()
+{
+  disconnect ();
+  connectToHost (m_host, m_port, m_nickname);
+}
+
+bool
+IRCClientImpl::isConnected ()
+{
+  return m_connected;
+}
+
+bool
+IRCClientImpl::isLoggedIn ()
+{
+  return m_loggedIn;
+}
+
+const QHostAddress&
+IRCClientImpl::host()
+{
+  return m_host;
+}
+
+int
+IRCClientImpl::port()
+{
+  return m_port;
+}
+
+IRCChannelProxyInterface *
+IRCClientImpl::ircChannelProxy (const QString &channel)
+{
+  if (!m_channels.contains (channel))
+      m_channels[channel] = new IRCChannelProxyImpl(this, channel);
+  return m_channels[channel];
+}
+
+void
+IRCClientImpl::sendNicknameChangeRequest (const QString &nickname)
+{
+  sendIRCCommand (IRCCommand::Nick, QStringList (nickname));
+}
+
+void
+IRCClientImpl::sendPrivateMessage (const QString &recipient, const QString &message)
+{
+  QStringList arguments;
+  arguments << recipient;
+  arguments << message;
+  sendIRCCommand (IRCCommand::PrivateMessage, arguments);
+}
+
+const QString&
+IRCClientImpl::nickname ()
+{
+  return m_nickname;
+}
+
+void
+IRCClientImpl::handleConnected ()
+{
+  m_connected = true;
+  QStringList arguments;
+  arguments << "na" << "0" << "0" << "na";
+  sendIRCCommand (IRCCommand::User, arguments);
+  sendNicknameChangeRequest (m_nickname);
+  emit connected (m_host.toString ());
+}
+
+void
+IRCClientImpl::handleDisconnected ()
+{
+  m_connected = false;
+  emit disconnected ();
+}
+
+void
+IRCClientImpl::handleReadyRead ()
+{
+  QByteArray line;
+  do
+    {
+      line = m_tcpSocket.readLine();
+      if (line.size ())
+        handleIncomingLine(QString::fromUtf8(line.data ()));
+      else
+        break;
+    }
+  while (true);
+}
+
+void
+IRCClientImpl::handleNicknameChanged (const QString &oldNick, const QString &newNick)
+{
+  // Check if our nickname changed.
+  if (oldNick == m_nickname)
+    {
+      m_nickname = newNick;
+      emit userNicknameChanged (m_nickname);
+    }
+  emit nicknameChanged (oldNick, newNick);
+}
+
+void
+IRCClientImpl::handleUserJoined (const QString &nick, const QString &channel)
+{
+  ircChannelProxy (channel)->handleJoin (nick);
+  emit userJoined (nick, channel);
+}
+
+void
+IRCClientImpl::handleUserQuit (const QString &nick, const QString &reason)
+{
+  emit userQuit (nick, reason);
+}
+
+void
+IRCClientImpl::handleIncomingLine (const QString &line)
+{
+  if (m_connected && !line.isEmpty())
+    {
+      IRCServerMessage ircServerMessage(line);
+      if (ircServerMessage.isNumeric () == true)
+        {
+          switch (ircServerMessage.numericValue ())
+            {
+              case IRCReply::Welcome:
+                m_loggedIn = true;
+                emit userNicknameChanged (nickname ());
+                emit loggedIn (nickname ());
+                break;
+              case IRCError::NicknameInUse:
+              case IRCError::NickCollision:
+                // If we are already logged in, the user attempted to
+                // switch to a username that is already existing.
+                // In that case warn him.
+                if (isLoggedIn ())
+                  {
+                    emit error ("The nickname is already in use.");
+                  }
+                // Otherwise we are attempting to log in to the server.
+                // Change the nick so that we can at least log in.
+                else
+                  {
+                    m_nickname += "_";
+                    sendNicknameChangeRequest (m_nickname);
+                  }
+                break;
+              case IRCError::PasswordMismatch:
+                emit error ("The password you provided is not correct.");
+                break;
+              case IRCReply::MessageOfTheDayStart:
+              case IRCReply::MessageOfTheDay:
+              case IRCReply::MessageOfTheDayEnd:
+              case IRCError::NoMessageOfTheDay:
+                break;
+              case IRCReply::NoTopic:
+              case IRCReply::Topic:
+                break;
+              case IRCReply::NameReply:
+                QString channel = ircServerMessage.parameter (2);
+                QString nickList = ircServerMessage.parameter (3);
+                emit debugMessage (nickList);
+                ircChannelProxy (channel)->setNickList (nickList.split (QRegExp ("\\s+"), QString::SkipEmptyParts));
+                break;
+            }
+        }
+      else
+        {
+          QString command = ircServerMessage.command ();
+          if (command == IRCCommand::Nick)
+            {
+              handleNicknameChanged (ircServerMessage.nick(), ircServerMessage.parameter (0));
+            }
+          else if (command == IRCCommand::Quit)
+            {
+              handleUserQuit (ircServerMessage.nick (), ircServerMessage.parameter (0));
+            }
+          else if (command == IRCCommand::Join)
+            {
+              handleUserJoined(ircServerMessage.nick (), ircServerMessage.parameter (0));
+            }
+          else if (command == IRCCommand::Part)
+            {
+              emit debugMessage ("WRITEME: Received part.");
+              //emit part (ircEvent.getNick ().toStdString ().c_str (),
+              //           ircEvent.getParam (0).toStdString ().c_str (),
+              //           ircEvent.getParam (1).toStdString ().c_str ());
+            }
+          else if (command == IRCCommand::Mode)
+            {
+              emit debugMessage ("WRITEME: Received mode.");
+              //emit mode (&ircEvent);
+            }
+          else if (command == IRCCommand::Topic)
+            {
+              emit debugMessage
+                (QString("WRITEME: Received topic: %1")
+                  .arg (ircServerMessage.parameter (0)));
+            }
+          else if (command == IRCCommand::Kick)
+            {
+              emit debugMessage ("WRITEME: Received kick command.");
+            }
+          else if (command == IRCCommand::Invite)
+            {
+              emit debugMessage ("WRITEME: Received invite command.");
+
+            }
+          else if (command == IRCCommand::PrivateMessage)
+            {
+              emit message (ircServerMessage.parameter (0), ircServerMessage.nick (), ircServerMessage.parameter (1));
+            }
+          else if (command == IRCCommand::Notice)
+            {
+              emit notification (ircServerMessage.nick ().toStdString ().c_str (),
+                                 ircServerMessage.parameter (1).toStdString ().c_str ());
+            }
+          else if (command == IRCCommand::Ping)
+            {
+              sendIRCCommand (IRCCommand::Pong, QStringList (m_nickname));
+            }
+          else if (command == IRCCommand::Error)
+            {
+              emit error (ircServerMessage.parameter (0));
+            }
+          else
+            {
+              emit debugMessage (QString("FIXME: Received unknown reply: %1").arg(command));
+            }
+        }
+    }
+}
+
+void
+IRCClientImpl::sendLine (const QString &line)
+{
+  if (m_connected)
+    m_tcpSocket.write ( (line +  + "\r\n").toUtf8 ());
+}
+
+void
+IRCClientImpl::sendIRCCommand (const QString &command, const QStringList &arguments)
+{
+  QString line = command;
+  for (int i = 0; i < arguments.size (); i++)
+    {
+      bool applyColon = false;
+      // Usually all parameters are separated by spaces.
+      // The last parameter of the message may contain spaces, it is usually used
+      // to transmit messages. In order to parse it correctly, if needs to be prefixed
+      // with a colon, so the server knows to ignore all forthcoming spaces and has to treat
+      // all remaining characters as a single parameter. If we detect any whitespace in the
+      // last argument, prefix it with a colon:
+      if ((i == arguments.size () - 1) && arguments.at (i).contains (QRegExp("\\s")))
+        applyColon = true;
+      line += QString (" %1%2").arg (applyColon ? ":" : "").arg (arguments.at (i));
+    }
+  sendLine (line);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/src/irc/IRCClientImpl.h	Sun Sep 25 21:13:59 2011 +0200
@@ -0,0 +1,355 @@
+/* OctaveGUI - A graphical user interface for Octave
+ * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef IRCCLIENTIMPL_H
+#define IRCCLIENTIMPL_H
+
+#include <QTcpSocket>
+#include <QHostInfo>
+#include <QStringList>
+#include <QTextDocument>
+#include <QStringListModel>
+#include "IRCClientInterface.h"
+
+/**
+  * \namespace IRCCommand
+  * This namespace includes all IRC commands.
+  */
+namespace IRCCommand
+{
+  const QString Password = "PASS";
+  const QString Nick = "NICK";
+  const QString User = "USER";
+  const QString Operation = "OPER";
+  const QString Service = "SERVICE";
+  const QString Quit = "QUIT";
+  const QString ServerQuit = "SQUIT";
+
+  const QString Join = "JOIN";
+  const QString Part = "PART";
+  const QString Mode = "MODE";
+  const QString Topic = "TOPIC";
+  const QString Names = "NAMES";
+  const QString List = "LIST";
+  const QString Invite = "INVITE";
+  const QString Kick = "KICK";
+
+  const QString PrivateMessage = "PRIVMSG";
+  const QString Notice = "NOTICE";
+
+  const QString MessageOfTheDay = "MOTD";
+  const QString ListUsers = "LUSERS";
+  const QString Version = "VERSION";
+  const QString Stats = "STATS";
+  const QString Links = "LINKS";
+  const QString Time = "TIME";
+  const QString Command = "CONNECT";
+  const QString Trace = "TRACE";
+  const QString Admin = "ADMIN";
+  const QString Info = "INFO";
+
+  const QString ServerList = "SERVLIST";
+  const QString ServerQuery = "SQUERY";
+
+  const QString Who = "WHO";
+  const QString WhoIs = "WHOIS";
+  const QString WhoWas = "WHOWAS";
+
+  const QString Kill = "KILL";
+  const QString Ping = "PING";
+  const QString Pong = "PONG";
+  const QString Error = "ERROR";
+
+  const QString Away = "AWAY";
+  const QString Rehash = "REHASH";
+  const QString Die = "DIE";
+  const QString Restart = "RESTART";
+  const QString Summon = "SUMMON";
+  const QString Users = "USERS";
+  const QString OperatorWall = "OPERWALL";
+  const QString UserHost = "USERHOST";
+  const QString IsOn = "ISON";
+};
+
+/**
+  * \namespace IRCReply
+  * This namespace includes all numeric IRC replies.
+  */
+namespace IRCReply
+{
+  const int Welcome = 1;
+  const int YourHost = 2;
+  const int Created = 3;
+  const int MyInfo = 4;
+  const int ReplyBounce = 5;
+  const int UserHost = 302;
+  const int IsOn = 303;
+  const int Away = 301;
+  const int UnAway = 305;
+  const int NoAway = 306;
+  const int WhoIsUser = 311;
+  const int WhoIsServer = 312;
+  const int WhoIsOperator = 313;
+  const int WhoIsIdle = 317;
+  const int EndOfWhoIs = 318;
+  const int WhoIsChannels = 319;
+  const int WhoWasUser = 314;
+  const int EndOfWhoWas = 369;
+  const int ListStart = 321;
+  const int List = 322;
+  const int ListEnd = 323;
+  const int UniqueOpIs = 325;
+  const int ChannelModeIs = 324;
+  const int NoTopic = 331;
+  const int Topic = 332;
+  const int Inviting = 341;
+  const int Summoning = 342;
+  const int InviteList = 346;
+  const int EndOfInviteList = 347;
+  const int ExceptList = 348;
+  const int EndOfExceptList = 349;
+  const int Version = 351;
+  const int WhoReply = 352;
+  const int EndOfWho = 315;
+  const int NameReply = 353;
+  const int EndOfNames = 366;
+  const int Links = 364;
+  const int EndOfLinks = 367;
+  const int BanList = 368;
+  const int Info = 371;
+  const int EndOfInfo = 374;
+  const int MessageOfTheDayStart = 375;
+  const int MessageOfTheDay = 372;
+  const int MessageOfTheDayEnd = 376;
+  const int YouAreOperator = 381;
+  const int Rehashing = 382;
+  const int YouAreService = 383;
+  const int Time = 391;
+  const int UserStart = 392;
+  const int Users = 393;
+  const int EndOfUsers = 394;
+  const int NoUsers = 395;
+  const int TraceLink = 200;
+  const int TraceConnecting = 201;
+  const int TraceHandshake = 202;
+  const int TraceUnknown = 203;
+  const int TraceOperator = 204;
+  const int TraceUser = 205;
+  const int TraceServer = 206;
+  const int TraceService = 207;
+  const int TraceNewType = 208;
+  const int TraceClass = 209;
+  const int TraceConnect = 210;
+  const int TraceLog = 261;
+  const int TraceEnd = 262;
+  const int StatsLinkInfo = 211;
+  const int StatsCommands = 212;
+  const int EndOfStats = 219;
+  const int StatsUptime = 242;
+  const int StatsOnline = 243;
+  const int UModeIs = 221;
+  const int ServerList = 234;
+  const int ServerListEnd = 235;
+  const int ListUserClient = 251;
+  const int ListUserOperator = 252;
+  const int ListUserUnknown = 253;
+  const int ListUserChannels = 254;
+  const int ListUserMe = 255;
+  const int AdminMe = 256;
+  const int AdminLoc1 = 257;
+  const int AdminLoc2 = 258;
+  const int AdminEmail = 259;
+  const int TryAgain = 263;
+};
+
+/**
+  * \namespace IRCError
+  * This namespace includes all numeric IRC errors.
+  */
+namespace IRCError
+{
+  const int NoSuchNick = 401;
+  const int NoSuchServer = 402;
+  const int NoSuchChannel = 403;
+  const int CannotSendToChannel = 404;
+  const int TooManyChannels = 405;
+  const int WasNoSuchNick = 406;
+  const int TooManyTargets = 407;
+  const int NoSuchService = 408;
+  const int NoOrigin = 409;
+  const int NoRecipient = 411;
+  const int NoTextToSend = 412;
+  const int NoTopLevel = 413;
+  const int WildTopLevel = 414;
+  const int BasMask = 415;
+  const int UnknownCommand = 421;
+  const int NoMessageOfTheDay = 422;
+  const int NoAdminInfo = 423;
+  const int FileError = 424;
+  const int NoNickNameGiven = 431;
+  const int ErroneusNick = 432;
+  const int NicknameInUse = 433;
+  const int NickCollision = 436;
+  const int UnavailResource = 437;
+  const int UserNotInChannel = 441;
+  const int NotOnChannel = 442;
+  const int UserOnChannel = 443;
+  const int NoLogin = 444;
+  const int SummonDisabled = 445;
+  const int UsersDisabled = 446;
+  const int NotRegistered = 451;
+  const int NeedMoreParams = 461;
+  const int AlreadyRegistered = 462;
+  const int NoPermissionForHost = 463;
+  const int PasswordMismatch = 464;
+  const int YouAreBannedCreep = 465;
+  const int YouWillBeBanned = 466;
+  const int KeySet = 467;
+  const int ChannelIsFull = 471;
+  const int UnknownMode = 472;
+  const int InviteOnlyChannel = 473;
+  const int BannedFromChannel = 474;
+  const int BadChannelKey = 475;
+  const int BadChannelMask = 476;
+  const int NoChannelModes = 477;
+  const int BanListFull = 478;
+  const int NoPrivileges = 481;
+  const int ChannelOperatorPrivilegesNeeded = 482;
+  const int CannotKillServer = 483;
+  const int Restricted = 484;
+  const int UniqueOperatorPrivilegesNeeded = 485;
+  const int NoOperatorHost = 491;
+  const int YourModeListUnknownFlag = 501;
+  const int UsersDontMatch = 502;
+};
+
+/**
+  * \class IRCServerMessage
+  * The IRCServerMessage class is a wrapper for server messages.
+  * It parses the server message into its single bits and makes these
+  * available through Getter-methods.
+  */
+class IRCServerMessage
+{
+public:
+  IRCServerMessage (const QString& serverMessage);
+
+  bool isNumeric ()
+  { return m_isNumeric; }
+
+  QString nick ()
+  { return m_nick; }
+
+  QString command ()
+  { return m_command; }
+
+  int numericValue ();
+  QString parameter (int index);
+
+private:
+  int         m_codeNumber;
+  bool        m_isNumeric;
+  QString     m_nick;
+  QString     m_user;
+  QString     m_host;
+  QString     m_command;
+  QStringList m_parameters;
+};
+
+/**
+  * \class IRCChannelProxyImpl
+  * Implements a handle to an IRC channel. This is usually provided by the
+  * the IRC client class.
+  */
+class IRCChannelProxyImpl : public IRCChannelProxyInterface
+{
+  Q_OBJECT
+public:
+  IRCChannelProxyImpl (IRCClientInterface *clientInterface, const QString& channelName, QObject *parent = 0);
+  QTextDocument *conversationModel ();
+  QStringListModel *userListModel ();
+  QString channelName ();
+
+  void setNickList (const QStringList &nickList);
+  void sendMessage (const QString& message);
+  void sendJoinRequest ();
+  void leave (const QString &reason);
+public slots:
+  void handleNickChange (const QString& oldNick, const QString& newNick);
+  void handleJoin (const QString& nick);
+private:
+  QString             m_channelName;
+  QStringList         m_userList;
+  QStringListModel    m_userListModel;
+  QTextDocument       m_conversationModel;
+  IRCClientInterface *m_clientInterface;
+};
+
+/**
+  * \class IRCClientImpl
+  * Implements an IRC client. This class can maintain a connection to one server.
+  * In order to interface an IRC channel, use the ircChannelProxy-method to retrieve
+  * a handle.
+  */
+class IRCClientImpl : public IRCClientInterface
+{
+  Q_OBJECT
+public:
+  IRCClientImpl (QObject *parent = 0);
+  ~IRCClientImpl ();
+
+  const QString& nickname ();
+  bool isConnected ();
+  bool isLoggedIn ();
+  const QHostAddress& host();
+  int port();
+  IRCChannelProxyInterface *ircChannelProxy(const QString& channel);
+  void sendIRCCommand (const QString& command, const QStringList& arguments);
+
+public slots:
+  void connectToHost (const QHostAddress& host, int port, const QString& initialNick);
+  void disconnect ();
+  void reconnect ();
+
+  void sendNicknameChangeRequest (const QString &nickname);
+  void sendPrivateMessage (const QString &recipient, const QString &message);
+
+signals:
+  void debugMessage (const QString& message);
+
+private slots:
+  void handleConnected ();
+  void handleDisconnected ();
+  void handleReadyRead ();
+
+private:
+  void handleNicknameChanged (const QString& oldNick, const QString& newNick);
+  void handleUserJoined (const QString& nick, const QString& channel);
+  void handleUserQuit (const QString& nick, const QString& reason);
+  void handleIncomingLine (const QString& line);
+  void sendLine (const QString& line);
+
+  QHostAddress                              m_host;
+  int                                       m_port;
+  QString                                   m_nickname;
+  bool                                      m_connected;
+  bool                                      m_loggedIn;
+  QTcpSocket                                m_tcpSocket;
+  QMap<QString, IRCChannelProxyInterface*>  m_channels;
+};
+
+#endif // IRCCLIENTIMPL_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/src/irc/IRCClientInterface.h	Sun Sep 25 21:13:59 2011 +0200
@@ -0,0 +1,221 @@
+/* OctaveGUI - A graphical user interface for Octave
+ * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef IRCCLIENTINTERFACE_H
+#define IRCCLIENTINTERFACE_H
+
+#include <QString>
+#include <QObject>
+#include <QHostAddress>
+#include <QTextDocument>
+#include <QStringListModel>
+
+class IRCClientInterface;
+/**
+  * \class IRCChannelProxyInterface
+  * Interface for a handle to an IRC channel.
+  */
+class IRCChannelProxyInterface : public QObject
+{
+  Q_OBJECT
+public:
+  IRCChannelProxyInterface (IRCClientInterface *, const QString&, QObject *parent = 0) : QObject (parent) { }
+  virtual ~IRCChannelProxyInterface () { }
+
+  /** Returns the conversation model part. */
+  virtual QTextDocument *conversationModel () = 0;
+
+  /** Returns a string list model for the user list. */
+  virtual QStringListModel *userListModel () = 0;
+
+  /** Returns the name of this channel. */
+  virtual QString channelName () = 0;
+
+  /**
+    * Overwrites the current nick list by settings a new nick list.
+    * \arg nickList The new nick list to set.
+    */
+  virtual void setNickList (const QStringList& nickList) = 0;
+
+  /**
+    * Sends a public message onto this channel.
+    * \arg message The message that should be sent.
+    */
+  virtual void sendMessage (const QString& message) = 0;
+
+  /** Requests to join this channel. */
+  virtual void sendJoinRequest () = 0;
+
+  /**
+    * Requests to leave this channel.
+    * \arg reason Reason for leaving the channel.
+    */
+  virtual void leave (const QString& reason) = 0;
+
+public slots:
+  virtual void handleNickChange (const QString& oldNick, const QString& newNick) = 0;
+  virtual void handleJoin (const QString& nick) = 0;
+};
+
+/**
+  * \class IRCClientInterface
+  * IRC Clients need to implement this interface.
+  */
+class IRCClientInterface : public QObject
+{
+  Q_OBJECT
+public:
+  IRCClientInterface (QObject *parent = 0) : QObject (parent) { }
+  virtual ~IRCClientInterface () { }
+
+  /** Returns the current nickname of this client. */
+  virtual const QString& nickname () = 0;
+
+  /** Returns true if connected to the server. */
+  virtual bool isConnected () = 0;
+
+  /**
+    * Returns true if logged in to the server.
+    * Note: There is a small difference between isConnected and isLoggedIn.
+    * isConnected returns true if there is a physical connection to the server.
+    * isLoggedIn only returns true if the server has already accepted you
+    * and you are ready to log into channels.
+    */
+  virtual bool isLoggedIn () = 0;
+
+  /** Returns the current host address. */
+  virtual const QHostAddress& host() = 0;
+
+  /** Returns the current port. */
+  virtual int port() = 0;
+
+  /**
+    * Returns a handle to an IRC channel.
+    * Note: Retrieving a handle does not mean you have joined this channel.
+    * \arg channel The channel to retrieve a handle for.
+    */
+  virtual IRCChannelProxyInterface *ircChannelProxy(const QString& channel) = 0;
+
+  /**
+    * Send an IRC command to the server.
+    * \arg command Command to send.
+    * \arg arguments Arguments to send.
+    */
+  virtual void sendIRCCommand (const QString& command, const QStringList& arguments) = 0;
+
+public slots:
+  /**
+    * Connects to a host.
+    * \arg host The host to connect tp.
+    * \arg port The port on which to connect to the host.
+    * \arg initialNick The initial nick to use when attempting to login.
+    */
+  virtual void connectToHost (const QHostAddress& host, int port, const QString& initialNick) = 0;
+
+  /** Disconnects from the host. */
+  virtual void disconnect () = 0;
+
+  /** Reconnects to the host. */
+  virtual void reconnect () = 0;
+
+  /**
+    * Sends a request to change the nickname.
+    * \arg nickname The new nickname to be requested.
+    */
+  virtual void sendNicknameChangeRequest (const QString& nickname) = 0;
+
+  /**
+    * Sends a private message.
+    * \arg recipient The nickname or channel that message should be sent to.
+    * \arg message The message that should be sent.
+    */
+  virtual void sendPrivateMessage (const QString& recipient, const QString& message) = 0;
+
+signals:
+  /**
+    * Sent upon the arrival of a new message.
+    * \arg channel The channel this message was sent from.
+    * \arg sender The nickname of the sender.
+    * \arg message The message that has been sent.
+    */
+  void newMessage (const QString& channel, const QString& sender, const QString& message);
+  void message (const QString& channel, const QString& sender, const QString& message);
+
+  /**
+    * Sent when the connection to a server has been established.
+    * \arg server The name of the server that the connection has been established to.
+    */
+  void connected (const QString& server);
+
+  /** Sent when the connection to the server has been interrupted. */
+  void disconnected ();
+
+  /**
+    * Sent when an error occurs.
+    * \arg message A descriptive message of the error that occured.
+    */
+  void error (const QString& message);
+
+  /**
+    * Sent when a notification arrives.
+    * \arg sender The source of the notification.
+    * \arg message The notification.
+    */
+  void notification (const QString& sender, const QString& message);
+
+  /**
+    * Sent when a nickname changed.
+    * \arg oldNick The previous nickname.
+    * \arg newNick The new nickname.
+    */
+  void nicknameChanged (const QString& oldNick, const QString& newNick);
+
+  /**
+    * Sent when the nickname of this client changed.
+    * \arg nick The new nickname of this client.
+    */
+  void userNicknameChanged (const QString& nick);
+
+  /**
+    * Sent when a user has joined a channel.
+    * \arg nick Nickname of the user that joined the channel.
+    * \arg channel Channel that this user joined.
+    */
+  void userJoined (const QString& nick, const QString& channel);
+
+  /**
+    * Sent when a user quits.
+    * \arg nick Nickname of the user that quit.
+    * \arg reason Reason of the user to quit.
+    */
+  void userQuit (const QString& nick, const QString& reason);
+
+  /**
+    * Sent when a user logged in.
+    * \arg nick The nickname of the user that logged in.
+    */
+  void loggedIn (const QString& nick);
+
+  /**
+    * Sent when the server provides a userlist for a channel.
+    * \arg channel The channel that userlist applies to.
+    * \arg list The actual userlist.
+    */
+  void userList (const QString& channel, const QStringList& list);
+};
+
+#endif // IRCCLIENTINTERFACE_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/src/irc/IRCCodes.h	Sun Sep 25 21:13:59 2011 +0200
@@ -0,0 +1,223 @@
+/* OctaveGUI - A graphical user interface for Octave
+ * Copyright (C) 2011 Jacob Dawid
+ * jacob.dawid@googlemail.com
+ *
+ * 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 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef IRCCODES_H
+#define IRCCODES_H
+#include <QString>
+
+namespace IRCCommand
+{
+  const QString Password = "PASS";
+  const QString Nick = "NICK";
+  const QString User = "USER";
+  const QString Operation = "OPER";
+  const QString Service = "SERVICE";
+  const QString Quit = "QUIT";
+  const QString ServerQuit = "SQUIT";
+
+  const QString Join = "JOIN";
+  const QString Part = "PART";
+  const QString Mode = "MODE";
+  const QString Topic = "TOPIC";
+  const QString Names = "NAMES";
+  const QString List = "LIST";
+  const QString Invite = "INVITE";
+  const QString Kick = "KICK";
+
+  const QString PrivateMessage = "PRIVMSG";
+  const QString Notice = "NOTICE";
+
+  const QString MessageOfTheDay = "MOTD";
+  const QString ListUsers = "LUSERS";
+  const QString Version = "VERSION";
+  const QString Stats = "STATS";
+  const QString Links = "LINKS";
+  const QString Time = "TIME";
+  const QString Command = "CONNECT";
+  const QString Trace = "TRACE";
+  const QString Admin = "ADMIN";
+  const QString Info = "INFO";
+
+  const QString ServerList = "SERVLIST";
+  const QString ServerQuery = "SQUERY";
+
+  const QString Who = "WHO";
+  const QString WhoIs = "WHOIS";
+  const QString WhoWas = "WHOWAS";
+
+  const QString Kill = "KILL";
+  const QString Ping = "PING";
+  const QString Pong = "PONG";
+  const QString Error = "ERROR";
+
+  const QString Away = "AWAY";
+  const QString Rehash = "REHASH";
+  const QString Die = "DIE";
+  const QString Restart = "RESTART";
+  const QString Summon = "SUMMON";
+  const QString Users = "USERS";
+  const QString OperatorWall = "OPERWALL";
+  const QString UserHost = "USERHOST";
+  const QString IsOn = "ISON";
+};
+
+namespace IRCReply
+{
+  const int Welcome = 1;
+  const int YourHost = 2;
+  const int Created = 3;
+  const int MyInfo = 4;
+  const int ReplyBounce = 5;
+  const int UserHost = 302;
+  const int IsOn = 303;
+  const int Away = 301;
+  const int UnAway = 305;
+  const int NoAway = 306;
+  const int WhoIsUser = 311;
+  const int WhoIsServer = 312;
+  const int WhoIsOperator = 313;
+  const int WhoIsIdle = 317;
+  const int EndOfWhoIs = 318;
+  const int WhoIsChannels = 319;
+  const int WhoWasUser = 314;
+  const int EndOfWhoWas = 369;
+  const int ListStart = 321;
+  const int List = 322;
+  const int ListEnd = 323;
+  const int UniqueOpIs = 325;
+  const int ChannelModeIs = 324;
+  const int NoTopic = 331;
+  const int Topic = 332;
+  const int Inviting = 341;
+  const int Summoning = 342;
+  const int InviteList = 346;
+  const int EndOfInviteList = 347;
+  const int ExceptList = 348;
+  const int EndOfExceptList = 349;
+  const int Version = 351;
+  const int WhoReply = 352;
+  const int EndOfWho = 315;
+  const int NameReply = 353;
+  const int EndOfNames = 366;
+  const int Links = 364;
+  const int EndOfLinks = 367;
+  const int BanList = 368;
+  const int Info = 371;
+  const int EndOfInfo = 374;
+  const int MessageOfTheDayStart = 375;
+  const int MessageOfTheDay = 372;
+  const int MessageOfTheDayEnd = 376;
+  const int YouAreOperator = 381;
+  const int Rehashing = 382;
+  const int YouAreService = 383;
+  const int Time = 391;
+  const int UserStart = 392;
+  const int Users = 393;
+  const int EndOfUsers = 394;
+  const int NoUsers = 395;
+  const int TraceLink = 200;
+  const int TraceConnecting = 201;
+  const int TraceHandshake = 202;
+  const int TraceUnknown = 203;
+  const int TraceOperator = 204;
+  const int TraceUser = 205;
+  const int TraceServer = 206;
+  const int TraceService = 207;
+  const int TraceNewType = 208;
+  const int TraceClass = 209;
+  const int TraceConnect = 210;
+  const int TraceLog = 261;
+  const int TraceEnd = 262;
+  const int StatsLinkInfo = 211;
+  const int StatsCommands = 212;
+  const int EndOfStats = 219;
+  const int StatsUptime = 242;
+  const int StatsOnline = 243;
+  const int UModeIs = 221;
+  const int ServerList = 234;
+  const int ServerListEnd = 235;
+  const int ListUserClient = 251;
+  const int ListUserOperator = 252;
+  const int ListUserUnknown = 253;
+  const int ListUserChannels = 254;
+  const int ListUserMe = 255;
+  const int AdminMe = 256;
+  const int AdminLoc1 = 257;
+  const int AdminLoc2 = 258;
+  const int AdminEmail = 259;
+  const int TryAgain = 263;
+};
+
+namespace IRCError
+{
+  const int NoSuchNick = 401;
+  const int NoSuchServer = 402;
+  const int NoSuchChannel = 403;
+  const int CannotSendToChannel = 404;
+  const int TooManyChannels = 405;
+  const int WasNoSuchNick = 406;
+  const int TooManyTargets = 407;
+  const int NoSuchService = 408;
+  const int NoOrigin = 409;
+  const int NoRecipient = 411;
+  const int NoTextToSend = 412;
+  const int NoTopLevel = 413;
+  const int WildTopLevel = 414;
+  const int BasMask = 415;
+  const int UnknownCommand = 421;
+  const int NoMessageOfTheDay = 422;
+  const int NoAdminInfo = 423;
+  const int FileError = 424;
+  const int NoNickNameGiven = 431;
+  const int ErroneusNick = 432;
+  const int NicknameInUse = 433;
+  const int NickCollision = 436;
+  const int UnavailResource = 437;
+  const int UserNotInChannel = 441;
+  const int NotOnChannel = 442;
+  const int UserOnChannel = 443;
+  const int NoLogin = 444;
+  const int SummonDisabled = 445;
+  const int UsersDisabled = 446;
+  const int NotRegistered = 451;
+  const int NeedMoreParams = 461;
+  const int AlreadyRegistered = 462;
+  const int NoPermissionForHost = 463;
+  const int PasswordMismatch = 464;
+  const int YouAreBannedCreep = 465;
+  const int YouWillBeBanned = 466;
+  const int KeySet = 467;
+  const int ChannelIsFull = 471;
+  const int UnknownMode = 472;
+  const int InviteOnlyChannel = 473;
+  const int BannedFromChannel = 474;
+  const int BadChannelKey = 475;
+  const int BadChannelMask = 476;
+  const int NoChannelModes = 477;
+  const int BanListFull = 478;
+  const int NoPrivileges = 481;
+  const int ChannelOperatorPrivilegesNeeded = 482;
+  const int CannotKillServer = 483;
+  const int Restricted = 484;
+  const int UniqueOperatorPrivilegesNeeded = 485;
+  const int NoOperatorHost = 491;
+  const int YourModeListUnknownFlag = 501;
+  const int UsersDontMatch = 502;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/src/irc/IRCWidget.cpp	Sun Sep 25 21:13:59 2011 +0200
@@ -0,0 +1,448 @@
+/* OctaveGUI - A graphical user interface for Octave
+ * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ResourceManager.h"
+#include "IRCWidget.h"
+#include <QMessageBox>
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+#include <QLabel>
+#include <QSettings>
+#include <QInputDialog>
+#include <QKeyEvent>
+#include <QScrollBar>
+#include <QApplication>
+#include "IRCClientImpl.h"
+
+ChatMessageTextEdit::ChatMessageTextEdit (QWidget *parent)
+  : QPlainTextEdit (parent), m_completer (0)
+{
+  setMaximumHeight (50);
+  setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
+}
+
+ChatMessageTextEdit::~ChatMessageTextEdit ()
+{
+}
+
+void
+ChatMessageTextEdit::setCompleter (QCompleter *completer)
+{
+  if (m_completer)
+    QObject::disconnect (m_completer, 0, this, 0);
+
+  m_completer = completer;
+
+  if (!m_completer)
+    return;
+
+  m_completer->setWidget (this);
+  m_completer->setCompletionMode (QCompleter::PopupCompletion);
+  m_completer->setCaseSensitivity (Qt::CaseInsensitive);
+  QObject::connect (m_completer, SIGNAL (activated (QString)),
+                    this, SLOT (insertCompletion (QString)));
+}
+
+QCompleter *
+ChatMessageTextEdit::completer () const
+{
+  return m_completer;
+}
+
+void
+ChatMessageTextEdit::insertCompletion(const QString& completion)
+{
+
+  if (m_completer->widget() != this)
+    return;
+  QTextCursor tc = textCursor();
+  int extra = completion.length() - m_completer->completionPrefix().length();
+  tc.movePosition(QTextCursor::Left);
+  tc.movePosition(QTextCursor::EndOfWord);
+  tc.insertText(completion.right(extra));
+  setTextCursor(tc);
+}
+
+QString
+ChatMessageTextEdit::textUnderCursor () const
+{
+  QTextCursor tc = textCursor ();
+  tc.select (QTextCursor::WordUnderCursor);
+  return tc.selectedText ();
+}
+
+void
+ChatMessageTextEdit::focusInEvent (QFocusEvent *e)
+{
+  if (m_completer)
+    m_completer->setWidget (this);
+  QPlainTextEdit::focusInEvent (e);
+}
+
+void
+ChatMessageTextEdit::keyPressEvent (QKeyEvent *keyPressEvent)
+{
+  if (m_completer) {
+    switch (keyPressEvent->key ()) {
+    case Qt::Key_Enter:
+    case Qt::Key_Return:
+      if (! (keyPressEvent->modifiers () & Qt::ShiftModifier))
+        {
+          emit sendMessage (document ()->toPlainText ());
+          document ()->setPlainText ("");
+        }
+      else
+        {
+          QPlainTextEdit::keyPressEvent (keyPressEvent);
+        }
+      break;
+    case Qt::Key_Escape:
+    case Qt::Key_Tab:
+    case Qt::Key_Backtab:
+      keyPressEvent->ignore ();
+      return;
+    default:
+      QPlainTextEdit::keyPressEvent(keyPressEvent);
+      break;
+      }
+
+    QString completionPrefix = textUnderCursor ();
+    if (completionPrefix != m_completer->completionPrefix ())
+      {
+        m_completer->setCompletionPrefix(completionPrefix);
+      }
+
+    if (completionPrefix.length() > 2)
+      {
+        m_completer->popup ()->setCurrentIndex (m_completer->completionModel ()->index (0, 0));
+        m_completer->complete ();
+      }
+    else
+      {
+        m_completer->popup ()->hide ();
+      }
+  }
+}
+
+IRCWidget::IRCWidget (QWidget * parent):
+QWidget (parent)
+{
+  QSettings *settings = ResourceManager::instance ()->settings ();
+  bool connectOnStartup = settings->value ("connectOnStartup").toBool ();
+  m_autoIdentification = settings->value ("autoIdentification").toBool ();
+  m_nickServPassword = settings->value ("nickServPassword").toString ();
+
+  m_initialNick = settings->value ("IRCNick").toString ();
+
+  if (m_initialNick.isEmpty ())
+    m_initialNick = "OctaveGUI-User";
+
+  QVBoxLayout *layout = new QVBoxLayout ();
+
+  m_chatWindow = new QTextEdit (this);
+  m_chatWindow->setReadOnly (true);
+  m_chatWindow->setEnabled (false);
+  QWidget *bottomWidget = new QWidget (this);
+
+  layout->addWidget (m_chatWindow);
+  layout->addWidget (bottomWidget);
+  layout->setMargin (0);
+  setLayout (layout);
+
+  QHBoxLayout *bottomLayout = new QHBoxLayout ();
+  m_nickButton = new QPushButton (bottomWidget);
+  m_nickButton->setStatusTip (tr ((char *) "Click here to change your nick."));
+  m_nickButton->setText (m_initialNick);
+  m_chatMessageTextEdit = new ChatMessageTextEdit (bottomWidget);
+  m_chatMessageTextEdit->setStatusTip (tr ((char *) "Enter your message here."));
+
+  bottomLayout->addWidget (m_nickButton);
+  bottomLayout->addWidget (new QLabel (":", this));
+  bottomLayout->addWidget (m_chatMessageTextEdit);
+  bottomLayout->setMargin (0);
+  bottomWidget->setLayout (bottomLayout);
+
+  m_nickButton->setEnabled (false);
+  m_chatMessageTextEdit->setEnabled (false);
+
+  //setFocusProxy (m_chatMessageTextEdit);
+  m_nickButton->setFocusProxy (m_chatMessageTextEdit);
+
+  QFont font;
+  font.setFamily ("Courier");
+  font.setPointSize (11);
+  m_chatWindow->setFont (font);
+  m_ircClientInterface = new IRCClientImpl (this);
+  m_octaveChannel = m_ircClientInterface->ircChannelProxy ("#octave");
+
+  connect (m_ircClientInterface, SIGNAL (connected (QString)),
+           this, SLOT (handleConnected (QString)));
+  connect (m_ircClientInterface, SIGNAL(loggedIn(QString)),
+           this, SLOT (joinOctaveChannel (QString)));
+  connect (m_ircClientInterface, SIGNAL (error (QString)),
+           this, SLOT (showErrorMessage (QString)));
+  connect (m_ircClientInterface, SIGNAL (debugMessage (QString)),
+           this, SLOT (showStatusMessage (QString)));
+  connect (m_ircClientInterface, SIGNAL (message (QString, QString, QString)),
+           this, SLOT (showMessage (QString, QString, QString )));
+  connect (m_ircClientInterface, SIGNAL (nicknameChanged (QString,QString)),
+           this, SLOT (handleNickChange (QString,QString)));
+  connect (m_ircClientInterface, SIGNAL (notification (QString,QString)),
+           this, SLOT (showNotification (QString,QString)));
+  connect (m_ircClientInterface, SIGNAL (loggedIn (QString)),
+           this, SLOT (handleLoggedIn(QString)));
+  connect (m_ircClientInterface, SIGNAL (userNicknameChanged (QString)),
+           this, SLOT (handleUserNicknameChanged (QString)));
+
+  connect (m_nickButton, SIGNAL (clicked ()), this, SLOT (showChangeUserNickPopup ()));
+  connect (m_chatMessageTextEdit, SIGNAL (sendMessage (QString)),
+           this, SLOT (sendMessage (QString)));
+
+  m_chatMessageTextEdit->setCompleter
+      (new QCompleter (m_ircClientInterface->ircChannelProxy ("#octave")->userListModel (), this));
+  m_chatWindow->setDocument (m_octaveChannel->conversationModel ());
+
+  if (connectOnStartup)
+    connectToServer ();
+}
+
+void
+IRCWidget::connectToServer ()
+{
+  showStatusMessage ("Looking up irc.freenode.net.");
+  QHostInfo hostInfo = QHostInfo::fromName ("irc.freenode.net");
+  QList<QHostAddress> hostAddresses = hostInfo.addresses();
+  if (hostAddresses.isEmpty ())
+    {
+      showStatusMessage ("Failed to lookup irc.freenode.net.");
+    }
+  else
+    {
+      showStatusMessage (QString ("Attempting to connect to %1.")
+                         .arg (hostAddresses.at (0).toString ()));
+      m_ircClientInterface->connectToHost(hostAddresses.at (0), 6667, m_initialNick);
+    }
+}
+
+void
+IRCWidget::showStatusMessage (const QString& message)
+{
+  m_chatWindow->append (QString ("<i>%1</i>").arg (message));
+}
+
+void
+IRCWidget::showErrorMessage (const QString& message)
+{
+  m_chatWindow->append (QString ("<i>Error: %1</i>").arg (message));
+}
+
+void
+IRCWidget::handleConnected (const QString &host)
+{
+  showStatusMessage (QString ("Connected to server %1.").arg (host));
+}
+
+void
+IRCWidget::joinOctaveChannel (const QString& nick)
+{
+  Q_UNUSED (nick);
+  showStatusMessage (QString ("Joining channel #octave."));
+  m_octaveChannel->sendJoinRequest ();
+}
+
+void
+IRCWidget::showMessage (const QString& channel, const QString& sender, const QString& message)
+{
+  Q_UNUSED (channel);
+
+  // TODO: This doesn't work properly!
+  // Every message makes it emit unreadMessage (true),
+  // though it should inly be emitted when this window
+  // does not have focus, ie. is not the active window.
+  if (!(hasFocus()
+      || m_chatMessageTextEdit->hasFocus ()
+      || m_nickButton->hasFocus ()
+      || m_chatWindow->hasFocus () ))
+    {
+      emit unreadMessages (true);
+    }
+
+  QString output;
+  QString htmlMessage = message;
+  htmlMessage.replace ("<", "&lt;");
+  htmlMessage.replace (">", "&gt;");
+  htmlMessage.replace ("\n", "<br>");
+  if (message.contains (m_ircClientInterface->nickname ()))
+    {
+      output =
+        QString ("<font color=\"#990000\"><b>%1:</b> %2</font>").arg (sender).
+        arg (htmlMessage);
+
+      QApplication::alert (this);
+    }
+  else
+    {
+      output =
+        QString ("<b>%1:</b> %2").arg (sender).
+        arg (htmlMessage);
+    }
+  m_chatWindow->append (output);
+  scrollToBottom ();
+}
+
+void
+IRCWidget::showNotification (const QString& sender, const QString& message)
+{
+  Q_UNUSED (sender);
+  m_chatWindow->append (QString ("<font color=\"#007700\">%1</font>").arg (message));
+  scrollToBottom ();
+}
+
+void
+IRCWidget::showChangeUserNickPopup ()
+{
+  bool ok;
+  QString newNick =
+    QInputDialog::getText (this, QString ("Nickname"),
+			   QString ("Type in your nickname:"),
+                           QLineEdit::Normal, m_ircClientInterface->nickname (), &ok);
+  if (ok)
+    {
+      m_ircClientInterface->sendNicknameChangeRequest (newNick);
+    }
+}
+
+void
+IRCWidget::sendMessage (QString message)
+{
+  // Do not send empty messages.
+  if (message.isEmpty ())
+    return;
+
+  // Remove trailing spaces.
+  while (message.at (0).isSpace ())
+    message.remove (0, 1);
+  if (message.startsWith ("/"))
+    {
+      QStringList line =
+	message.split (QRegExp ("\\s+"), QString::SkipEmptyParts);
+      if (line.at (0) == "/join")
+	{
+          IRCChannelProxyInterface *ircChannel = m_ircClientInterface->ircChannelProxy (line.at (1));
+          ircChannel->sendJoinRequest ();
+	}
+      else if (line.at (0) == "/nick")
+	{
+          m_ircClientInterface->sendNicknameChangeRequest (line.at (1));
+	}
+      else if (line.at (0) == "/msg")
+	{
+	  QString recipient = line.at (1);
+	  // Since we splitted the message before, we have to glue it together again.
+	  QString pmsg = "";
+	  for (int i = 2; i < line.length (); i++)
+	    {
+	      pmsg += line.at (i);
+	      pmsg += " ";
+	    }
+          m_ircClientInterface->sendPrivateMessage(recipient, pmsg);
+	}
+    }
+  else
+    {
+      m_octaveChannel->sendMessage (message);
+      message.replace ("<", "&lt;");
+      message.replace (">", "&gt;");
+      message.replace ("\n", "<br>");
+      m_chatWindow->append (QString ("<b>%1:</b> %2").
+                            arg (m_ircClientInterface->nickname ()).arg (message));
+    }
+
+  scrollToBottom ();
+}
+
+void
+IRCWidget::maybeIdentifyOnNickServ ()
+{
+  if (m_autoIdentification)
+    {
+      m_ircClientInterface->sendPrivateMessage("NickServ", QString ("identify %1").
+                                          arg (m_nickServPassword));
+    }
+}
+
+void
+IRCWidget::scrollToBottom ()
+{
+  if (m_chatWindow->verticalScrollBar ())
+    {
+      m_chatWindow->verticalScrollBar ()->setValue (m_chatWindow->verticalScrollBar ()->maximum ());
+    }
+}
+
+void
+IRCWidget::focusInEvent (QFocusEvent *focusEvent)
+{
+  Q_UNUSED (focusEvent);
+  emit unreadMessages (false);
+  QWidget::focusInEvent (focusEvent);
+
+  m_chatMessageTextEdit->setFocus ();
+}
+
+void
+IRCWidget::handleLoggedIn (const QString &nick)
+{
+  m_chatWindow->
+    append (QString
+            ("<i><font color=\"#00AA00\"><b>Successfully logged in as %1.</b></font></i>").
+            arg (nick));
+  m_nickButton->setEnabled (true);
+  m_chatMessageTextEdit->setEnabled (true);
+  m_chatWindow->setEnabled (true);
+  m_chatMessageTextEdit->setFocus ();
+}
+
+void
+IRCWidget::handleNickChange (const QString &oldNick, const QString &newNick)
+{
+  m_chatWindow->append (QString ("%1 is now known as %2.").arg (oldNick).arg (newNick));
+  scrollToBottom ();
+}
+
+void
+IRCWidget::handleUserJoined (const QString &nick, const QString &channel)
+{
+  m_chatWindow->append (QString ("<i>%1 has joined %2.</i>").arg (nick).arg (channel));
+  scrollToBottom ();
+}
+
+void
+IRCWidget::handleUserQuit (const QString &nick, const QString &reason)
+{
+  m_chatWindow->append (QString ("<i>%1 has quit.(%2).</i>").arg (nick).arg (reason));
+  scrollToBottom ();
+}
+
+void
+IRCWidget::handleUserNicknameChanged (const QString &nick)
+{
+  m_nickButton->setText (nick);
+  QSettings *settings = ResourceManager::instance ()->settings ();
+  settings->setValue ("IRCNick", nick);
+  maybeIdentifyOnNickServ ();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/src/irc/IRCWidget.h	Sun Sep 25 21:13:59 2011 +0200
@@ -0,0 +1,101 @@
+/* OctaveGUI - A graphical user interface for Octave
+ * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com)
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef IRCWIDGET_H
+#define IRCWIDGET_H
+
+#include <QWidget>
+#include <QPlainTextEdit>
+#include <QPushButton>
+#include <QLineEdit>
+#include <QCompleter>
+#include "IRCClientInterface.h"
+
+class ChatMessageTextEdit : public QPlainTextEdit
+{
+  Q_OBJECT
+public:
+  explicit ChatMessageTextEdit(QWidget *parent = 0);
+  ~ChatMessageTextEdit();
+
+  void setCompleter(QCompleter *m_completer);
+  QCompleter *completer() const;
+
+signals:
+  void sendMessage (const QString& message);
+
+protected:
+  void keyPressEvent(QKeyEvent *e);
+  void focusInEvent(QFocusEvent *e);
+
+private slots:
+  void insertCompletion(const QString &completion);
+
+private:
+  QString textUnderCursor() const;
+
+private:
+  QCompleter *m_completer;
+};
+
+class IRCWidget : public QWidget
+{
+Q_OBJECT public:
+  explicit IRCWidget (QWidget * parent);
+  void connectToServer ();
+
+public slots:
+  void showStatusMessage (const QString&);
+  void showErrorMessage (const QString&);
+  void showMessage (const QString& channel, const QString& sender, const QString& message);
+  void showNotification (const QString& sender, const QString& message);
+
+  void handleConnected (const QString& host);
+  void joinOctaveChannel (const QString& nick);
+
+  void handleLoggedIn (const QString& nick);
+  void handleNickChange (const QString& oldNick, const QString& newNick);
+  void handleUserJoined (const QString& nick, const QString& channel);
+  void handleUserQuit (const QString& nick, const QString& reason);
+  void handleUserNicknameChanged (const QString& nick);
+
+  void showChangeUserNickPopup ();
+  void sendMessage (QString);
+
+  void maybeIdentifyOnNickServ ();
+  void scrollToBottom ();
+
+signals:
+  void unreadMessages (bool yes);
+
+protected:
+  void focusInEvent (QFocusEvent *focusEvent);
+
+private:
+  IRCClientInterface *m_ircClientInterface;
+  IRCChannelProxyInterface *m_octaveChannel;
+  QTextEdit *m_chatWindow;
+  QPushButton *m_nickButton;
+  ChatMessageTextEdit *m_chatMessageTextEdit;
+
+  QString m_initialNick;
+  bool m_autoIdentification;
+  QString m_nickServPassword;
+  QString m_settingsFile;
+};
+
+#endif // IRCWIDGET_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gui/src/irc/Makefile.am	Sun Sep 25 21:13:59 2011 +0200
@@ -0,0 +1,34 @@
+####### kdevelop will overwrite this part!!! (begin)##########
+bin_PROGRAMS = qirc
+  qirc_SOURCES =
+  programcommand.cpp newtab.cpp MainTab.cpp notifyshowcase.cpp channellist.
+  cpp dccget.cpp dccsend.cpp IServerSocket.cpp general.cpp listanicks.
+  cpp qirc.cpp ventanas.cpp inputBox.cpp cuadroListaNicks.
+  cpp cuadroConfiguracion.cpp cuadroConectarCon.cpp colamensajes.
+  cpp IRCClient.cpp IClientSocket.cpp Config.cpp ChatView.cpp main.
+  cpp qirc_LDADD = -lqt - lXext - lX11 $ (LIBSOCKET) SUBDIRS =
+  docs EXTRA_DIST =
+  main.cpp qirc.h ChatView.cpp ChatView.h Config.cpp Config.h IClientSocket.
+  cpp IClientSocket.h IRCClient.cpp IRCClient.h IRCCodes.h colamensajes.
+  cpp colamensajes.h cuadroConectarCon.cpp cuadroConectarCon.
+  h cuadroConfiguracion.cpp cuadroConfiguracion.h cuadroListaNicks.
+  cpp cuadroListaNicks.h inputBox.cpp inputBox.h ventanas.cpp ventanas.h qirc.
+  cpp resource.h qirc16x16.xpm qirc32x32.xpm qirc64x64.xpm listanicks.
+  cpp listanicks.h general.h general.cpp IServerSocket.cpp IServerSocket.
+  h dccsend.cpp dccsend.h dccget.cpp dccget.h connect.xpm dccsend.xpm help.
+  xpm connectto.xpm disconnect.xpm join.xpm part.xpm list.xpm channellist.
+  cpp channellist.h notifyshowcase.cpp notifyshowcase.h offline.xpm online.
+  xpm operator.xpm justconn.xpm MainTab.cpp MainTab.h newtab.cpp newtab.
+  h leftArrowDisabled.xpm leftArrowEnabled.xpm rightArrowDisabled.
+  xpm rightArrowEnabled.xpm tabLeft.xpm tabMiddle.xpm tabRight.xpm tabClose.
+  xpm programcommand.cpp programcommand.h
+####### kdevelop will overwrite this part!!! (end)############
+#set the include path for X, qt and KDE
+  INCLUDES = $ (all_includes)
+#claim, which subdirectories you want to install
+#you can add here more. This one gets installed
+  bin_PROGRAMS = qirc qirc_METASOURCES = USE_AUTOMOC
+#the library search path.
+  qirc_LDFLAGS = $ (all_libraries)
+#them while "make clean", use CLEANFILES
+  DISTCLEANFILES = $ (qirc_METASOURCES)
--- a/gui/src/qirc/IRCClientImpl.cpp	Sun Sep 25 21:12:47 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,511 +0,0 @@
-/* OctaveGUI - A graphical user interface for Octave
- * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "IRCClientImpl.h"
-
-IRCServerMessage::IRCServerMessage (const QString& serverMessage)
-{
-  if (serverMessage.isEmpty ())
-    return;
-
-  int position = 0;
-  QString buffer;
-
-  m_nick = "";
-  m_user = "";
-  m_host = "";
-
-  // A server message starting with a prefix indicates
-  // a prefix. A prefix has the format:
-  // :nick!user@host
-  // followed by a space character.
-  if (serverMessage.startsWith (":"))
-    {
-      position++;
-      while ((position < serverMessage.size ())
-             &&(serverMessage.at (position) != '!')
-             && !serverMessage.at (position).isSpace ())
-        {
-          buffer.append (serverMessage.at (position));
-          position++;
-        }
-      m_nick = buffer, buffer.clear (), position++;
-
-      // If it belongs to the prefix, it must be concatenanted neatlessly without
-      // any spaces.
-      if (!serverMessage.at (position - 1).isSpace ())
-        {
-          while ((position < serverMessage.size ())
-                 && serverMessage.at (position) != '@')
-            {
-              buffer.append (serverMessage.at (position));
-              position++;
-            }
-          m_user = buffer, buffer.clear (), position++;
-        }
-
-      // If it belongs to the prefix, it must be concatenanted neatlessly without
-      // any spaces.
-      if (!serverMessage.at (position - 1).isSpace ())
-        {
-          while ((position < serverMessage.size ())
-                 && serverMessage.at (position) != ' ')
-            {
-              buffer.append (serverMessage.at (position));
-              position++;
-            }
-          m_host = buffer, buffer.clear (), position++;
-        }
-    }
-
-  // The next part is the command. The command can either be numeric
-  // or a written command.
-  while ((position < serverMessage.size ())
-         && !serverMessage.at (position).isSpace ())
-    {
-      buffer.append (serverMessage.at (position));
-      position++;
-    }
-  m_command = buffer.toUpper (), buffer.clear (), position++;
-  m_codeNumber = m_command.toInt (&m_isNumeric);
-
-  // Next: a list of parameters. If any of these parameters
-  // starts with a colon, we have to read everything that follows
-  // as a single parameter.
-  bool readUntilEnd = false;
-  while (position < serverMessage.size ())
-    {
-      if (buffer.isEmpty () && !readUntilEnd && (serverMessage.at (position) == ':'))
-        {
-          readUntilEnd = true;
-        }
-      else
-        {
-          if (readUntilEnd)
-            {
-              buffer.append (serverMessage.at (position));
-            }
-          else
-            {
-              if (serverMessage.at (position).isSpace ())
-                {
-                  if (!buffer.isEmpty ())
-                    {
-                      m_parameters.append (buffer);
-                      buffer.clear ();
-                    }
-                }
-              else
-                {
-                  buffer.append (serverMessage.at (position));
-                }
-            }
-        }
-      position++;
-    }
-
-  if (!buffer.isEmpty ())
-    {
-      // We need to chop off \r\n here.
-      buffer.chop (2);
-      m_parameters.append (buffer);
-    }
-}
-
-int
-IRCServerMessage::numericValue ()
-{
-  if (m_isNumeric)
-    return m_codeNumber;
-  return -1;
-}
-
-QString
-IRCServerMessage::parameter (int index)
-{
-  if (index >= 0 && index < m_parameters.size ())
-    return m_parameters.at (index);
-  return "";
-}
-
-
-IRCChannelProxyImpl::IRCChannelProxyImpl (IRCClientInterface *clientInterface, const QString& channelName, QObject *parent)
-  : IRCChannelProxyInterface (clientInterface, channelName, parent),
-    m_clientInterface (clientInterface)
-{
-  m_channelName = channelName;
-  connect (clientInterface, SIGNAL (nicknameChanged (QString,QString)),
-           this, SLOT (handleNickChange (QString,QString)));
-}
-
-QTextDocument *
-IRCChannelProxyImpl::conversationModel ()
-{
-  return &m_conversationModel;
-}
-
-QStringListModel *
-IRCChannelProxyImpl::userListModel ()
-{
-  return &m_userListModel;
-}
-
-QString
-IRCChannelProxyImpl::channelName ()
-{
-  return m_channelName;
-}
-
-void
-IRCChannelProxyImpl::setNickList (const QStringList &nickList)
-{
-  m_userList = nickList;
-  m_userListModel.setStringList (nickList);
-}
-
-void
-IRCChannelProxyImpl::sendMessage (const QString& message)
-{
-  QStringList arguments;
-  arguments << m_channelName;
-  arguments << message;
-  m_clientInterface->sendIRCCommand (IRCCommand::PrivateMessage, arguments);
-}
-
-void
-IRCChannelProxyImpl::sendJoinRequest ()
-{
-  m_clientInterface->sendIRCCommand (IRCCommand::Join, QStringList (m_channelName));
-}
-
-
-void
-IRCChannelProxyImpl::leave (const QString& reason)
-{
-  Q_UNUSED (reason);
-}
-
-void
-IRCChannelProxyImpl::handleNickChange (const QString &oldNick, const QString &newNick)
-{
-  m_userList = m_userListModel.stringList ();
-  m_userList.removeAll (oldNick);
-  m_userList.append (newNick);
-  m_userListModel.setStringList (m_userList);
-}
-
-void
-IRCChannelProxyImpl::handleJoin (const QString &nick)
-{
-  m_userList = m_userListModel.stringList ();
-  m_userList.append (nick);
-  m_userListModel.setStringList (m_userList);
-}
-
-IRCClientImpl::IRCClientImpl (QObject *parent)
-  : IRCClientInterface (parent)
-{
-  m_loggedIn = false;
-  connect (&m_tcpSocket, SIGNAL (connected ()), this, SLOT (handleConnected ()));
-  connect (&m_tcpSocket, SIGNAL (disconnected ()), this, SLOT (handleDisconnected ()));
-  connect (&m_tcpSocket, SIGNAL (readyRead ()), this, SLOT (handleReadyRead ()));
-}
-
-IRCClientImpl::~IRCClientImpl ()
-{
-  foreach (IRCChannelProxyInterface *ircChannelProxy, m_channels)
-    {
-      delete ircChannelProxy;
-    }
-}
-
-void
-IRCClientImpl::connectToHost (const QHostAddress& host, int port, const QString& initialNick)
-{
-  m_host = host;
-  m_nickname = initialNick;
-  m_tcpSocket.connectToHost(host, port);
-}
-
-void
-IRCClientImpl::disconnect ()
-{
-  m_tcpSocket.disconnect ();
-}
-
-void
-IRCClientImpl::reconnect ()
-{
-  disconnect ();
-  connectToHost (m_host, m_port, m_nickname);
-}
-
-bool
-IRCClientImpl::isConnected ()
-{
-  return m_connected;
-}
-
-bool
-IRCClientImpl::isLoggedIn ()
-{
-  return m_loggedIn;
-}
-
-const QHostAddress&
-IRCClientImpl::host()
-{
-  return m_host;
-}
-
-int
-IRCClientImpl::port()
-{
-  return m_port;
-}
-
-IRCChannelProxyInterface *
-IRCClientImpl::ircChannelProxy (const QString &channel)
-{
-  if (!m_channels.contains (channel))
-      m_channels[channel] = new IRCChannelProxyImpl(this, channel);
-  return m_channels[channel];
-}
-
-void
-IRCClientImpl::sendNicknameChangeRequest (const QString &nickname)
-{
-  sendIRCCommand (IRCCommand::Nick, QStringList (nickname));
-}
-
-void
-IRCClientImpl::sendPrivateMessage (const QString &recipient, const QString &message)
-{
-  QStringList arguments;
-  arguments << recipient;
-  arguments << message;
-  sendIRCCommand (IRCCommand::PrivateMessage, arguments);
-}
-
-const QString&
-IRCClientImpl::nickname ()
-{
-  return m_nickname;
-}
-
-void
-IRCClientImpl::handleConnected ()
-{
-  m_connected = true;
-  QStringList arguments;
-  arguments << "na" << "0" << "0" << "na";
-  sendIRCCommand (IRCCommand::User, arguments);
-  sendNicknameChangeRequest (m_nickname);
-  emit connected (m_host.toString ());
-}
-
-void
-IRCClientImpl::handleDisconnected ()
-{
-  m_connected = false;
-  emit disconnected ();
-}
-
-void
-IRCClientImpl::handleReadyRead ()
-{
-  QByteArray line;
-  do
-    {
-      line = m_tcpSocket.readLine();
-      if (line.size ())
-        handleIncomingLine(QString::fromUtf8(line.data ()));
-      else
-        break;
-    }
-  while (true);
-}
-
-void
-IRCClientImpl::handleNicknameChanged (const QString &oldNick, const QString &newNick)
-{
-  // Check if our nickname changed.
-  if (oldNick == m_nickname)
-    {
-      m_nickname = newNick;
-      emit userNicknameChanged (m_nickname);
-    }
-  emit nicknameChanged (oldNick, newNick);
-}
-
-void
-IRCClientImpl::handleUserJoined (const QString &nick, const QString &channel)
-{
-  ircChannelProxy (channel)->handleJoin (nick);
-  emit userJoined (nick, channel);
-}
-
-void
-IRCClientImpl::handleUserQuit (const QString &nick, const QString &reason)
-{
-  emit userQuit (nick, reason);
-}
-
-void
-IRCClientImpl::handleIncomingLine (const QString &line)
-{
-  if (m_connected && !line.isEmpty())
-    {
-      IRCServerMessage ircServerMessage(line);
-      if (ircServerMessage.isNumeric () == true)
-        {
-          switch (ircServerMessage.numericValue ())
-            {
-              case IRCReply::Welcome:
-                m_loggedIn = true;
-                emit userNicknameChanged (nickname ());
-                emit loggedIn (nickname ());
-                break;
-              case IRCError::NicknameInUse:
-              case IRCError::NickCollision:
-                // If we are already logged in, the user attempted to
-                // switch to a username that is already existing.
-                // In that case warn him.
-                if (isLoggedIn ())
-                  {
-                    emit error ("The nickname is already in use.");
-                  }
-                // Otherwise we are attempting to log in to the server.
-                // Change the nick so that we can at least log in.
-                else
-                  {
-                    m_nickname += "_";
-                    sendNicknameChangeRequest (m_nickname);
-                  }
-                break;
-              case IRCError::PasswordMismatch:
-                emit error ("The password you provided is not correct.");
-                break;
-              case IRCReply::MessageOfTheDayStart:
-              case IRCReply::MessageOfTheDay:
-              case IRCReply::MessageOfTheDayEnd:
-              case IRCError::NoMessageOfTheDay:
-                break;
-              case IRCReply::NoTopic:
-              case IRCReply::Topic:
-                break;
-              case IRCReply::NameReply:
-                QString channel = ircServerMessage.parameter (2);
-                QString nickList = ircServerMessage.parameter (3);
-                emit debugMessage (nickList);
-                ircChannelProxy (channel)->setNickList (nickList.split (QRegExp ("\\s+"), QString::SkipEmptyParts));
-                break;
-            }
-        }
-      else
-        {
-          QString command = ircServerMessage.command ();
-          if (command == IRCCommand::Nick)
-            {
-              handleNicknameChanged (ircServerMessage.nick(), ircServerMessage.parameter (0));
-            }
-          else if (command == IRCCommand::Quit)
-            {
-              handleUserQuit (ircServerMessage.nick (), ircServerMessage.parameter (0));
-            }
-          else if (command == IRCCommand::Join)
-            {
-              handleUserJoined(ircServerMessage.nick (), ircServerMessage.parameter (0));
-            }
-          else if (command == IRCCommand::Part)
-            {
-              emit debugMessage ("WRITEME: Received part.");
-              //emit part (ircEvent.getNick ().toStdString ().c_str (),
-              //           ircEvent.getParam (0).toStdString ().c_str (),
-              //           ircEvent.getParam (1).toStdString ().c_str ());
-            }
-          else if (command == IRCCommand::Mode)
-            {
-              emit debugMessage ("WRITEME: Received mode.");
-              //emit mode (&ircEvent);
-            }
-          else if (command == IRCCommand::Topic)
-            {
-              emit debugMessage
-                (QString("WRITEME: Received topic: %1")
-                  .arg (ircServerMessage.parameter (0)));
-            }
-          else if (command == IRCCommand::Kick)
-            {
-              emit debugMessage ("WRITEME: Received kick command.");
-            }
-          else if (command == IRCCommand::Invite)
-            {
-              emit debugMessage ("WRITEME: Received invite command.");
-
-            }
-          else if (command == IRCCommand::PrivateMessage)
-            {
-              emit message (ircServerMessage.parameter (0), ircServerMessage.nick (), ircServerMessage.parameter (1));
-            }
-          else if (command == IRCCommand::Notice)
-            {
-              emit notification (ircServerMessage.nick ().toStdString ().c_str (),
-                                 ircServerMessage.parameter (1).toStdString ().c_str ());
-            }
-          else if (command == IRCCommand::Ping)
-            {
-              sendIRCCommand (IRCCommand::Pong, QStringList (m_nickname));
-            }
-          else if (command == IRCCommand::Error)
-            {
-              emit error (ircServerMessage.parameter (0));
-            }
-          else
-            {
-              emit debugMessage (QString("FIXME: Received unknown reply: %1").arg(command));
-            }
-        }
-    }
-}
-
-void
-IRCClientImpl::sendLine (const QString &line)
-{
-  if (m_connected)
-    m_tcpSocket.write ( (line +  + "\r\n").toUtf8 ());
-}
-
-void
-IRCClientImpl::sendIRCCommand (const QString &command, const QStringList &arguments)
-{
-  QString line = command;
-  for (int i = 0; i < arguments.size (); i++)
-    {
-      bool applyColon = false;
-      // Usually all parameters are separated by spaces.
-      // The last parameter of the message may contain spaces, it is usually used
-      // to transmit messages. In order to parse it correctly, if needs to be prefixed
-      // with a colon, so the server knows to ignore all forthcoming spaces and has to treat
-      // all remaining characters as a single parameter. If we detect any whitespace in the
-      // last argument, prefix it with a colon:
-      if ((i == arguments.size () - 1) && arguments.at (i).contains (QRegExp("\\s")))
-        applyColon = true;
-      line += QString (" %1%2").arg (applyColon ? ":" : "").arg (arguments.at (i));
-    }
-  sendLine (line);
-}
--- a/gui/src/qirc/IRCClientImpl.h	Sun Sep 25 21:12:47 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,355 +0,0 @@
-/* OctaveGUI - A graphical user interface for Octave
- * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef IRCCLIENTIMPL_H
-#define IRCCLIENTIMPL_H
-
-#include <QTcpSocket>
-#include <QHostInfo>
-#include <QStringList>
-#include <QTextDocument>
-#include <QStringListModel>
-#include "IRCClientInterface.h"
-
-/**
-  * \namespace IRCCommand
-  * This namespace includes all IRC commands.
-  */
-namespace IRCCommand
-{
-  const QString Password = "PASS";
-  const QString Nick = "NICK";
-  const QString User = "USER";
-  const QString Operation = "OPER";
-  const QString Service = "SERVICE";
-  const QString Quit = "QUIT";
-  const QString ServerQuit = "SQUIT";
-
-  const QString Join = "JOIN";
-  const QString Part = "PART";
-  const QString Mode = "MODE";
-  const QString Topic = "TOPIC";
-  const QString Names = "NAMES";
-  const QString List = "LIST";
-  const QString Invite = "INVITE";
-  const QString Kick = "KICK";
-
-  const QString PrivateMessage = "PRIVMSG";
-  const QString Notice = "NOTICE";
-
-  const QString MessageOfTheDay = "MOTD";
-  const QString ListUsers = "LUSERS";
-  const QString Version = "VERSION";
-  const QString Stats = "STATS";
-  const QString Links = "LINKS";
-  const QString Time = "TIME";
-  const QString Command = "CONNECT";
-  const QString Trace = "TRACE";
-  const QString Admin = "ADMIN";
-  const QString Info = "INFO";
-
-  const QString ServerList = "SERVLIST";
-  const QString ServerQuery = "SQUERY";
-
-  const QString Who = "WHO";
-  const QString WhoIs = "WHOIS";
-  const QString WhoWas = "WHOWAS";
-
-  const QString Kill = "KILL";
-  const QString Ping = "PING";
-  const QString Pong = "PONG";
-  const QString Error = "ERROR";
-
-  const QString Away = "AWAY";
-  const QString Rehash = "REHASH";
-  const QString Die = "DIE";
-  const QString Restart = "RESTART";
-  const QString Summon = "SUMMON";
-  const QString Users = "USERS";
-  const QString OperatorWall = "OPERWALL";
-  const QString UserHost = "USERHOST";
-  const QString IsOn = "ISON";
-};
-
-/**
-  * \namespace IRCReply
-  * This namespace includes all numeric IRC replies.
-  */
-namespace IRCReply
-{
-  const int Welcome = 1;
-  const int YourHost = 2;
-  const int Created = 3;
-  const int MyInfo = 4;
-  const int ReplyBounce = 5;
-  const int UserHost = 302;
-  const int IsOn = 303;
-  const int Away = 301;
-  const int UnAway = 305;
-  const int NoAway = 306;
-  const int WhoIsUser = 311;
-  const int WhoIsServer = 312;
-  const int WhoIsOperator = 313;
-  const int WhoIsIdle = 317;
-  const int EndOfWhoIs = 318;
-  const int WhoIsChannels = 319;
-  const int WhoWasUser = 314;
-  const int EndOfWhoWas = 369;
-  const int ListStart = 321;
-  const int List = 322;
-  const int ListEnd = 323;
-  const int UniqueOpIs = 325;
-  const int ChannelModeIs = 324;
-  const int NoTopic = 331;
-  const int Topic = 332;
-  const int Inviting = 341;
-  const int Summoning = 342;
-  const int InviteList = 346;
-  const int EndOfInviteList = 347;
-  const int ExceptList = 348;
-  const int EndOfExceptList = 349;
-  const int Version = 351;
-  const int WhoReply = 352;
-  const int EndOfWho = 315;
-  const int NameReply = 353;
-  const int EndOfNames = 366;
-  const int Links = 364;
-  const int EndOfLinks = 367;
-  const int BanList = 368;
-  const int Info = 371;
-  const int EndOfInfo = 374;
-  const int MessageOfTheDayStart = 375;
-  const int MessageOfTheDay = 372;
-  const int MessageOfTheDayEnd = 376;
-  const int YouAreOperator = 381;
-  const int Rehashing = 382;
-  const int YouAreService = 383;
-  const int Time = 391;
-  const int UserStart = 392;
-  const int Users = 393;
-  const int EndOfUsers = 394;
-  const int NoUsers = 395;
-  const int TraceLink = 200;
-  const int TraceConnecting = 201;
-  const int TraceHandshake = 202;
-  const int TraceUnknown = 203;
-  const int TraceOperator = 204;
-  const int TraceUser = 205;
-  const int TraceServer = 206;
-  const int TraceService = 207;
-  const int TraceNewType = 208;
-  const int TraceClass = 209;
-  const int TraceConnect = 210;
-  const int TraceLog = 261;
-  const int TraceEnd = 262;
-  const int StatsLinkInfo = 211;
-  const int StatsCommands = 212;
-  const int EndOfStats = 219;
-  const int StatsUptime = 242;
-  const int StatsOnline = 243;
-  const int UModeIs = 221;
-  const int ServerList = 234;
-  const int ServerListEnd = 235;
-  const int ListUserClient = 251;
-  const int ListUserOperator = 252;
-  const int ListUserUnknown = 253;
-  const int ListUserChannels = 254;
-  const int ListUserMe = 255;
-  const int AdminMe = 256;
-  const int AdminLoc1 = 257;
-  const int AdminLoc2 = 258;
-  const int AdminEmail = 259;
-  const int TryAgain = 263;
-};
-
-/**
-  * \namespace IRCError
-  * This namespace includes all numeric IRC errors.
-  */
-namespace IRCError
-{
-  const int NoSuchNick = 401;
-  const int NoSuchServer = 402;
-  const int NoSuchChannel = 403;
-  const int CannotSendToChannel = 404;
-  const int TooManyChannels = 405;
-  const int WasNoSuchNick = 406;
-  const int TooManyTargets = 407;
-  const int NoSuchService = 408;
-  const int NoOrigin = 409;
-  const int NoRecipient = 411;
-  const int NoTextToSend = 412;
-  const int NoTopLevel = 413;
-  const int WildTopLevel = 414;
-  const int BasMask = 415;
-  const int UnknownCommand = 421;
-  const int NoMessageOfTheDay = 422;
-  const int NoAdminInfo = 423;
-  const int FileError = 424;
-  const int NoNickNameGiven = 431;
-  const int ErroneusNick = 432;
-  const int NicknameInUse = 433;
-  const int NickCollision = 436;
-  const int UnavailResource = 437;
-  const int UserNotInChannel = 441;
-  const int NotOnChannel = 442;
-  const int UserOnChannel = 443;
-  const int NoLogin = 444;
-  const int SummonDisabled = 445;
-  const int UsersDisabled = 446;
-  const int NotRegistered = 451;
-  const int NeedMoreParams = 461;
-  const int AlreadyRegistered = 462;
-  const int NoPermissionForHost = 463;
-  const int PasswordMismatch = 464;
-  const int YouAreBannedCreep = 465;
-  const int YouWillBeBanned = 466;
-  const int KeySet = 467;
-  const int ChannelIsFull = 471;
-  const int UnknownMode = 472;
-  const int InviteOnlyChannel = 473;
-  const int BannedFromChannel = 474;
-  const int BadChannelKey = 475;
-  const int BadChannelMask = 476;
-  const int NoChannelModes = 477;
-  const int BanListFull = 478;
-  const int NoPrivileges = 481;
-  const int ChannelOperatorPrivilegesNeeded = 482;
-  const int CannotKillServer = 483;
-  const int Restricted = 484;
-  const int UniqueOperatorPrivilegesNeeded = 485;
-  const int NoOperatorHost = 491;
-  const int YourModeListUnknownFlag = 501;
-  const int UsersDontMatch = 502;
-};
-
-/**
-  * \class IRCServerMessage
-  * The IRCServerMessage class is a wrapper for server messages.
-  * It parses the server message into its single bits and makes these
-  * available through Getter-methods.
-  */
-class IRCServerMessage
-{
-public:
-  IRCServerMessage (const QString& serverMessage);
-
-  bool isNumeric ()
-  { return m_isNumeric; }
-
-  QString nick ()
-  { return m_nick; }
-
-  QString command ()
-  { return m_command; }
-
-  int numericValue ();
-  QString parameter (int index);
-
-private:
-  int         m_codeNumber;
-  bool        m_isNumeric;
-  QString     m_nick;
-  QString     m_user;
-  QString     m_host;
-  QString     m_command;
-  QStringList m_parameters;
-};
-
-/**
-  * \class IRCChannelProxyImpl
-  * Implements a handle to an IRC channel. This is usually provided by the
-  * the IRC client class.
-  */
-class IRCChannelProxyImpl : public IRCChannelProxyInterface
-{
-  Q_OBJECT
-public:
-  IRCChannelProxyImpl (IRCClientInterface *clientInterface, const QString& channelName, QObject *parent = 0);
-  QTextDocument *conversationModel ();
-  QStringListModel *userListModel ();
-  QString channelName ();
-
-  void setNickList (const QStringList &nickList);
-  void sendMessage (const QString& message);
-  void sendJoinRequest ();
-  void leave (const QString &reason);
-public slots:
-  void handleNickChange (const QString& oldNick, const QString& newNick);
-  void handleJoin (const QString& nick);
-private:
-  QString             m_channelName;
-  QStringList         m_userList;
-  QStringListModel    m_userListModel;
-  QTextDocument       m_conversationModel;
-  IRCClientInterface *m_clientInterface;
-};
-
-/**
-  * \class IRCClientImpl
-  * Implements an IRC client. This class can maintain a connection to one server.
-  * In order to interface an IRC channel, use the ircChannelProxy-method to retrieve
-  * a handle.
-  */
-class IRCClientImpl : public IRCClientInterface
-{
-  Q_OBJECT
-public:
-  IRCClientImpl (QObject *parent = 0);
-  ~IRCClientImpl ();
-
-  const QString& nickname ();
-  bool isConnected ();
-  bool isLoggedIn ();
-  const QHostAddress& host();
-  int port();
-  IRCChannelProxyInterface *ircChannelProxy(const QString& channel);
-  void sendIRCCommand (const QString& command, const QStringList& arguments);
-
-public slots:
-  void connectToHost (const QHostAddress& host, int port, const QString& initialNick);
-  void disconnect ();
-  void reconnect ();
-
-  void sendNicknameChangeRequest (const QString &nickname);
-  void sendPrivateMessage (const QString &recipient, const QString &message);
-
-signals:
-  void debugMessage (const QString& message);
-
-private slots:
-  void handleConnected ();
-  void handleDisconnected ();
-  void handleReadyRead ();
-
-private:
-  void handleNicknameChanged (const QString& oldNick, const QString& newNick);
-  void handleUserJoined (const QString& nick, const QString& channel);
-  void handleUserQuit (const QString& nick, const QString& reason);
-  void handleIncomingLine (const QString& line);
-  void sendLine (const QString& line);
-
-  QHostAddress                              m_host;
-  int                                       m_port;
-  QString                                   m_nickname;
-  bool                                      m_connected;
-  bool                                      m_loggedIn;
-  QTcpSocket                                m_tcpSocket;
-  QMap<QString, IRCChannelProxyInterface*>  m_channels;
-};
-
-#endif // IRCCLIENTIMPL_H
--- a/gui/src/qirc/IRCClientInterface.h	Sun Sep 25 21:12:47 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,221 +0,0 @@
-/* OctaveGUI - A graphical user interface for Octave
- * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef IRCCLIENTINTERFACE_H
-#define IRCCLIENTINTERFACE_H
-
-#include <QString>
-#include <QObject>
-#include <QHostAddress>
-#include <QTextDocument>
-#include <QStringListModel>
-
-class IRCClientInterface;
-/**
-  * \class IRCChannelProxyInterface
-  * Interface for a handle to an IRC channel.
-  */
-class IRCChannelProxyInterface : public QObject
-{
-  Q_OBJECT
-public:
-  IRCChannelProxyInterface (IRCClientInterface *, const QString&, QObject *parent = 0) : QObject (parent) { }
-  virtual ~IRCChannelProxyInterface () { }
-
-  /** Returns the conversation model part. */
-  virtual QTextDocument *conversationModel () = 0;
-
-  /** Returns a string list model for the user list. */
-  virtual QStringListModel *userListModel () = 0;
-
-  /** Returns the name of this channel. */
-  virtual QString channelName () = 0;
-
-  /**
-    * Overwrites the current nick list by settings a new nick list.
-    * \arg nickList The new nick list to set.
-    */
-  virtual void setNickList (const QStringList& nickList) = 0;
-
-  /**
-    * Sends a public message onto this channel.
-    * \arg message The message that should be sent.
-    */
-  virtual void sendMessage (const QString& message) = 0;
-
-  /** Requests to join this channel. */
-  virtual void sendJoinRequest () = 0;
-
-  /**
-    * Requests to leave this channel.
-    * \arg reason Reason for leaving the channel.
-    */
-  virtual void leave (const QString& reason) = 0;
-
-public slots:
-  virtual void handleNickChange (const QString& oldNick, const QString& newNick) = 0;
-  virtual void handleJoin (const QString& nick) = 0;
-};
-
-/**
-  * \class IRCClientInterface
-  * IRC Clients need to implement this interface.
-  */
-class IRCClientInterface : public QObject
-{
-  Q_OBJECT
-public:
-  IRCClientInterface (QObject *parent = 0) : QObject (parent) { }
-  virtual ~IRCClientInterface () { }
-
-  /** Returns the current nickname of this client. */
-  virtual const QString& nickname () = 0;
-
-  /** Returns true if connected to the server. */
-  virtual bool isConnected () = 0;
-
-  /**
-    * Returns true if logged in to the server.
-    * Note: There is a small difference between isConnected and isLoggedIn.
-    * isConnected returns true if there is a physical connection to the server.
-    * isLoggedIn only returns true if the server has already accepted you
-    * and you are ready to log into channels.
-    */
-  virtual bool isLoggedIn () = 0;
-
-  /** Returns the current host address. */
-  virtual const QHostAddress& host() = 0;
-
-  /** Returns the current port. */
-  virtual int port() = 0;
-
-  /**
-    * Returns a handle to an IRC channel.
-    * Note: Retrieving a handle does not mean you have joined this channel.
-    * \arg channel The channel to retrieve a handle for.
-    */
-  virtual IRCChannelProxyInterface *ircChannelProxy(const QString& channel) = 0;
-
-  /**
-    * Send an IRC command to the server.
-    * \arg command Command to send.
-    * \arg arguments Arguments to send.
-    */
-  virtual void sendIRCCommand (const QString& command, const QStringList& arguments) = 0;
-
-public slots:
-  /**
-    * Connects to a host.
-    * \arg host The host to connect tp.
-    * \arg port The port on which to connect to the host.
-    * \arg initialNick The initial nick to use when attempting to login.
-    */
-  virtual void connectToHost (const QHostAddress& host, int port, const QString& initialNick) = 0;
-
-  /** Disconnects from the host. */
-  virtual void disconnect () = 0;
-
-  /** Reconnects to the host. */
-  virtual void reconnect () = 0;
-
-  /**
-    * Sends a request to change the nickname.
-    * \arg nickname The new nickname to be requested.
-    */
-  virtual void sendNicknameChangeRequest (const QString& nickname) = 0;
-
-  /**
-    * Sends a private message.
-    * \arg recipient The nickname or channel that message should be sent to.
-    * \arg message The message that should be sent.
-    */
-  virtual void sendPrivateMessage (const QString& recipient, const QString& message) = 0;
-
-signals:
-  /**
-    * Sent upon the arrival of a new message.
-    * \arg channel The channel this message was sent from.
-    * \arg sender The nickname of the sender.
-    * \arg message The message that has been sent.
-    */
-  void newMessage (const QString& channel, const QString& sender, const QString& message);
-  void message (const QString& channel, const QString& sender, const QString& message);
-
-  /**
-    * Sent when the connection to a server has been established.
-    * \arg server The name of the server that the connection has been established to.
-    */
-  void connected (const QString& server);
-
-  /** Sent when the connection to the server has been interrupted. */
-  void disconnected ();
-
-  /**
-    * Sent when an error occurs.
-    * \arg message A descriptive message of the error that occured.
-    */
-  void error (const QString& message);
-
-  /**
-    * Sent when a notification arrives.
-    * \arg sender The source of the notification.
-    * \arg message The notification.
-    */
-  void notification (const QString& sender, const QString& message);
-
-  /**
-    * Sent when a nickname changed.
-    * \arg oldNick The previous nickname.
-    * \arg newNick The new nickname.
-    */
-  void nicknameChanged (const QString& oldNick, const QString& newNick);
-
-  /**
-    * Sent when the nickname of this client changed.
-    * \arg nick The new nickname of this client.
-    */
-  void userNicknameChanged (const QString& nick);
-
-  /**
-    * Sent when a user has joined a channel.
-    * \arg nick Nickname of the user that joined the channel.
-    * \arg channel Channel that this user joined.
-    */
-  void userJoined (const QString& nick, const QString& channel);
-
-  /**
-    * Sent when a user quits.
-    * \arg nick Nickname of the user that quit.
-    * \arg reason Reason of the user to quit.
-    */
-  void userQuit (const QString& nick, const QString& reason);
-
-  /**
-    * Sent when a user logged in.
-    * \arg nick The nickname of the user that logged in.
-    */
-  void loggedIn (const QString& nick);
-
-  /**
-    * Sent when the server provides a userlist for a channel.
-    * \arg channel The channel that userlist applies to.
-    * \arg list The actual userlist.
-    */
-  void userList (const QString& channel, const QStringList& list);
-};
-
-#endif // IRCCLIENTINTERFACE_H
--- a/gui/src/qirc/IRCCodes.h	Sun Sep 25 21:12:47 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,223 +0,0 @@
-/* OctaveGUI - A graphical user interface for Octave
- * Copyright (C) 2011 Jacob Dawid
- * jacob.dawid@googlemail.com
- *
- * 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 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef IRCCODES_H
-#define IRCCODES_H
-#include <QString>
-
-namespace IRCCommand
-{
-  const QString Password = "PASS";
-  const QString Nick = "NICK";
-  const QString User = "USER";
-  const QString Operation = "OPER";
-  const QString Service = "SERVICE";
-  const QString Quit = "QUIT";
-  const QString ServerQuit = "SQUIT";
-
-  const QString Join = "JOIN";
-  const QString Part = "PART";
-  const QString Mode = "MODE";
-  const QString Topic = "TOPIC";
-  const QString Names = "NAMES";
-  const QString List = "LIST";
-  const QString Invite = "INVITE";
-  const QString Kick = "KICK";
-
-  const QString PrivateMessage = "PRIVMSG";
-  const QString Notice = "NOTICE";
-
-  const QString MessageOfTheDay = "MOTD";
-  const QString ListUsers = "LUSERS";
-  const QString Version = "VERSION";
-  const QString Stats = "STATS";
-  const QString Links = "LINKS";
-  const QString Time = "TIME";
-  const QString Command = "CONNECT";
-  const QString Trace = "TRACE";
-  const QString Admin = "ADMIN";
-  const QString Info = "INFO";
-
-  const QString ServerList = "SERVLIST";
-  const QString ServerQuery = "SQUERY";
-
-  const QString Who = "WHO";
-  const QString WhoIs = "WHOIS";
-  const QString WhoWas = "WHOWAS";
-
-  const QString Kill = "KILL";
-  const QString Ping = "PING";
-  const QString Pong = "PONG";
-  const QString Error = "ERROR";
-
-  const QString Away = "AWAY";
-  const QString Rehash = "REHASH";
-  const QString Die = "DIE";
-  const QString Restart = "RESTART";
-  const QString Summon = "SUMMON";
-  const QString Users = "USERS";
-  const QString OperatorWall = "OPERWALL";
-  const QString UserHost = "USERHOST";
-  const QString IsOn = "ISON";
-};
-
-namespace IRCReply
-{
-  const int Welcome = 1;
-  const int YourHost = 2;
-  const int Created = 3;
-  const int MyInfo = 4;
-  const int ReplyBounce = 5;
-  const int UserHost = 302;
-  const int IsOn = 303;
-  const int Away = 301;
-  const int UnAway = 305;
-  const int NoAway = 306;
-  const int WhoIsUser = 311;
-  const int WhoIsServer = 312;
-  const int WhoIsOperator = 313;
-  const int WhoIsIdle = 317;
-  const int EndOfWhoIs = 318;
-  const int WhoIsChannels = 319;
-  const int WhoWasUser = 314;
-  const int EndOfWhoWas = 369;
-  const int ListStart = 321;
-  const int List = 322;
-  const int ListEnd = 323;
-  const int UniqueOpIs = 325;
-  const int ChannelModeIs = 324;
-  const int NoTopic = 331;
-  const int Topic = 332;
-  const int Inviting = 341;
-  const int Summoning = 342;
-  const int InviteList = 346;
-  const int EndOfInviteList = 347;
-  const int ExceptList = 348;
-  const int EndOfExceptList = 349;
-  const int Version = 351;
-  const int WhoReply = 352;
-  const int EndOfWho = 315;
-  const int NameReply = 353;
-  const int EndOfNames = 366;
-  const int Links = 364;
-  const int EndOfLinks = 367;
-  const int BanList = 368;
-  const int Info = 371;
-  const int EndOfInfo = 374;
-  const int MessageOfTheDayStart = 375;
-  const int MessageOfTheDay = 372;
-  const int MessageOfTheDayEnd = 376;
-  const int YouAreOperator = 381;
-  const int Rehashing = 382;
-  const int YouAreService = 383;
-  const int Time = 391;
-  const int UserStart = 392;
-  const int Users = 393;
-  const int EndOfUsers = 394;
-  const int NoUsers = 395;
-  const int TraceLink = 200;
-  const int TraceConnecting = 201;
-  const int TraceHandshake = 202;
-  const int TraceUnknown = 203;
-  const int TraceOperator = 204;
-  const int TraceUser = 205;
-  const int TraceServer = 206;
-  const int TraceService = 207;
-  const int TraceNewType = 208;
-  const int TraceClass = 209;
-  const int TraceConnect = 210;
-  const int TraceLog = 261;
-  const int TraceEnd = 262;
-  const int StatsLinkInfo = 211;
-  const int StatsCommands = 212;
-  const int EndOfStats = 219;
-  const int StatsUptime = 242;
-  const int StatsOnline = 243;
-  const int UModeIs = 221;
-  const int ServerList = 234;
-  const int ServerListEnd = 235;
-  const int ListUserClient = 251;
-  const int ListUserOperator = 252;
-  const int ListUserUnknown = 253;
-  const int ListUserChannels = 254;
-  const int ListUserMe = 255;
-  const int AdminMe = 256;
-  const int AdminLoc1 = 257;
-  const int AdminLoc2 = 258;
-  const int AdminEmail = 259;
-  const int TryAgain = 263;
-};
-
-namespace IRCError
-{
-  const int NoSuchNick = 401;
-  const int NoSuchServer = 402;
-  const int NoSuchChannel = 403;
-  const int CannotSendToChannel = 404;
-  const int TooManyChannels = 405;
-  const int WasNoSuchNick = 406;
-  const int TooManyTargets = 407;
-  const int NoSuchService = 408;
-  const int NoOrigin = 409;
-  const int NoRecipient = 411;
-  const int NoTextToSend = 412;
-  const int NoTopLevel = 413;
-  const int WildTopLevel = 414;
-  const int BasMask = 415;
-  const int UnknownCommand = 421;
-  const int NoMessageOfTheDay = 422;
-  const int NoAdminInfo = 423;
-  const int FileError = 424;
-  const int NoNickNameGiven = 431;
-  const int ErroneusNick = 432;
-  const int NicknameInUse = 433;
-  const int NickCollision = 436;
-  const int UnavailResource = 437;
-  const int UserNotInChannel = 441;
-  const int NotOnChannel = 442;
-  const int UserOnChannel = 443;
-  const int NoLogin = 444;
-  const int SummonDisabled = 445;
-  const int UsersDisabled = 446;
-  const int NotRegistered = 451;
-  const int NeedMoreParams = 461;
-  const int AlreadyRegistered = 462;
-  const int NoPermissionForHost = 463;
-  const int PasswordMismatch = 464;
-  const int YouAreBannedCreep = 465;
-  const int YouWillBeBanned = 466;
-  const int KeySet = 467;
-  const int ChannelIsFull = 471;
-  const int UnknownMode = 472;
-  const int InviteOnlyChannel = 473;
-  const int BannedFromChannel = 474;
-  const int BadChannelKey = 475;
-  const int BadChannelMask = 476;
-  const int NoChannelModes = 477;
-  const int BanListFull = 478;
-  const int NoPrivileges = 481;
-  const int ChannelOperatorPrivilegesNeeded = 482;
-  const int CannotKillServer = 483;
-  const int Restricted = 484;
-  const int UniqueOperatorPrivilegesNeeded = 485;
-  const int NoOperatorHost = 491;
-  const int YourModeListUnknownFlag = 501;
-  const int UsersDontMatch = 502;
-};
-
-#endif
--- a/gui/src/qirc/IRCWidget.cpp	Sun Sep 25 21:12:47 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,448 +0,0 @@
-/* OctaveGUI - A graphical user interface for Octave
- * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "ResourceManager.h"
-#include "IRCWidget.h"
-#include <QMessageBox>
-#include <QHBoxLayout>
-#include <QVBoxLayout>
-#include <QLabel>
-#include <QSettings>
-#include <QInputDialog>
-#include <QKeyEvent>
-#include <QScrollBar>
-#include <QApplication>
-#include "IRCClientImpl.h"
-
-ChatMessageTextEdit::ChatMessageTextEdit (QWidget *parent)
-  : QPlainTextEdit (parent), m_completer (0)
-{
-  setMaximumHeight (50);
-  setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
-}
-
-ChatMessageTextEdit::~ChatMessageTextEdit ()
-{
-}
-
-void
-ChatMessageTextEdit::setCompleter (QCompleter *completer)
-{
-  if (m_completer)
-    QObject::disconnect (m_completer, 0, this, 0);
-
-  m_completer = completer;
-
-  if (!m_completer)
-    return;
-
-  m_completer->setWidget (this);
-  m_completer->setCompletionMode (QCompleter::PopupCompletion);
-  m_completer->setCaseSensitivity (Qt::CaseInsensitive);
-  QObject::connect (m_completer, SIGNAL (activated (QString)),
-                    this, SLOT (insertCompletion (QString)));
-}
-
-QCompleter *
-ChatMessageTextEdit::completer () const
-{
-  return m_completer;
-}
-
-void
-ChatMessageTextEdit::insertCompletion(const QString& completion)
-{
-
-  if (m_completer->widget() != this)
-    return;
-  QTextCursor tc = textCursor();
-  int extra = completion.length() - m_completer->completionPrefix().length();
-  tc.movePosition(QTextCursor::Left);
-  tc.movePosition(QTextCursor::EndOfWord);
-  tc.insertText(completion.right(extra));
-  setTextCursor(tc);
-}
-
-QString
-ChatMessageTextEdit::textUnderCursor () const
-{
-  QTextCursor tc = textCursor ();
-  tc.select (QTextCursor::WordUnderCursor);
-  return tc.selectedText ();
-}
-
-void
-ChatMessageTextEdit::focusInEvent (QFocusEvent *e)
-{
-  if (m_completer)
-    m_completer->setWidget (this);
-  QPlainTextEdit::focusInEvent (e);
-}
-
-void
-ChatMessageTextEdit::keyPressEvent (QKeyEvent *keyPressEvent)
-{
-  if (m_completer) {
-    switch (keyPressEvent->key ()) {
-    case Qt::Key_Enter:
-    case Qt::Key_Return:
-      if (! (keyPressEvent->modifiers () & Qt::ShiftModifier))
-        {
-          emit sendMessage (document ()->toPlainText ());
-          document ()->setPlainText ("");
-        }
-      else
-        {
-          QPlainTextEdit::keyPressEvent (keyPressEvent);
-        }
-      break;
-    case Qt::Key_Escape:
-    case Qt::Key_Tab:
-    case Qt::Key_Backtab:
-      keyPressEvent->ignore ();
-      return;
-    default:
-      QPlainTextEdit::keyPressEvent(keyPressEvent);
-      break;
-      }
-
-    QString completionPrefix = textUnderCursor ();
-    if (completionPrefix != m_completer->completionPrefix ())
-      {
-        m_completer->setCompletionPrefix(completionPrefix);
-      }
-
-    if (completionPrefix.length() > 2)
-      {
-        m_completer->popup ()->setCurrentIndex (m_completer->completionModel ()->index (0, 0));
-        m_completer->complete ();
-      }
-    else
-      {
-        m_completer->popup ()->hide ();
-      }
-  }
-}
-
-IRCWidget::IRCWidget (QWidget * parent):
-QWidget (parent)
-{
-  QSettings *settings = ResourceManager::instance ()->settings ();
-  bool connectOnStartup = settings->value ("connectOnStartup").toBool ();
-  m_autoIdentification = settings->value ("autoIdentification").toBool ();
-  m_nickServPassword = settings->value ("nickServPassword").toString ();
-
-  m_initialNick = settings->value ("IRCNick").toString ();
-
-  if (m_initialNick.isEmpty ())
-    m_initialNick = "OctaveGUI-User";
-
-  QVBoxLayout *layout = new QVBoxLayout ();
-
-  m_chatWindow = new QTextEdit (this);
-  m_chatWindow->setReadOnly (true);
-  m_chatWindow->setEnabled (false);
-  QWidget *bottomWidget = new QWidget (this);
-
-  layout->addWidget (m_chatWindow);
-  layout->addWidget (bottomWidget);
-  layout->setMargin (0);
-  setLayout (layout);
-
-  QHBoxLayout *bottomLayout = new QHBoxLayout ();
-  m_nickButton = new QPushButton (bottomWidget);
-  m_nickButton->setStatusTip (tr ((char *) "Click here to change your nick."));
-  m_nickButton->setText (m_initialNick);
-  m_chatMessageTextEdit = new ChatMessageTextEdit (bottomWidget);
-  m_chatMessageTextEdit->setStatusTip (tr ((char *) "Enter your message here."));
-
-  bottomLayout->addWidget (m_nickButton);
-  bottomLayout->addWidget (new QLabel (":", this));
-  bottomLayout->addWidget (m_chatMessageTextEdit);
-  bottomLayout->setMargin (0);
-  bottomWidget->setLayout (bottomLayout);
-
-  m_nickButton->setEnabled (false);
-  m_chatMessageTextEdit->setEnabled (false);
-
-  //setFocusProxy (m_chatMessageTextEdit);
-  m_nickButton->setFocusProxy (m_chatMessageTextEdit);
-
-  QFont font;
-  font.setFamily ("Courier");
-  font.setPointSize (11);
-  m_chatWindow->setFont (font);
-  m_ircClientInterface = new IRCClientImpl (this);
-  m_octaveChannel = m_ircClientInterface->ircChannelProxy ("#octave");
-
-  connect (m_ircClientInterface, SIGNAL (connected (QString)),
-           this, SLOT (handleConnected (QString)));
-  connect (m_ircClientInterface, SIGNAL(loggedIn(QString)),
-           this, SLOT (joinOctaveChannel (QString)));
-  connect (m_ircClientInterface, SIGNAL (error (QString)),
-           this, SLOT (showErrorMessage (QString)));
-  connect (m_ircClientInterface, SIGNAL (debugMessage (QString)),
-           this, SLOT (showStatusMessage (QString)));
-  connect (m_ircClientInterface, SIGNAL (message (QString, QString, QString)),
-           this, SLOT (showMessage (QString, QString, QString )));
-  connect (m_ircClientInterface, SIGNAL (nicknameChanged (QString,QString)),
-           this, SLOT (handleNickChange (QString,QString)));
-  connect (m_ircClientInterface, SIGNAL (notification (QString,QString)),
-           this, SLOT (showNotification (QString,QString)));
-  connect (m_ircClientInterface, SIGNAL (loggedIn (QString)),
-           this, SLOT (handleLoggedIn(QString)));
-  connect (m_ircClientInterface, SIGNAL (userNicknameChanged (QString)),
-           this, SLOT (handleUserNicknameChanged (QString)));
-
-  connect (m_nickButton, SIGNAL (clicked ()), this, SLOT (showChangeUserNickPopup ()));
-  connect (m_chatMessageTextEdit, SIGNAL (sendMessage (QString)),
-           this, SLOT (sendMessage (QString)));
-
-  m_chatMessageTextEdit->setCompleter
-      (new QCompleter (m_ircClientInterface->ircChannelProxy ("#octave")->userListModel (), this));
-  m_chatWindow->setDocument (m_octaveChannel->conversationModel ());
-
-  if (connectOnStartup)
-    connectToServer ();
-}
-
-void
-IRCWidget::connectToServer ()
-{
-  showStatusMessage ("Looking up irc.freenode.net.");
-  QHostInfo hostInfo = QHostInfo::fromName ("irc.freenode.net");
-  QList<QHostAddress> hostAddresses = hostInfo.addresses();
-  if (hostAddresses.isEmpty ())
-    {
-      showStatusMessage ("Failed to lookup irc.freenode.net.");
-    }
-  else
-    {
-      showStatusMessage (QString ("Attempting to connect to %1.")
-                         .arg (hostAddresses.at (0).toString ()));
-      m_ircClientInterface->connectToHost(hostAddresses.at (0), 6667, m_initialNick);
-    }
-}
-
-void
-IRCWidget::showStatusMessage (const QString& message)
-{
-  m_chatWindow->append (QString ("<i>%1</i>").arg (message));
-}
-
-void
-IRCWidget::showErrorMessage (const QString& message)
-{
-  m_chatWindow->append (QString ("<i>Error: %1</i>").arg (message));
-}
-
-void
-IRCWidget::handleConnected (const QString &host)
-{
-  showStatusMessage (QString ("Connected to server %1.").arg (host));
-}
-
-void
-IRCWidget::joinOctaveChannel (const QString& nick)
-{
-  Q_UNUSED (nick);
-  showStatusMessage (QString ("Joining channel #octave."));
-  m_octaveChannel->sendJoinRequest ();
-}
-
-void
-IRCWidget::showMessage (const QString& channel, const QString& sender, const QString& message)
-{
-  Q_UNUSED (channel);
-
-  // TODO: This doesn't work properly!
-  // Every message makes it emit unreadMessage (true),
-  // though it should inly be emitted when this window
-  // does not have focus, ie. is not the active window.
-  if (!(hasFocus()
-      || m_chatMessageTextEdit->hasFocus ()
-      || m_nickButton->hasFocus ()
-      || m_chatWindow->hasFocus () ))
-    {
-      emit unreadMessages (true);
-    }
-
-  QString output;
-  QString htmlMessage = message;
-  htmlMessage.replace ("<", "&lt;");
-  htmlMessage.replace (">", "&gt;");
-  htmlMessage.replace ("\n", "<br>");
-  if (message.contains (m_ircClientInterface->nickname ()))
-    {
-      output =
-        QString ("<font color=\"#990000\"><b>%1:</b> %2</font>").arg (sender).
-        arg (htmlMessage);
-
-      QApplication::alert (this);
-    }
-  else
-    {
-      output =
-        QString ("<b>%1:</b> %2").arg (sender).
-        arg (htmlMessage);
-    }
-  m_chatWindow->append (output);
-  scrollToBottom ();
-}
-
-void
-IRCWidget::showNotification (const QString& sender, const QString& message)
-{
-  Q_UNUSED (sender);
-  m_chatWindow->append (QString ("<font color=\"#007700\">%1</font>").arg (message));
-  scrollToBottom ();
-}
-
-void
-IRCWidget::showChangeUserNickPopup ()
-{
-  bool ok;
-  QString newNick =
-    QInputDialog::getText (this, QString ("Nickname"),
-			   QString ("Type in your nickname:"),
-                           QLineEdit::Normal, m_ircClientInterface->nickname (), &ok);
-  if (ok)
-    {
-      m_ircClientInterface->sendNicknameChangeRequest (newNick);
-    }
-}
-
-void
-IRCWidget::sendMessage (QString message)
-{
-  // Do not send empty messages.
-  if (message.isEmpty ())
-    return;
-
-  // Remove trailing spaces.
-  while (message.at (0).isSpace ())
-    message.remove (0, 1);
-  if (message.startsWith ("/"))
-    {
-      QStringList line =
-	message.split (QRegExp ("\\s+"), QString::SkipEmptyParts);
-      if (line.at (0) == "/join")
-	{
-          IRCChannelProxyInterface *ircChannel = m_ircClientInterface->ircChannelProxy (line.at (1));
-          ircChannel->sendJoinRequest ();
-	}
-      else if (line.at (0) == "/nick")
-	{
-          m_ircClientInterface->sendNicknameChangeRequest (line.at (1));
-	}
-      else if (line.at (0) == "/msg")
-	{
-	  QString recipient = line.at (1);
-	  // Since we splitted the message before, we have to glue it together again.
-	  QString pmsg = "";
-	  for (int i = 2; i < line.length (); i++)
-	    {
-	      pmsg += line.at (i);
-	      pmsg += " ";
-	    }
-          m_ircClientInterface->sendPrivateMessage(recipient, pmsg);
-	}
-    }
-  else
-    {
-      m_octaveChannel->sendMessage (message);
-      message.replace ("<", "&lt;");
-      message.replace (">", "&gt;");
-      message.replace ("\n", "<br>");
-      m_chatWindow->append (QString ("<b>%1:</b> %2").
-                            arg (m_ircClientInterface->nickname ()).arg (message));
-    }
-
-  scrollToBottom ();
-}
-
-void
-IRCWidget::maybeIdentifyOnNickServ ()
-{
-  if (m_autoIdentification)
-    {
-      m_ircClientInterface->sendPrivateMessage("NickServ", QString ("identify %1").
-                                          arg (m_nickServPassword));
-    }
-}
-
-void
-IRCWidget::scrollToBottom ()
-{
-  if (m_chatWindow->verticalScrollBar ())
-    {
-      m_chatWindow->verticalScrollBar ()->setValue (m_chatWindow->verticalScrollBar ()->maximum ());
-    }
-}
-
-void
-IRCWidget::focusInEvent (QFocusEvent *focusEvent)
-{
-  Q_UNUSED (focusEvent);
-  emit unreadMessages (false);
-  QWidget::focusInEvent (focusEvent);
-
-  m_chatMessageTextEdit->setFocus ();
-}
-
-void
-IRCWidget::handleLoggedIn (const QString &nick)
-{
-  m_chatWindow->
-    append (QString
-            ("<i><font color=\"#00AA00\"><b>Successfully logged in as %1.</b></font></i>").
-            arg (nick));
-  m_nickButton->setEnabled (true);
-  m_chatMessageTextEdit->setEnabled (true);
-  m_chatWindow->setEnabled (true);
-  m_chatMessageTextEdit->setFocus ();
-}
-
-void
-IRCWidget::handleNickChange (const QString &oldNick, const QString &newNick)
-{
-  m_chatWindow->append (QString ("%1 is now known as %2.").arg (oldNick).arg (newNick));
-  scrollToBottom ();
-}
-
-void
-IRCWidget::handleUserJoined (const QString &nick, const QString &channel)
-{
-  m_chatWindow->append (QString ("<i>%1 has joined %2.</i>").arg (nick).arg (channel));
-  scrollToBottom ();
-}
-
-void
-IRCWidget::handleUserQuit (const QString &nick, const QString &reason)
-{
-  m_chatWindow->append (QString ("<i>%1 has quit.(%2).</i>").arg (nick).arg (reason));
-  scrollToBottom ();
-}
-
-void
-IRCWidget::handleUserNicknameChanged (const QString &nick)
-{
-  m_nickButton->setText (nick);
-  QSettings *settings = ResourceManager::instance ()->settings ();
-  settings->setValue ("IRCNick", nick);
-  maybeIdentifyOnNickServ ();
-}
--- a/gui/src/qirc/IRCWidget.h	Sun Sep 25 21:12:47 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,101 +0,0 @@
-/* OctaveGUI - A graphical user interface for Octave
- * Copyright (C) 2011 Jacob Dawid (jacob.dawid@googlemail.com)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef IRCWIDGET_H
-#define IRCWIDGET_H
-
-#include <QWidget>
-#include <QPlainTextEdit>
-#include <QPushButton>
-#include <QLineEdit>
-#include <QCompleter>
-#include "IRCClientInterface.h"
-
-class ChatMessageTextEdit : public QPlainTextEdit
-{
-  Q_OBJECT
-public:
-  explicit ChatMessageTextEdit(QWidget *parent = 0);
-  ~ChatMessageTextEdit();
-
-  void setCompleter(QCompleter *m_completer);
-  QCompleter *completer() const;
-
-signals:
-  void sendMessage (const QString& message);
-
-protected:
-  void keyPressEvent(QKeyEvent *e);
-  void focusInEvent(QFocusEvent *e);
-
-private slots:
-  void insertCompletion(const QString &completion);
-
-private:
-  QString textUnderCursor() const;
-
-private:
-  QCompleter *m_completer;
-};
-
-class IRCWidget : public QWidget
-{
-Q_OBJECT public:
-  explicit IRCWidget (QWidget * parent);
-  void connectToServer ();
-
-public slots:
-  void showStatusMessage (const QString&);
-  void showErrorMessage (const QString&);
-  void showMessage (const QString& channel, const QString& sender, const QString& message);
-  void showNotification (const QString& sender, const QString& message);
-
-  void handleConnected (const QString& host);
-  void joinOctaveChannel (const QString& nick);
-
-  void handleLoggedIn (const QString& nick);
-  void handleNickChange (const QString& oldNick, const QString& newNick);
-  void handleUserJoined (const QString& nick, const QString& channel);
-  void handleUserQuit (const QString& nick, const QString& reason);
-  void handleUserNicknameChanged (const QString& nick);
-
-  void showChangeUserNickPopup ();
-  void sendMessage (QString);
-
-  void maybeIdentifyOnNickServ ();
-  void scrollToBottom ();
-
-signals:
-  void unreadMessages (bool yes);
-
-protected:
-  void focusInEvent (QFocusEvent *focusEvent);
-
-private:
-  IRCClientInterface *m_ircClientInterface;
-  IRCChannelProxyInterface *m_octaveChannel;
-  QTextEdit *m_chatWindow;
-  QPushButton *m_nickButton;
-  ChatMessageTextEdit *m_chatMessageTextEdit;
-
-  QString m_initialNick;
-  bool m_autoIdentification;
-  QString m_nickServPassword;
-  QString m_settingsFile;
-};
-
-#endif // IRCWIDGET_H
--- a/gui/src/qirc/Makefile.am	Sun Sep 25 21:12:47 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-####### kdevelop will overwrite this part!!! (begin)##########
-bin_PROGRAMS = qirc
-  qirc_SOURCES =
-  programcommand.cpp newtab.cpp MainTab.cpp notifyshowcase.cpp channellist.
-  cpp dccget.cpp dccsend.cpp IServerSocket.cpp general.cpp listanicks.
-  cpp qirc.cpp ventanas.cpp inputBox.cpp cuadroListaNicks.
-  cpp cuadroConfiguracion.cpp cuadroConectarCon.cpp colamensajes.
-  cpp IRCClient.cpp IClientSocket.cpp Config.cpp ChatView.cpp main.
-  cpp qirc_LDADD = -lqt - lXext - lX11 $ (LIBSOCKET) SUBDIRS =
-  docs EXTRA_DIST =
-  main.cpp qirc.h ChatView.cpp ChatView.h Config.cpp Config.h IClientSocket.
-  cpp IClientSocket.h IRCClient.cpp IRCClient.h IRCCodes.h colamensajes.
-  cpp colamensajes.h cuadroConectarCon.cpp cuadroConectarCon.
-  h cuadroConfiguracion.cpp cuadroConfiguracion.h cuadroListaNicks.
-  cpp cuadroListaNicks.h inputBox.cpp inputBox.h ventanas.cpp ventanas.h qirc.
-  cpp resource.h qirc16x16.xpm qirc32x32.xpm qirc64x64.xpm listanicks.
-  cpp listanicks.h general.h general.cpp IServerSocket.cpp IServerSocket.
-  h dccsend.cpp dccsend.h dccget.cpp dccget.h connect.xpm dccsend.xpm help.
-  xpm connectto.xpm disconnect.xpm join.xpm part.xpm list.xpm channellist.
-  cpp channellist.h notifyshowcase.cpp notifyshowcase.h offline.xpm online.
-  xpm operator.xpm justconn.xpm MainTab.cpp MainTab.h newtab.cpp newtab.
-  h leftArrowDisabled.xpm leftArrowEnabled.xpm rightArrowDisabled.
-  xpm rightArrowEnabled.xpm tabLeft.xpm tabMiddle.xpm tabRight.xpm tabClose.
-  xpm programcommand.cpp programcommand.h
-####### kdevelop will overwrite this part!!! (end)############
-#set the include path for X, qt and KDE
-  INCLUDES = $ (all_includes)
-#claim, which subdirectories you want to install
-#you can add here more. This one gets installed
-  bin_PROGRAMS = qirc qirc_METASOURCES = USE_AUTOMOC
-#the library search path.
-  qirc_LDFLAGS = $ (all_libraries)
-#them while "make clean", use CLEANFILES
-  DISTCLEANFILES = $ (qirc_METASOURCES)