summaryrefslogtreecommitdiff
authorskyhusker <skyhusker>2005-02-03 21:47:50 (UTC)
committer skyhusker <skyhusker>2005-02-03 21:47:50 (UTC)
commit8aaae9e3eca7853e9c693d2401f721d75209acf7 (patch) (side-by-side diff)
tree6f700d154fac8510b322242496604d0ad7589377
parent875b3b63624308f4e50f82e17db27edeb9609d6c (diff)
downloadopie-8aaae9e3eca7853e9c693d2401f721d75209acf7.zip
opie-8aaae9e3eca7853e9c693d2401f721d75209acf7.tar.gz
opie-8aaae9e3eca7853e9c693d2401f721d75209acf7.tar.bz2
Added DCC receive support
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/net/opieirc/dccprogress.cpp75
-rw-r--r--noncore/net/opieirc/dccprogress.h35
-rw-r--r--noncore/net/opieirc/dcctransfer.cpp41
-rw-r--r--noncore/net/opieirc/dcctransfer.h44
-rw-r--r--noncore/net/opieirc/dcctransferrecv.cpp53
-rw-r--r--noncore/net/opieirc/dcctransferrecv.h21
-rw-r--r--noncore/net/opieirc/dcctransfertab.cpp81
-rw-r--r--noncore/net/opieirc/dcctransfertab.h41
-rw-r--r--noncore/net/opieirc/ircmessageparser.cpp30
-rw-r--r--noncore/net/opieirc/ircservertab.cpp4
-rw-r--r--noncore/net/opieirc/ircservertab.h1
-rw-r--r--noncore/net/opieirc/ircsession.cpp5
-rw-r--r--noncore/net/opieirc/ircsession.h4
-rw-r--r--noncore/net/opieirc/mainwindow.cpp20
-rw-r--r--noncore/net/opieirc/mainwindow.h8
-rw-r--r--noncore/net/opieirc/opieirc.pro9
16 files changed, 459 insertions, 13 deletions
diff --git a/noncore/net/opieirc/dccprogress.cpp b/noncore/net/opieirc/dccprogress.cpp
new file mode 100644
index 0000000..28277f7
--- a/dev/null
+++ b/noncore/net/opieirc/dccprogress.cpp
@@ -0,0 +1,75 @@
+#include <qprogressbar.h>
+#include <qlabel.h>
+#include <qvbox.h>
+
+#include "dcctransfer.h"
+#include "dcctransferrecv.h"
+#include "dccprogress.h"
+
+DCCProgress::DCCProgress(DCCTransfer::Type type, Q_UINT32 ip4Addr, Q_UINT16 port,
+ const QString &filename, const QString &nickname, unsigned int size, QWidget *parent, char *name, WFlags f)
+ : QWidget(parent, name, f), m_vbox(new QVBox(this)),
+ m_label(new QLabel(m_vbox)),
+ m_bar(new QProgressBar(m_vbox))
+{
+
+ if (DCCTransfer::Recv == type)
+ m_transfer = new DCCTransferRecv(ip4Addr, port, filename, size);
+
+
+ connect(m_transfer, SIGNAL(progress(int)), this, SLOT(slotSetProgress(int)));
+ connect(m_transfer, SIGNAL(finished(DCCTransfer *, DCCTransfer::EndCode)),
+ this, SLOT(slotFinished(DCCTransfer *, DCCTransfer::EndCode)));
+
+ m_label->setText(tr("Receiving file %1 from %2...").arg(m_transfer->filename()).arg(nickname));
+
+ m_label->show();
+ m_bar->show();
+ show();
+
+}
+
+bool DCCProgress::finished()
+{
+ return ( m_transfer == 0);
+}
+
+void DCCProgress::cancel()
+{
+ if (m_transfer)
+ m_transfer->cancel();
+}
+
+void DCCProgress::slotSetProgress(int progress)
+{
+ m_bar->setProgress(progress);
+}
+
+void DCCProgress::slotFinished(DCCTransfer *transfer, DCCTransfer::EndCode code)
+{
+ if(transfer != m_transfer)
+ // WTF!!
+ return;
+
+ QString msg;
+
+ switch(code) {
+ case DCCTransfer::Successfull:
+ msg = tr("Successfully received %1").arg(m_transfer->filename());
+ break;
+ case DCCTransfer::SelfAborted:
+ msg = tr("Aborted");
+ break;
+ case DCCTransfer::PeerAborted:
+ msg = tr("Peer Aborted");
+ break;
+ case DCCTransfer::Timeout:
+ msg = tr("Timeout");
+ break;
+ }
+
+ m_label->setText(msg);
+ delete m_transfer;
+ m_transfer = 0;
+}
+
diff --git a/noncore/net/opieirc/dccprogress.h b/noncore/net/opieirc/dccprogress.h
new file mode 100644
index 0000000..81b922e
--- a/dev/null
+++ b/noncore/net/opieirc/dccprogress.h
@@ -0,0 +1,35 @@
+#ifndef DCCPROGRESS_H
+#define DCCPROGRESS_H
+
+
+#include <qwidget.h>
+
+#include "dcctransfer.h"
+
+class QProgressBar;
+class QLabel;
+class QVBox;
+
+class DCCProgress: public QWidget {
+
+ Q_OBJECT
+public:
+ DCCProgress(DCCTransfer::Type type, Q_UINT32 ip4Addr, Q_UINT16 port,
+ const QString &filename, const QString &nickname, unsigned int size,
+ QWidget *parent = 0, char *name = 0, WFlags f = 0);
+
+ bool finished();
+ void cancel();
+
+public slots:
+ void slotSetProgress(int progress);
+ void slotFinished(DCCTransfer *transfer, DCCTransfer::EndCode code);
+
+private:
+ QVBox *m_vbox;
+ QLabel *m_label;
+ QProgressBar *m_bar;
+ DCCTransfer *m_transfer;
+};
+
+#endif
diff --git a/noncore/net/opieirc/dcctransfer.cpp b/noncore/net/opieirc/dcctransfer.cpp
new file mode 100644
index 0000000..cfa9f74
--- a/dev/null
+++ b/noncore/net/opieirc/dcctransfer.cpp
@@ -0,0 +1,41 @@
+#include <qsocket.h>
+#include <qfile.h>
+
+#include "dcctransfer.h"
+
+
+DCCTransfer::DCCTransfer(Q_UINT32 ip4Addr, Q_UINT16 port, const QString &filename, unsigned int size)
+ : m_socket(new QSocket), m_file(new QFile), m_bufSize(4096), m_buffer(new char[m_bufSize]),
+ m_ip4Addr(ip4Addr), m_port(port), m_totalSize(size), m_processedSize(0)
+{
+ m_file->setName(filename);
+}
+
+DCCTransfer::~DCCTransfer()
+{
+ if(m_socket)
+ delete m_socket;
+ if(m_file) {
+ m_file->close();
+ delete m_file;
+ }
+ if(m_buffer)
+ delete []m_buffer;
+}
+
+
+void DCCTransfer::cancel()
+{
+ if(m_socket)
+ m_socket->close();
+
+ emit(finished(DCCTransfer::SelfAborted));
+}
+
+QString DCCTransfer::filename()
+{
+ if(!m_file)
+ return QString::null;
+
+ return m_file->name().mid(m_file->name().findRev('/') + 1);
+}
diff --git a/noncore/net/opieirc/dcctransfer.h b/noncore/net/opieirc/dcctransfer.h
new file mode 100644
index 0000000..775ed24
--- a/dev/null
+++ b/noncore/net/opieirc/dcctransfer.h
@@ -0,0 +1,44 @@
+#ifndef DCCTRANSFER_H
+#define DCCTRANSFER_H
+
+#include <qobject.h>
+
+class QSocket;
+class QFile;
+class QString;
+
+class DCCTransfer: public QObject {
+ Q_OBJECT
+public:
+ enum Type { Send, Recv };
+ enum EndCode { Successfull, SelfAborted, PeerAborted, Timeout };
+
+ DCCTransfer(Q_UINT32 ip4Addr, Q_UINT16 port, const QString &filename, unsigned int size);
+ virtual ~DCCTransfer();
+
+ void cancel();
+
+ QString filename();
+
+signals:
+ virtual void finished(DCCTransfer *transfer, EndCode code);
+ virtual void progress(int progress);
+
+protected slots:
+ virtual void slotProcess() = 0;
+ virtual void slotFinished() = 0;
+
+protected:
+ QSocket *m_socket;
+ QFile *m_file;
+ unsigned int m_bufSize;
+ char *m_buffer;
+ Q_UINT32 m_ip4Addr;
+ Q_UINT16 m_port;
+ unsigned int m_totalSize;
+ unsigned int m_processedSize;
+ bool m_cancel;
+ bool m_timeout;
+};
+
+#endif
diff --git a/noncore/net/opieirc/dcctransferrecv.cpp b/noncore/net/opieirc/dcctransferrecv.cpp
new file mode 100644
index 0000000..58e8d09
--- a/dev/null
+++ b/noncore/net/opieirc/dcctransferrecv.cpp
@@ -0,0 +1,53 @@
+#include <netinet/in.h>
+
+#include <qfile.h>
+#include <qsocket.h>
+#include <qhostaddress.h>
+
+#include <opie2/odebug.h>
+
+
+#include "dcctransferrecv.h"
+
+
+DCCTransferRecv::DCCTransferRecv(Q_UINT32 ip4Addr, Q_UINT16 port, const QString &filename, unsigned int size)
+ : DCCTransfer(ip4Addr, port, filename, size)
+{
+ QHostAddress ip(ip4Addr);
+ m_socket->connectToHost(ip.toString(), m_port);
+ connect(m_socket, SIGNAL(readyRead()), this, SLOT(slotProcess()));
+ connect(m_socket, SIGNAL(connectionClosed()), this, SLOT(slotFinished()));
+
+ m_file->open(IO_WriteOnly);
+}
+
+
+void DCCTransferRecv::slotProcess()
+{
+ int availableBytes = m_socket->bytesAvailable();
+ int receivedBytes = 0;
+
+ while(receivedBytes < availableBytes) {
+ int bytes = m_socket->readBlock(m_buffer, m_bufSize);
+ receivedBytes += bytes;
+ m_file->writeBlock(m_buffer, bytes);
+ }
+
+ m_file->flush();
+ m_processedSize += availableBytes;
+ unsigned long value = htonl(m_processedSize);
+ m_socket->writeBlock((char*)&value, sizeof(unsigned long));
+
+ emit (progress((m_processedSize * 100) / m_totalSize));
+}
+
+void DCCTransferRecv::slotFinished()
+{
+ m_file->close();
+
+ if(m_processedSize == m_totalSize)
+ emit(finished(this, DCCTransfer::Successfull));
+ else
+ emit(finished(this, DCCTransfer::PeerAborted));
+}
+
diff --git a/noncore/net/opieirc/dcctransferrecv.h b/noncore/net/opieirc/dcctransferrecv.h
new file mode 100644
index 0000000..bfc55ef
--- a/dev/null
+++ b/noncore/net/opieirc/dcctransferrecv.h
@@ -0,0 +1,21 @@
+#ifndef DCCTRANSFERRECV_H
+#define DCCTRANSFERRECV_H
+
+#include "dcctransfer.h"
+
+
+class DCCTransferRecv: public DCCTransfer {
+ Q_OBJECT
+public:
+ DCCTransferRecv(Q_UINT32 ip4Addr, Q_UINT16 port, const QString &filename, unsigned int size);
+
+signals:
+ void finished(DCCTransfer *transfer, DCCTransfer::EndCode code);
+
+public slots:
+ void slotProcess();
+ void slotFinished();
+};
+
+#endif
+
diff --git a/noncore/net/opieirc/dcctransfertab.cpp b/noncore/net/opieirc/dcctransfertab.cpp
new file mode 100644
index 0000000..ea0ff1f
--- a/dev/null
+++ b/noncore/net/opieirc/dcctransfertab.cpp
@@ -0,0 +1,81 @@
+#include <qlist.h>
+#include <qlabel.h>
+#include <qstring.h>
+#include <qvbox.h>
+#include <qmessagebox.h>
+
+#include "dcctransfer.h"
+#include "dccprogress.h"
+#include "mainwindow.h"
+#include "dcctransfertab.h"
+
+#include <stdio.h>
+
+DCCTransferTab::DCCTransferTab(QWidget *parent, const char *name, WFlags f)
+ :IRCTab(parent, name, f), m_hbox(new QHBox(this)), m_parent(static_cast<MainWindow*>(parent))
+{
+ m_description->setText("");
+ m_layout->add(m_hbox);
+ m_hbox->show();
+}
+
+DCCTransferTab::~DCCTransferTab()
+{
+ if(m_hbox)
+ delete m_hbox;
+}
+
+QString DCCTransferTab::title()
+{
+ return "DCC";
+}
+
+void DCCTransferTab::remove()
+{
+ //Clean finished transfers
+ for(QListIterator <DCCProgress> it(m_progressList); it.current(); ++it) {
+ DCCProgress *current = it.current();
+ if (current->finished()) {
+ m_progressList.remove(current);
+ current->hide();
+ delete current;
+ }
+ }
+
+ if (m_progressList.count() > 0) {
+ int retval = QMessageBox::information( parentWidget() , tr("DCC Transfers in Progress"),
+ tr( "There are transfers in progress. <br>If you close this tab, they will be canceled."
+ "<br>Do you want to close it anyway?"),
+ tr("&Close"), tr("&Don't Close"));
+ if ( retval != 0 ) {
+ return;
+ }
+ //Cancel active transfers (user accepted)
+ for(QListIterator <DCCProgress> itr(m_progressList); itr.current(); ++itr) {
+ DCCProgress *current = itr.current();
+ m_progressList.remove(current);
+ current->hide();
+ current->cancel();
+ delete current;
+ }
+ }
+
+ //Remove
+ m_parent->killTab(this);
+}
+
+bool DCCTransferTab::confirm(QWidget *parent, const QString &nickname, const QString &filename, unsigned int size)
+{
+ int retval = QMessageBox::information(parent, tr("DCC Transfer from %1").arg(nickname),
+ tr( "%1 is trying to send you the file %2\n(%3 bytes)").arg(nickname).arg(filename).arg(size),
+ tr("&Accept"), tr("&Reject"));
+
+ return ( 0 == retval);
+
+}
+
+void DCCTransferTab::addTransfer(DCCTransfer::Type type, Q_UINT32 ip4Addr, Q_UINT16 port,
+ const QString &filename, const QString &nickname, unsigned int size)
+{
+ m_progressList.append(new DCCProgress(type, ip4Addr, port, filename, nickname, size, this));
+}
diff --git a/noncore/net/opieirc/dcctransfertab.h b/noncore/net/opieirc/dcctransfertab.h
new file mode 100644
index 0000000..a21323d
--- a/dev/null
+++ b/noncore/net/opieirc/dcctransfertab.h
@@ -0,0 +1,41 @@
+#ifndef DCCTRANSFERTAB_H
+#define DCCTRANSFERTAB_H
+
+#include "dcctransfer.h"
+#include "irctab.h"
+
+template <class T> class QList;
+
+class DCCProgress;
+class IRCSession;
+class QString;
+class QHBox;
+class MainWindow;
+
+class DCCTransferTab: public IRCTab {
+ Q_OBJECT
+public:
+
+ DCCTransferTab(QWidget *parent = 0, const char *name = 0, WFlags f = 0);
+ ~DCCTransferTab();
+ virtual QString DCCTransferTab::title();
+ virtual IRCSession* DCCTransferTab::session(){return 0;};
+ virtual void DCCTransferTab::appendText(QString){};
+ virtual void DCCTransferTab::remove();
+ virtual void DCCTransferTab::settingsChanged() {};
+ void addTransfer(DCCTransfer::Type type, Q_UINT32 ip4Addr,
+ Q_UINT16 port, const QString &filename,
+ const QString &nickname, unsigned int size);
+ static bool confirm(QWidget *parent = 0,
+ const QString &nickname = QString::null,
+ const QString &filename = QString::null,
+ unsigned int size = 0);
+private:
+ QHBox *m_hbox;
+ QList <DCCProgress> m_progressList;
+ MainWindow *m_parent;
+
+};
+
+#endif
+
diff --git a/noncore/net/opieirc/ircmessageparser.cpp b/noncore/net/opieirc/ircmessageparser.cpp
index ad9de2b..939cdae 100644
--- a/noncore/net/opieirc/ircmessageparser.cpp
+++ b/noncore/net/opieirc/ircmessageparser.cpp
@@ -1,199 +1,204 @@
#include <qtextstream.h>
#include <qdatetime.h>
+#include <opie2/ofiledialog.h>
+#include <opie2/ofileselector.h>
+#include <opie2/odebug.h>
+
#include "ircmessageparser.h"
#include "ircversion.h"
#include "ircchannelperson.h"
-//#include "transferreceiver.h"
+#include "dcctransfertab.h"
+#include "ircservertab.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", 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", 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) {
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) 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())));
emit outputReady(IRCOutput(OUTPUT_SERVERMESSAGE, tr("%1 signed on %2").arg(message->param(1)).arg(dt.toString())));
}
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 {
@@ -272,378 +277,391 @@ void IRCMessageParser::parseLiteralPrivMsg(IRCMessage *message) {
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 %1").arg(message->param(0).lower()) ));
}
}
else {emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Received PRIVMSG of unknown type")));
}
}
void IRCMessageParser::parseLiteralNick(IRCMessage *message) {
IRCPerson mask(message->prefix());
m_session->updateNickname(mask.nick(), message->param(0));
/* this way of handling nick changes really sucks
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 %1").arg( message->param(0)));
output.addParam(0);
emit outputReady(output);
} else {
Someone else is
RCPerson *person = m_session->getPerson(mask.nick());
if (person) {
//IRCOutput output(OUTPUT_NICKCHANGE, tr("%1 is now known as %2").arg( mask.nick() ).arg( message->param(0)));
new code starts here -- this removes the person from all channels
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);
chanperson->person->setNick(message->param(0));
it.current()->addPerson(chanperson);
IRCOutput output(OUTPUT_NICKCHANGE, tr("%1 is now known as %2").arg( mask.nick() ).arg( message->param(0)));
output.addParam(person);
emit outputReady(output);
}
new code ends here
} 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);
delete chanperson;
}
m_session->removePerson(person);
IRCOutput output(OUTPUT_QUIT, tr("%1 has quit (%2)" ).arg( mask.nick() ).arg( message->param(0) ));
output.addParam(person);
emit outputReady(output);
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());
if(message->isCTCPReply()) {
unsigned int sentTime = message->param(0).toUInt();
QDateTime tm;
tm.setTime_t(0);
unsigned int receivedTime = tm.secsTo(QDateTime::currentDateTime());
emit outputReady(IRCOutput(OUTPUT_CTCP, tr("Received a CTCP PING reply from %1: %2 seconds").arg(mask.nick()).arg(receivedTime-sentTime)));
return;
}
m_session->m_connection->sendCTCPReply(mask.nick(), "PING", message->allParameters());
emit outputReady(IRCOutput(OUTPUT_CTCP, tr("Received a CTCP PING request from %1").arg(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());
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;
+
+ if(params[0] == "SEND") {
+ QString nickname = IRCPerson(message->prefix()).nick();
+ if( params.count() != 5) {
+ emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Malformed DCC request from %1").arg(nickname)));
+ return;
+ }
+ bool accepted = DCCTransferTab::confirm(static_cast<QWidget*>(m_session->parent()), nickname, params[1], params[4].toUInt());
+ if(!accepted)
+ return;
+ QString filename = Opie::Ui::OFileDialog::getSaveFileName(Opie::Ui::OFileSelector::EXTENDED_ALL,
+ QString::null, params[1], MimeTypes(), 0, tr("Save As"));
+ if(filename.isEmpty())
+ return;
+
+ odebug << "Receiving file " << filename << " from " << nickname << oendl;
+ static_cast<IRCServerTab*>(m_session->parent())->mainwindow()->addDCC(DCCTransfer::Recv, params[2].toUInt(), params[3].toUInt(),
+ filename, nickname, params[4].toUInt());
}
-
- //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;
}
if (temp == "o") {
stream >> temp;
IRCChannelPerson *person = channel->getPerson(temp);
if (person) {
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) {
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 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->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->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 = 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;
}
IRCPerson *person = m_session->getPerson(nick);
if (person == 0) {
person = new IRCPerson();
person->setNick(nick);
m_session->addPerson(person);
}
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 */
if(m_session->isLoggedIn())
return;
emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Nickname is in use, please reconnect with a different nickname")));
m_session->endSession();
}
void IRCMessageParser::parseNumericalNoSuchNick(IRCMessage *) {
emit outputReady(IRCOutput(OUTPUT_ERROR, tr("No such nickname")));
}
void IRCMessageParser::parseNumericalTopic(IRCMessage *message) {
IRCChannel *channel = m_session->getChannel(message->param(1).lower());
if (channel) {
IRCOutput output(OUTPUT_TOPIC, tr("Topic for channel " + channel->channelname() + " is \"" + message->param(2) + "\""));
output.addParam(channel);
emit outputReady(output);
} else {
IRCOutput output(OUTPUT_TOPIC, tr("Topic for channel " + message->param(1) + " is \"" + message->param(2) + "\""));
output.addParam(0);
emit outputReady(output);
}
}
void IRCMessageParser::parseNumericalTopicWhoTime(IRCMessage *) {
}
diff --git a/noncore/net/opieirc/ircservertab.cpp b/noncore/net/opieirc/ircservertab.cpp
index 62a06e8..d3c0448 100644
--- a/noncore/net/opieirc/ircservertab.cpp
+++ b/noncore/net/opieirc/ircservertab.cpp
@@ -223,193 +223,197 @@ void IRCServerTab::executeCommand(IRCTab *tab, QString line) {
}
}
}
else {
tab->appendText("<font color=\"" + m_errorColor + "\">Unknown command</font><br>");
}
}
void IRCServerTab::processCommand() {
QString text = m_field->text();
if (text.startsWith("/") && !text.startsWith("//")) {
/* Command mode */
executeCommand(this, text);
}
m_field->clear();
}
void IRCServerTab::doConnect() {
m_session->beginSession();
}
void IRCServerTab::remove() {
/* Close requested */
if (m_session->isSessionActive()) {
/* While there is a running session */
m_close = TRUE;
m_session->endSession();
} else {
/* Session has previously been closed */
m_channelTabs.first();
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);
}
}
IRCChannelTab *IRCServerTab::getTabForChannel(IRCChannel *channel) {
QListIterator<IRCChannelTab> it(m_channelTabs);
for (; it.current(); ++it) {
if (it.current()->channel() == channel)
return it.current();
}
return 0;
}
IRCQueryTab *IRCServerTab::getTabForQuery(IRCPerson *person) {
QListIterator<IRCQueryTab> it(m_queryTabs);
for (; it.current(); ++it) {
if (it.current()->person()->nick() == person->nick())
return it.current();
}
return 0;
}
void IRCServerTab::display(IRCOutput output) {
/* All messages to be displayed inside the GUI get here */
switch (output.type()) {
case OUTPUT_CONNCLOSE:
if (m_close) {
m_channelTabs.first();
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))->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);
}
break;
case OUTPUT_CHANACTION: {
IRCChannelTab *channelTab = getTabForChannel((IRCChannel *)output.getParam(0));
channelTab->appendText("<font color=\"" + m_otherColor + "\">"+output.htmlMessage()+"</font><br>");
}
break;
case OUTPUT_TOPIC: {
IRCChannel *channel = (IRCChannel *) output.getParam(0);
if (channel) {
IRCChannelTab *channelTab = getTabForChannel(channel);
if (channelTab) {
channelTab->appendText("<font color=\"" + m_notificationColor + "\">"+output.htmlMessage()+"</font><br>");
return;
}
}
IRCChannelTab::enqueue(channel->channelname(), "<font color=\"" + m_notificationColor + "\">"+output.htmlMessage()+"</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=\"" + m_notificationColor + "\">"+output.htmlMessage()+"</font><br>");
it.current()->list()->update();
}
}
}
break;
case OUTPUT_NICKCHANGE: {
QString *nick = static_cast<QString*>(output.getParam(0));
if(!nick) {
appendText("<font color=\"" + m_notificationColor + "\">"+output.htmlMessage()+"</font><br>");
break;
}
QListIterator<IRCChannelTab> it(m_channelTabs);
for (; it.current(); ++it) {
if (it.current()->list()->hasPerson(*nick)) {
it.current()->appendText("<font color=\"" + m_notificationColor + "\">"+output.htmlMessage()+"</font><br>");
}
}
delete nick;
}
break;
case OUTPUT_OTHERJOIN:
case OUTPUT_OTHERKICK:
case OUTPUT_CHANPERSONMODE:
case OUTPUT_OTHERPART: {
IRCChannelTab *channelTab = getTabForChannel((IRCChannel *)output.getParam(0));
channelTab->appendText("<font color=\"" + m_notificationColor + "\">"+output.htmlMessage()+"</font><br>");
channelTab->list()->update();
}
break;
case OUTPUT_CTCP:
appendText("<font color=\"" + m_notificationColor + "\">" + output.htmlMessage() + "</font><br>");
break;
case OUTPUT_ERROR:
appendText("<font color=\"" + m_errorColor + "\">" + output.htmlMessage() + "</font><br>");
break;
case OUTPUT_TITLE:
m_description->setText(output.message());
break;
default:
appendText("<font color=\"" + m_serverColor + "\">" + output.htmlMessage() + "</font><br>");
break;
}
}
void IRCServerTab::slotUpdateChannels() {
QListIterator<IRCChannelTab> it(m_channelTabs);
for (; it.current(); ++it) {
it.current()->list()->update();
}
}
+
+MainWindow *IRCServerTab::mainwindow() {
+ return m_mainWindow;
+}
diff --git a/noncore/net/opieirc/ircservertab.h b/noncore/net/opieirc/ircservertab.h
index 42f6f57..fe48a3b 100644
--- a/noncore/net/opieirc/ircservertab.h
+++ b/noncore/net/opieirc/ircservertab.h
@@ -1,82 +1,83 @@
/*
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 <qpe/qpeapplication.h>
#include <qpe/qcopenvelope_qws.h>
#include "irctab.h"
#include "ircsession.h"
#include "mainwindow.h"
#include "ircchanneltab.h"
#include "ircquerytab.h"
#include "ircmisc.h"
class IRCServerTab : public IRCTab {
Q_OBJECT
public:
static bool containsPing(const QString& text, IRCServerTab *tab);
/* IRCTab implementation */
IRCServerTab(IRCServer server, MainWindow *mainWindow, QWidget *parent = 0, const char *name = 0, WFlags f = 0);
~IRCServerTab();
QString title();
IRCSession *session();
IRCServer *server();
+ MainWindow *mainwindow();
/* Start the server session */
void doConnect();
// QString *mynick();
/* Remove tabs from the internal tab lists */
void removeChannelTab(IRCChannelTab *tab);
void removeQueryTab(IRCQueryTab *tab);
/* Return tabs from the internal tab lists */
IRCChannelTab *getTabForChannel(IRCChannel *channel);
IRCQueryTab *getTabForQuery(IRCPerson *person);
/* Add tabs to the internal tab lists */
void addQueryTab(IRCQueryTab *tab);
/* Execute a user command such as /join, /msg etc */
void executeCommand(IRCTab *tab, QString line);
protected:
void appendText(QString text);
public slots:
void scrolling();
void remove();
void processCommand();
void settingsChanged();
void slotUpdateChannels();
protected slots:
void display(IRCOutput output);
protected:
int m_lines;
bool m_close;
IRCServer m_server;
IRCSession *m_session;
MainWindow *m_mainWindow;
QTextView *m_textview;
IRCHistoryLineEdit *m_field;
/* Channel tabs associated with this server tab */
QList<IRCChannelTab> m_channelTabs;
/* Query tabs associated with this server tab */
QList<IRCQueryTab> m_queryTabs;
};
#endif /* __IRCSERVERTAB_H */
diff --git a/noncore/net/opieirc/ircsession.cpp b/noncore/net/opieirc/ircsession.cpp
index fd8ba72..c8d7869 100644
--- a/noncore/net/opieirc/ircsession.cpp
+++ b/noncore/net/opieirc/ircsession.cpp
@@ -1,203 +1,204 @@
#include "ircsession.h"
#include "ircmessageparser.h"
#include "ircchannelperson.h"
#include "ircversion.h"
-IRCSession::IRCSession(QWidget *parent, IRCServer *server) {
+IRCSession::IRCSession(QObject *parent, IRCServer *server)
+ : QObject(parent)
+{
m_server = server;
m_connection = new IRCConnection(m_server);
m_parser = new IRCMessageParser(this);
- m_parent = parent;
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();
}
void IRCSession::join(QString channelname) {
m_connection->sendLine("JOIN " + channelname);
}
void IRCSession::quit(){
m_connection->sendLine("QUIT :[OI] I'm too good to need a reason");
}
void IRCSession::quit(QString message){
m_connection->sendLine("QUIT :" + message);
}
void IRCSession::topic(IRCChannel *channel, QString message){
m_connection->sendLine("TOPIC :" + channel->channelname() + " " + message);
}
void IRCSession::mode(IRCChannel *channel, QString message){
m_connection->sendLine("MODE " + channel->channelname() + " " + message);
}
void IRCSession::mode(IRCPerson *person, QString message){
m_connection->sendLine("MODE " + person->nick() + " " + message);
}
void IRCSession::mode(QString message){
m_connection->sendLine("MODE " + message);
}
void IRCSession::raw(QString message){
m_connection->sendLine(message);
}
void IRCSession::kick(IRCChannel *channel, IRCPerson *person) {
m_connection->sendLine("KICK " + channel->channelname() + " " + person->nick() +" :0wn3d - no reason");
}
void IRCSession::op(IRCChannel *channel, IRCPerson *person) {
m_connection->sendLine("MODE " + channel->channelname() + " +ooo " + person->nick());
}
void IRCSession::kick(IRCChannel *channel, IRCPerson *person, QString message) {
m_connection->sendLine("KICK " + channel->channelname() + " " + person->nick() +" :" + message);
}
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);
}
void IRCSession::sendAction(IRCChannel *channel, QString message) {
m_connection->sendLine("PRIVMSG " + channel->channelname() + " :\001ACTION " + message + "\001");
}
void IRCSession::sendAction(IRCPerson *person, QString message) {
m_connection->sendLine("PRIVMSG " + person->nick() + " :\001ACTION " + message + "\001");
}
bool IRCSession::isSessionActive() {
return m_connection->isConnected();
}
bool IRCSession::isLoggedIn() {
return m_connection->isLoggedIn();
}
void IRCSession::endSession() {
if (m_connection->isLoggedIn())
quit(APP_VERSION);
else
m_connection->close();
}
void IRCSession::part(IRCChannel *channel) {
m_connection->sendLine("PART " + channel->channelname() + " :" + APP_VERSION);
}
void IRCSession::setValidUsermodes(const QString &modes) {
m_validUsermodes = modes;
}
void IRCSession::setValidChannelmodes(const QString &modes) {
m_validChannelmodes = modes;
}
void IRCSession::updateNickname(const QString &oldNickname, const QString &newNickname) {
QList<IRCChannel> channels;
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->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();
}
}
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);
}
void IRCSession::whois(const QString &nickname) {
m_connection->whois(nickname);
}
diff --git a/noncore/net/opieirc/ircsession.h b/noncore/net/opieirc/ircsession.h
index 7c91893..23a2540 100644
--- a/noncore/net/opieirc/ircsession.h
+++ b/noncore/net/opieirc/ircsession.h
@@ -1,96 +1,96 @@
/*
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;
+class IRCServerTab;
/* 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(QWidget *parent, IRCServer *server);
+ IRCSession(QObject *parent, IRCServer *server);
~IRCSession();
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;
- QWidget *m_parent;
};
#endif /* __IRCSESSION_H */
diff --git a/noncore/net/opieirc/mainwindow.cpp b/noncore/net/opieirc/mainwindow.cpp
index 1811a0c..3d60107 100644
--- a/noncore/net/opieirc/mainwindow.cpp
+++ b/noncore/net/opieirc/mainwindow.cpp
@@ -1,139 +1,159 @@
#include <qmenubar.h>
#include <qpe/resource.h>
#include <opie2/odebug.h>
#include <qwhatsthis.h>
#include "mainwindow.h"
#include "ircservertab.h"
+#include "dcctransfertab.h"
#include "ircserverlist.h"
#include "ircsettings.h"
+#include <stdio.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()));
a->setWhatsThis(tr("Create a new connection to an IRC server"));
a->addTo(irc);
a = new QAction(tr("Settings"), Resource::loadPixmap("SettingsIcon"), QString::null, 0, this, 0);
a->setWhatsThis(tr("Configure OpieIRC's behavior and appearance"));
connect(a, SIGNAL(activated()), this, SLOT(settings()));
a->addTo(irc);
+ m_dccTab = 0;
loadSettings();
}
/*IRCTabWidget MainWindow::getTabWidget(){
return m_tabWidget;
} */
void MainWindow::loadSettings() {
Config config("OpieIRC");
config.setGroup("OpieIRC");
IRCTab::m_backgroundColor = config.readEntry("BackgroundColor", "#FFFFFF");
IRCTab::m_textColor = config.readEntry("TextColor", "#000000");
IRCTab::m_errorColor = config.readEntry("ErrorColor", "#FF0000");
IRCTab::m_selfColor = config.readEntry("SelfColor", "#CC0000");
IRCTab::m_otherColor = config.readEntry("OtherColor", "#0000BB");
IRCTab::m_serverColor = config.readEntry("ServerColor", "#0000FF");
IRCTab::m_notificationColor = config.readEntry("NotificationColor", "#AA3300");
IRCTab::m_maxLines = config.readNumEntry("Lines", 100);
IRCTab::setUseTimeStamps( config.readBoolEntry("DisplayTime", false ) );
}
void MainWindow::selected(QWidget *) {
m_tabWidget->setTabColor(m_tabWidget->currentPageIndex(), black);
emit updateScroll();
}
void MainWindow::addTab(IRCTab *tab) {
connect(tab, SIGNAL(changed(IRCTab*)), this, SLOT(changeEvent(IRCTab*)));
connect(tab, SIGNAL(ping (const QString&)), this, SLOT(slotPing(const QString&)));
connect(tab, SIGNAL(nextTab()), this, SLOT(slotNextTab()));
connect(tab, SIGNAL(prevTab()), this, SLOT(slotPrevTab()));
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) {
+ if (tab == m_dccTab)
+ m_dccTab = 0;
+
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();
}
}
}
void MainWindow::slotNextTab() {
int i = m_tabWidget->currentPageIndex ();
m_tabWidget->setCurrentPage ( i+1 );
int j = m_tabWidget->currentPageIndex ();
if ( i == j )
m_tabWidget->setCurrentPage ( 1 );
}
void MainWindow::slotPrevTab() {
int i = m_tabWidget->currentPageIndex ();
if ( i > 1 )
m_tabWidget->setCurrentPage ( i-1 );
}
void MainWindow::slotPing( const QString& /*channel*/ ) {
raise();
}
+void MainWindow::addDCC(DCCTransfer::Type type, Q_UINT32 ip4Addr, Q_UINT16 port,
+ const QString &filename, const QString &nickname, unsigned int size) {
+
+ if (!m_dccTab) {
+ m_dccTab = new DCCTransferTab(this);
+ addTab(m_dccTab);
+ m_dccTab->show();
+ }
+
+ m_dccTab->addTransfer(type, ip4Addr, port, filename, nickname, size);
+}
+
diff --git a/noncore/net/opieirc/mainwindow.h b/noncore/net/opieirc/mainwindow.h
index abf205d..873a685 100644
--- a/noncore/net/opieirc/mainwindow.h
+++ b/noncore/net/opieirc/mainwindow.h
@@ -1,61 +1,67 @@
/*
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 <qlist.h>
-#include "mainwindow.h"
+
+#include "dcctransfer.h"
#include "ircmisc.h"
#include "irctab.h"
+class DCCTransferTab;
+
class MainWindow : public QMainWindow {
Q_OBJECT
public:
MainWindow(QWidget *parent = 0, const char *name = 0, WFlags f = 0);
// IRCTabWidget getTabWidget();
void addTab(IRCTab *tab);
void killTab(IRCTab *tab, bool now = false);
static QString appName() { return QString::fromLatin1("opieirc"); }
static QString appCaption();
+ void addDCC(DCCTransfer::Type type, Q_UINT32 ip4Addr, Q_UINT16 port,
+ const QString &filename, const QString &nickname, unsigned int size);
signals:
void updateScroll();
protected slots:
void newConnection();
void settings();
void selected(QWidget *);
void changeEvent(IRCTab *);
void slotNextTab();
void slotPrevTab();
void slotPing(const QString&);
void slotKillTabsLater();
protected:
void loadSettings();
protected:
IRCTabWidget *m_tabWidget;
QList<IRCTab> m_tabs;
QList<IRCTab> m_toDelete;
+ DCCTransferTab *m_dccTab;
};
#endif /* __MAINWINDOW_H */
diff --git a/noncore/net/opieirc/opieirc.pro b/noncore/net/opieirc/opieirc.pro
index 1ef9be2..5e91450 100644
--- a/noncore/net/opieirc/opieirc.pro
+++ b/noncore/net/opieirc/opieirc.pro
@@ -1,30 +1,35 @@
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 \
- ircchannelperson.h
+ ircchannelperson.h dcctransfertab.h \
+ dccprogress.h dcctransfer.h \
+ dcctransferrecv.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 \
- ircchannelperson.cpp
+ ircchannelperson.cpp dcctransfertab.cpp \
+ dccprogress.cpp dcctransfer.cpp \
+ dcctransferrecv.cpp
+
INCLUDEPATH += $(OPIEDIR)/include
DEPENDPATH += $(OPIEDIR)/include
PRECOMPILED_HEADER = stable.h
LIBS += -lqpe -lopiecore2 -lopieui2 -lqtaux2
TARGET = opieirc
include( $(OPIEDIR)/include.pro )