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("<<font color=\"#dd0000\">"+m_parentTab->server()->nick()+"</font>> "+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(¶meters); + 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("<<font color=\"#0000dd\">"+((IRCChannelPerson *)output.getParam(1))->person->nick()+"</font>> "+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 + |