summaryrefslogtreecommitdiff
path: root/noncore/net/opieirc
authorskyhusker <skyhusker>2005-01-14 20:54:49 (UTC)
committer skyhusker <skyhusker>2005-01-14 20:54:49 (UTC)
commita808497c334275c4b73e31a9bea37f84e344964d (patch) (unidiff)
tree490b0396494b83b1145fc65ab81e3e437af9aed5 /noncore/net/opieirc
parentb6c5c3b8b1ab130217678ec789db573ffc52c3eb (diff)
downloadopie-a808497c334275c4b73e31a9bea37f84e344964d.zip
opie-a808497c334275c4b73e31a9bea37f84e344964d.tar.gz
opie-a808497c334275c4b73e31a9bea37f84e344964d.tar.bz2
Added message queue, now topics always appear in channel tab
Diffstat (limited to 'noncore/net/opieirc') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/net/opieirc/ircchannellist.cpp2
-rw-r--r--noncore/net/opieirc/ircchanneltab.cpp17
-rw-r--r--noncore/net/opieirc/ircchanneltab.h3
-rw-r--r--noncore/net/opieirc/ircmessage.cpp35
-rw-r--r--noncore/net/opieirc/ircmessage.h6
-rw-r--r--noncore/net/opieirc/ircmessageparser.cpp158
-rw-r--r--noncore/net/opieirc/ircmessageparser.h10
-rw-r--r--noncore/net/opieirc/ircserver.cpp13
-rw-r--r--noncore/net/opieirc/ircservereditor.cpp8
-rw-r--r--noncore/net/opieirc/ircservertab.cpp39
-rw-r--r--noncore/net/opieirc/ircservertab.h1
-rw-r--r--noncore/net/opieirc/ircsession.cpp56
-rw-r--r--noncore/net/opieirc/ircsession.h7
13 files changed, 276 insertions, 79 deletions
diff --git a/noncore/net/opieirc/ircchannellist.cpp b/noncore/net/opieirc/ircchannellist.cpp
index 6bef318..c32c535 100644
--- a/noncore/net/opieirc/ircchannellist.cpp
+++ b/noncore/net/opieirc/ircchannellist.cpp
@@ -59,7 +59,7 @@ void IRCChannelList::adjustNicks() {
59 } 59 }
60 else { 60 else {
61 removeItem(i); 61 removeItem(i);
62 insertItem(txt,i); 62 insertItem(txt, i);
63 } 63 }
64 } 64 }
65} 65}
diff --git a/noncore/net/opieirc/ircchanneltab.cpp b/noncore/net/opieirc/ircchanneltab.cpp
index 581f9a5..4a35929 100644
--- a/noncore/net/opieirc/ircchanneltab.cpp
+++ b/noncore/net/opieirc/ircchanneltab.cpp
@@ -1,11 +1,14 @@
1#include <qpe/resource.h> 1#include <qpe/resource.h>
2#include <qwhatsthis.h> 2#include <qwhatsthis.h>
3#include <qhbox.h> 3#include <qhbox.h>
4#include <qdict.h>
4 5
5#include "ircchanneltab.h" 6#include "ircchanneltab.h"
6#include "ircservertab.h" 7#include "ircservertab.h"
7#include "ircmessageparser.h" 8#include "ircmessageparser.h"
8 9
10QDict<QString> IRCChannelTab::m_queuedMessages (17);
11
9IRCChannelTab::IRCChannelTab(IRCChannel *channel, IRCServerTab *parentTab, MainWindow *mainWindow, QWidget *parent, const char *name, WFlags f) : IRCTab(parent, name, f) { 12IRCChannelTab::IRCChannelTab(IRCChannel *channel, IRCServerTab *parentTab, MainWindow *mainWindow, QWidget *parent, const char *name, WFlags f) : IRCTab(parent, name, f) {
10 m_mainWindow = mainWindow; 13 m_mainWindow = mainWindow;
11 m_parentTab = parentTab; 14 m_parentTab = parentTab;
@@ -53,6 +56,12 @@ IRCChannelTab::IRCChannelTab(IRCChannel *channel, IRCServerTab *parentTab, MainW
53 connect(m_field, SIGNAL(returnPressed()), this, SLOT(processCommand())); 56 connect(m_field, SIGNAL(returnPressed()), this, SLOT(processCommand()));
54 connect(m_list, SIGNAL(doubleClicked ( QListBoxItem * ) ), this, SLOT(popupQuery( QListBoxItem * ) )); 57 connect(m_list, SIGNAL(doubleClicked ( QListBoxItem * ) ), this, SLOT(popupQuery( QListBoxItem * ) ));
55 settingsChanged(); 58 settingsChanged();
59
60 if(m_queuedMessages[m_channel->channelname()]) {
61 appendText(*m_queuedMessages[m_channel->channelname()]);
62 delete m_queuedMessages[m_channel->channelname()];
63 m_queuedMessages.remove(m_channel->channelname());
64 }
56} 65}
57 66
58void IRCChannelTab::scrolling(){ 67void IRCChannelTab::scrolling(){
@@ -182,6 +191,13 @@ void IRCChannelTab::remove() {
182 } 191 }
183} 192}
184 193
194void IRCChannelTab::enqueue(const QString &channel, const QString &message) {
195 if (m_queuedMessages.count() == (m_queuedMessages.size() - 1) )
196 /* 17 messages max */
197 return;
198 m_queuedMessages.insert(channel, new QString(message));
199}
200
185IRCChannel *IRCChannelTab::channel() { 201IRCChannel *IRCChannelTab::channel() {
186 return m_channel; 202 return m_channel;
187} 203}
@@ -189,3 +205,4 @@ IRCChannel *IRCChannelTab::channel() {
189IRCChannelList *IRCChannelTab::list() { 205IRCChannelList *IRCChannelTab::list() {
190 return m_list; 206 return m_list;
191} 207}
208
diff --git a/noncore/net/opieirc/ircchanneltab.h b/noncore/net/opieirc/ircchanneltab.h
index 70b212c..ffd1d5f 100644
--- a/noncore/net/opieirc/ircchanneltab.h
+++ b/noncore/net/opieirc/ircchanneltab.h
@@ -31,6 +31,7 @@
31 31
32#define LISTWIDTH 70 32#define LISTWIDTH 70
33 33
34template <class T> class QDict;
34class IRCServerTab; 35class IRCServerTab;
35class IRCChannelTab : public IRCTab { 36class IRCChannelTab : public IRCTab {
36 Q_OBJECT 37 Q_OBJECT
@@ -44,6 +45,7 @@ public:
44 IRCChannelList *list(); 45 IRCChannelList *list();
45public: 46public:
46 void appendText(QString text); 47 void appendText(QString text);
48 static void enqueue(const QString &channel, const QString &message);
47public slots: 49public slots:
48 void remove(); 50 void remove();
49 void settingsChanged(); 51 void settingsChanged();
@@ -70,6 +72,7 @@ protected:
70 QPopupMenu *m_popup; 72 QPopupMenu *m_popup;
71 bool m_listVisible; 73 bool m_listVisible;
72 int m_lines; 74 int m_lines;
75 static QDict<QString> m_queuedMessages;
73}; 76};
74 77
75#endif /* __IRCCHANNELTAB_H */ 78#endif /* __IRCCHANNELTAB_H */
diff --git a/noncore/net/opieirc/ircmessage.cpp b/noncore/net/opieirc/ircmessage.cpp
index d823ad1..d0b2652 100644
--- a/noncore/net/opieirc/ircmessage.cpp
+++ b/noncore/net/opieirc/ircmessage.cpp
@@ -1,4 +1,7 @@
1#include <qtextstream.h> 1#include <qtextstream.h>
2#include <qstring.h>
3#include <qstringlist.h>
4
2#include "ircmessage.h" 5#include "ircmessage.h"
3 6
4/* 7/*
@@ -64,8 +67,8 @@ IRCMessage::IRCMessage(QString line) {
64 m_ctcp = FALSE; 67 m_ctcp = FALSE;
65 } 68 }
66 69
67 /* 70 /*
68 -- Uncomment to debug -- 71 //-- Uncomment to debug --
69 72
70 printf("Parsed : '%s'\n", line.ascii()); 73 printf("Parsed : '%s'\n", line.ascii());
71 printf("Prefix : '%s'\n", m_prefix.ascii()); 74 printf("Prefix : '%s'\n", m_prefix.ascii());
@@ -76,7 +79,8 @@ IRCMessage::IRCMessage(QString line) {
76 } 79 }
77 printf("CTCP Command : '%s'\n", m_ctcpCommand.latin1()); 80 printf("CTCP Command : '%s'\n", m_ctcpCommand.latin1());
78 printf("CTCP Destination : '%s'\n", m_ctcpDestination.latin1()); 81 printf("CTCP Destination : '%s'\n", m_ctcpDestination.latin1());
79 printf("CTCP param count is : '%i'\n", m_parameters.count()); 82 printf("CTCP param count is : '%i'\n", m_parameters.count());
83
80 */ 84 */
81} 85}
82 86
@@ -84,6 +88,31 @@ QString IRCMessage::param(int param) {
84 return m_parameters[param]; 88 return m_parameters[param];
85} 89}
86 90
91QStringList IRCMessage::params(const QString &paramstring) const {
92 QStringList params, retvalue;
93 params = QStringList::split(',', paramstring);
94 QStringList::Iterator end = params.end();
95
96 for (QStringList::Iterator it = params.begin(); it != end; ++it) {
97 int pos = (*it).find(':');
98 if(pos < 0) {
99 if((*it).toInt() < m_parameters.count())
100 retvalue << m_parameters[(*it).toInt()];
101 }
102
103 else {
104 int start, end;
105 start = (*it).left(pos).toInt();
106 end = (*it).mid(pos+1).toInt();
107 for (int i=start;i<=end && i < m_parameters.count() ;++i) {
108 retvalue << m_parameters[i];
109 }
110 }
111 }
112
113 return retvalue;
114}
115
87QString IRCMessage::prefix() { 116QString IRCMessage::prefix() {
88 return m_prefix; 117 return m_prefix;
89} 118}
diff --git a/noncore/net/opieirc/ircmessage.h b/noncore/net/opieirc/ircmessage.h
index 0c5c879..10ba450 100644
--- a/noncore/net/opieirc/ircmessage.h
+++ b/noncore/net/opieirc/ircmessage.h
@@ -21,8 +21,8 @@
21#ifndef __IRCMESSAGE_H 21#ifndef __IRCMESSAGE_H
22#define __IRCMESSAGE_H 22#define __IRCMESSAGE_H
23 23
24#include <qstring.h> 24class QString;
25#include <qstringlist.h> 25class QStringList;
26 26
27/* IRCMessage objects are used to encapsulate information 27/* IRCMessage objects are used to encapsulate information
28 which the IRC server sent to us. */ 28 which the IRC server sent to us. */
@@ -52,6 +52,8 @@ public:
52 QString allParameters(); 52 QString allParameters();
53 /* Return one parameter */ 53 /* Return one parameter */
54 QString param(int param); 54 QString param(int param);
55 /* Return some parameters */
56 QStringList params(const QString &paramstring) const;
55protected: 57protected:
56 QString m_prefix; 58 QString m_prefix;
57 QString m_command; 59 QString m_command;
diff --git a/noncore/net/opieirc/ircmessageparser.cpp b/noncore/net/opieirc/ircmessageparser.cpp
index f8ccbb6..fde156c 100644
--- a/noncore/net/opieirc/ircmessageparser.cpp
+++ b/noncore/net/opieirc/ircmessageparser.cpp
@@ -1,4 +1,6 @@
1#include <qtextstream.h> 1#include <qtextstream.h>
2#include <qdatetime.h>
3
2#include "ircmessageparser.h" 4#include "ircmessageparser.h"
3#include "ircversion.h" 5#include "ircversion.h"
4 6
@@ -27,36 +29,55 @@ IRCCTCPMessageParserStruct IRCMessageParser::ctcpParserProcTable[] = {
27 { 0 , 0 } 29 { 0 , 0 }
28}; 30};
29 31
30/* Lookup table for numerical commands */ 32/* Lookup table for numerical commands
33 * According to:
34 * http://www.faqs.org/rfcs/rfc1459.html
35 * http://www.faqs.org/rfcs/rfc2812.html
36*/
37
31IRCNumericalMessageParserStruct IRCMessageParser::numericalParserProcTable[] = { 38IRCNumericalMessageParserStruct IRCMessageParser::numericalParserProcTable[] = {
32 { 1, FUNC(parseNumericalSecondParam) }, // RPL_WELCOME 39 { 1, "%1", "1", FUNC(parseNumericalServerName) }, // RPL_WELCOME
33 { 2, FUNC(parseNumericalSecondParam) }, // RPL_YOURHOST 40 { 2, "%1", "1", 0 }, // RPL_YOURHOST
34 { 3, FUNC(parseNumericalSecondParam) }, // RPL_CREATED 41 { 3, "%1", "1", 0 }, // RPL_CREATED
35 { 4, FUNC(parseNumericalAllParams) }, // RPL_MYINFO 42 { 4, QT_TR_NOOP("Server %1 version %2 supports usermodes '%3' and channelmodes '%4'"), "1:4", FUNC(parseNumericalServerFeatures) }, // RPL_MYINFO
36 { 5, FUNC(parseNumericalSecondParam) }, // RPL_BOUNCE, RPL_PROTOCTL 43 { 5, 0, 0, FUNC(parseNumericalServerProtocol) }, // RPL_BOUNCE, RPL_PROTOCTL
37 { 250, FUNC(parseNumericalAllParams) }, // RPL_STATSCONN 44 { 250, "%1", "1", 0 }, // RPL_STATSCONN
38 { 251, FUNC(parseNumericalSecondParam) }, // RPL_LUSERCLIENT 45 { 251, "%1", "1", 0 }, // RPL_LUSERCLIENT
39 { 252, FUNC(parseNumericalAllParams) }, // RPL_LUSEROP 46 { 252, QT_TR_NOOP("There are %1 operators connected"), "1", 0 }, // RPL_LUSEROP
40 { 253, FUNC(parseNumericalAllParams) }, // RPL_LUSERUNKNOWN 47 { 253, QT_TR_NOOP("There are %1 unknown connection(s)"), "1", 0 }, // RPL_LUSERUNKNOWN
41 { 254, FUNC(parseNumericalAllParams) }, // RPL_LUSERCHANNELS 48 { 254, QT_TR_NOOP("There are %1 channels formed"), "1", 0 }, // RPL_LUSERCHANNELS
42 { 255, FUNC(parseNumericalSecondParam) }, // RPL_LUSERME 49 { 255, "%1", "1", 0 }, // RPL_LUSERME
43 { 265, FUNC(parseNumericalAllParams) }, // RPL_LOCALUSERS 50 { 263, QT_TR_NOOP("Please wait a while and try again"), 0, 0 }, // RPL_TRYAGAIN
44 { 266, FUNC(parseNumericalAllParams) }, // RPL_GLOBALUSERS 51 { 265, "%1", "1", 0 }, // RPL_LOCALUSERS
45 { 332, FUNC(parseNumericalTopic) }, // RPL_TOPIC 52 { 266, "%1", "1", 0 }, // RPL_GLOBALUSERS
46 { 333, FUNC(parseNumericalTopicWhoTime) }, // RPL_TOPICWHOTIME 53 { 311, QT_TR_NOOP("Whois %1 (%2@%3)\nReal name: %4"), "1:3,5" }, // RPL_WHOISUSER
47 { 353, FUNC(parseNumericalNames) }, // RPL_NAMREPLY 54 { 312, QT_TR_NOOP("%1 is using server %2"), "1,2", 0 }, // RPL_WHOISSERVER
48 { 366, FUNC(parseNumericalEndOfNames) }, // RPL_ENDOFNAMES 55 { 317, 0, 0, FUNC(parseNumericalWhoisIdle) }, // RPL_WHOISIDLE
49 { 372, FUNC(parseNumericalSecondParam) }, // RPL_MOTD 56 { 318, "%1 :%2", "1,2", 0 }, // RPL_ENDOFWHOIS
50 { 375, FUNC(parseNumericalSecondParam) }, // RPL_MOTDSTART 57 { 320, "%1 %2", "1,2", 0}, // RPL_WHOISVIRT
51 { 376, FUNC(parseNumericalSecondParam) }, // RPL_ENDOFMOTD 58 { 332, 0, 0, FUNC(parseNumericalTopic) }, // RPL_TOPIC
52 { 377, FUNC(parseNumericalSecondParam) }, // RPL_MOTD2 59 { 333, 0, 0, FUNC(parseNumericalTopicWhoTime) }, // RPL_TOPICWHOTIME*/
53 { 378, FUNC(parseNumericalSecondParam) }, // RPL_MOTD3 60 { 353, QT_TR_NOOP("Names for %1: %2"), "2,3", FUNC(parseNumericalNames) }, // RPL_NAMREPLY
54 { 401, FUNC(parseNumericalNoSuchNick) }, // ERR_NOSUCHNICK 61 { 366, "%1 :%2", "1,2", FUNC(parseNumericalEndOfNames) }, // RPL_ENDOFNAMES
55 { 406, FUNC(parseNumericalNoSuchNick) }, // ERR_WASNOSUCHNICK 62 { 369, "%1 :%2", "1,2", 0 }, // RPL_ENDOFWHOWAS
56 { 412, FUNC(parseNumericalSecondParam) }, // ERR_NOTEXTTOSEND 63 { 372, "%1", "1", 0 }, // RPL_MOTD
57 { 422, FUNC(parseNumericalSecondParam) }, // ERR_NOMOTD 64 { 375, "%1", "1", 0 }, // RPL_MOTDSTART
58 { 433, FUNC(parseNumericalNicknameInUse) }, // ERR_NICKNAMEINUSE 65 { 376, "%1", "1", 0 }, // RPL_ENDOFMOTD
59 { 0, 0 } 66 { 377, "%1", "1", 0 }, // RPL_MOTD2
67 { 378, "%1", "1", 0 }, // RPL_MOTD3
68 { 391, QT_TR_NOOP("Time on server %1 is %2"), "1,2", 0 }, // RPL_TIME
69 { 401, QT_TR_NOOP("Channel or nick %1 doesn't exists"), "1", 0 }, // ERR_NOSUCHNICK
70 { 406, QT_TR_NOOP("There is no history information for %1"), "1" }, // ERR_WASNOSUCHNICK
71 { 409, "%1", "1", 0 }, // ERR_NOORIGIN
72 { 411, "%1", "1", 0 }, // ERR_NORECIPIENT
73 { 412, "%1", "1", 0 }, // ERR_NOTEXTTOSEND
74 { 421, QT_TR_NOOP("Unknown command: %1"), "1", 0 }, // ERR_NOMOTD
75 { 422, QT_TR_NOOP("You're not on channel %1"), "1", 0}, // ERR_NOTONCHANNEL
76 { 422, "%1", "1", 0 }, // ERR_NOMOTD
77 { 433, QT_TR_NOOP("Can't change nick to %1: %2"), "1,2", FUNC(parseNumericalNicknameInUse) }, // ERR_NICKNAMEINUSE
78 { 477, "%1", "1", 0 }, // ERR_NOCHANMODES || ERR_NEEDREGGEDNICK
79 { 482, QT_TR_NOOP("[%1] Operation not permitted, you don't have enough channel privileges"), "1", 0 }, //ERR_CHANOPRIVSNEEDED
80 { 0, 0, 0, 0 }
60}; 81};
61 82
62 83
@@ -70,7 +91,7 @@ void IRCMessageParser::parse(IRCMessage *message) {
70 if (message->isNumerical()) { 91 if (message->isNumerical()) {
71 for (int i=0; i<numericalParserProcTable[i].commandNumber; i++) { 92 for (int i=0; i<numericalParserProcTable[i].commandNumber; i++) {
72 if (message->commandNumber() == numericalParserProcTable[i].commandNumber) { 93 if (message->commandNumber() == numericalParserProcTable[i].commandNumber) {
73 (this->*(numericalParserProcTable[i].proc))(message); 94 parseNumerical(message, i);
74 return; 95 return;
75 } 96 }
76 } 97 }
@@ -94,8 +115,50 @@ void IRCMessageParser::parse(IRCMessage *message) {
94 } 115 }
95} 116}
96 117
97void IRCMessageParser::nullFunc(IRCMessage *) { 118void IRCMessageParser::parseNumerical(IRCMessage *message, int position) {
98 /* Do nothing */ 119 QString out = tr(numericalParserProcTable[position].message);
120 QString paramString = numericalParserProcTable[position].params;
121
122 if(!out.isEmpty() && !paramString.isEmpty()) {
123 QStringList params = message->params(numericalParserProcTable[position].params);
124
125 QStringList::Iterator end = params.end();
126 for (QStringList::Iterator it = params.begin(); it != end; ++it) {
127 out = out.arg(*it);
128 }
129
130 emit outputReady(IRCOutput(OUTPUT_SERVERMESSAGE, out));
131 }
132
133 if(numericalParserProcTable[position].proc)
134 (this->*(numericalParserProcTable[position].proc))(message);
135}
136
137void IRCMessageParser::parseNumericalServerName(IRCMessage *message) {
138 emit outputReady(IRCOutput(OUTPUT_TITLE, tr("Connected to")+" <b>" + message->prefix() + "</b>"));
139}
140
141void IRCMessageParser::parseNumericalServerFeatures(IRCMessage *message) {
142 m_session->setValidUsermodes(message->param(2));
143 m_session->setValidChannelmodes(message->param(3));
144
145}
146
147void IRCMessageParser::parseNumericalServerProtocol(IRCMessage *message) {
148 /* XXX: Add some usefull features here */
149 QString out = message->allParameters();
150 out = out.mid(out.find(' ')+1);
151 emit outputReady(IRCOutput(OUTPUT_SERVERMESSAGE, out));
152}
153void IRCMessageParser::parseNumericalWhoisIdle(IRCMessage *message) {
154 QDateTime dt;
155 QTime t;
156 t = t.addSecs(message->param(2).toInt());
157 dt.setTime_t(message->param(3).toInt());
158
159 emit outputReady(IRCOutput(OUTPUT_SERVERMESSAGE, tr("%1 has been idle for %2").arg(message->param(1)).arg(t.toString())));
160 emit outputReady(IRCOutput(OUTPUT_SERVERMESSAGE, tr("%1 signed on %2").arg(message->param(1)).arg(dt.toString())));
161
99} 162}
100 163
101void IRCMessageParser::parseLiteralPing(IRCMessage *message) { 164void IRCMessageParser::parseLiteralPing(IRCMessage *message) {
@@ -209,22 +272,22 @@ void IRCMessageParser::parseLiteralPrivMsg(IRCMessage *message) {
209} 272}
210 273
211void IRCMessageParser::parseLiteralNick(IRCMessage *message) { 274void IRCMessageParser::parseLiteralNick(IRCMessage *message) {
212
213 IRCPerson mask(message->prefix()); 275 IRCPerson mask(message->prefix());
214 /* this way of handling nick changes really sucks */ 276 m_session->updateNickname(mask.nick(), message->param(0));
277 /* this way of handling nick changes really sucks
215 if (mask.nick() == m_session->m_server->nick()) { 278 if (mask.nick() == m_session->m_server->nick()) {
216 /* We are changing our nickname */ 279 We are changing our nickname
217 m_session->m_server->setNick(message->param(0)); 280 m_session->m_server->setNick(message->param(0));
218 IRCOutput output(OUTPUT_NICKCHANGE, tr("You are now known as %1").arg( message->param(0))); 281 IRCOutput output(OUTPUT_NICKCHANGE, tr("You are now known as %1").arg( message->param(0)));
219 output.addParam(0); 282 output.addParam(0);
220 emit outputReady(output); 283 emit outputReady(output);
221 } else { 284 } else {
222 /* Someone else is */ 285 Someone else is
223 IRCPerson *person = m_session->getPerson(mask.nick()); 286 RCPerson *person = m_session->getPerson(mask.nick());
224 if (person) { 287 if (person) {
225 //IRCOutput output(OUTPUT_NICKCHANGE, tr("%1 is now known as %2").arg( mask.nick() ).arg( message->param(0))); 288 //IRCOutput output(OUTPUT_NICKCHANGE, tr("%1 is now known as %2").arg( mask.nick() ).arg( message->param(0)));
226 289
227 /* new code starts here -- this removes the person from all channels */ 290 new code starts here -- this removes the person from all channels
228 QList<IRCChannel> channels; 291 QList<IRCChannel> channels;
229 m_session->getChannelsByPerson(person, channels); 292 m_session->getChannelsByPerson(person, channels);
230 QListIterator<IRCChannel> it(channels); 293 QListIterator<IRCChannel> it(channels);
@@ -237,11 +300,11 @@ void IRCMessageParser::parseLiteralNick(IRCMessage *message) {
237 output.addParam(person); 300 output.addParam(person);
238 emit outputReady(output); 301 emit outputReady(output);
239 } 302 }
240 /* new code ends here */ 303 new code ends here
241 } else { 304 } else {
242 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Nickname change of an unknown person"))); 305 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Nickname change of an unknown person")));
243 } 306 }
244 } 307 }*/
245} 308}
246 309
247void IRCMessageParser::parseLiteralQuit(IRCMessage *message) { 310void IRCMessageParser::parseLiteralQuit(IRCMessage *message) {
@@ -324,7 +387,7 @@ void IRCMessageParser::parseCTCPPing(IRCMessage *message) {
324 387
325void IRCMessageParser::parseCTCPVersion(IRCMessage *message) { 388void IRCMessageParser::parseCTCPVersion(IRCMessage *message) {
326 IRCPerson mask(message->prefix()); 389 IRCPerson mask(message->prefix());
327 m_session->m_connection->sendCTCP(mask.nick(), APP_VERSION " " APP_COPYSTR); 390 m_session->m_connection->sendCTCP(mask.nick(), "VERSION " APP_VERSION " " APP_COPYSTR);
328 emit outputReady(IRCOutput(OUTPUT_CTCP, tr("Received a CTCP VERSION from ")+mask.nick())); 391 emit outputReady(IRCOutput(OUTPUT_CTCP, tr("Received a CTCP VERSION from ")+mask.nick()));
329} 392}
330 393
@@ -463,15 +526,6 @@ void IRCMessageParser::parseLiteralKick(IRCMessage *message) {
463 } 526 }
464} 527}
465 528
466
467void IRCMessageParser::parseNumericalSecondParam(IRCMessage *message) {
468 emit outputReady(IRCOutput(OUTPUT_SERVERMESSAGE, message->param(1)));
469}
470
471void IRCMessageParser::parseNumericalAllParams(IRCMessage *message) {
472 emit outputReady(IRCOutput(OUTPUT_SERVERMESSAGE, message->allParameters()));
473}
474
475void IRCMessageParser::parseNumericalNames(IRCMessage *message) { 529void IRCMessageParser::parseNumericalNames(IRCMessage *message) {
476 /* Name list sent when joining a channel */ 530 /* Name list sent when joining a channel */
477 IRCChannel *channel = m_session->getChannel(message->param(2).lower()); 531 IRCChannel *channel = m_session->getChannel(message->param(2).lower());
@@ -532,6 +586,10 @@ void IRCMessageParser::parseNumericalEndOfNames(IRCMessage *message) {
532 586
533 587
534void IRCMessageParser::parseNumericalNicknameInUse(IRCMessage *) { 588void IRCMessageParser::parseNumericalNicknameInUse(IRCMessage *) {
589 /* If we are connnected this error is not critical */
590 if(m_session->isLoggedIn())
591 return;
592
535 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Nickname is in use, please reconnect with a different nickname"))); 593 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Nickname is in use, please reconnect with a different nickname")));
536 m_session->endSession(); 594 m_session->endSession();
537} 595}
diff --git a/noncore/net/opieirc/ircmessageparser.h b/noncore/net/opieirc/ircmessageparser.h
index 5412f5f..2fca61e 100644
--- a/noncore/net/opieirc/ircmessageparser.h
+++ b/noncore/net/opieirc/ircmessageparser.h
@@ -46,6 +46,8 @@ typedef struct IRCCTCPMessageParserStruct {
46/* Struct representing a numerical command handler */ 46/* Struct representing a numerical command handler */
47typedef struct IRCNumericalMessageParserStruct { 47typedef struct IRCNumericalMessageParserStruct {
48 unsigned short commandNumber; 48 unsigned short commandNumber;
49 char *message;
50 char *params;
49 IRCMessageParseProc proc; 51 IRCMessageParseProc proc;
50}; 52};
51 53
@@ -61,7 +63,6 @@ signals:
61 void outputReady(IRCOutput output); 63 void outputReady(IRCOutput output);
62private: 64private:
63 /* Parser functions */ 65 /* Parser functions */
64 void nullFunc(IRCMessage *message);
65 void parseLiteralPing(IRCMessage *message); 66 void parseLiteralPing(IRCMessage *message);
66 void parseLiteralNotice(IRCMessage *message); 67 void parseLiteralNotice(IRCMessage *message);
67 void parseLiteralJoin(IRCMessage *message); 68 void parseLiteralJoin(IRCMessage *message);
@@ -73,8 +74,11 @@ private:
73 void parseLiteralMode(IRCMessage *message); 74 void parseLiteralMode(IRCMessage *message);
74 void parseLiteralKick(IRCMessage *message); 75 void parseLiteralKick(IRCMessage *message);
75 void parseLiteralTopic(IRCMessage *message); 76 void parseLiteralTopic(IRCMessage *message);
76 void parseNumericalSecondParam(IRCMessage *message); 77 void parseNumerical(IRCMessage *message, int position);
77 void parseNumericalAllParams(IRCMessage *message); 78 void parseNumericalServerName(IRCMessage *message);
79 void parseNumericalServerFeatures(IRCMessage *message);
80 void parseNumericalServerProtocol(IRCMessage *message);
81 void parseNumericalWhoisIdle(IRCMessage *message);
78 void parseNumericalNames(IRCMessage *message); 82 void parseNumericalNames(IRCMessage *message);
79 void parseNumericalEndOfNames(IRCMessage *message); 83 void parseNumericalEndOfNames(IRCMessage *message);
80 void parseNumericalNicknameInUse(IRCMessage *message); 84 void parseNumericalNicknameInUse(IRCMessage *message);
diff --git a/noncore/net/opieirc/ircserver.cpp b/noncore/net/opieirc/ircserver.cpp
index e27e41d..7e7e412 100644
--- a/noncore/net/opieirc/ircserver.cpp
+++ b/noncore/net/opieirc/ircserver.cpp
@@ -1,4 +1,7 @@
1#include "ircserver.h" 1#include "ircserver.h"
2#include "ircversion.h"
3
4#include <qobject.h>
2 5
3IRCServer::IRCServer() { 6IRCServer::IRCServer() {
4 m_port = 6667; 7 m_port = 6667;
@@ -49,7 +52,10 @@ QString IRCServer::name() {
49} 52}
50 53
51unsigned short int IRCServer::port() { 54unsigned short int IRCServer::port() {
52 return m_port; 55 if(m_port)
56 return m_port;
57
58 return 6667;
53} 59}
54 60
55QString IRCServer::username() { 61QString IRCServer::username() {
@@ -65,7 +71,10 @@ QString IRCServer::nick() {
65} 71}
66 72
67QString IRCServer::realname() { 73QString IRCServer::realname() {
68 return m_realname; 74 if(!m_realname.isEmpty())
75 return m_realname;
76
77 return QString(QObject::tr("Using")) + " " + QString(APP_VERSION);
69} 78}
70 79
71QString IRCServer::channels() { 80QString IRCServer::channels() {
diff --git a/noncore/net/opieirc/ircservereditor.cpp b/noncore/net/opieirc/ircservereditor.cpp
index 2d11bf0..1fda868 100644
--- a/noncore/net/opieirc/ircservereditor.cpp
+++ b/noncore/net/opieirc/ircservereditor.cpp
@@ -58,12 +58,12 @@ void IRCServerEditor::accept() {
58 QMessageBox::critical(this, tr("Error"), tr("Profile name required")); 58 QMessageBox::critical(this, tr("Error"), tr("Profile name required"));
59 else if (m_hostname->text().length()==0) 59 else if (m_hostname->text().length()==0)
60 QMessageBox::critical(this, tr("Error"), tr("Host name required")); 60 QMessageBox::critical(this, tr("Error"), tr("Host name required"));
61 else if (m_port->text().toInt()<=0) 61 //else if (m_port->text().toInt()<=0)
62 QMessageBox::critical(this, tr("Error"), tr("Port required")); 62 // QMessageBox::critical(this, tr("Error"), tr("Port required"));
63 else if (m_nickname->text().length()==0) 63 else if (m_nickname->text().length()==0)
64 QMessageBox::critical(this, tr("Error"), tr("Nickname required")); 64 QMessageBox::critical(this, tr("Error"), tr("Nickname required"));
65 else if (m_realname->text().length()==0) 65 //else if (m_realname->text().length()==0)
66 QMessageBox::critical(this, tr("Error"), tr("Realname required")); 66 // QMessageBox::critical(this, tr("Error"), tr("Realname required"));
67 else { 67 else {
68 /* Now verify whether the channel list has a valid format */ 68 /* Now verify whether the channel list has a valid format */
69 QStringList channels = QStringList::split(QChar(','), m_channels->text()); 69 QStringList channels = QStringList::split(QChar(','), m_channels->text());
diff --git a/noncore/net/opieirc/ircservertab.cpp b/noncore/net/opieirc/ircservertab.cpp
index e031d4d..90353f2 100644
--- a/noncore/net/opieirc/ircservertab.cpp
+++ b/noncore/net/opieirc/ircservertab.cpp
@@ -17,7 +17,7 @@ IRCServerTab::IRCServerTab(IRCServer server, MainWindow *mainWindow, QWidget *pa
17 m_mainWindow = mainWindow; 17 m_mainWindow = mainWindow;
18 m_close = FALSE; 18 m_close = FALSE;
19 m_lines = 0; 19 m_lines = 0;
20 m_description->setText(tr("Connection to")+" <b>" + server.hostname() + ":" + QString::number(server.port()) + "</b>"); 20 m_description->setText(tr("Connecting to")+" <b>" + server.hostname() + ":" + QString::number(server.port()) + "</b>");
21 m_textview = new QTextView(this); 21 m_textview = new QTextView(this);
22 m_textview->setHScrollBarMode(QScrollView::AlwaysOff); 22 m_textview->setHScrollBarMode(QScrollView::AlwaysOff);
23 m_textview->setVScrollBarMode(QScrollView::AlwaysOn); 23 m_textview->setVScrollBarMode(QScrollView::AlwaysOn);
@@ -35,6 +35,7 @@ IRCServerTab::IRCServerTab(IRCServer server, MainWindow *mainWindow, QWidget *pa
35 connect(m_field, SIGNAL(returnPressed()), this, SLOT(processCommand())); 35 connect(m_field, SIGNAL(returnPressed()), this, SLOT(processCommand()));
36 connect(m_session, SIGNAL(outputReady(IRCOutput)), this, SLOT(display(IRCOutput))); 36 connect(m_session, SIGNAL(outputReady(IRCOutput)), this, SLOT(display(IRCOutput)));
37 connect(m_mainWindow, SIGNAL(updateScroll()), this, SLOT(scrolling())); 37 connect(m_mainWindow, SIGNAL(updateScroll()), this, SLOT(scrolling()));
38 connect(m_session, SIGNAL(updateChannels()), this, SLOT(slotUpdateChannels()));
38 settingsChanged(); 39 settingsChanged();
39 40
40 m_field->setFocus(); 41 m_field->setFocus();
@@ -113,7 +114,13 @@ void IRCServerTab::executeCommand(IRCTab *tab, QString line) {
113 if (command == "JOIN" || command == "J") { 114 if (command == "JOIN" || command == "J") {
114 QString channel; 115 QString channel;
115 stream >> channel; 116 stream >> channel;
116 if (channel.length() > 0 && (channel.startsWith("#") || channel.startsWith("+"))) { 117 /* According to RFC 1459 */
118 if (channel.length() > 0 && channel.length() < 200 &&
119 channel.find(",") == -1 && channel.find("") == -1) {
120
121 if (!channel.startsWith("#") && !channel.startsWith("&")) {
122 channel = channel.prepend("#");
123 }
117 m_session->join(channel); 124 m_session->join(channel);
118 } else { 125 } else {
119 tab->appendText("<font color=\"" + m_errorColor + "\">Unknown channel format!</font><br>"); 126 tab->appendText("<font color=\"" + m_errorColor + "\">Unknown channel format!</font><br>");
@@ -345,7 +352,7 @@ void IRCServerTab::display(IRCOutput output) {
345 return; 352 return;
346 } 353 }
347 } 354 }
348 appendText("<font color=\"" + m_notificationColor + "\">"+output.htmlMessage()+"</font><br>"); 355 IRCChannelTab::enqueue(channel->channelname(), "<font color=\"" + m_notificationColor + "\">"+output.htmlMessage()+"</font><br>");
349 } 356 }
350 break; 357 break;
351 case OUTPUT_QUIT: { 358 case OUTPUT_QUIT: {
@@ -359,19 +366,22 @@ void IRCServerTab::display(IRCOutput output) {
359 } 366 }
360 } 367 }
361 break; 368 break;
362/* case OUTPUT_NICKCHANGE: { 369 case OUTPUT_NICKCHANGE: {
363 //WAS HERE 370 QString *nick = static_cast<QString*>(output.getParam(0));
364 QString nick = ((IRCPerson *)output.getParam(0))->nick(); 371 if(!nick) {
372 appendText("<font color=\"" + m_notificationColor + "\">"+output.htmlMessage()+"</font><br>");
373 break;
374 }
365 QListIterator<IRCChannelTab> it(m_channelTabs); 375 QListIterator<IRCChannelTab> it(m_channelTabs);
366 for (; it.current(); ++it) { 376 for (; it.current(); ++it) {
367 if (it.current()->list()->hasPerson(nick)) { 377 if (it.current()->list()->hasPerson(*nick)) {
368 it.current()->appendText("<font color=\"" + m_notificationColor + "\">"+output.htmlMessage()+"</font><br>"); 378 it.current()->appendText("<font color=\"" + m_notificationColor + "\">"+output.htmlMessage()+"</font><br>");
369 it.current()->list()->update();
370 } 379 }
371 } 380 }
381 delete nick;
372 } 382 }
373 break; 383 break;
374 */ case OUTPUT_OTHERJOIN: 384 case OUTPUT_OTHERJOIN:
375 case OUTPUT_OTHERKICK: 385 case OUTPUT_OTHERKICK:
376 case OUTPUT_CHANPERSONMODE: 386 case OUTPUT_CHANPERSONMODE:
377 case OUTPUT_OTHERPART: { 387 case OUTPUT_OTHERPART: {
@@ -386,8 +396,19 @@ void IRCServerTab::display(IRCOutput output) {
386 case OUTPUT_ERROR: 396 case OUTPUT_ERROR:
387 appendText("<font color=\"" + m_errorColor + "\">" + output.htmlMessage() + "</font><br>"); 397 appendText("<font color=\"" + m_errorColor + "\">" + output.htmlMessage() + "</font><br>");
388 break; 398 break;
399 case OUTPUT_TITLE:
400 m_description->setText(output.message());
401 break;
389 default: 402 default:
390 appendText("<font color=\"" + m_serverColor + "\">" + output.htmlMessage() + "</font><br>"); 403 appendText("<font color=\"" + m_serverColor + "\">" + output.htmlMessage() + "</font><br>");
391 break; 404 break;
392 } 405 }
393} 406}
407
408void IRCServerTab::slotUpdateChannels() {
409 QListIterator<IRCChannelTab> it(m_channelTabs);
410 for (; it.current(); ++it) {
411 it.current()->list()->update();
412 }
413}
414
diff --git a/noncore/net/opieirc/ircservertab.h b/noncore/net/opieirc/ircservertab.h
index 69543fc..42f6f57 100644
--- a/noncore/net/opieirc/ircservertab.h
+++ b/noncore/net/opieirc/ircservertab.h
@@ -62,6 +62,7 @@ public slots:
62 void remove(); 62 void remove();
63 void processCommand(); 63 void processCommand();
64 void settingsChanged(); 64 void settingsChanged();
65 void slotUpdateChannels();
65protected slots: 66protected slots:
66 void display(IRCOutput output); 67 void display(IRCOutput output);
67protected: 68protected:
diff --git a/noncore/net/opieirc/ircsession.cpp b/noncore/net/opieirc/ircsession.cpp
index 3b176d0..ca0df50 100644
--- a/noncore/net/opieirc/ircsession.cpp
+++ b/noncore/net/opieirc/ircsession.cpp
@@ -25,7 +25,7 @@ void IRCSession::beginSession() {
25} 25}
26 26
27void IRCSession::join(QString channelname) { 27void IRCSession::join(QString channelname) {
28 m_connection->sendLine("JOIN "+channelname); 28 m_connection->sendLine("JOIN " + channelname);
29} 29}
30 30
31void IRCSession::quit(){ 31void IRCSession::quit(){
@@ -57,15 +57,15 @@ void IRCSession::raw(QString message){
57} 57}
58 58
59void IRCSession::kick(IRCChannel *channel, IRCPerson *person) { 59void IRCSession::kick(IRCChannel *channel, IRCPerson *person) {
60 m_connection->sendLine("KICK "+ channel->channelname() + " " + person->nick() +" :0wn3d - no reason"); 60 m_connection->sendLine("KICK " + channel->channelname() + " " + person->nick() +" :0wn3d - no reason");
61} 61}
62 62
63void IRCSession::op(IRCChannel *channel, IRCPerson *person) { 63void IRCSession::op(IRCChannel *channel, IRCPerson *person) {
64 m_connection->sendLine("MODE "+ channel->channelname() + " +ooo " + person->nick()); 64 m_connection->sendLine("MODE " + channel->channelname() + " +ooo " + person->nick());
65} 65}
66 66
67void IRCSession::kick(IRCChannel *channel, IRCPerson *person, QString message) { 67void IRCSession::kick(IRCChannel *channel, IRCPerson *person, QString message) {
68 m_connection->sendLine("KICK "+ channel->channelname() + " " + person->nick() +" :" + message); 68 m_connection->sendLine("KICK " + channel->channelname() + " " + person->nick() +" :" + message);
69} 69}
70 70
71void IRCSession::sendMessage(IRCPerson *person, QString message) { 71void IRCSession::sendMessage(IRCPerson *person, QString message) {
@@ -88,9 +88,13 @@ bool IRCSession::isSessionActive() {
88 return m_connection->isConnected(); 88 return m_connection->isConnected();
89} 89}
90 90
91bool IRCSession::isLoggedIn() {
92 return m_connection->isLoggedIn();
93}
94
91void IRCSession::endSession() { 95void IRCSession::endSession() {
92 if (m_connection->isLoggedIn()) 96 if (m_connection->isLoggedIn())
93 m_connection->sendLine("QUIT :" APP_VERSION); 97 quit(APP_VERSION);
94 else 98 else
95 m_connection->close(); 99 m_connection->close();
96} 100}
@@ -99,6 +103,48 @@ void IRCSession::part(IRCChannel *channel) {
99 m_connection->sendLine("PART " + channel->channelname() + " :" + APP_VERSION); 103 m_connection->sendLine("PART " + channel->channelname() + " :" + APP_VERSION);
100} 104}
101 105
106void IRCSession::setValidUsermodes(const QString &modes) {
107 m_validUsermodes = modes;
108}
109
110void IRCSession::setValidChannelmodes(const QString &modes) {
111 m_validChannelmodes = modes;
112}
113
114void IRCSession::updateNickname(const QString &oldNickname, const QString &newNickname) {
115 QList<IRCChannel> channels;
116 IRCOutput output;
117
118 if (oldNickname == m_server->nick()) {
119 m_server->setNick(newNickname);
120 output = IRCOutput(OUTPUT_NICKCHANGE, tr("You are now known as %1").arg(newNickname));
121 channels = m_channels;
122 }
123
124 else {
125 IRCPerson *person = getPerson(oldNickname);
126
127 if(!person) {
128 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Nickname change of an unknown person")));
129 return;
130 }
131
132 getChannelsByPerson(person, channels);
133 output = IRCOutput(OUTPUT_NICKCHANGE, tr("%1 is now known as %2").arg(oldNickname).arg(newNickname));
134 }
135
136 QListIterator<IRCChannel> it(channels);
137 for (;it.current(); ++it) {
138 IRCChannelPerson *chanperson = it.current()->getPerson(oldNickname);
139 it.current()->removePerson(chanperson);
140 chanperson->person->setNick(newNickname);
141 it.current()->addPerson(chanperson);
142 }
143
144 emit updateChannels();
145 output.addParam(new QString(newNickname));
146 emit outputReady(output);
147}
102 148
103IRCChannel *IRCSession::getChannel(QString channelname) { 149IRCChannel *IRCSession::getChannel(QString channelname) {
104 QListIterator<IRCChannel> it(m_channels); 150 QListIterator<IRCChannel> it(m_channels);
diff --git a/noncore/net/opieirc/ircsession.h b/noncore/net/opieirc/ircsession.h
index f6330d8..96de3e4 100644
--- a/noncore/net/opieirc/ircsession.h
+++ b/noncore/net/opieirc/ircsession.h
@@ -57,10 +57,14 @@ public:
57 void beginSession(); 57 void beginSession();
58 bool isSessionActive(); 58 bool isSessionActive();
59 void endSession(); 59 void endSession();
60 bool isLoggedIn();
60 void sendMessage(IRCPerson *person, QString message); 61 void sendMessage(IRCPerson *person, QString message);
61 void sendMessage(IRCChannel *channel, QString message); 62 void sendMessage(IRCChannel *channel, QString message);
62 void sendAction(IRCPerson *person, QString message); 63 void sendAction(IRCPerson *person, QString message);
63 void sendAction(IRCChannel *channel, QString message); 64 void sendAction(IRCChannel *channel, QString message);
65 void updateNickname(const QString &oldNickname, const QString &newNickname);
66 void setValidUsermodes(const QString &modes);
67 void setValidChannelmodes(const QString &modes);
64 IRCChannel *getChannel(QString channelname); 68 IRCChannel *getChannel(QString channelname);
65 IRCPerson *getPerson(QString nickname); 69 IRCPerson *getPerson(QString nickname);
66protected: 70protected:
@@ -73,12 +77,15 @@ protected slots:
73 void handleMessage(IRCMessage *message); 77 void handleMessage(IRCMessage *message);
74signals: 78signals:
75 void outputReady(IRCOutput output); 79 void outputReady(IRCOutput output);
80 void updateChannels();
76protected: 81protected:
77 IRCServer *m_server; 82 IRCServer *m_server;
78 IRCConnection *m_connection; 83 IRCConnection *m_connection;
79 IRCMessageParser *m_parser; 84 IRCMessageParser *m_parser;
80 QList<IRCChannel> m_channels; 85 QList<IRCChannel> m_channels;
81 QList<IRCPerson> m_people; 86 QList<IRCPerson> m_people;
87 QString m_validUsermodes;
88 QString m_validChannelmodes;
82}; 89};
83 90
84#endif /* __IRCSESSION_H */ 91#endif /* __IRCSESSION_H */