summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/net/opieirc/ircchannel.cpp3
-rw-r--r--noncore/net/opieirc/ircchannel.h15
-rw-r--r--noncore/net/opieirc/ircchannellist.cpp16
-rw-r--r--noncore/net/opieirc/ircchannelperson.cpp62
-rw-r--r--noncore/net/opieirc/ircchannelperson.h34
-rw-r--r--noncore/net/opieirc/ircchanneltab.cpp18
-rw-r--r--noncore/net/opieirc/ircconnection.cpp24
-rw-r--r--noncore/net/opieirc/ircconnection.h6
-rw-r--r--noncore/net/opieirc/ircmessageparser.cpp132
-rw-r--r--noncore/net/opieirc/ircmessageparser.h2
-rw-r--r--noncore/net/opieirc/ircservertab.cpp3
-rw-r--r--noncore/net/opieirc/ircsession.cpp20
-rw-r--r--noncore/net/opieirc/ircsession.h4
-rw-r--r--noncore/net/opieirc/mainwindow.cpp4
-rw-r--r--noncore/net/opieirc/opieirc.pro6
15 files changed, 258 insertions, 91 deletions
diff --git a/noncore/net/opieirc/ircchannel.cpp b/noncore/net/opieirc/ircchannel.cpp
index 5c380e5..5d81596 100644
--- a/noncore/net/opieirc/ircchannel.cpp
+++ b/noncore/net/opieirc/ircchannel.cpp
@@ -1,47 +1,48 @@
#include "ircchannel.h"
+#include "ircchannelperson.h"
IRCChannel::IRCChannel(QString channelname) {
m_hasPeople = FALSE;
m_channelname = channelname;
}
IRCChannel::~IRCChannel() {
/* We want this to get deleted */
m_people.setAutoDelete(TRUE);
}
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) {
+ if (it.current()->nick() == nickname) {
return it.current();
}
}
return 0;
}
diff --git a/noncore/net/opieirc/ircchannel.h b/noncore/net/opieirc/ircchannel.h
index e78f182..a276f10 100644
--- a/noncore/net/opieirc/ircchannel.h
+++ b/noncore/net/opieirc/ircchannel.h
@@ -3,63 +3,52 @@
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
-};
+#include "ircperson.h"
-/* This struct encapsulates a IRCPerson and adds
- channel specific information */
-typedef struct IRCChannelPerson {
- IRCPerson *person;
- unsigned int flags;
-};
+class IRCChannelPerson;
/* 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);
~IRCChannel();
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;
diff --git a/noncore/net/opieirc/ircchannellist.cpp b/noncore/net/opieirc/ircchannellist.cpp
index c32c535..8cf144e 100644
--- a/noncore/net/opieirc/ircchannellist.cpp
+++ b/noncore/net/opieirc/ircchannellist.cpp
@@ -1,47 +1,49 @@
#include <qpe/resource.h>
+
#include "ircchannellist.h"
+#include "ircchannelperson.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, "1" + person->person->nick());
- } else if (person->flags & PERSON_FLAG_HALFOP) {
- insertItem(op, "2" + person->person->nick());
- } else if (person->flags & PERSON_FLAG_VOICE) {
- insertItem(voice, "3" + person->person->nick());
+ if (person->flags() & IRCChannelPerson::PERSON_FLAG_OP) {
+ insertItem(op, "1" + person->nick());
+ } else if (person->flags() & IRCChannelPerson::PERSON_FLAG_HALFOP) {
+ insertItem(op, "2" + person->nick());
+ } else if (person->flags() & IRCChannelPerson::PERSON_FLAG_VOICE) {
+ insertItem(voice, "3" + person->nick());
} else {
- insertItem("4" + person->person->nick());
+ insertItem("4" + person->nick());
}
}
sort();
adjustNicks();
}
bool IRCChannelList::hasPerson(QString nick) {
for (unsigned int i=0; i<count(); i++) {
if (text(i) == nick)
return TRUE;
}
return FALSE;
}
bool IRCChannelList::removePerson(QString nick) {
for (unsigned int i=0; i<count(); i++) {
if (text(i) == nick){
removeItem(i);
return TRUE;
}
}
return FALSE;
}
diff --git a/noncore/net/opieirc/ircchannelperson.cpp b/noncore/net/opieirc/ircchannelperson.cpp
new file mode 100644
index 0000000..1e8ebe4
--- a/dev/null
+++ b/noncore/net/opieirc/ircchannelperson.cpp
@@ -0,0 +1,62 @@
+#include "ircperson.h"
+#include "ircchannelperson.h"
+
+#include <qstring.h>
+#include <qobject.h>
+
+IRCChannelPerson::IRCChannelPerson(IRCPerson *person)
+{
+ m_person = person;
+ m_flags = 0;
+}
+
+IRCChannelPerson::~IRCChannelPerson()
+{
+ //if(m_person)
+ // delete m_person;
+}
+
+QString IRCChannelPerson::setOp(const QString &nickname, bool set)
+{
+ if(set) {
+ m_flags |= PERSON_FLAG_OP;
+ return ( nickname + QObject::tr(" gives channel operator status to ") + nick());
+ }
+
+ m_flags &= 0xFFFF - PERSON_FLAG_OP;
+ return ( nickname + QObject::tr(" removes channel operator status from ") + nick());
+}
+
+QString IRCChannelPerson::setVoice(const QString &nickname, bool set)
+{
+ if(set) {
+ m_flags |= PERSON_FLAG_VOICE;
+ return ( nickname + QObject::tr(" gives voice to ") + nick() );
+ }
+
+ m_flags &= 0xFFFF - PERSON_FLAG_VOICE;
+ return ( nickname + QObject::tr(" removes voice from ") + nick());
+}
+
+QString IRCChannelPerson::nick()
+{
+ if(m_person)
+ return m_person->nick();
+
+ return QString::null;
+}
+
+void IRCChannelPerson::setFlags(int flags)
+{
+ m_flags = flags;
+}
+
+void IRCChannelPerson::setNick(const QString &nickname)
+{
+ m_person->setNick(nickname);
+}
+
+const unsigned int IRCChannelPerson::flags()
+{
+ return m_flags;
+}
diff --git a/noncore/net/opieirc/ircchannelperson.h b/noncore/net/opieirc/ircchannelperson.h
new file mode 100644
index 0000000..a8c4791
--- a/dev/null
+++ b/noncore/net/opieirc/ircchannelperson.h
@@ -0,0 +1,34 @@
+#ifndef IRCCHANNELPERSON_H
+#define IRCCHANNELPERSON_H
+
+class QString;
+class IRCPerson;
+
+/* This class encapsulates a IRCPerson and adds
+ * channel specific information */
+class IRCChannelPerson {
+
+public:
+ /* Flags which a person can have inside a channel */
+ enum IRCChannelPersonFlag {
+ PERSON_FLAG_OP = 0x01,
+ PERSON_FLAG_VOICE = 0x02,
+ PERSON_FLAG_HALFOP = 0x04
+ };
+
+ IRCChannelPerson(IRCPerson *person = 0);
+ ~IRCChannelPerson();
+
+ QString setOp(const QString &nickname, bool set);
+ QString setVoice(const QString &nickname, bool set);
+ QString nick();
+ const unsigned int flags();
+ void setFlags(int flags);
+ void setNick(const QString &nickname);
+
+protected:
+ IRCPerson *m_person;
+ unsigned int m_flags;
+};
+
+#endif
diff --git a/noncore/net/opieirc/ircchanneltab.cpp b/noncore/net/opieirc/ircchanneltab.cpp
index 4a35929..3272a8a 100644
--- a/noncore/net/opieirc/ircchanneltab.cpp
+++ b/noncore/net/opieirc/ircchanneltab.cpp
@@ -1,72 +1,75 @@
#include <qpe/resource.h>
#include <qwhatsthis.h>
#include <qhbox.h>
#include <qdict.h>
#include "ircchanneltab.h"
#include "ircservertab.h"
#include "ircmessageparser.h"
+#include <opie2/odebug.h>
QDict<QString> IRCChannelTab::m_queuedMessages (17);
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_listButton->setFlat( true );
m_textview->setCornerWidget(m_listButton);
m_textview->setTextFormat(RichText);
QWhatsThis::add(m_textview, tr("Channel discussion"));
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 IRCHistoryLineEdit(this);
connect(m_field, SIGNAL(nextTab()), this, SIGNAL(nextTab()));
connect(m_field, SIGNAL(prevTab()), this, SIGNAL(prevTab()));
connect(m_field, SIGNAL(closeTab()), this, SLOT(remove()));
connect(this, SIGNAL(editFocus()), m_field, SLOT(setEditFocus()));
QWhatsThis::add(m_field, tr("Type your message here to participate in the channel discussion"));
m_popup = new QPopupMenu(m_list);
m_lines = 0;
/* Required so that embedded-style "right" clicks work */
QPEApplication::setStylusOperation(m_list->viewport(), QPEApplication::RightOnHold);
connect(m_list, SIGNAL(mouseButtonPressed(int,QListBoxItem*,const QPoint&)), this, SLOT(mouseButtonPressed(int,QListBoxItem*,const QPoint&)));
/* Construct the popup menu */
- QPopupMenu *ctcpMenu = new QPopupMenu(m_list);
+ //QPopupMenu *ctcpMenu = new QPopupMenu(m_list);
m_popup->insertItem(Resource::loadPixmap("opieirc/query"), tr("Query"), this, SLOT(popupQuery()));
- ctcpMenu->insertItem(Resource::loadPixmap("opieirc/ping"), tr("Ping"), this, SLOT(popupPing()));
- ctcpMenu->insertItem(Resource::loadPixmap("opieirc/version"), tr("Version"), this, SLOT(popupVersion()));
- ctcpMenu->insertItem(Resource::loadPixmap("opieirc/whois"), tr("Whois"), this, SLOT(popupWhois()));
+ m_popup->insertSeparator();
+ m_popup->insertItem(Resource::loadPixmap("opieirc/ping"), tr("Ping"), this, SLOT(popupPing()));
+ m_popup->insertItem(Resource::loadPixmap("opieirc/version"), tr("Version"), this, SLOT(popupVersion()));
+ m_popup->insertItem(Resource::loadPixmap("opieirc/whois"), tr("Whois"), this, SLOT(popupWhois()));
+ //m_popup->insertItem(ctcpMenu, "CTCP");
connect(m_mainWindow, SIGNAL(updateScroll()), this, SLOT(scrolling()));
m_layout->add(hbox);
hbox->show();
m_layout->add(m_field);
m_field->setFocus();
m_field->setActiveWindow();
connect(m_field, SIGNAL(returnPressed()), this, SLOT(processCommand()));
connect(m_list, SIGNAL(doubleClicked ( QListBoxItem * ) ), this, SLOT(popupQuery( QListBoxItem * ) ));
settingsChanged();
if(m_queuedMessages[m_channel->channelname()]) {
appendText(*m_queuedMessages[m_channel->channelname()]);
delete m_queuedMessages[m_channel->channelname()];
m_queuedMessages.remove(m_channel->channelname());
}
}
void IRCChannelTab::scrolling(){
m_textview->ensureVisible(0, m_textview->contentsHeight());
}
void IRCChannelTab::appendText(QString text) {
/* not using append because it creates layout problems */
@@ -145,55 +148,60 @@ void IRCChannelTab::mouseButtonPressed(int mouse, QListBoxItem *, const QPoint &
break;
};
}
void IRCChannelTab::popupQuery( QListBoxItem *item) {
if (item) {
IRCPerson *person = session()->getPerson(item->text());
if (person) {
IRCQueryTab *tab = m_parentTab->getTabForQuery(person);
if (!tab) {
tab = new IRCQueryTab(person, m_parentTab, m_mainWindow, (QWidget *)parent());
m_parentTab->addQueryTab(tab);
m_mainWindow->addTab(tab);
}
}
}
}
void IRCChannelTab::popupQuery() {
if ( m_list->currentItem() != -1 )
popupQuery( m_list->item(m_list->currentItem()));
}
void IRCChannelTab::popupPing() {
- //HAHA, no wonder these don't work
+ if(m_list->currentItem() != -1)
+ m_parentTab->session()->sendCTCPPing(m_list->text(m_list->currentItem()));
}
void IRCChannelTab::popupVersion() {
+ if(m_list->currentItem() != -1)
+ m_parentTab->session()->sendCTCPRequest(m_list->text(m_list->currentItem()), "VERSION", "");
}
void IRCChannelTab::popupWhois() {
+ if(m_list->currentItem() != -1)
+ m_parentTab->session()->whois(m_list->text(m_list->currentItem()));
}
QString IRCChannelTab::title() {
return m_channel->channelname();
}
IRCSession *IRCChannelTab::session() {
return m_parentTab->session();
}
void IRCChannelTab::remove() {
if (session()->isSessionActive()) {
session()->part(m_channel);
} else {
m_mainWindow->killTab(this);
}
}
void IRCChannelTab::enqueue(const QString &channel, const QString &message) {
if (m_queuedMessages.count() == (m_queuedMessages.size() - 1) )
/* 17 messages max */
return;
m_queuedMessages.insert(channel, new QString(message));
}
diff --git a/noncore/net/opieirc/ircconnection.cpp b/noncore/net/opieirc/ircconnection.cpp
index 2325cca..88e63f7 100644
--- a/noncore/net/opieirc/ircconnection.cpp
+++ b/noncore/net/opieirc/ircconnection.cpp
@@ -1,56 +1,75 @@
#include <unistd.h>
#include <string.h>
+
+#include <qstringlist.h>
+#include <qdatetime.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");
+void IRCConnection::sendCTCPReply(const QString &nickname, const QString &type, const QString &args) {
+ sendLine("NOTICE " + nickname + " :\001" + type + " " + args + "\001");
+}
+
+void IRCConnection::sendCTCPRequest(const QString &nickname, const QString &type, const QString &args) {
+ sendLine("PRIVMSG " + nickname + " :\001" + type + " " + args + "\001");
+}
+
+void IRCConnection::sendCTCPPing(const QString &nickname) {
+ QDateTime tm;
+ tm.setTime_t(0);
+ QString strtime = QString::number(tm.secsTo(QDateTime::currentDateTime()));
+ sendCTCPRequest(nickname, "PING", strtime);
+}
+
+void IRCConnection::whois(const QString &nickname) {
+ sendLine("WHOIS " + nickname);
}
/*
* 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);
}
@@ -79,24 +98,25 @@ void IRCConnection::dataReady() {
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
index 75cdf6d..382b1c0 100644
--- a/noncore/net/opieirc/ircconnection.h
+++ b/noncore/net/opieirc/ircconnection.h
@@ -16,49 +16,53 @@
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 sendCTCPReply(const QString &nickname, const QString &type, const QString &args);
+ void sendCTCPRequest(const QString &nickname, const QString &type, const QString &args);
+ void sendCTCPPing(const QString &nickname);
+ void whois(const QString &nickname);
+ void sendCTCPping(const QString &nickname);
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;
};
diff --git a/noncore/net/opieirc/ircmessageparser.cpp b/noncore/net/opieirc/ircmessageparser.cpp
index cfad2c1..9c1492c 100644
--- a/noncore/net/opieirc/ircmessageparser.cpp
+++ b/noncore/net/opieirc/ircmessageparser.cpp
@@ -1,163 +1,174 @@
#include <qtextstream.h>
#include <qdatetime.h>
#include "ircmessageparser.h"
#include "ircversion.h"
+#include "ircchannelperson.h"
+//#include "transferreceiver.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) },
{ "TOPIC", FUNC(parseLiteralTopic) },
{ 0 , 0 }
};
/* Lookup table for literal commands */
IRCCTCPMessageParserStruct IRCMessageParser::ctcpParserProcTable[] = {
{ "PING", FUNC(parseCTCPPing) },
{ "VERSION", FUNC(parseCTCPVersion) },
{ "ACTION", FUNC(parseCTCPAction) },
+ { "DCC", FUNC(parseCTCPDCC) },
{ 0 , 0 }
};
/* Lookup table for numerical commands
* According to:
* http://www.faqs.org/rfcs/rfc1459.html
* http://www.faqs.org/rfcs/rfc2812.html
*/
IRCNumericalMessageParserStruct IRCMessageParser::numericalParserProcTable[] = {
{ 1, "%1", "1", FUNC(parseNumericalServerName) }, // RPL_WELCOME
{ 2, "%1", "1", 0 }, // RPL_YOURHOST
{ 3, "%1", "1", 0 }, // RPL_CREATED
{ 4, QT_TR_NOOP("Server %1 version %2 supports usermodes '%3' and channelmodes '%4'"), "1:4", FUNC(parseNumericalServerFeatures) }, // RPL_MYINFO
{ 5, 0, 0, FUNC(parseNumericalServerProtocol) }, // RPL_BOUNCE, RPL_PROTOCTL
{ 250, "%1", "1", 0 }, // RPL_STATSCONN
{ 251, "%1", "1", 0 }, // RPL_LUSERCLIENT
{ 252, QT_TR_NOOP("There are %1 operators connected"), "1", 0 }, // RPL_LUSEROP
{ 253, QT_TR_NOOP("There are %1 unknown connection(s)"), "1", 0 }, // RPL_LUSERUNKNOWN
{ 254, QT_TR_NOOP("There are %1 channels formed"), "1", 0 }, // RPL_LUSERCHANNELS
{ 255, "%1", "1", 0 }, // RPL_LUSERME
{ 263, QT_TR_NOOP("Please wait a while and try again"), 0, 0 }, // RPL_TRYAGAIN
{ 265, "%1", "1", 0 }, // RPL_LOCALUSERS
{ 266, "%1", "1", 0 }, // RPL_GLOBALUSERS
- { 311, QT_TR_NOOP("Whois %1 (%2@%3)\nReal name: %4"), "1:3,5" }, // RPL_WHOISUSER
+ { 311, QT_TR_NOOP("Whois %1 (%2@%3)\nReal name: %4"), "1:3,5", 0 }, // RPL_WHOISUSER
{ 312, QT_TR_NOOP("%1 is using server %2"), "1,2", 0 }, // RPL_WHOISSERVER
{ 317, 0, 0, FUNC(parseNumericalWhoisIdle) }, // RPL_WHOISIDLE
{ 318, "%1 :%2", "1,2", 0 }, // RPL_ENDOFWHOIS
+ { 319, QT_TR_NOOP("%1 is on channels: %2"), "1,2", 0 }, // RPL_WHOISCHANNELS
{ 320, "%1 %2", "1,2", 0}, // RPL_WHOISVIRT
{ 332, 0, 0, FUNC(parseNumericalTopic) }, // RPL_TOPIC
{ 333, 0, 0, FUNC(parseNumericalTopicWhoTime) }, // RPL_TOPICWHOTIME*/
{ 353, QT_TR_NOOP("Names for %1: %2"), "2,3", FUNC(parseNumericalNames) }, // RPL_NAMREPLY
{ 366, "%1 :%2", "1,2", FUNC(parseNumericalEndOfNames) }, // RPL_ENDOFNAMES
{ 369, "%1 :%2", "1,2", 0 }, // RPL_ENDOFWHOWAS
{ 372, "%1", "1", 0 }, // RPL_MOTD
{ 375, "%1", "1", 0 }, // RPL_MOTDSTART
{ 376, "%1", "1", 0 }, // RPL_ENDOFMOTD
{ 377, "%1", "1", 0 }, // RPL_MOTD2
{ 378, "%1", "1", 0 }, // RPL_MOTD3
{ 391, QT_TR_NOOP("Time on server %1 is %2"), "1,2", 0 }, // RPL_TIME
{ 401, QT_TR_NOOP("Channel or nick %1 doesn't exists"), "1", 0 }, // ERR_NOSUCHNICK
- { 406, QT_TR_NOOP("There is no history information for %1"), "1" }, // ERR_WASNOSUCHNICK
+ { 406, QT_TR_NOOP("There is no history information for %1"), "1", 0 }, // ERR_WASNOSUCHNICK
{ 409, "%1", "1", 0 }, // ERR_NOORIGIN
{ 411, "%1", "1", 0 }, // ERR_NORECIPIENT
{ 412, "%1", "1", 0 }, // ERR_NOTEXTTOSEND
{ 421, QT_TR_NOOP("Unknown command: %1"), "1", 0 }, // ERR_ERR_UNKNOWNCOMMAND
{ 422, "%1", "1", 0 }, // ERR_NOMOTD
{ 433, QT_TR_NOOP("Can't change nick to %1: %2"), "1,2", FUNC(parseNumericalNicknameInUse) }, // ERR_NICKNAMEINUSE
{ 442, QT_TR_NOOP("You're not on channel %1"), "1", 0}, // ERR_NOTONCHANNEL
{ 477, "%1", "1", 0 }, // ERR_NOCHANMODES || ERR_NEEDREGGEDNICK
{ 482, QT_TR_NOOP("[%1] Operation not permitted, you don't have enough channel privileges"), "1", 0 }, //ERR_CHANOPRIVSNEEDED
{ 0, 0, 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) {
parseNumerical(message, i);
return;
}
}
emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Received unhandled numeric command: %1").arg( 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);
+ parseCTCP(message, i);
return;
}
}
emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Received unhandled ctcp command: %1").arg( 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: %1").arg( message->command()) ));
}
}
void IRCMessageParser::parseNumerical(IRCMessage *message, int position) {
QString out = tr(numericalParserProcTable[position].message);
QString paramString = numericalParserProcTable[position].params;
if(!out.isEmpty() && !paramString.isEmpty()) {
QStringList params = message->params(numericalParserProcTable[position].params);
QStringList::Iterator end = params.end();
for (QStringList::Iterator it = params.begin(); it != end; ++it) {
out = out.arg(*it);
}
emit outputReady(IRCOutput(OUTPUT_SERVERMESSAGE, out));
}
if(numericalParserProcTable[position].proc)
(this->*(numericalParserProcTable[position].proc))(message);
}
+void IRCMessageParser::parseCTCP(IRCMessage *message, int position) {
+ if(ctcpParserProcTable[position].proc)
+ (this->*(ctcpParserProcTable[position].proc))(message);
+}
+
+
+
void IRCMessageParser::parseNumericalServerName(IRCMessage *message) {
emit outputReady(IRCOutput(OUTPUT_TITLE, tr("Connected to")+" <b>" + message->prefix() + "</b>"));
- /* Register EFFECTIVE nickname, some networks (as irc-hispano) uses nick:password
+ /* Register EFFECTIVE nickname, some networks (as irc-hispano) use nick:password
* for authentication and the parser gets confused */
m_session->m_server->setNick(message->param(0));
}
void IRCMessageParser::parseNumericalServerFeatures(IRCMessage *message) {
m_session->setValidUsermodes(message->param(2));
m_session->setValidChannelmodes(message->param(3));
}
void IRCMessageParser::parseNumericalServerProtocol(IRCMessage *message) {
/* XXX: Add some usefull features here */
QString out = message->allParameters();
out = out.mid(out.find(' ')+1);
emit outputReady(IRCOutput(OUTPUT_SERVERMESSAGE, out));
}
void IRCMessageParser::parseNumericalWhoisIdle(IRCMessage *message) {
QDateTime dt;
QTime t;
t = t.addSecs(message->param(2).toInt());
dt.setTime_t(message->param(3).toInt());
emit outputReady(IRCOutput(OUTPUT_SERVERMESSAGE, tr("%1 has been idle for %2").arg(message->param(1)).arg(t.toString())));
@@ -168,56 +179,54 @@ void IRCMessageParser::parseNumericalWhoisIdle(IRCMessage *message) {
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).lower();
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;
+ IRCChannelPerson *chanperson = new IRCChannelPerson(person);
channel->addPerson(chanperson);
IRCOutput output(OUTPUT_OTHERJOIN ,tr("%1 joined channel %2").arg( mask.nick() ).arg( 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).lower();
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 %1").arg( channelName ));
output.addParam(channel);
emit outputReady(output);
@@ -334,264 +343,271 @@ void IRCMessageParser::parseLiteralQuit(IRCMessage *message) {
delete person;
} else {
emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Unknown person quit - desynchronized?")));
}
}
void IRCMessageParser::parseLiteralTopic(IRCMessage *message) {
IRCPerson mask(message->prefix());
IRCChannel *channel = m_session->getChannel(message->param(0).lower());
if (channel) {
IRCOutput output(OUTPUT_TOPIC, mask.nick() + tr(" changed topic to ") + "\"" + message->param(1) + "\"");
output.addParam(channel);
emit outputReady(output);
} else {
emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Unknown channel topic - 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()));
+ m_session->m_connection->sendCTCPReply(mask.nick(), "PING", message->allParameters());
+ emit outputReady(IRCOutput(OUTPUT_CTCP, tr("Received a CTCP PING from ") + mask.nick()));
//IRCPerson mask(message->prefix());
QString dest = message->ctcpDestination();
if (dest.startsWith("#")) {
IRCChannel *channel = m_session->getChannel(dest.lower());
if (channel) {
IRCChannelPerson *person = channel->getPerson(mask.nick());
if (person) {
IRCOutput output(OUTPUT_CHANACTION, tr("Received a CTCP PING from ")+ mask.nick()) ;
output.addParam(channel);
output.addParam(person);
emit outputReady(output);
} else {
emit outputReady(IRCOutput(OUTPUT_ERROR, tr("CTCP PING with unknown person - Desynchronized?")));
}
} else {
emit outputReady(IRCOutput(OUTPUT_ERROR, tr("CTCP PING 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, tr("Received a CTCP PING from ")+ mask.nick() );
output.addParam(person);
emit outputReady(output);
} else {
emit outputReady(IRCOutput(OUTPUT_ERROR, tr("CTCP PING with bad recipient")));
}
}
}
void IRCMessageParser::parseCTCPVersion(IRCMessage *message) {
IRCPerson mask(message->prefix());
- m_session->m_connection->sendCTCP(mask.nick(), "VERSION " APP_VERSION " " APP_COPYSTR);
- emit outputReady(IRCOutput(OUTPUT_CTCP, tr("Received a CTCP VERSION from ")+mask.nick()));
+ IRCOutput output(OUTPUT_CTCP);
+ if(message->isCTCPRequest()) {
+ m_session->m_connection->sendCTCPReply(mask.nick(), "VERSION", APP_VERSION " " APP_COPYSTR);
+ output.setMessage(tr("Received a CTCP VERSION request from ") + mask.nick());
+ }
+
+ else {
+ output.setMessage("Received CTCP VERSION reply from " + mask.nick() + ":" + message->param(0));
+ }
+ emit outputReady(output);
}
void IRCMessageParser::parseCTCPAction(IRCMessage *message) {
IRCPerson mask(message->prefix());
QString dest = message->ctcpDestination();
if (dest.startsWith("#")) {
IRCChannel *channel = m_session->getChannel(dest.lower());
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::parseCTCPDCC(IRCMessage *message) {
+ QStringList params = QStringList::split(' ', message->param(0).stripWhiteSpace());
+ if( params.count() != 5) {
+ emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Malformed DCC request from ") + IRCPerson(message->prefix()).nick()));
+ return;
+ }
+
+ //TransferReceiver *foo = new TransferReceiver(params[2].toUInt(), params[3].toUInt(), params[1], params[4].toUInt());
+}
+
void IRCMessageParser::parseLiteralMode(IRCMessage *message) {
IRCPerson mask(message->prefix());
if (message->param(0).startsWith("#")) {
IRCChannel *channel = m_session->getChannel(message->param(0).lower());
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;
- }
+ }
+ 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 {
+ IRCOutput output(OUTPUT_CHANPERSONMODE, person->setOp(mask.nick(), set));
+ 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()));
+ }
+ else
+ if (temp == "v") {
+ stream >> temp;
+ IRCChannelPerson *person = channel->getPerson(temp);
+ if (person) {
+ IRCOutput output(OUTPUT_CHANPERSONMODE, person->setVoice(mask.nick(), set));
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 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 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).lower());
if (channel) {
IRCChannelPerson *person = channel->getPerson(message->param(1));
if (person) {
- if (person->person->nick() == m_session->m_server->nick()) {
+ if (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 {
/* someone else got kicked */
channel->removePerson(person);
- IRCOutput output(OUTPUT_OTHERKICK, person->person->nick() + tr(" was kicked from ") + channel->channelname() + tr(" by ") + mask.nick()+ " (" + message->param(2) + ")");
+ IRCOutput output(OUTPUT_OTHERKICK, 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::parseNumericalNames(IRCMessage *message) {
/* Name list sent when joining a channel */
IRCChannel *channel = m_session->getChannel(message->param(2).lower());
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;
+ case '@': flag = IRCChannelPerson::PERSON_FLAG_OP; break;
+ case '+': flag = IRCChannelPerson::PERSON_FLAG_VOICE; break;
+ case '%': flag = IRCChannelPerson::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;
+ IRCChannelPerson *chan_person = new IRCChannelPerson(person);
+ chan_person->setFlags(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).lower());
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 *) {
/* If we are connnected this error is not critical */
diff --git a/noncore/net/opieirc/ircmessageparser.h b/noncore/net/opieirc/ircmessageparser.h
index 2fca61e..4ebbddd 100644
--- a/noncore/net/opieirc/ircmessageparser.h
+++ b/noncore/net/opieirc/ircmessageparser.h
@@ -54,46 +54,48 @@ typedef struct IRCNumericalMessageParserStruct {
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 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 parseLiteralTopic(IRCMessage *message);
void parseNumerical(IRCMessage *message, int position);
+ void parseCTCP(IRCMessage *message, int position);
void parseNumericalServerName(IRCMessage *message);
void parseNumericalServerFeatures(IRCMessage *message);
void parseNumericalServerProtocol(IRCMessage *message);
void parseNumericalWhoisIdle(IRCMessage *message);
void parseNumericalNames(IRCMessage *message);
void parseNumericalEndOfNames(IRCMessage *message);
void parseNumericalNicknameInUse(IRCMessage *message);
void parseNumericalNoSuchNick(IRCMessage *message);
void parseNumericalTopic(IRCMessage *message);
void parseNumericalTopicWhoTime(IRCMessage *message);
void parseCTCPPing(IRCMessage *message);
void parseCTCPVersion(IRCMessage *message);
void parseCTCPAction(IRCMessage *message);
+ void parseCTCPDCC(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/ircservertab.cpp b/noncore/net/opieirc/ircservertab.cpp
index 90353f2..bddc37e 100644
--- a/noncore/net/opieirc/ircservertab.cpp
+++ b/noncore/net/opieirc/ircservertab.cpp
@@ -1,29 +1,30 @@
#include <qtextstream.h>
#include <qwhatsthis.h>
#include "ircservertab.h"
#include "ircmessageparser.h"
+#include "ircchannelperson.h"
bool IRCServerTab::containsPing( const QString& text, IRCServerTab* tab ) {
return (text.contains(IRCMessageParser::tr("Received a CTCP PING from "))) ||
(text.find("ping") != -1 && text.find( tab->server()->nick() != -1));
}
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_lines = 0;
m_description->setText(tr("Connecting 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_textview->setTextFormat(RichText);
QWhatsThis::add(m_textview, tr("Server messages"));
m_layout->add(m_textview);
m_field = new IRCHistoryLineEdit(this);
connect(m_field, SIGNAL(nextTab()), this, SIGNAL(nextTab()));
connect(m_field, SIGNAL(prevTab()), this, SIGNAL(prevTab()));
@@ -290,49 +291,49 @@ void IRCServerTab::display(IRCOutput output) {
while (m_channelTabs.current() != 0) {
m_mainWindow->killTab(m_channelTabs.current(), true);
}
m_queryTabs.first();
while (m_queryTabs.current() != 0) {
m_mainWindow->killTab(m_queryTabs.current(), true);
}
m_mainWindow->killTab(this);
} else {
appendText("<font color=\"" + m_errorColor + "\">" + output.htmlMessage() +"</font><br>");
QListIterator<IRCChannelTab> it(m_channelTabs);
for (; it.current(); ++it) {
it.current()->appendText("<font color=\"" + m_serverColor + "\">" + output.htmlMessage() +"</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=\"" + m_textColor + "\">&lt;</font><font color=\"" + m_otherColor + "\">"+IRCOutput::toHTML(((IRCChannelPerson *)output.getParam(1))->person->nick())+"</font><font color=\"" + m_textColor + "\">&gt; " + output.htmlMessage()+"</font><br>");
+ channelTab->appendText("<font color=\"" + m_textColor + "\">&lt;</font><font color=\"" + m_otherColor + "\">"+IRCOutput::toHTML(((IRCChannelPerson *)output.getParam(1))->nick())+"</font><font color=\"" + m_textColor + "\">&gt; " + output.htmlMessage()+"</font><br>");
}
break;
case OUTPUT_QUERYACTION:
case OUTPUT_QUERYPRIVMSG: {
IRCQueryTab *queryTab = getTabForQuery((IRCPerson *)output.getParam(0));
if (!queryTab) {
queryTab = new IRCQueryTab((IRCPerson *)output.getParam(0), this, m_mainWindow, (QWidget *)parent());
m_queryTabs.append(queryTab);
m_mainWindow->addTab(queryTab);
}
queryTab->display(output);
}
break;
case OUTPUT_SELFPART: {
IRCChannelTab *channelTab = getTabForChannel((IRCChannel *)output.getParam(0));
if (channelTab)
m_mainWindow->killTab(channelTab, true);
}
break;
case OUTPUT_SELFKICK: {
appendText("<font color=\"" + m_errorColor + "\">" + output.htmlMessage() + "</font><br>");
IRCChannelTab *channelTab = getTabForChannel((IRCChannel *)output.getParam(0));
if (channelTab)
m_mainWindow->killTab(channelTab, true);
diff --git a/noncore/net/opieirc/ircsession.cpp b/noncore/net/opieirc/ircsession.cpp
index ca0df50..80a327a 100644
--- a/noncore/net/opieirc/ircsession.cpp
+++ b/noncore/net/opieirc/ircsession.cpp
@@ -1,26 +1,28 @@
+
#include "ircsession.h"
#include "ircmessageparser.h"
+#include "ircchannelperson.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() {
/* We want this to get deleted automatically */
m_channels.setAutoDelete(TRUE);
m_people.setAutoDelete(TRUE);
delete m_parser;
delete m_connection;
}
void IRCSession::beginSession() {
m_connection->doConnect();
}
@@ -116,49 +118,49 @@ void IRCSession::updateNickname(const QString &oldNickname, const QString &newNi
IRCOutput output;
if (oldNickname == m_server->nick()) {
m_server->setNick(newNickname);
output = IRCOutput(OUTPUT_NICKCHANGE, tr("You are now known as %1").arg(newNickname));
channels = m_channels;
}
else {
IRCPerson *person = getPerson(oldNickname);
if(!person) {
emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Nickname change of an unknown person")));
return;
}
getChannelsByPerson(person, channels);
output = IRCOutput(OUTPUT_NICKCHANGE, tr("%1 is now known as %2").arg(oldNickname).arg(newNickname));
}
QListIterator<IRCChannel> it(channels);
for (;it.current(); ++it) {
IRCChannelPerson *chanperson = it.current()->getPerson(oldNickname);
it.current()->removePerson(chanperson);
- chanperson->person->setNick(newNickname);
+ chanperson->setNick(newNickname);
it.current()->addPerson(chanperson);
}
emit updateChannels();
output.addParam(new QString(newNickname));
emit outputReady(output);
}
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();
}
@@ -173,24 +175,40 @@ void IRCSession::getChannelsByPerson(IRCPerson *person, QList<IRCChannel> &chann
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);
}
+
+void IRCSession::whois(const QString &nickname) {
+ m_connection->whois(nickname);
+}
+
+void IRCSession::sendCTCPPing(const QString &nickname) {
+ m_connection->sendCTCPPing(nickname);
+}
+
+void IRCSession::sendCTCPRequest(const QString &nickname, const QString &type, const QString &args) {
+ m_connection->sendCTCPRequest(nickname, type, args);
+}
+
+void IRCSession::sendCTCPReply(const QString &nickname, const QString &type, const QString &args) {
+ m_connection->sendCTCPReply(nickname, type, args);
+}
diff --git a/noncore/net/opieirc/ircsession.h b/noncore/net/opieirc/ircsession.h
index 96de3e4..3859b68 100644
--- a/noncore/net/opieirc/ircsession.h
+++ b/noncore/net/opieirc/ircsession.h
@@ -44,48 +44,52 @@ public:
void join(QString channel);
void quit(QString message);
void quit();
void raw(QString message);
void topic(IRCChannel *channel, QString message);
void mode(IRCChannel *channel, QString message);
void mode(IRCPerson *person, QString message);
void mode(QString message);
void part(IRCChannel *channel);
void op(IRCChannel *channel, IRCPerson *person);
void kick(IRCChannel *channel, IRCPerson *person);
void kick(IRCChannel *channel, IRCPerson *person, QString message);
void beginSession();
bool isSessionActive();
void endSession();
bool isLoggedIn();
void sendMessage(IRCPerson *person, QString message);
void sendMessage(IRCChannel *channel, QString message);
void sendAction(IRCPerson *person, QString message);
void sendAction(IRCChannel *channel, QString message);
void updateNickname(const QString &oldNickname, const QString &newNickname);
void setValidUsermodes(const QString &modes);
void setValidChannelmodes(const QString &modes);
+ void whois(const QString &nickname);
+ void sendCTCPPing(const QString &nickname);
+ void sendCTCPRequest(const QString &nickname, const QString &type, const QString &args);
+ void sendCTCPReply(const QString &nickname, const QString &type, const QString &args);
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);
void updateChannels();
protected:
IRCServer *m_server;
IRCConnection *m_connection;
IRCMessageParser *m_parser;
QList<IRCChannel> m_channels;
QList<IRCPerson> m_people;
QString m_validUsermodes;
QString m_validChannelmodes;
};
#endif /* __IRCSESSION_H */
diff --git a/noncore/net/opieirc/mainwindow.cpp b/noncore/net/opieirc/mainwindow.cpp
index 2562f33..1811a0c 100644
--- a/noncore/net/opieirc/mainwindow.cpp
+++ b/noncore/net/opieirc/mainwindow.cpp
@@ -1,26 +1,29 @@
#include <qmenubar.h>
#include <qpe/resource.h>
+
+#include <opie2/odebug.h>
+
#include <qwhatsthis.h>
#include "mainwindow.h"
#include "ircservertab.h"
#include "ircserverlist.h"
#include "ircsettings.h"
QString MainWindow::appCaption() {
return QObject::tr("Opie IRC");
}
MainWindow::MainWindow(QWidget *parent, const char *name, WFlags) : QMainWindow(parent, name, WStyle_ContextHelp) {
setCaption(tr("IRC Client"));
m_tabWidget = new IRCTabWidget(this);
QWhatsThis::add(m_tabWidget, tr("Server connections, channels, queries and other things will be placed here"));
connect(m_tabWidget, SIGNAL(currentChanged(QWidget*)), this, SLOT(selected(QWidget*)));
setCentralWidget(m_tabWidget);
setToolBarsMovable(FALSE);
QMenuBar *menuBar = new QMenuBar(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()));
@@ -64,48 +67,49 @@ void MainWindow::addTab(IRCTab *tab) {
m_tabWidget->addTab(tab, tab->title());
m_tabWidget->showPage(tab);
tab->setID(m_tabWidget->currentPageIndex());
m_tabs.append(tab);
}
void MainWindow::changeEvent(IRCTab *tab) {
if (tab->id() != m_tabWidget->currentPageIndex())
m_tabWidget->setTabColor(tab->id(), blue);
}
void MainWindow::killTab(IRCTab *tab, bool imediate) {
m_toDelete.append( tab );
if ( imediate )
slotKillTabsLater();
else
QTimer::singleShot(0, this, SLOT(slotKillTabsLater()) );
}
void MainWindow::slotKillTabsLater() {
for ( QListIterator<IRCTab> it(m_toDelete); it.current(); ++it ) {
m_tabWidget->removePage( it.current() );
+ odebug << it.current() << oendl;
m_tabs.remove( it.current() );
}
m_toDelete.setAutoDelete( true );
m_toDelete.clear();
m_toDelete.setAutoDelete( false );
}
void MainWindow::newConnection() {
IRCServerList list(this, "ServerList", TRUE);
if (list.exec() == QDialog::Accepted && list.hasServer()) {
IRCServerTab *serverTab = new IRCServerTab(list.server(), this, m_tabWidget);
addTab(serverTab);
serverTab->doConnect();
}
}
void MainWindow::settings() {
IRCSettings settings(this, "Settings", TRUE);
if (settings.exec() == QDialog::Accepted) {
QListIterator<IRCTab> it(m_tabs);
for (; it.current(); ++it) {
/* Inform all tabs about the new settings */
it.current()->settingsChanged();
diff --git a/noncore/net/opieirc/opieirc.pro b/noncore/net/opieirc/opieirc.pro
index db89fa6..1ef9be2 100644
--- a/noncore/net/opieirc/opieirc.pro
+++ b/noncore/net/opieirc/opieirc.pro
@@ -1,28 +1,30 @@
CONFIG = qt warn_on quick-app
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 \
- ircquerytab.h ircsettings.h ircmisc.h
+ ircquerytab.h ircsettings.h ircmisc.h \
+ ircchannelperson.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 \
- ircquerytab.cpp ircsettings.cpp ircmisc.cpp
+ ircquerytab.cpp ircsettings.cpp ircmisc.cpp \
+ ircchannelperson.cpp
INCLUDEPATH += $(OPIEDIR)/include
DEPENDPATH += $(OPIEDIR)/include
PRECOMPILED_HEADER = stable.h
LIBS += -lqpe -lopiecore2 -lopieui2 -lqtaux2
TARGET = opieirc
include( $(OPIEDIR)/include.pro )