summaryrefslogtreecommitdiff
authorwazlaf <wazlaf>2002-09-10 23:12:17 (UTC)
committer wazlaf <wazlaf>2002-09-10 23:12:17 (UTC)
commitd478be344e2ba383a1e38d2a1705de1cdbe2e838 (patch) (side-by-side diff)
tree9daf7b496c74c695ed8bd72a6ccd321f770b043c
parent2d6c8bd7290b766c31c100cd2d66ef0d1d0c407c (diff)
downloadopie-d478be344e2ba383a1e38d2a1705de1cdbe2e838.zip
opie-d478be344e2ba383a1e38d2a1705de1cdbe2e838.tar.gz
opie-d478be344e2ba383a1e38d2a1705de1cdbe2e838.tar.bz2
initial import of OpieIRC v0.1
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/net/opieirc/ircchannel.cpp43
-rw-r--r--noncore/net/opieirc/ircchannel.h68
-rw-r--r--noncore/net/opieirc/ircchannellist.cpp37
-rw-r--r--noncore/net/opieirc/ircchannellist.h36
-rw-r--r--noncore/net/opieirc/ircchanneltab.cpp77
-rw-r--r--noncore/net/opieirc/ircchanneltab.h60
-rw-r--r--noncore/net/opieirc/ircconnection.cpp94
-rw-r--r--noncore/net/opieirc/ircconnection.h65
-rw-r--r--noncore/net/opieirc/ircmessage.cpp120
-rw-r--r--noncore/net/opieirc/ircmessage.h68
-rw-r--r--noncore/net/opieirc/ircmessageparser.cpp478
-rw-r--r--noncore/net/opieirc/ircmessageparser.h95
-rw-r--r--noncore/net/opieirc/ircoutput.cpp22
-rw-r--r--noncore/net/opieirc/ircoutput.h70
-rw-r--r--noncore/net/opieirc/ircperson.cpp50
-rw-r--r--noncore/net/opieirc/ircperson.h50
-rw-r--r--noncore/net/opieirc/ircserver.cpp62
-rw-r--r--noncore/net/opieirc/ircserver.h58
-rw-r--r--noncore/net/opieirc/ircservereditor.cpp49
-rw-r--r--noncore/net/opieirc/ircservereditor.h43
-rw-r--r--noncore/net/opieirc/ircserverlist.cpp55
-rw-r--r--noncore/net/opieirc/ircserverlist.h46
-rw-r--r--noncore/net/opieirc/ircservertab.cpp147
-rw-r--r--noncore/net/opieirc/ircservertab.h60
-rw-r--r--noncore/net/opieirc/ircsession.cpp99
-rw-r--r--noncore/net/opieirc/ircsession.h73
-rw-r--r--noncore/net/opieirc/irctab.cpp19
-rw-r--r--noncore/net/opieirc/irctab.h47
-rw-r--r--noncore/net/opieirc/ircversion.h27
-rw-r--r--noncore/net/opieirc/main.cpp10
-rw-r--r--noncore/net/opieirc/mainwindow.cpp79
-rw-r--r--noncore/net/opieirc/mainwindow.h47
-rw-r--r--noncore/net/opieirc/opieirc.pro22
33 files changed, 2376 insertions, 0 deletions
diff --git a/noncore/net/opieirc/ircchannel.cpp b/noncore/net/opieirc/ircchannel.cpp
new file mode 100644
index 0000000..71ec03b
--- a/dev/null
+++ b/noncore/net/opieirc/ircchannel.cpp
@@ -0,0 +1,43 @@
+#include "ircchannel.h"
+#include <stdio.h>
+
+IRCChannel::IRCChannel(QString channelname) {
+ m_hasPeople = FALSE;
+ m_channelname = channelname;
+}
+
+QString IRCChannel::channelname() {
+ return m_channelname;
+}
+
+bool IRCChannel::hasPeople() {
+ return m_hasPeople;
+}
+
+void IRCChannel::setHasPeople(bool hasPeople) {
+ m_hasPeople = hasPeople;
+}
+
+void IRCChannel::addPerson(IRCChannelPerson *person) {
+ m_people.append(person);
+}
+
+void IRCChannel::removePerson(IRCChannelPerson *person) {
+ m_people.remove(person);
+}
+
+QListIterator<IRCChannelPerson> IRCChannel::people() {
+ QListIterator<IRCChannelPerson> it(m_people);
+ return it;
+}
+
+IRCChannelPerson *IRCChannel::getPerson(QString nickname) {
+ QListIterator<IRCChannelPerson> it(m_people);
+ for (; it.current(); ++it) {
+ if (it.current()->person->nick() == nickname) {
+ return it.current();
+ }
+ }
+ return 0;
+}
+
diff --git a/noncore/net/opieirc/ircchannel.h b/noncore/net/opieirc/ircchannel.h
new file mode 100644
index 0000000..c800b99
--- a/dev/null
+++ b/noncore/net/opieirc/ircchannel.h
@@ -0,0 +1,68 @@
+/*
+ OpieIRC - An embedded IRC client
+ Copyright (C) 2002 Wenzel Jakob
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+#ifndef __IRCCHANNEL_H
+#define __IRCCHANNEL_H
+
+#include <qobject.h>
+#include <qlist.h>
+#include <qstring.h>
+#include "ircperson.h"
+
+/* Flags which a person can have inside a channel */
+enum IRCChannelPersonFlag {
+ PERSON_FLAG_OP = 0x01,
+ PERSON_FLAG_VOICE = 0x02,
+ PERSON_FLAG_HALFOP = 0x04
+};
+
+/* This struct encapsulates a IRCPerson and adds
+ channel specific information */
+typedef struct IRCChannelPerson {
+ IRCPerson *person;
+ unsigned int flags;
+};
+
+/* IRCChannel is the object-oriented representation
+ of an IRC channel. It basically acts as a container
+ for IRCChannelPersons */
+class IRCChannel : public QObject {
+ Q_OBJECT
+public:
+ IRCChannel(QString channelname);
+
+ void addPerson(IRCChannelPerson *person);
+ void removePerson(IRCChannelPerson *person);
+ IRCChannelPerson *getPerson(QString nickname);
+ QListIterator<IRCChannelPerson> people();
+
+ /* hasPeople identifies whether the irc channel is
+ done synchronizing with the current state -
+ this is only relevant when joining a channel */
+ void setHasPeople(bool hasPeople);
+ QString channelname();
+ bool hasPeople();
+protected:
+ QList<IRCChannelPerson> m_people;
+ QString m_channelname;
+ bool m_hasPeople;
+};
+
+#endif /* __IRCCHANNEL_H */
diff --git a/noncore/net/opieirc/ircchannellist.cpp b/noncore/net/opieirc/ircchannellist.cpp
new file mode 100644
index 0000000..e592d05
--- a/dev/null
+++ b/noncore/net/opieirc/ircchannellist.cpp
@@ -0,0 +1,37 @@
+#include <qpe/resource.h>
+#include <qpixmap.h>
+#include "ircchannellist.h"
+
+IRCChannelList::IRCChannelList(IRCChannel *channel, QWidget *parent, const char *name, WFlags f) : QListBox(parent, name, f) {
+ m_channel = channel;
+}
+
+void IRCChannelList::update() {
+ QPixmap op = Resource::loadPixmap("opieirc/op");
+ QPixmap hop = Resource::loadPixmap("opieirc/hop");
+ QPixmap voice = Resource::loadPixmap("opieirc/voice");
+ QListIterator<IRCChannelPerson> it = m_channel->people();
+ clear();
+ for (; it.current(); ++it) {
+ IRCChannelPerson *person = it.current();
+ if (person->flags & PERSON_FLAG_OP) {
+ insertItem(op, person->person->nick());
+ } else if (person->flags & PERSON_FLAG_HALFOP) {
+ insertItem(op, person->person->nick());
+ } else if (person->flags & PERSON_FLAG_VOICE) {
+ insertItem(voice, person->person->nick());
+ } else {
+ insertItem(person->person->nick());
+ }
+ }
+ sort();
+}
+
+
+bool IRCChannelList::hasPerson(QString nick) {
+ for (unsigned int i=0; i<count(); i++) {
+ if (text(i) == nick)
+ return TRUE;
+ }
+ return FALSE;
+}
diff --git a/noncore/net/opieirc/ircchannellist.h b/noncore/net/opieirc/ircchannellist.h
new file mode 100644
index 0000000..fa3c8cd
--- a/dev/null
+++ b/noncore/net/opieirc/ircchannellist.h
@@ -0,0 +1,36 @@
+/*
+ OpieIRC - An embedded IRC client
+ Copyright (C) 2002 Wenzel Jakob
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+#ifndef __IRCCHANNELLIST_H
+#define __IRCCHANNELLIST_H
+
+#include <qlistbox.h>
+#include "ircchannel.h"
+
+class IRCChannelList : public QListBox {
+public:
+ IRCChannelList(IRCChannel *channel, QWidget *parent = 0, const char *name = 0, WFlags f = 0);
+ void update();
+ bool hasPerson(QString nick);
+protected:
+ IRCChannel *m_channel;
+};
+
+#endif /* __IRCCHANNELLIST_H */
diff --git a/noncore/net/opieirc/ircchanneltab.cpp b/noncore/net/opieirc/ircchanneltab.cpp
new file mode 100644
index 0000000..c96a365
--- a/dev/null
+++ b/noncore/net/opieirc/ircchanneltab.cpp
@@ -0,0 +1,77 @@
+#include <qhbox.h>
+#include "ircchanneltab.h"
+#include "ircservertab.h"
+
+IRCChannelTab::IRCChannelTab(IRCChannel *channel, IRCServerTab *parentTab, MainWindow *mainWindow, QWidget *parent, const char *name, WFlags f) : IRCTab(parent, name, f) {
+ m_mainWindow = mainWindow;
+ m_parentTab = parentTab;
+ m_channel = channel;
+ m_description->setText(tr("Talking on channel") + " <b>" + channel->channelname() + "</b>");
+ QHBox *hbox = new QHBox(this);
+ m_textview = new QTextView(hbox);
+ m_textview->setHScrollBarMode(QScrollView::AlwaysOff);
+ m_textview->setVScrollBarMode(QScrollView::AlwaysOn);
+ m_listVisible = TRUE;
+ m_listButton = new QPushButton(">", m_textview);
+ m_textview->setCornerWidget(m_listButton);
+ connect(m_listButton, SIGNAL(clicked()), this, SLOT(toggleList()));
+ m_list = new IRCChannelList(m_channel, hbox);
+ m_list->update();
+ m_list->setMaximumWidth(LISTWIDTH);
+ m_field = new QLineEdit(this);
+ m_layout->add(hbox);
+ hbox->show();
+ m_layout->add(m_field);
+ m_field->setFocus();
+ connect(m_field, SIGNAL(returnPressed()), this, SLOT(processCommand()));
+
+}
+
+void IRCChannelTab::appendText(QString text) {
+ /* not using append because it creates layout problems */
+ m_textview->setText(m_textview->text() + text);
+ m_textview->ensureVisible(0, m_textview->contentsHeight());
+}
+
+IRCChannelTab::~IRCChannelTab() {
+ m_parentTab->removeChannelTab(this);
+}
+
+void IRCChannelTab::processCommand() {
+ if (m_field->text().length()>0) {
+ session()->sendMessage(m_channel, m_field->text());
+ appendText("&lt;<font color=\"#dd0000\">"+m_parentTab->server()->nick()+"</font>&gt; "+m_field->text()+"<br>");
+ m_field->clear();
+ }
+}
+
+void IRCChannelTab::toggleList() {
+ if (m_listVisible) {
+ m_list->setMaximumWidth(0);
+ m_listButton->setText("<");
+ } else {
+ m_list->setMaximumWidth(LISTWIDTH);
+ m_listButton->setText(">");
+ }
+ m_listVisible = !m_listVisible;
+}
+
+QString IRCChannelTab::title() {
+ return m_channel->channelname();
+}
+
+IRCSession *IRCChannelTab::session() {
+ return m_parentTab->session();
+}
+
+void IRCChannelTab::remove() {
+ session()->part(m_channel);
+}
+
+IRCChannel *IRCChannelTab::channel() {
+ return m_channel;
+}
+
+IRCChannelList *IRCChannelTab::list() {
+ return m_list;
+}
diff --git a/noncore/net/opieirc/ircchanneltab.h b/noncore/net/opieirc/ircchanneltab.h
new file mode 100644
index 0000000..2127c4d
--- a/dev/null
+++ b/noncore/net/opieirc/ircchanneltab.h
@@ -0,0 +1,60 @@
+/*
+ OpieIRC - An embedded IRC client
+ Copyright (C) 2002 Wenzel Jakob
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+#ifndef __IRCCHANNELTAB_H
+#define __IRCCHANNELTAB_H
+
+#include <qpushbutton.h>
+#include "irctab.h"
+#include "ircsession.h"
+#include "mainwindow.h"
+#include "ircchannellist.h"
+
+#define LISTWIDTH 70
+
+class IRCServerTab;
+class IRCChannelTab : public IRCTab {
+ Q_OBJECT
+public:
+ /* IRCTab implementation */
+ IRCChannelTab(IRCChannel *channel, IRCServerTab *parentTab, MainWindow *mainWindow, QWidget *parent = 0, const char *name = 0, WFlags f = 0);
+ ~IRCChannelTab();
+ QString title();
+ IRCSession *session();
+ IRCChannel *channel();
+ IRCChannelList *list();
+public:
+ void appendText(QString text);
+public slots:
+ void remove();
+ void processCommand();
+ void toggleList();
+protected:
+ IRCServerTab *m_parentTab;
+ IRCChannel *m_channel;
+ IRCChannelList *m_list;
+ QPushButton *m_listButton;
+ MainWindow *m_mainWindow;
+ QTextView *m_textview;
+ QLineEdit *m_field;
+ bool m_listVisible;
+};
+
+#endif /* __IRCCHANNELTAB_H */
diff --git a/noncore/net/opieirc/ircconnection.cpp b/noncore/net/opieirc/ircconnection.cpp
new file mode 100644
index 0000000..02c4897
--- a/dev/null
+++ b/noncore/net/opieirc/ircconnection.cpp
@@ -0,0 +1,94 @@
+#include <unistd.h>
+#include <string.h>
+#include "ircconnection.h"
+
+IRCConnection::IRCConnection(IRCServer *server) {
+ m_server = server;
+ m_socket = new QSocket(this);
+ m_connected = FALSE;
+ m_loggedIn = FALSE;
+ connect(m_socket, SIGNAL(connected()), this, SLOT(login()));
+ connect(m_socket, SIGNAL(readyRead()), this, SLOT(dataReady()));
+ connect(m_socket, SIGNAL(error(int)), this, SLOT(error(int)));
+ connect(m_socket, SIGNAL(connectionClosed()), this, SLOT(disconnect()));
+ connect(m_socket, SIGNAL(delayedCloseFinished()), this, SLOT(disconnect()));
+}
+
+/* Connect to the IRC server */
+void IRCConnection::doConnect() {
+ ASSERT(!m_connected);
+ m_socket->connectToHost(m_server->hostname(), m_server->port());
+}
+
+/* Send commands to the IRC server */
+void IRCConnection::sendLine(QString line) {
+ while((line.right(1) == "\n") || (line.right(1) == "\r"))
+ line = line.left(line.length() - 1);
+ line.append("\r\n");
+ m_socket->writeBlock(line, line.length());
+}
+
+void IRCConnection::sendCTCP(QString nick, QString line) {
+ sendLine("NOTICE " + nick + " :\001"+line+"\001");
+}
+
+/*
+ * login() is called right after the connection
+ * to the IRC server has been established
+ */
+void IRCConnection::login() {
+ char hostname[256];
+ QString loginString;
+
+ emit outputReady(IRCOutput(OUTPUT_CLIENTMESSAGE, tr("Connected, logging in ..")));
+ m_connected = TRUE;
+ gethostname(hostname, sizeof(hostname)-1);
+ hostname[sizeof (hostname) - 1] = 0;
+
+ /* Create a logon string and send it */
+ if (m_server->password().length()>0) {
+ loginString += "PASS " + m_server->password() + "\r\n";
+ }
+ loginString += "NICK " + m_server->nick() + "\r\n" +
+ "USER " + m_server->username() + " " + hostname +
+ " " + m_server->hostname() + " :" + m_server->realname() + "\r\n";
+ sendLine(loginString);
+}
+
+/* Called when data arrives on the socket */
+void IRCConnection::dataReady() {
+ while(m_socket->canReadLine()) {
+ IRCMessage message(m_socket->readLine());
+ if (!m_loggedIn && message.isNumerical() && message.commandNumber() == 1) {
+ m_loggedIn = TRUE;
+ emit outputReady(IRCOutput(OUTPUT_CLIENTMESSAGE, tr("Successfully logged in.")));
+ }
+ emit messageArrived(&message);
+ }
+}
+
+/* Called if any type of socket error occurs */
+void IRCConnection::error(int num) {
+ emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Socket error : ") + strerror(num)));
+}
+
+void IRCConnection::disconnect() {
+ m_connected = FALSE;
+ m_loggedIn = FALSE;
+ emit outputReady(IRCOutput(OUTPUT_CONNCLOSE, tr("Connection closed")));
+}
+
+bool IRCConnection::isConnected() {
+ return m_connected;
+}
+
+bool IRCConnection::isLoggedIn() {
+ return m_loggedIn;
+}
+
+void IRCConnection::close() {
+ m_socket->close();
+ if (m_socket->state()==QSocket::Idle) {
+ disconnect();
+ }
+}
diff --git a/noncore/net/opieirc/ircconnection.h b/noncore/net/opieirc/ircconnection.h
new file mode 100644
index 0000000..75cdf6d
--- a/dev/null
+++ b/noncore/net/opieirc/ircconnection.h
@@ -0,0 +1,65 @@
+/*
+ OpieIRC - An embedded IRC client
+ Copyright (C) 2002 Wenzel Jakob
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+#ifndef __IRCCONNECTION_H
+#define __IRCCONNECTION_H
+
+#include <qsocket.h>
+#include "ircserver.h"
+#include "ircmessage.h"
+#include "ircoutput.h"
+
+/* IRCConnection acts as a wrapper around QSocket
+ and is responsible for the communication with the
+ IRC server */
+class IRCConnection : public QObject {
+ Q_OBJECT
+public:
+ IRCConnection(IRCServer *server);
+ void doConnect();
+ /* used to send commands to the IRC server */
+ void sendLine(QString line);
+ /* used to send CTCP commands to the IRC server */
+ void sendCTCP(QString nick, QString line);
+ void close();
+ bool isConnected();
+ bool isLoggedIn();
+signals:
+ /* triggered when the server sent us a message */
+ void messageArrived(IRCMessage *message);
+ /* Used to send commands to the UI (such as displaying text etc) */
+ void outputReady(IRCOutput output);
+protected slots:
+ /* automatically executed after the connection is established */
+ void login();
+ /* called when there are socket errors */
+ void error(int num);
+ /* called when data arrived on m_socket (triggers messageArrived) */
+ void dataReady();
+ /* called when the IRC server closes the connection */
+ void disconnect();
+protected:
+ IRCServer *m_server;
+ QSocket *m_socket;
+ bool m_connected;
+ bool m_loggedIn;
+};
+
+#endif /* __IRCCONNECTION_H */
diff --git a/noncore/net/opieirc/ircmessage.cpp b/noncore/net/opieirc/ircmessage.cpp
new file mode 100644
index 0000000..74e9c6f
--- a/dev/null
+++ b/noncore/net/opieirc/ircmessage.cpp
@@ -0,0 +1,120 @@
+#include <qtextstream.h>
+#include "ircmessage.h"
+
+/*
+ * Create a new IRCMessage by evaluating
+ * a received string
+ */
+
+IRCMessage::IRCMessage(QString line) {
+ /* Remove CRs from the message */
+ while((line.right(1) == "\n") || (line.right(1) == "\r"))
+ line = line.left(line.length() - 1);
+ QTextIStream stream(&line);
+ QString temp;
+
+ stream >> temp;
+ if (temp.startsWith(":")) {
+ /* extract the prefix */
+ m_prefix = temp.right(temp.length()-1);
+ stream >> temp;
+ m_command = temp.upper();
+ m_allParameters = line.right(line.length() - m_prefix.length() - m_command.length() - 3);
+ } else {
+ m_command = temp.upper();
+ m_allParameters = line.right(line.length() - m_command.length() - 1);
+ }
+ /* Create a list of all parameters */
+ while(!(stream.atEnd())) {
+ stream >> temp;
+ if (temp.startsWith(":")) {
+ /* last parameter */
+ m_trailing = line.right(line.length() - line.find(QChar(':'), 1) - 1);
+ m_parameters << m_trailing;
+ break;
+ } else {
+ m_parameters << temp;
+ }
+ }
+ m_commandNumber = m_command.toInt(&m_isNumerical);
+ /* Is this a CTCP command */
+ if ((m_command == "PRIVMSG" || m_command == "NOTICE") && m_trailing.length()>0 && m_trailing.left(1) == QChar(1)) {
+ m_ctcp = TRUE;
+ /* Strip CTCP \001 characters */
+ m_allParameters = m_allParameters.replace(QRegExp(QChar(1)), "");
+ QTextIStream ctcpStream(&m_allParameters);
+ if (m_command == "PRIVMSG")
+ ctcpStream >> m_ctcpDestination;
+ ctcpStream >> temp;
+ m_ctcpCommand = temp.upper().right(temp.length()-1);
+ m_parameters.clear();
+ int length = m_allParameters.length() - m_ctcpCommand.length() - 1;
+ if (m_command == "PRIVMSG")
+ length -= m_ctcpDestination.length() + 1;
+ if (length <= 0) {
+ m_allParameters = "";
+ } else {
+ m_allParameters = m_allParameters.right(length);
+ m_parameters << m_allParameters;
+ }
+ } else {
+ m_ctcp = FALSE;
+ }
+
+ /*
+ -- Uncomment to debug --
+
+ printf("Parsed : '%s'\n", line.ascii());
+ printf("Prefix : '%s'\n", m_prefix.ascii());
+ printf("Command : '%s'\n", m_command.ascii());
+ printf("Allparameters : '%s'\n", m_allParameters.ascii());
+ for (unsigned int i=0; i<m_parameters.count(); i++) {
+ printf("Parameter %i : '%s'\n", i, m_parameters[i].ascii());
+ }
+ printf("CTCP Command : '%s'\n", m_ctcpCommand.latin1());
+ printf("CTCP Destination : '%s'\n", m_ctcpDestination.latin1());
+ printf("CTCP param count is : '%i'\n", m_parameters.count());
+
+ */
+}
+
+QString IRCMessage::param(int param) {
+ return m_parameters[param];
+}
+
+QString IRCMessage::prefix() {
+ return m_prefix;
+}
+
+QString IRCMessage::command() {
+ return m_command;
+}
+
+QString IRCMessage::ctcpCommand() {
+ return m_ctcpCommand;
+}
+
+QString IRCMessage::ctcpDestination() {
+ return m_ctcpDestination;
+}
+
+unsigned short IRCMessage::commandNumber() {
+ return m_commandNumber;
+}
+
+bool IRCMessage::isNumerical() {
+ return m_isNumerical;
+}
+
+bool IRCMessage::isCTCP() {
+ return m_ctcp;
+}
+
+QString IRCMessage::trailing() {
+ return m_trailing;
+}
+
+QString IRCMessage::allParameters() {
+ return m_allParameters;
+}
+
diff --git a/noncore/net/opieirc/ircmessage.h b/noncore/net/opieirc/ircmessage.h
new file mode 100644
index 0000000..0c5c879
--- a/dev/null
+++ b/noncore/net/opieirc/ircmessage.h
@@ -0,0 +1,68 @@
+/*
+ OpieIRC - An embedded IRC client
+ Copyright (C) 2002 Wenzel Jakob
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+#ifndef __IRCMESSAGE_H
+#define __IRCMESSAGE_H
+
+#include <qstring.h>
+#include <qstringlist.h>
+
+/* IRCMessage objects are used to encapsulate information
+ which the IRC server sent to us. */
+
+class IRCMessage {
+public:
+ /* Parse an IRC message and create the IRCMessage object */
+ IRCMessage(QString line);
+
+ /* Return the IRC message prefix (usually sender etc) */
+ QString prefix();
+ /* Check if this IRCMessage's command is literal or numerical */
+ bool isNumerical();
+ /* CHeck if this IRCMessage is a CTCP message */
+ bool isCTCP();
+ /* Return the IRC command (literal commands) */
+ QString command();
+ /* Return the CTCP command */
+ QString ctcpCommand();
+ /* Return the CTCP destination if applicable (channel/person) */
+ QString ctcpDestination();
+ /* Return the IRC command (numerical commands) */
+ unsigned short commandNumber();
+ /* Return the trailing parameter string */
+ QString trailing();
+ /* Return the complete parameter string */
+ QString allParameters();
+ /* Return one parameter */
+ QString param(int param);
+protected:
+ QString m_prefix;
+ QString m_command;
+ QString m_ctcpCommand;
+ QString m_ctcpDestination;
+ unsigned short m_commandNumber;
+ QString m_allParameters;
+ QString m_trailing;
+ QStringList m_parameters;
+ bool m_isNumerical;
+ bool m_ctcp;
+};
+
+#endif
diff --git a/noncore/net/opieirc/ircmessageparser.cpp b/noncore/net/opieirc/ircmessageparser.cpp
new file mode 100644
index 0000000..a2be5a4
--- a/dev/null
+++ b/noncore/net/opieirc/ircmessageparser.cpp
@@ -0,0 +1,478 @@
+#include <qtextstream.h>
+#include "ircmessageparser.h"
+#include "ircversion.h"
+#include <stdio.h>
+
+/* Lookup table for literal commands */
+IRCLiteralMessageParserStruct IRCMessageParser::literalParserProcTable[] = {
+ { "PING", FUNC(parseLiteralPing) },
+ { "NOTICE", FUNC(parseLiteralNotice) },
+ { "JOIN", FUNC(parseLiteralJoin) },
+ { "PRIVMSG", FUNC(parseLiteralPrivMsg) },
+ { "NICK", FUNC(parseLiteralNick) },
+ { "PART", FUNC(parseLiteralPart) },
+ { "QUIT", FUNC(parseLiteralQuit) },
+ { "ERROR", FUNC(parseLiteralError) },
+ { "ERROR:", FUNC(parseLiteralError) },
+ { "MODE", FUNC(parseLiteralMode) },
+ { "KICK", FUNC(parseLiteralKick) },
+ { 0 , 0 }
+};
+
+/* Lookup table for literal commands */
+IRCCTCPMessageParserStruct IRCMessageParser::ctcpParserProcTable[] = {
+ { "PING", FUNC(parseCTCPPing) },
+ { "VERSION", FUNC(parseCTCPVersion) },
+ { "ACTION", FUNC(parseCTCPAction) },
+ { 0 , 0 }
+};
+/* Lookup table for numerical commands */
+IRCNumericalMessageParserStruct IRCMessageParser::numericalParserProcTable[] = {
+ { 1, FUNC(parseNumerical001) }, // RPL_WELCOME
+ { 2, FUNC(parseNumerical002) }, // RPL_YOURHOST
+ { 3, FUNC(parseNumerical003) }, // RPL_CREATED
+ { 4, FUNC(parseNumerical004) }, // RPL_MYINFO
+ { 5, FUNC(parseNumerical005) }, // RPL_BOUNCE, RPL_PROTOCTL
+ { 251, FUNC(parseNumericalStats) }, // RPL_LUSERCLIENT
+ { 254, FUNC(nullFunc)}, // RPL_LUSERCHANNELS
+ { 255, FUNC(parseNumericalStats) }, // RPL_LUSERNAME
+ { 353, FUNC(parseNumericalNames) }, // RPL_NAMREPLY
+ { 366, FUNC(parseNumericalEndOfNames) }, // RPL_ENDOFNAMES
+ { 375, FUNC(parseNumericalStats) }, // RPL_MOTDSTART
+ { 372, FUNC(parseNumericalStats) }, // RPL_MOTD
+ { 376, FUNC(parseNumericalStats) }, // RPL_ENDOFMOTD
+ { 377, FUNC(parseNumericalStats) }, // RPL_MOTD2
+ { 378, FUNC(parseNumericalStats) }, // RPL_MOTD3
+ { 412, FUNC(parseNumericalStats) }, // ERNOTEXTTOSEND
+ { 433, FUNC(parseNumericalNicknameInUse) }, // ERR_NICKNAMEINUSE
+ { 0, 0 }
+};
+
+IRCMessageParser::IRCMessageParser(IRCSession *session) {
+ m_session = session;
+}
+
+void IRCMessageParser::parse(IRCMessage *message) {
+ /* Find out what kind of message we have here and call the appropriate handler using
+ the parser tables. If no handler can be found, print out an error message */
+ if (message->isNumerical()) {
+ for (int i=0; i<numericalParserProcTable[i].commandNumber; i++) {
+ if (message->commandNumber() == numericalParserProcTable[i].commandNumber) {
+ (this->*(numericalParserProcTable[i].proc))(message);
+ return;
+ }
+ }
+ emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Received unhandled numeric command : ")+QString::number(message->commandNumber())));
+ } else if (message->isCTCP()) {
+ for (int i=0; ctcpParserProcTable[i].commandName; i++) {
+ if (message->ctcpCommand() == ctcpParserProcTable[i].commandName) {
+ (this->*(ctcpParserProcTable[i].proc))(message);
+ return;
+ }
+ }
+ emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Received unhandled ctcp command : ")+message->ctcpCommand()));
+ } else {
+ for (int i=0; literalParserProcTable[i].commandName; i++) {
+ if (message->command() == literalParserProcTable[i].commandName) {
+ (this->*(literalParserProcTable[i].proc))(message);
+ return;
+ }
+ }
+ emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Received unhandled literal command : ")+message->command()));
+ }
+}
+
+void IRCMessageParser::nullFunc(IRCMessage *) {
+ /* Do nothing */
+}
+
+void IRCMessageParser::parseLiteralPing(IRCMessage *message) {
+ m_session->m_connection->sendLine("PONG " + message->allParameters());
+}
+
+void IRCMessageParser::parseLiteralNotice(IRCMessage *message) {
+ emit outputReady(IRCOutput(OUTPUT_SERVERMESSAGE, message->allParameters()));
+}
+
+void IRCMessageParser::parseLiteralJoin(IRCMessage *message) {
+ QString channelName = message->param(0);
+ IRCPerson mask(message->prefix());
+ IRCChannel *channel = m_session->getChannel(channelName);
+ if (!channel) {
+ /* We joined */
+ if (mask.nick() == m_session->m_server->nick()) {
+ channel = new IRCChannel(channelName);
+ m_session->addChannel(channel);
+ } else {
+ emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Nonexistant channel join - desynchronized?")));
+ }
+ } else {
+ /* Someone else joined */
+ if (mask.nick() != m_session->m_server->nick()) {
+ if (!channel->getPerson(mask.nick())) {
+ IRCChannelPerson *chanperson = new IRCChannelPerson();
+ IRCPerson *person = m_session->getPerson(mask.nick());
+ if (!person) {
+ person = new IRCPerson(message->prefix());
+ m_session->addPerson(person);
+ }
+ chanperson->flags = 0;
+ chanperson->person = person;
+ channel->addPerson(chanperson);
+ IRCOutput output(OUTPUT_OTHERJOIN, mask.nick() + tr(" joined channel ") + channelName);
+ output.addParam(channel);
+ output.addParam(chanperson);
+ emit outputReady(output);
+ } else {
+ emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Person has already joined the channel - desynchronized?")));
+ }
+ } else {
+ emit outputReady(IRCOutput(OUTPUT_ERROR, tr("You already joined the channel - desynchronized?")));
+ }
+ }
+}
+
+void IRCMessageParser::parseLiteralPart(IRCMessage *message) {
+ QString channelName = message->param(0);
+ IRCChannel *channel = m_session->getChannel(channelName);
+ IRCPerson mask(message->prefix());
+ if (channel) {
+ if (mask.nick() == m_session->m_server->nick()) {
+ m_session->removeChannel(channel);
+ IRCOutput output(OUTPUT_SELFPART, tr("You left channel ") + channelName);
+ output.addParam(channel);
+ emit outputReady(output);
+ delete channel;
+ } else {
+ IRCChannelPerson *person = channel->getPerson(mask.nick());
+ if (person) {
+ channel->removePerson(person);
+ IRCOutput output(OUTPUT_OTHERPART, mask.nick() + tr(" left channel ") + channelName);
+ output.addParam(channel);
+ output.addParam(person);
+ emit outputReady(output);
+ delete person;
+ } else {
+ emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Parting person not found - desynchronized?")));
+ }
+ }
+ } else {
+ emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Channel for part not found - desynchronized?")));
+ }
+}
+
+void IRCMessageParser::parseLiteralPrivMsg(IRCMessage *message) {
+ if (m_session->m_server->nick() == message->param(0)) {
+ /* IRC Query message detected, verify sender and display it */
+ IRCPerson mask(message->prefix());
+ IRCPerson *person = m_session->getPerson(mask.nick());
+ if (!person) {
+ /* Person not yet known, create and add to the current session */
+ person = new IRCPerson(message->prefix());
+ m_session->addPerson(person);
+ }
+ IRCOutput output(OUTPUT_CHANPRIVMSG, message->param(1));
+ output.addParam(person);
+ emit outputReady(output);
+ } else if (message->param(0).at(0) == '#') {
+ /* IRC Channel message detected, verify sender, channel and display it */
+ IRCChannel *channel = m_session->getChannel(message->param(0));
+ if (channel) {
+ IRCPerson mask(message->prefix());
+ IRCChannelPerson *person = channel->getPerson(mask.nick());
+ if (person) {
+ IRCOutput output(OUTPUT_CHANPRIVMSG, message->param(1));
+ output.addParam(channel);
+ output.addParam(person);
+ emit outputReady(output);
+ } else {
+ emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Channel message with unknown sender")));
+ }
+ } else {
+ emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Channel message with unknown channel")));
+ }
+ } else {
+ emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Received PRIVMSG of unknown type")));
+ }
+}
+
+void IRCMessageParser::parseLiteralNick(IRCMessage *message) {
+ IRCPerson mask(message->prefix());
+
+ if (mask.nick() == m_session->m_server->nick()) {
+ /* We are changing our nickname */
+ m_session->m_server->setNick(message->param(0));
+ IRCOutput output(OUTPUT_NICKCHANGE, tr("You are now known as ")+message->param(0));
+ output.addParam(0);
+ emit outputReady(output);
+ } else {
+ /* Someone else is */
+ IRCPerson *person = m_session->getPerson(mask.nick());
+ if (person) {
+ IRCOutput output(OUTPUT_NICKCHANGE, mask.nick() + tr(" is now known as ") + message->param(0));
+ output.addParam(person);
+ emit outputReady(output);
+ } else {
+ emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Nickname change of an unknown person")));
+ }
+ }
+}
+
+void IRCMessageParser::parseLiteralQuit(IRCMessage *message) {
+ IRCPerson mask(message->prefix());
+ IRCPerson *person = m_session->getPerson(mask.nick());
+ if (person) {
+ QList<IRCChannel> channels;
+ m_session->getChannelsByPerson(person, channels);
+ QListIterator<IRCChannel> it(channels);
+ for (;it.current(); ++it) {
+ IRCChannelPerson *chanperson = it.current()->getPerson(mask.nick());
+ it.current()->removePerson(chanperson);
+ }
+ m_session->removePerson(person);
+ IRCOutput output(OUTPUT_QUIT, mask.nick() + tr(" has quit ") + "(" + message->param(0) + ")");
+ output.addParam(person);
+ emit outputReady(output);
+ } else {
+ emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Unknown person quit - desynchronized?")));
+ }
+}
+
+void IRCMessageParser::parseLiteralError(IRCMessage *message) {
+ emit outputReady(IRCOutput(OUTPUT_ERROR, message->allParameters()));
+}
+
+void IRCMessageParser::parseCTCPPing(IRCMessage *message) {
+ IRCPerson mask(message->prefix());
+ m_session->m_connection->sendCTCP(mask.nick(), "PING " + message->allParameters());
+ emit outputReady(IRCOutput(OUTPUT_CTCP, tr("Received a CTCP PING from ")+mask.nick()));
+}
+
+void IRCMessageParser::parseCTCPVersion(IRCMessage *message) {
+ IRCPerson mask(message->prefix());
+ m_session->m_connection->sendCTCP(mask.nick(), APP_VERSION " " APP_COPYSTR);
+ emit outputReady(IRCOutput(OUTPUT_CTCP, tr("Received a CTCP VERSION from ")+mask.nick()));
+}
+
+void IRCMessageParser::parseCTCPAction(IRCMessage *message) {
+ IRCPerson mask(message->prefix());
+ QString dest = message->ctcpDestination();
+ if (dest.startsWith("#")) {
+ IRCChannel *channel = m_session->getChannel(dest);
+ if (channel) {
+ IRCChannelPerson *person = channel->getPerson(mask.nick());
+ if (person) {
+ IRCOutput output(OUTPUT_CHANACTION, "*" + mask.nick() + message->param(0));
+ output.addParam(channel);
+ output.addParam(person);
+ emit outputReady(output);
+ } else {
+ emit outputReady(IRCOutput(OUTPUT_ERROR, tr("CTCP ACTION with unknown person - Desynchronized?")));
+ }
+ } else {
+ emit outputReady(IRCOutput(OUTPUT_ERROR, tr("CTCP ACTION with unknown channel - Desynchronized?")));
+ }
+ } else {
+ if (message->ctcpDestination() == m_session->m_server->nick()) {
+ IRCPerson *person = m_session->getPerson(mask.nick());
+ if (!person) {
+ /* Person not yet known, create and add to the current session */
+ person = new IRCPerson(message->prefix());
+ m_session->addPerson(person);
+ }
+ IRCOutput output(OUTPUT_QUERYACTION, "*" + mask.nick() + message->param(0));
+ output.addParam(person);
+ emit outputReady(output);
+ } else {
+ emit outputReady(IRCOutput(OUTPUT_ERROR, tr("CTCP ACTION with bad recipient")));
+ }
+ }
+}
+
+void IRCMessageParser::parseLiteralMode(IRCMessage *message) {
+ IRCPerson mask(message->prefix());
+
+ if (message->param(0).startsWith("#")) {
+ IRCChannel *channel = m_session->getChannel(message->param(0));
+ if (channel) {
+ QString temp, parameters = message->allParameters().right(message->allParameters().length() - channel->channelname().length() - 1);
+ QTextIStream stream(&parameters);
+ bool set = FALSE;
+ while (!stream.atEnd()) {
+ stream >> temp;
+ if (temp.startsWith("+")) {
+ set = TRUE;
+ temp = temp.right(1);
+ } else if (temp.startsWith("-")) {
+ set = FALSE;
+ temp = temp.right(1);
+ } else {
+ emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Mode change has unknown type")));
+ return;
+ }
+ if (temp == "o") {
+ stream >> temp;
+ IRCChannelPerson *person = channel->getPerson(temp);
+ if (person) {
+ if (set) {
+ person->flags |= PERSON_FLAG_OP;
+ IRCOutput output(OUTPUT_CHANPERSONMODE, mask.nick() + tr(" gives channel operator status to " + person->person->nick()));
+ output.addParam(channel);
+ output.addParam(person);
+ emit outputReady(output);
+ } else {
+ person->flags &= 0xFFFF - PERSON_FLAG_OP;
+ IRCOutput output(OUTPUT_CHANPERSONMODE, mask.nick() + tr(" removes channel operator status from " + person->person->nick()));
+ output.addParam(channel);
+ output.addParam(person);
+ emit outputReady(output);
+ }
+ } else {
+ emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Mode change with unknown person - Desynchronized?")));
+ }
+ } else if (temp == "v") {
+ stream >> temp;
+ IRCChannelPerson *person = channel->getPerson(temp);
+ if (person) {
+ if (set) {
+ person->flags |= PERSON_FLAG_VOICE;
+ IRCOutput output(OUTPUT_CHANPERSONMODE, mask.nick() + tr(" gives voice to " + person->person->nick()));
+ output.addParam(channel);
+ output.addParam(person);
+ emit outputReady(output);
+ } else {
+ person->flags &= 0xFFFF - PERSON_FLAG_VOICE;
+ IRCOutput output(OUTPUT_CHANPERSONMODE, mask.nick() + tr(" removes voice from " + person->person->nick()));
+ output.addParam(channel);
+ output.addParam(person);
+ emit outputReady(output);
+ }
+ } else {
+ emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Mode change with unknown person - Desynchronized?")));
+ }
+ } else {
+ emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Mode change with unknown flag")));
+ }
+ }
+ } else {
+ emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Mode change with unknown kannel - Desynchronized?")));
+ }
+ } else {
+ emit outputReady(IRCOutput(OUTPUT_ERROR, tr("User modes not supported yet")));
+ }
+}
+
+void IRCMessageParser::parseLiteralKick(IRCMessage *message) {
+ IRCPerson mask(message->prefix());
+ IRCChannel *channel = m_session->getChannel(message->param(0));
+ if (channel) {
+ IRCChannelPerson *person = channel->getPerson(message->param(1));
+ if (person) {
+ if (person->person->nick() == m_session->m_server->nick()) {
+ m_session->removeChannel(channel);
+ IRCOutput output(OUTPUT_SELFKICK, tr("You were kicked from ") + channel->channelname() + tr(" by ") + mask.nick() + " (" + message->param(2) + ")");
+ output.addParam(channel);
+ emit outputReady(output);
+ } else {
+ channel->removePerson(person);
+ IRCOutput output(OUTPUT_OTHERKICK, person->person->nick() + tr(" was kicked from ") + channel->channelname() + tr(" by ") + mask.nick()+ " (" + message->param(2) + ")");
+ output.addParam(channel);
+ output.addParam(person);
+ emit outputReady(output);
+ }
+ } else {
+ emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Unknown person kick - desynchronized?")));
+ }
+ } else {
+ emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Unknown channel kick - desynchronized?")));
+ }
+}
+
+void IRCMessageParser::parseNumerical001(IRCMessage *message) {
+ /* Welcome to IRC message, display */
+ emit outputReady(IRCOutput(OUTPUT_SERVERMESSAGE, message->param(1)));
+}
+
+void IRCMessageParser::parseNumerical002(IRCMessage *message) {
+ emit outputReady(IRCOutput(OUTPUT_SERVERMESSAGE, message->param(1)));
+}
+
+void IRCMessageParser::parseNumerical003(IRCMessage *message) {
+ emit outputReady(IRCOutput(OUTPUT_SERVERMESSAGE, message->param(1)));
+}
+
+void IRCMessageParser::parseNumerical004(IRCMessage *message) {
+ emit outputReady(IRCOutput(OUTPUT_SERVERMESSAGE, message->allParameters()));
+}
+
+void IRCMessageParser::parseNumerical005(IRCMessage *message) {
+ emit outputReady(IRCOutput(OUTPUT_SERVERMESSAGE, message->allParameters()));
+}
+
+void IRCMessageParser::parseNumericalStats(IRCMessage *message) {
+ emit outputReady(IRCOutput(OUTPUT_SERVERMESSAGE, message->param(1)));
+}
+
+void IRCMessageParser::parseNumericalNames(IRCMessage *message) {
+ /* Name list sent when joining a channel */
+ IRCChannel *channel = m_session->getChannel(message->param(2));
+ if (channel != 0) {
+ QString people = message->param(3);
+ QTextIStream stream(&people);
+ QString temp;
+
+ while (!stream.atEnd()) {
+ stream >> temp;
+
+ char flagch = temp.at(0).latin1();
+ int flag = 0;
+ QString nick;
+ /* Parse person flags */
+ if (flagch == '@' || flagch == '+' || flagch=='%' || flagch == '*') {
+
+ nick = temp.right(temp.length()-1);
+ switch (flagch) {
+ case '@': flag = PERSON_FLAG_OP; break;
+ case '+': flag = PERSON_FLAG_VOICE; break;
+ case '%': flag = PERSON_FLAG_HALFOP; break;
+ default : flag = 0; break;
+ }
+ } else {
+ nick = temp;
+ }
+
+ IRCChannelPerson *chan_person = new IRCChannelPerson();
+ IRCPerson *person = m_session->getPerson(nick);
+ if (person == 0) {
+ person = new IRCPerson();
+ person->setNick(nick);
+ m_session->addPerson(person);
+ }
+ chan_person->person = person;
+ chan_person->flags = flag;
+ channel->addPerson(chan_person);
+ }
+ } else {
+ emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Server message with unknown channel")));
+ }
+}
+
+void IRCMessageParser::parseNumericalEndOfNames(IRCMessage *message) {
+ /* Done syncing to channel */
+ IRCChannel *channel = m_session->getChannel(message->param(1));
+ if (channel) {
+ channel->setHasPeople(TRUE);
+ /* Yes, we want the names before anything happens inside the GUI */
+ IRCOutput output(OUTPUT_SELFJOIN, tr("You joined channel ") + channel->channelname());
+ output.addParam(channel);
+ emit outputReady(output);
+ } else {
+ emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Server message with unknown channel")));
+ }
+}
+
+
+void IRCMessageParser::parseNumericalNicknameInUse(IRCMessage *) {
+ emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Nickname is in use, please reconnect with a different nickname")));
+ m_session->endSession();
+}
diff --git a/noncore/net/opieirc/ircmessageparser.h b/noncore/net/opieirc/ircmessageparser.h
new file mode 100644
index 0000000..b45b8f0
--- a/dev/null
+++ b/noncore/net/opieirc/ircmessageparser.h
@@ -0,0 +1,95 @@
+/*
+ OpieIRC - An embedded IRC client
+ Copyright (C) 2002 Wenzel Jakob
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+#ifndef __IRCMESSAGEPARSER_H
+#define __IRCMESSAGEPARSER_H
+
+#include "ircsession.h"
+
+/* Macro to facilitate the parser table's creation */
+#define FUNC(__proc) &IRCMessageParser::__proc
+
+class IRCMessageParser;
+
+/* Typedef representing a parser function */
+typedef void (IRCMessageParser::*IRCMessageParseProc)(IRCMessage *);
+
+/* Struct representing a literal command handler */
+typedef struct IRCLiteralMessageParserStruct {
+ char *commandName;
+ IRCMessageParseProc proc;
+};
+
+/* Struct representing a ctcp command handler */
+typedef struct IRCCTCPMessageParserStruct {
+ char *commandName;
+ IRCMessageParseProc proc;
+};
+
+/* Struct representing a numerical command handler */
+typedef struct IRCNumericalMessageParserStruct {
+ unsigned short commandNumber;
+ IRCMessageParseProc proc;
+};
+
+class IRCMessageParser : public QObject {
+ Q_OBJECT
+public:
+ /* Create an IRCMessageParser object */
+ IRCMessageParser(IRCSession *session);
+ /* Parse a server message and take the appropriate actions */
+ void parse(IRCMessage *message);
+signals:
+ /* Used to send commands to the UI (such as displaying text etc) */
+ void outputReady(IRCOutput output);
+private:
+ /* Parser functions */
+ void nullFunc(IRCMessage *message);
+ void parseLiteralPing(IRCMessage *message);
+ void parseLiteralNotice(IRCMessage *message);
+ void parseLiteralJoin(IRCMessage *message);
+ void parseLiteralPrivMsg(IRCMessage *message);
+ void parseLiteralNick(IRCMessage *message);
+ void parseLiteralPart(IRCMessage *message);
+ void parseLiteralQuit(IRCMessage *message);
+ void parseLiteralError(IRCMessage *message);
+ void parseLiteralMode(IRCMessage *message);
+ void parseLiteralKick(IRCMessage *message);
+ void parseNumerical001(IRCMessage *message);
+ void parseNumerical002(IRCMessage *message);
+ void parseNumerical003(IRCMessage *message);
+ void parseNumerical004(IRCMessage *message);
+ void parseNumerical005(IRCMessage *message);
+ void parseNumericalStats(IRCMessage *message);
+ void parseNumericalNames(IRCMessage *message);
+ void parseNumericalEndOfNames(IRCMessage *message);
+ void parseNumericalNicknameInUse(IRCMessage *message);
+ void parseCTCPPing(IRCMessage *message);
+ void parseCTCPVersion(IRCMessage *message);
+ void parseCTCPAction(IRCMessage *message);
+protected:
+ IRCSession *m_session;
+ /* Parser tables */
+ static IRCLiteralMessageParserStruct literalParserProcTable[];
+ static IRCNumericalMessageParserStruct numericalParserProcTable[];
+ static IRCCTCPMessageParserStruct ctcpParserProcTable[];
+};
+
+#endif /* __IRCMESSAGEPARSER_H */
diff --git a/noncore/net/opieirc/ircoutput.cpp b/noncore/net/opieirc/ircoutput.cpp
new file mode 100644
index 0000000..aa57d86
--- a/dev/null
+++ b/noncore/net/opieirc/ircoutput.cpp
@@ -0,0 +1,22 @@
+#include "ircoutput.h"
+
+IRCOutput::IRCOutput(IRCOutputType type, QString message) {
+ m_type = type;
+ m_message = message;
+}
+
+IRCOutputType IRCOutput::type() {
+ return m_type;
+}
+
+QString IRCOutput::message() {
+ return m_message;
+}
+
+void IRCOutput::addParam(void *data) {
+ m_parameters.append(data);
+}
+
+void *IRCOutput::getParam(int index) {
+ return m_parameters.at(index);
+}
diff --git a/noncore/net/opieirc/ircoutput.h b/noncore/net/opieirc/ircoutput.h
new file mode 100644
index 0000000..4b757ed
--- a/dev/null
+++ b/noncore/net/opieirc/ircoutput.h
@@ -0,0 +1,70 @@
+/*
+ OpieIRC - An embedded IRC client
+ Copyright (C) 2002 Wenzel Jakob
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+#ifndef __IRCOUTPUT_H
+#define __IRCOUTPUT_H
+
+#include <qstring.h>
+#include <qlist.h>
+#include "ircchannel.h"
+
+/* Types of possible IRC output */
+enum IRCOutputType {
+ OUTPUT_ERROR = -1, /* parameters : none */
+ OUTPUT_SERVERMESSAGE = 0, /* parameters : none */
+ OUTPUT_CLIENTMESSAGE = 1, /* parameters : none */
+ OUTPUT_CHANPRIVMSG = 2, /* parameters : channel (IRCChannel), person (IRCChannelPerson) */
+ OUTPUT_QUERYPRIVMSG = 3, /* parameters : person (IRCPerson) */
+ OUTPUT_NICKCHANGE = 4, /* parameters : person (IRCPerson) */
+ OUTPUT_SELFJOIN = 5, /* parameters : channel (IRCChannel) */
+ OUTPUT_OTHERJOIN = 6, /* parameters : channel (IRCChannel), person (IRCChannelPerson) */
+ OUTPUT_SELFPART = 7, /* parameters : channel (IRCChannel) */
+ OUTPUT_OTHERPART = 8, /* parameters : channel (IRCChannel), person (IRCChannelPerson) */
+ OUTPUT_QUIT = 9, /* parameters : person (IRCPerson) */
+ OUTPUT_CONNCLOSE = 10, /* parameters : none */
+ OUTPUT_CTCP = 11, /* parameters : none */
+ OUTPUT_SELFKICK = 12, /* parameters : channel (IRCChannel) */
+ OUTPUT_OTHERKICK = 13, /* parameters : channel (IRCChannel) person (IRCChannelPerson) */
+ OUTPUT_CHANACTION = 14, /* parameters : channel (IRCChannel) person (IRCChannelPerson) */
+ OUTPUT_QUERYACTION = 15, /* parameters : person (IRCPerson) */
+ OUTPUT_CHANPERSONMODE = 16 /* parameters : channel (IRCCHannel) person (IRCChannelPerson) */
+};
+
+/* The IRCOutput class is used as a kind of message which is sent by the
+ IRC parser to inform the GUI of changes. This could for example be a
+ channel message or a nickname change */
+
+class IRCOutput {
+public:
+ IRCOutput(IRCOutputType type, QString message);
+ /* Used to add a parameter to this IRCOutput. Parameters are dependent
+ on which IRCOutputType we are using (see above) */
+ void addParam(void *data);
+
+ IRCOutputType type();
+ QString message();
+ void *getParam(int index);
+protected:
+ IRCOutputType m_type;
+ QString m_message;
+ QList<void> m_parameters;
+};
+
+#endif
diff --git a/noncore/net/opieirc/ircperson.cpp b/noncore/net/opieirc/ircperson.cpp
new file mode 100644
index 0000000..bd6b8d6
--- a/dev/null
+++ b/noncore/net/opieirc/ircperson.cpp
@@ -0,0 +1,50 @@
+#include "ircperson.h"
+#include <stdio.h>
+
+IRCPerson::IRCPerson() {
+ m_nick = "";
+ m_user = "";
+ m_host = "";
+}
+
+IRCPerson::IRCPerson(QString mask) {
+ IRCPerson();
+ fromMask(mask);
+}
+
+void IRCPerson::fromMask(QString mask) {
+ int sep1 = mask.find("!");
+ int sep2 = mask.find("@");
+
+ m_nick = mask.left(sep1);
+ m_user = mask.mid(sep1+1, sep2-sep1-1);
+ m_host = mask.right(mask.length()-sep2-1);
+}
+
+QString IRCPerson::toMask() {
+ return m_nick + "!" + m_user + "@" + m_host;
+}
+
+void IRCPerson::setNick(QString nick) {
+ m_nick = nick;
+}
+
+void IRCPerson::setUser(QString user) {
+ m_user = user;
+}
+
+void IRCPerson::setHost(QString host) {
+ m_host = host;
+}
+
+QString IRCPerson::nick() {
+ return m_nick;
+}
+
+QString IRCPerson::user() {
+ return m_user;
+}
+
+QString IRCPerson::host() {
+ return m_host;
+}
diff --git a/noncore/net/opieirc/ircperson.h b/noncore/net/opieirc/ircperson.h
new file mode 100644
index 0000000..850f91b
--- a/dev/null
+++ b/noncore/net/opieirc/ircperson.h
@@ -0,0 +1,50 @@
+/*
+ OpieIRC - An embedded IRC client
+ Copyright (C) 2002 Wenzel Jakob
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+#ifndef __IRCPERSON
+#define __IRCPERSON
+
+#include <qstring.h>
+
+/* This class requires all required information relating to a person
+ on the IRC network. This class can be used as an input mask for
+ IRCMessage-prefixes too
+*/
+
+class IRCPerson {
+public:
+ IRCPerson();
+ IRCPerson(QString mask);
+
+ void fromMask(QString mask);
+ void setNick(QString name);
+ void setUser(QString user);
+ void setHost(QString host);
+ QString toMask();
+ QString nick();
+ QString user();
+ QString host();
+protected:
+ QString m_nick;
+ QString m_user;
+ QString m_host;
+};
+
+#endif /* __IRCPERSON */
diff --git a/noncore/net/opieirc/ircserver.cpp b/noncore/net/opieirc/ircserver.cpp
new file mode 100644
index 0000000..33a788b
--- a/dev/null
+++ b/noncore/net/opieirc/ircserver.cpp
@@ -0,0 +1,62 @@
+#include "ircserver.h"
+
+IRCServer::IRCServer() {
+ m_port = 0;
+}
+
+void IRCServer::setHostname(QString hostname) {
+ m_hostname = hostname;
+}
+
+void IRCServer::setDescription(QString description) {
+ m_description = description;
+}
+
+void IRCServer::setPort(int port) {
+ m_port = port;
+}
+
+void IRCServer::setUsername(QString username) {
+ m_username = username;
+}
+
+void IRCServer::setPassword(QString password) {
+ m_password = password;
+}
+
+void IRCServer::setNick(QString nick) {
+ m_nick = nick;
+}
+
+void IRCServer::setRealname(QString realname) {
+ m_realname = realname;
+}
+
+QString IRCServer::hostname() {
+ return m_hostname;
+}
+
+QString IRCServer::description() {
+ return m_description;
+}
+
+unsigned short int IRCServer::port() {
+ return m_port;
+}
+
+QString IRCServer::username() {
+ return m_username;
+}
+
+QString IRCServer::password() {
+ return m_password;
+}
+
+QString IRCServer::nick() {
+ return m_nick;
+}
+
+QString IRCServer::realname() {
+ return m_realname;
+}
+
diff --git a/noncore/net/opieirc/ircserver.h b/noncore/net/opieirc/ircserver.h
new file mode 100644
index 0000000..5f06c73
--- a/dev/null
+++ b/noncore/net/opieirc/ircserver.h
@@ -0,0 +1,58 @@
+/*
+ OpieIRC - An embedded IRC client
+ Copyright (C) 2002 Wenzel Jakob
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+#ifndef __IRCSERVER_H
+#define __IRCSERVER_H
+
+#include <qstring.h>
+
+/* IRCServer stores all information required to
+ establish a connection to a server. */
+
+class IRCServer {
+public:
+ IRCServer();
+
+ void setHostname(QString hostname);
+ void setDescription(QString description);
+ void setPort(int port);
+ void setUsername(QString username);
+ void setPassword(QString password);
+ void setNick(QString nick);
+ void setRealname(QString realname);
+
+ QString hostname();
+ QString description();
+ unsigned short int port();
+ QString username();
+ QString password();
+ QString nick();
+ QString realname();
+protected:
+ QString m_hostname;
+ QString m_description;
+ unsigned short int m_port;
+ QString m_username;
+ QString m_password;
+ QString m_nick;
+ QString m_realname;
+};
+
+#endif /* __IRCSERVER_H */
diff --git a/noncore/net/opieirc/ircservereditor.cpp b/noncore/net/opieirc/ircservereditor.cpp
new file mode 100644
index 0000000..1b157d6
--- a/dev/null
+++ b/noncore/net/opieirc/ircservereditor.cpp
@@ -0,0 +1,49 @@
+#include <qlayout.h>
+#include <qlabel.h>
+#include "ircservereditor.h"
+
+IRCServerEditor::IRCServerEditor(IRCServer server, QWidget* parent, const char* name, bool modal = FALSE, WFlags f) : QDialog(parent, name, modal, f) {
+ QGridLayout *layout = new QGridLayout(this, 6, 2, 5, 5);
+ QLabel *label = new QLabel(tr("Hostname :"), this);
+ m_hostname = new QLineEdit(server.hostname(), this);
+ layout->addWidget(label, 0, 0);
+ layout->addWidget(m_hostname, 0, 1);
+ label = new QLabel(tr("Port :"), this);
+ m_port = new QLineEdit(QString::number(server.port()), this);
+ layout->addWidget(label, 1, 0);
+ layout->addWidget(m_port, 1, 1);
+ label = new QLabel(tr("Nickname :"), this);
+ m_nickname = new QLineEdit(server.nick(), this);
+ layout->addWidget(label, 2, 0);
+ layout->addWidget(m_nickname, 2, 1);
+ label = new QLabel(tr("Description :"), this);
+ m_description = new QLineEdit(server.description(), this);
+ layout->addWidget(label, 3, 0);
+ layout->addWidget(m_description, 3, 1);
+ label = new QLabel(tr("Realname :"), this);
+ m_realname = new QLineEdit(server.realname(), this);
+ layout->addWidget(label, 4, 0);
+ layout->addWidget(m_realname, 4, 1);
+ label = new QLabel(tr("Username :"), this);
+ m_username = new QLineEdit(server.username(), this);
+ layout->addWidget(label, 3, 0);
+ layout->addWidget(m_username, 3, 1);
+ label = new QLabel(tr("Password :"), this);
+ m_password = new QLineEdit(server.password(), this);
+ layout->addWidget(label, 5, 0);
+ layout->addWidget(m_password, 5, 1);
+ showMaximized();
+}
+
+
+IRCServer IRCServerEditor::getServer() {
+ IRCServer server;
+ server.setHostname(m_hostname->text());
+ server.setPort(m_port->text().toInt());
+ server.setNick(m_nickname->text());
+ server.setDescription(m_description->text());
+ server.setRealname(m_realname->text());
+ server.setUsername(m_username->text());
+ server.setPassword(m_password->text());
+ return server;
+}
diff --git a/noncore/net/opieirc/ircservereditor.h b/noncore/net/opieirc/ircservereditor.h
new file mode 100644
index 0000000..86cdf32
--- a/dev/null
+++ b/noncore/net/opieirc/ircservereditor.h
@@ -0,0 +1,43 @@
+/*
+ OpieIRC - An embedded IRC client
+ Copyright (C) 2002 Wenzel Jakob
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+#ifndef __IRCSERVEREDITOR
+#define __IRCSERVEREDITOR
+
+#include <qdialog.h>
+#include <qlineedit.h>
+#include "ircserver.h"
+
+class IRCServerEditor : public QDialog {
+ Q_OBJECT
+public:
+ IRCServerEditor(IRCServer server, QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags f = 0);
+ IRCServer getServer();
+protected:
+ QLineEdit *m_hostname;
+ QLineEdit *m_port;
+ QLineEdit *m_description;
+ QLineEdit *m_nickname;
+ QLineEdit *m_username;
+ QLineEdit *m_password;
+ QLineEdit *m_realname;
+};
+
+#endif /* __IRCSERVEREDITOR_H */
diff --git a/noncore/net/opieirc/ircserverlist.cpp b/noncore/net/opieirc/ircserverlist.cpp
new file mode 100644
index 0000000..964fa13
--- a/dev/null
+++ b/noncore/net/opieirc/ircserverlist.cpp
@@ -0,0 +1,55 @@
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qhbox.h>
+#include <qpushbutton.h>
+#include "ircserverlist.h"
+#include "ircservereditor.h"
+
+class IRCListBoxServer : public QListBoxText {
+public:
+ IRCListBoxServer(IRCServer server);
+ QString text();
+};
+
+IRCServerList::IRCServerList(QWidget* parent, const char *name, bool modal, WFlags f) : QDialog(parent, name, modal, f) {
+ QVBoxLayout *layout = new QVBoxLayout(this, 5, 5);
+ setCaption(tr("Serverlist Browser"));
+ m_config = new Config("OpieIRC");
+ m_config->setGroup("OpieIRC");
+ QLabel *label = new QLabel(tr("Please choose a server profile"), this);
+ layout->addWidget(label);
+ m_list = new QListBox(this);
+ layout->addWidget(m_list);
+ QHBox *buttons = new QHBox(this);
+ QPushButton *del = new QPushButton(tr("Delete"), buttons);
+ QPushButton *edit = new QPushButton(tr("Edit"), buttons);
+ QPushButton *add = new QPushButton(tr("Add"), buttons);
+ connect(del, SIGNAL(clicked()), this, SLOT(delServer()));
+ connect(edit, SIGNAL(clicked()), this, SLOT(editServer()));
+ connect(add, SIGNAL(clicked()), this, SLOT(addServer()));
+ layout->addWidget(buttons);
+ showMaximized();
+}
+
+void IRCServerList::addServer() {
+ IRCServer server;
+ IRCServerEditor editor(server, this, "ServerEditor", TRUE);
+ if (editor.exec() == QDialog::Accepted) {
+ server = editor.getServer();
+ //m_servers->append(server);
+ update();
+ }
+}
+
+void IRCServerList::delServer() {
+}
+
+void IRCServerList::editServer() {
+}
+
+void IRCServerList::update() {
+}
+
+IRCServerList::~IRCServerList() {
+ delete m_config;
+}
diff --git a/noncore/net/opieirc/ircserverlist.h b/noncore/net/opieirc/ircserverlist.h
new file mode 100644
index 0000000..ad9231d
--- a/dev/null
+++ b/noncore/net/opieirc/ircserverlist.h
@@ -0,0 +1,46 @@
+/*
+ OpieIRC - An embedded IRC client
+ Copyright (C) 2002 Wenzel Jakob
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+#ifndef __IRCSERVERLIST_H
+#define __IRCSERVERLIST_H
+
+#include <qdialog.h>
+#include <qpe/config.h>
+#include <qlistbox.h>
+#include <qlist.h>
+#include "ircserver.h"
+
+class IRCServerList : public QDialog {
+ Q_OBJECT
+public:
+ IRCServerList(QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags f = 0);
+ ~IRCServerList();
+public slots:
+ void addServer();
+ void delServer();
+ void editServer();
+protected:
+ void update();
+protected:
+ Config *m_config;
+ QListBox *m_list;
+};
+
+#endif /* __IRCSERVERLIST_H */
diff --git a/noncore/net/opieirc/ircservertab.cpp b/noncore/net/opieirc/ircservertab.cpp
new file mode 100644
index 0000000..1f377aa
--- a/dev/null
+++ b/noncore/net/opieirc/ircservertab.cpp
@@ -0,0 +1,147 @@
+#include <stdio.h>
+#include "ircservertab.h"
+
+IRCServerTab::IRCServerTab(IRCServer *server, MainWindow *mainWindow, QWidget *parent, const char *name, WFlags f) : IRCTab(parent, name, f) {
+ m_server = server;
+ m_session = new IRCSession(m_server);
+ m_mainWindow = mainWindow;
+ m_close = FALSE;
+ m_description->setText(tr("Connection to")+" <b>" + server->hostname() + ":" + QString::number(server->port()) + "</b>");
+ m_textview = new QTextView(this);
+ m_textview->setHScrollBarMode(QScrollView::AlwaysOff);
+ m_textview->setVScrollBarMode(QScrollView::AlwaysOn);
+ m_layout->add(m_textview);
+ m_field = new QLineEdit(this);
+ m_layout->add(m_field);
+ connect(m_field, SIGNAL(returnPressed()), this, SLOT(processCommand()));
+ m_field->setFocus();
+ connect(m_session, SIGNAL(outputReady(IRCOutput)), this, SLOT(display(IRCOutput)));
+}
+
+void IRCServerTab::appendText(QString text) {
+ /* not using append because it creates layout problems */
+ m_textview->setText(m_textview->text() + text);
+ m_textview->ensureVisible(0, m_textview->contentsHeight());
+}
+
+IRCServerTab::~IRCServerTab() {
+ QListIterator<IRCChannelTab> it(m_channelTabs);
+ for (; it.current(); ++it) {
+ m_mainWindow->killTab(it.current());
+ }
+ delete m_session;
+ delete m_server;
+}
+
+void IRCServerTab::removeChannelTab(IRCChannelTab *tab) {
+ m_channelTabs.remove(tab);
+}
+
+QString IRCServerTab::title() {
+ return "Server";
+}
+
+IRCSession *IRCServerTab::session() {
+ return m_session;
+}
+
+IRCServer *IRCServerTab::server() {
+ return m_server;
+}
+
+void IRCServerTab::processCommand() {
+ m_field->clear();
+ appendText("<font color=\"#ff0000\">Not supported yet</font><br>");
+}
+
+void IRCServerTab::doConnect() {
+ m_session->beginSession();
+}
+
+void IRCServerTab::remove() {
+ if (m_session->isSessionActive()) {
+ m_close = TRUE;
+ m_session->endSession();
+ } else {
+ m_mainWindow->killTab(this);
+ }
+}
+
+IRCChannelTab *IRCServerTab::getTabForChannel(IRCChannel *channel) {
+ QListIterator<IRCChannelTab> it(m_channelTabs);
+
+ for (; it.current(); ++it) {
+ if (it.current()->channel() == channel)
+ return it.current();
+ }
+ return 0;
+}
+
+void IRCServerTab::display(IRCOutput output) {
+ switch (output.type()) {
+ case OUTPUT_CONNCLOSE:
+ if (m_close)
+ m_mainWindow->killTab(this);
+ else
+ appendText("<font color=\"#0000dd\">" + output.message() +"</font><br>");
+ break;
+ case OUTPUT_SELFJOIN: {
+ IRCChannelTab *channeltab = new IRCChannelTab((IRCChannel *)output.getParam(0), this, m_mainWindow, (QWidget *)parent());
+ m_channelTabs.append(channeltab);
+ m_mainWindow->addTab(channeltab);
+ }
+ break;
+ case OUTPUT_CHANPRIVMSG: {
+ IRCChannelTab *channelTab = getTabForChannel((IRCChannel *)output.getParam(0));
+ channelTab->appendText("&lt;<font color=\"#0000dd\">"+((IRCChannelPerson *)output.getParam(1))->person->nick()+"</font>&gt; "+output.message()+"<br>");
+ }
+ break;
+ case OUTPUT_SELFPART: {
+ IRCChannelTab *channelTab = getTabForChannel((IRCChannel *)output.getParam(0));
+ if (channelTab)
+ m_mainWindow->killTab(channelTab);
+ }
+ break;
+ case OUTPUT_SELFKICK: {
+ appendText("<font color=\"#ff0000\">" + output.message() + "</font><br>");
+ IRCChannelTab *channelTab = getTabForChannel((IRCChannel *)output.getParam(0));
+ if (channelTab)
+ m_mainWindow->killTab(channelTab);
+ }
+ break;
+ case OUTPUT_CHANACTION: {
+ IRCChannelTab *channelTab = getTabForChannel((IRCChannel *)output.getParam(0));
+ channelTab->appendText("<font color=\"#cc0000\">"+output.message()+"</font><br>");
+ }
+ break;
+ case OUTPUT_QUIT: {
+ QString nick = ((IRCPerson *)output.getParam(0))->nick();
+ QListIterator<IRCChannelTab> it(m_channelTabs);
+ for (; it.current(); ++it) {
+ if (it.current()->list()->hasPerson(nick)) {
+ it.current()->appendText("<font color=\"#aa3e00\">"+output.message()+"</font><br>");
+ it.current()->list()->update();
+ }
+ }
+ }
+ break;
+ case OUTPUT_OTHERJOIN:
+ case OUTPUT_OTHERKICK:
+ case OUTPUT_CHANPERSONMODE:
+ case OUTPUT_OTHERPART: {
+ IRCChannelTab *channelTab = getTabForChannel((IRCChannel *)output.getParam(0));
+ channelTab->appendText("<font color=\"#aa3e00\">"+output.message()+"</font><br>");
+ channelTab->list()->update();
+ }
+ break;
+ case OUTPUT_CTCP:
+ appendText("<font color=\"#00bb00\">" + output.message() + "</font><br>");
+ break;
+ case OUTPUT_ERROR:
+ appendText("<font color=\"#ff0000\">" + output.message() + "</font><br>");
+ break;
+ default:
+ appendText("<font color=\"#0000dd\">" + output.message() + "</font><br>");
+ break;
+ }
+}
diff --git a/noncore/net/opieirc/ircservertab.h b/noncore/net/opieirc/ircservertab.h
new file mode 100644
index 0000000..79b5876
--- a/dev/null
+++ b/noncore/net/opieirc/ircservertab.h
@@ -0,0 +1,60 @@
+/*
+ OpieIRC - An embedded IRC client
+ Copyright (C) 2002 Wenzel Jakob
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+#ifndef __IRCSERVERTAB_H
+#define __IRCSERVERTAB_H
+
+#include "irctab.h"
+#include "ircsession.h"
+#include "mainwindow.h"
+#include "ircchanneltab.h"
+
+class IRCServerTab : public IRCTab {
+ Q_OBJECT
+public:
+ /* IRCTab implementation */
+ IRCServerTab(IRCServer *server, MainWindow *mainWindow, QWidget *parent = 0, const char *name = 0, WFlags f = 0);
+ ~IRCServerTab();
+ QString title();
+ IRCSession *session();
+ IRCServer *server();
+
+ /* Start the server session */
+ void doConnect();
+ void removeChannelTab(IRCChannelTab *tab);
+protected:
+ void appendText(QString text);
+ IRCChannelTab *getTabForChannel(IRCChannel *channel);
+public slots:
+ void remove();
+ void processCommand();
+protected slots:
+ void display(IRCOutput output);
+protected:
+ bool m_close;
+ IRCServer *m_server;
+ IRCSession *m_session;
+ MainWindow *m_mainWindow;
+ QTextView *m_textview;
+ QLineEdit *m_field;
+ QList<IRCChannelTab> m_channelTabs;
+};
+
+#endif /* __IRCSERVERTAB_H */
diff --git a/noncore/net/opieirc/ircsession.cpp b/noncore/net/opieirc/ircsession.cpp
new file mode 100644
index 0000000..b81038f
--- a/dev/null
+++ b/noncore/net/opieirc/ircsession.cpp
@@ -0,0 +1,99 @@
+#include "ircsession.h"
+#include "ircmessageparser.h"
+#include "ircversion.h"
+
+IRCSession::IRCSession(IRCServer *server) {
+ m_server = server;
+ m_connection = new IRCConnection(m_server);
+ m_parser = new IRCMessageParser(this);
+ connect(m_connection, SIGNAL(messageArrived(IRCMessage *)), this, SLOT(handleMessage(IRCMessage *)));
+ connect(m_parser, SIGNAL(outputReady(IRCOutput)), this, SIGNAL(outputReady(IRCOutput)));
+ connect(m_connection, SIGNAL(outputReady(IRCOutput)), this, SIGNAL(outputReady(IRCOutput)));
+}
+
+IRCSession::~IRCSession() {
+ delete m_parser;
+ delete m_connection;
+}
+
+void IRCSession::beginSession() {
+ m_connection->doConnect();
+}
+
+void IRCSession::join(QString channelname) {
+ m_connection->sendLine("JOIN "+channelname);
+}
+
+void IRCSession::sendMessage(IRCPerson *person, QString message) {
+ m_connection->sendLine("PRIVMSG " + person->nick() + " :" + message);
+}
+
+void IRCSession::sendMessage(IRCChannel *channel, QString message) {
+ m_connection->sendLine("PRIVMSG " + channel->channelname() + " :" + message);
+}
+
+bool IRCSession::isSessionActive() {
+ return m_connection->isConnected();
+}
+
+void IRCSession::endSession() {
+ if (m_connection->isLoggedIn())
+ m_connection->sendLine("QUIT :" APP_VERSION);
+ else
+ m_connection->close();
+}
+
+void IRCSession::part(IRCChannel *channel) {
+ m_connection->sendLine("PART " + channel->channelname() + " :" + APP_VERSION);
+}
+
+
+IRCChannel *IRCSession::getChannel(QString channelname) {
+ QListIterator<IRCChannel> it(m_channels);
+ for (; it.current(); ++it) {
+ if (it.current()->channelname() == channelname) {
+ return it.current();
+ }
+ }
+ return 0;
+}
+
+IRCPerson *IRCSession::getPerson(QString nickname) {
+ QListIterator<IRCPerson> it(m_people);
+ for (; it.current(); ++it) {
+ if (it.current()->nick() == nickname) {
+ return it.current();
+ }
+ }
+ return 0;
+}
+
+void IRCSession::getChannelsByPerson(IRCPerson *person, QList<IRCChannel> &channels) {
+ QListIterator<IRCChannel> it(m_channels);
+ for (; it.current(); ++it) {
+ if (it.current()->getPerson(person->nick()) != 0) {
+ channels.append(it.current());
+ }
+ }
+}
+
+void IRCSession::addPerson(IRCPerson *person) {
+ m_people.append(person);
+}
+
+void IRCSession::addChannel(IRCChannel *channel) {
+ m_channels.append(channel);
+}
+
+void IRCSession::removeChannel(IRCChannel *channel) {
+ m_channels.remove(channel);
+}
+
+void IRCSession::removePerson(IRCPerson *person) {
+ m_people.remove(person);
+}
+
+void IRCSession::handleMessage(IRCMessage *message) {
+ m_parser->parse(message);
+}
+
diff --git a/noncore/net/opieirc/ircsession.h b/noncore/net/opieirc/ircsession.h
new file mode 100644
index 0000000..59c26aa
--- a/dev/null
+++ b/noncore/net/opieirc/ircsession.h
@@ -0,0 +1,73 @@
+/*
+ OpieIRC - An embedded IRC client
+ Copyright (C) 2002 Wenzel Jakob
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+#ifndef __IRCSESSION_H
+#define __IRCSESSION_H
+
+#include <qstring.h>
+#include <qlist.h>
+#include "ircserver.h"
+#include "ircconnection.h"
+#include "ircmessage.h"
+#include "ircchannel.h"
+#include "ircoutput.h"
+
+class IRCMessageParser;
+
+/* The IRCSession stores all information relating to the connection
+ to one IRC server. IRCSession makes it possible to run multiple
+ IRC server connections from within the same program */
+
+class IRCSession : public QObject {
+friend class IRCMessageParser;
+ Q_OBJECT
+public:
+ IRCSession(IRCServer *server);
+ ~IRCSession();
+
+ void join(QString channel);
+ void part(IRCChannel *channel);
+ void beginSession();
+ bool isSessionActive();
+ void endSession();
+
+ void sendMessage(IRCPerson *person, QString message);
+ void sendMessage(IRCChannel *channel, QString message);
+ IRCChannel *getChannel(QString channelname);
+ IRCPerson *getPerson(QString nickname);
+protected:
+ void addPerson(IRCPerson *person);
+ void addChannel(IRCChannel *channel);
+ void removeChannel(IRCChannel *channel);
+ void removePerson(IRCPerson *person);
+ void getChannelsByPerson(IRCPerson *person, QList<IRCChannel> &channels);
+protected slots:
+ void handleMessage(IRCMessage *message);
+signals:
+ void outputReady(IRCOutput output);
+protected:
+ IRCServer *m_server;
+ IRCConnection *m_connection;
+ IRCMessageParser *m_parser;
+ QList<IRCChannel> m_channels;
+ QList<IRCPerson> m_people;
+};
+
+#endif /* __IRCSESSION_H */
diff --git a/noncore/net/opieirc/irctab.cpp b/noncore/net/opieirc/irctab.cpp
new file mode 100644
index 0000000..36976ab
--- a/dev/null
+++ b/noncore/net/opieirc/irctab.cpp
@@ -0,0 +1,19 @@
+#include <qpe/resource.h>
+#include <qpixmap.h>
+#include <qpushbutton.h>
+#include "irctab.h"
+
+IRCTab::IRCTab(QWidget *parent, const char *name, WFlags f) : QWidget(parent, name, f) {
+ m_layout = new QVBoxLayout(this);
+ QHBoxLayout *descLayout = new QHBoxLayout(m_layout);
+ descLayout->setMargin(5);
+ m_description = new QLabel(tr("Missing description"), this);
+ descLayout->addWidget(m_description);
+ descLayout->setStretchFactor(m_description, 5);
+ QPushButton *close = new QPushButton(this);
+ close->setPixmap(Resource::loadPixmap("opieirc/close"));
+ connect(close, SIGNAL(clicked()), this, SLOT(remove()));
+ descLayout->addWidget(close);
+ descLayout->setStretchFactor(m_description, 1);
+}
+
diff --git a/noncore/net/opieirc/irctab.h b/noncore/net/opieirc/irctab.h
new file mode 100644
index 0000000..3124980
--- a/dev/null
+++ b/noncore/net/opieirc/irctab.h
@@ -0,0 +1,47 @@
+/*
+ OpieIRC - An embedded IRC client
+ Copyright (C) 2002 Wenzel Jakob
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+#ifndef __IRCTAB_H
+#define __IRCTAB_H
+
+#include <qwidget.h>
+#include <qtextview.h>
+#include <qlineedit.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include "ircsession.h"
+
+/* This is the base class for any tabs which need to be integrated into
+ the main GUI tab widget */
+
+class IRCTab : public QWidget {
+ Q_OBJECT
+public:
+ IRCTab(QWidget *parent = 0, const char *name = 0, WFlags f = 0);
+ virtual QString title() = 0;
+ virtual IRCSession *session() = 0;
+public slots:
+ virtual void remove() = 0;
+protected:
+ QLabel *m_description;
+ QVBoxLayout *m_layout;
+};
+
+#endif /* __IRCTAB_H */
diff --git a/noncore/net/opieirc/ircversion.h b/noncore/net/opieirc/ircversion.h
new file mode 100644
index 0000000..0ef0d2f
--- a/dev/null
+++ b/noncore/net/opieirc/ircversion.h
@@ -0,0 +1,27 @@
+/*
+ OpieIRC - An embedded IRC client
+ Copyright (C) 2002 Wenzel Jakob
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+#ifndef __IRCVERSION_H
+#define __IRCVERSION_H
+
+#define APP_VERSION "OpieIRC 0.1"
+#define APP_COPYSTR "(c) 2002 by Wenzel Jakob"
+
+#endif /* __IRCVERSION_H */
diff --git a/noncore/net/opieirc/main.cpp b/noncore/net/opieirc/main.cpp
new file mode 100644
index 0000000..43e63af
--- a/dev/null
+++ b/noncore/net/opieirc/main.cpp
@@ -0,0 +1,10 @@
+#include <qpe/qpeapplication.h>
+#include "mainwindow.h"
+
+int main(int argc, char **argv) {
+ QPEApplication a(argc, argv);
+ MainWindow mw;
+ a.showMainWidget(&mw);
+ return a.exec();
+}
+
diff --git a/noncore/net/opieirc/mainwindow.cpp b/noncore/net/opieirc/mainwindow.cpp
new file mode 100644
index 0000000..bc0b0d1
--- a/dev/null
+++ b/noncore/net/opieirc/mainwindow.cpp
@@ -0,0 +1,79 @@
+#include <qpe/qpemenubar.h>
+#include <qpe/resource.h>
+#include <qpe/config.h>
+#include <qpopupmenu.h>
+
+#include "mainwindow.h"
+#include "ircservertab.h"
+#include "ircserverlist.h"
+
+MainWindow::MainWindow(QWidget *parent, const char *name, WFlags f) : QMainWindow(parent, name, f) {
+ setCaption(tr("IRC Client"));
+ m_tabWidget = new QTabWidget(this);
+ connect(m_tabWidget, SIGNAL(currentChanged(QWidget *)), this, SLOT(tabSelected(QWidget *)));
+ setCentralWidget(m_tabWidget);
+ setToolBarsMovable(FALSE);
+ QPEMenuBar *menuBar = new QPEMenuBar(this);
+ QPopupMenu *irc = new QPopupMenu(this);
+ menuBar->insertItem(tr("IRC"), irc);
+ QAction *a = new QAction(tr("New connection"), Resource::loadPixmap("pass"), QString::null, 0, this, 0);
+ connect(a, SIGNAL(activated()), this, SLOT(newConnection()));
+ a->addTo(irc);
+
+ m_joinAction = new QAction(tr("Join channel"), Resource::loadPixmap("forward"), QString::null, 0, this, 0);
+ m_joinAction->setEnabled(FALSE);
+ connect(m_joinAction, SIGNAL(activated()), this, SLOT(join()));
+ m_joinAction->addTo(irc);
+}
+
+void MainWindow::tabSelected(QWidget *) {
+ m_joinAction->setEnabled(TRUE);
+}
+
+void MainWindow::closeTab() {
+ /* Does not directly close the tab but triggers an action
+ which at some point will close the tab using a callback */
+ IRCTab *tab = (IRCTab *)m_tabWidget->currentPage();
+ if (tab) {
+ tab->remove();
+ }
+}
+
+void MainWindow::join() {
+ IRCTab *tab = (IRCTab *)m_tabWidget->currentPage();
+ if (tab) {
+ tab->session()->join("#opie.de");
+ }
+}
+
+void MainWindow::addTab(IRCTab *tab) {
+ m_tabWidget->addTab(tab, tab->title());
+ m_tabWidget->showPage(tab);
+ tabSelected(tab);
+}
+
+void MainWindow::killTab(IRCTab *tab) {
+ m_tabWidget->removePage(tab);
+ /* there might be nicer ways to do this .. */
+ delete tab;
+}
+
+void MainWindow::newConnection() {
+ IRCServer *server = new IRCServer();
+ server->setHostname("irc.openprojects.net");
+ server->setPort(6667);
+ server->setDescription("OpenProjects");
+ server->setNick("opie-irc");
+ server->setUsername("opie-irc");
+ server->setRealname("opie-irc");
+ IRCServerTab *serverTab = new IRCServerTab(server, this, m_tabWidget);
+ addTab(serverTab);
+ serverTab->doConnect();
+
+ /*
+ * Serverlist : not functional yet
+ IRCServerList *list = new IRCServerList(this, "ServerList", TRUE);
+ list->exec();
+ delete list;
+ */
+}
diff --git a/noncore/net/opieirc/mainwindow.h b/noncore/net/opieirc/mainwindow.h
new file mode 100644
index 0000000..c197f5b
--- a/dev/null
+++ b/noncore/net/opieirc/mainwindow.h
@@ -0,0 +1,47 @@
+/*
+ OpieIRC - An embedded IRC client
+ Copyright (C) 2002 Wenzel Jakob
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+#ifndef __MAINWINDOW_H
+#define __MAINWINDOW_H
+
+#include <qmainwindow.h>
+#include <qaction.h>
+#include <qtabwidget.h>
+#include "mainwindow.h"
+#include "irctab.h"
+
+class MainWindow : public QMainWindow {
+ Q_OBJECT
+public:
+ MainWindow(QWidget *parent = 0, const char *name = 0, WFlags f = 0);
+
+ void addTab(IRCTab *tab);
+ void killTab(IRCTab *tab);
+protected slots:
+ void newConnection();
+ void closeTab();
+ void join();
+ void tabSelected(QWidget *widget);
+protected:
+ QTabWidget *m_tabWidget;
+ QAction *m_joinAction;
+};
+
+#endif /* __MAINWINDOW_H */
diff --git a/noncore/net/opieirc/opieirc.pro b/noncore/net/opieirc/opieirc.pro
new file mode 100644
index 0000000..d24535b
--- a/dev/null
+++ b/noncore/net/opieirc/opieirc.pro
@@ -0,0 +1,22 @@
+TEMPLATE = app
+CONFIG = qt warn_on release
+DESTDIR = $(OPIEDIR)/bin
+HEADERS = ircchannel.h ircconnection.h \
+ ircmessage.h \
+ ircmessageparser.h ircoutput.h \
+ ircperson.h ircserver.h ircsession.h \
+ mainwindow.h irctab.h ircservertab.h \
+ ircchanneltab.h ircchannellist.h \
+ ircserverlist.h ircservereditor.h
+SOURCES = ircchannel.cpp ircconnection.cpp \
+ ircmessage.cpp \
+ ircmessageparser.cpp ircoutput.cpp \
+ ircperson.cpp ircserver.cpp \
+ ircsession.cpp main.cpp mainwindow.cpp \
+ irctab.cpp ircservertab.cpp \
+ ircchanneltab.cpp ircchannellist.cpp \
+ ircserverlist.cpp ircservereditor.cpp
+INCLUDEPATH += $(OPIEDIR)/include
+DEPENDPATH += $(OPIEDIR)/include
+LIBS += -lqpe
+