summaryrefslogtreecommitdiff
authorskyhusker <skyhusker>2005-01-14 20:54:49 (UTC)
committer skyhusker <skyhusker>2005-01-14 20:54:49 (UTC)
commita808497c334275c4b73e31a9bea37f84e344964d (patch) (unidiff)
tree490b0396494b83b1145fc65ab81e3e437af9aed5
parentb6c5c3b8b1ab130217678ec789db573ffc52c3eb (diff)
downloadopie-a808497c334275c4b73e31a9bea37f84e344964d.zip
opie-a808497c334275c4b73e31a9bea37f84e344964d.tar.gz
opie-a808497c334275c4b73e31a9bea37f84e344964d.tar.bz2
Added message queue, now topics always appear in channel tab
Diffstat (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
@@ -46,20 +46,20 @@ bool IRCChannelList::removePerson(QString nick) {
46 return FALSE; 46 return FALSE;
47} 47}
48 48
49void IRCChannelList::adjustNicks() { 49void IRCChannelList::adjustNicks() {
50 QString txt; 50 QString txt;
51 QPixmap pm; 51 QPixmap pm;
52 52
53 for(unsigned int i=0; i<count(); i++) { 53 for(unsigned int i=0; i<count(); i++) {
54 txt = text(i).remove(0,1); 54 txt = text(i).remove(0,1);
55 if(pixmap(i)) { 55 if(pixmap(i)) {
56 pm = *pixmap(i); 56 pm = *pixmap(i);
57 removeItem(i); 57 removeItem(i);
58 insertItem(pm, txt, i); 58 insertItem(pm, txt, i);
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,24 +1,27 @@
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;
12 m_channel = channel; 15 m_channel = channel;
13 m_description->setText(tr("Talking on channel") + " <b>" + channel->channelname() + "</b>"); 16 m_description->setText(tr("Talking on channel") + " <b>" + channel->channelname() + "</b>");
14 QHBox *hbox = new QHBox(this); 17 QHBox *hbox = new QHBox(this);
15 m_textview = new QTextView(hbox); 18 m_textview = new QTextView(hbox);
16 m_textview->setHScrollBarMode(QScrollView::AlwaysOff); 19 m_textview->setHScrollBarMode(QScrollView::AlwaysOff);
17 m_textview->setVScrollBarMode(QScrollView::AlwaysOn); 20 m_textview->setVScrollBarMode(QScrollView::AlwaysOn);
18 m_listVisible = TRUE; 21 m_listVisible = TRUE;
19 m_listButton = new QPushButton(">", m_textview); 22 m_listButton = new QPushButton(">", m_textview);
20 m_listButton->setFlat( true ); 23 m_listButton->setFlat( true );
21 m_textview->setCornerWidget(m_listButton); 24 m_textview->setCornerWidget(m_listButton);
22 m_textview->setTextFormat(RichText); 25 m_textview->setTextFormat(RichText);
23 QWhatsThis::add(m_textview, tr("Channel discussion")); 26 QWhatsThis::add(m_textview, tr("Channel discussion"));
24 connect(m_listButton, SIGNAL(clicked()), this, SLOT(toggleList())); 27 connect(m_listButton, SIGNAL(clicked()), this, SLOT(toggleList()));
@@ -40,32 +43,38 @@ IRCChannelTab::IRCChannelTab(IRCChannel *channel, IRCServerTab *parentTab, MainW
40 /* Construct the popup menu */ 43 /* Construct the popup menu */
41 QPopupMenu *ctcpMenu = new QPopupMenu(m_list); 44 QPopupMenu *ctcpMenu = new QPopupMenu(m_list);
42 m_popup->insertItem(Resource::loadPixmap("opieirc/query"), tr("Query"), this, SLOT(popupQuery())); 45 m_popup->insertItem(Resource::loadPixmap("opieirc/query"), tr("Query"), this, SLOT(popupQuery()));
43 ctcpMenu->insertItem(Resource::loadPixmap("opieirc/ping"), tr("Ping"), this, SLOT(popupPing())); 46 ctcpMenu->insertItem(Resource::loadPixmap("opieirc/ping"), tr("Ping"), this, SLOT(popupPing()));
44 ctcpMenu->insertItem(Resource::loadPixmap("opieirc/version"), tr("Version"), this, SLOT(popupVersion())); 47 ctcpMenu->insertItem(Resource::loadPixmap("opieirc/version"), tr("Version"), this, SLOT(popupVersion()));
45 ctcpMenu->insertItem(Resource::loadPixmap("opieirc/whois"), tr("Whois"), this, SLOT(popupWhois())); 48 ctcpMenu->insertItem(Resource::loadPixmap("opieirc/whois"), tr("Whois"), this, SLOT(popupWhois()));
46 connect(m_mainWindow, SIGNAL(updateScroll()), this, SLOT(scrolling())); 49 connect(m_mainWindow, SIGNAL(updateScroll()), this, SLOT(scrolling()));
47 m_layout->add(hbox); 50 m_layout->add(hbox);
48 hbox->show(); 51 hbox->show();
49 m_layout->add(m_field); 52 m_layout->add(m_field);
50 m_field->setFocus(); 53 m_field->setFocus();
51 m_field->setActiveWindow(); 54 m_field->setActiveWindow();
52 55
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(){
59 m_textview->ensureVisible(0, m_textview->contentsHeight()); 68 m_textview->ensureVisible(0, m_textview->contentsHeight());
60} 69}
61 70
62void IRCChannelTab::appendText(QString text) { 71void IRCChannelTab::appendText(QString text) {
63 /* not using append because it creates layout problems */ 72 /* not using append because it creates layout problems */
64 QString txt = m_textview->text() + IRCTab::appendTimestamp( text ); 73 QString txt = m_textview->text() + IRCTab::appendTimestamp( text );
65 if (m_maxLines > 0 && m_lines >= m_maxLines) { 74 if (m_maxLines > 0 && m_lines >= m_maxLines) {
66 int firstBreak = txt.find('\n'); 75 int firstBreak = txt.find('\n');
67 if (firstBreak != -1) { 76 if (firstBreak != -1) {
68 txt = "<qt bgcolor=\"" + m_backgroundColor + "\"/>" + txt.right(txt.length() - (firstBreak + 1)); 77 txt = "<qt bgcolor=\"" + m_backgroundColor + "\"/>" + txt.right(txt.length() - (firstBreak + 1));
69 } 78 }
70 } else { 79 } else {
71 m_lines++; 80 m_lines++;
@@ -169,23 +178,31 @@ void IRCChannelTab::popupWhois() {
169QString IRCChannelTab::title() { 178QString IRCChannelTab::title() {
170 return m_channel->channelname(); 179 return m_channel->channelname();
171} 180}
172 181
173IRCSession *IRCChannelTab::session() { 182IRCSession *IRCChannelTab::session() {
174 return m_parentTab->session(); 183 return m_parentTab->session();
175} 184}
176 185
177void IRCChannelTab::remove() { 186void IRCChannelTab::remove() {
178 if (session()->isSessionActive()) { 187 if (session()->isSessionActive()) {
179 session()->part(m_channel); 188 session()->part(m_channel);
180 } else { 189 } else {
181 m_mainWindow->killTab(this); 190 m_mainWindow->killTab(this);
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}
188 204
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
@@ -18,58 +18,61 @@
18 18
19*/ 19*/
20 20
21#ifndef __IRCCHANNELTAB_H 21#ifndef __IRCCHANNELTAB_H
22#define __IRCCHANNELTAB_H 22#define __IRCCHANNELTAB_H
23 23
24#include <qpopupmenu.h> 24#include <qpopupmenu.h>
25#include <qpushbutton.h> 25#include <qpushbutton.h>
26#include "irctab.h" 26#include "irctab.h"
27#include "ircsession.h" 27#include "ircsession.h"
28#include "ircmisc.h" 28#include "ircmisc.h"
29#include "mainwindow.h" 29#include "mainwindow.h"
30#include "ircchannellist.h" 30#include "ircchannellist.h"
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
37public: 38public:
38 /* IRCTab implementation */ 39 /* IRCTab implementation */
39 IRCChannelTab(IRCChannel *channel, IRCServerTab *parentTab, MainWindow *mainWindow, QWidget *parent = 0, const char *name = 0, WFlags f = 0); 40 IRCChannelTab(IRCChannel *channel, IRCServerTab *parentTab, MainWindow *mainWindow, QWidget *parent = 0, const char *name = 0, WFlags f = 0);
40 ~IRCChannelTab(); 41 ~IRCChannelTab();
41 QString title(); 42 QString title();
42 IRCSession *session(); 43 IRCSession *session();
43 IRCChannel *channel(); 44 IRCChannel *channel();
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();
50 void scrolling(); 52 void scrolling();
51protected slots: 53protected slots:
52 void processCommand(); 54 void processCommand();
53 void toggleList(); 55 void toggleList();
54 void mouseButtonPressed(int mouse, QListBoxItem *item, const QPoint &point); 56 void mouseButtonPressed(int mouse, QListBoxItem *item, const QPoint &point);
55 /* Popup slots */ 57 /* Popup slots */
56 void popupQuery(QListBoxItem*); 58 void popupQuery(QListBoxItem*);
57 void popupQuery(); 59 void popupQuery();
58 60
59 void popupPing(); 61 void popupPing();
60 void popupVersion(); 62 void popupVersion();
61 void popupWhois(); 63 void popupWhois();
62protected: 64protected:
63 IRCServerTab *m_parentTab; 65 IRCServerTab *m_parentTab;
64 IRCChannel *m_channel; 66 IRCChannel *m_channel;
65 IRCChannelList *m_list; 67 IRCChannelList *m_list;
66 QPushButton *m_listButton; 68 QPushButton *m_listButton;
67 MainWindow *m_mainWindow; 69 MainWindow *m_mainWindow;
68 QTextView *m_textview; 70 QTextView *m_textview;
69 IRCHistoryLineEdit *m_field; 71 IRCHistoryLineEdit *m_field;
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,17 +1,20 @@
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/*
5 * Create a new IRCMessage by evaluating 8 * Create a new IRCMessage by evaluating
6 * a received string 9 * a received string
7 */ 10 */
8 11
9IRCMessage::IRCMessage(QString line) { 12IRCMessage::IRCMessage(QString line) {
10 /* Remove CRs from the message */ 13 /* Remove CRs from the message */
11 while((line.right(1) == "\n") || (line.right(1) == "\r")) 14 while((line.right(1) == "\n") || (line.right(1) == "\r"))
12 line = line.left(line.length() - 1); 15 line = line.left(line.length() - 1);
13 QTextIStream stream(&line); 16 QTextIStream stream(&line);
14 QString temp; 17 QString temp;
15 18
16 stream >> temp; 19 stream >> temp;
17 if (temp.startsWith(":")) { 20 if (temp.startsWith(":")) {
@@ -51,52 +54,78 @@ IRCMessage::IRCMessage(QString line) {
51 ctcpStream >> temp; 54 ctcpStream >> temp;
52 m_ctcpCommand = temp.upper().right(temp.length()-1); 55 m_ctcpCommand = temp.upper().right(temp.length()-1);
53 m_parameters.clear(); 56 m_parameters.clear();
54 int length = m_allParameters.length() - m_ctcpCommand.length() - 1; 57 int length = m_allParameters.length() - m_ctcpCommand.length() - 1;
55 if (m_command == "PRIVMSG") 58 if (m_command == "PRIVMSG")
56 length -= m_ctcpDestination.length() + 1; 59 length -= m_ctcpDestination.length() + 1;
57 if (length <= 0) { 60 if (length <= 0) {
58 m_allParameters = ""; 61 m_allParameters = "";
59 } else { 62 } else {
60 m_allParameters = m_allParameters.right(length); 63 m_allParameters = m_allParameters.right(length);
61 m_parameters << m_allParameters; 64 m_parameters << m_allParameters;
62 } 65 }
63 } else { 66 } else {
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());
72 printf("Command : '%s'\n", m_command.ascii()); 75 printf("Command : '%s'\n", m_command.ascii());
73 printf("Allparameters : '%s'\n", m_allParameters.ascii()); 76 printf("Allparameters : '%s'\n", m_allParameters.ascii());
74 for (unsigned int i=0; i<m_parameters.count(); i++) { 77 for (unsigned int i=0; i<m_parameters.count(); i++) {
75 printf("Parameter %i : '%s'\n", i, m_parameters[i].ascii()); 78 printf("Parameter %i : '%s'\n", i, m_parameters[i].ascii());
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
83QString IRCMessage::param(int param) { 87QString 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}
90 119
91QString IRCMessage::command() { 120QString IRCMessage::command() {
92 return m_command; 121 return m_command;
93} 122}
94 123
95QString IRCMessage::ctcpCommand() { 124QString IRCMessage::ctcpCommand() {
96 return m_ctcpCommand; 125 return m_ctcpCommand;
97} 126}
98 127
99QString IRCMessage::ctcpDestination() { 128QString IRCMessage::ctcpDestination() {
100 return m_ctcpDestination; 129 return m_ctcpDestination;
101} 130}
102 131
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
@@ -8,61 +8,63 @@
8 (at your option) any later version. 8 (at your option) any later version.
9 9
10 This program is distributed in the hope that it will be useful, 10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details. 13 GNU General Public License for more details.
14 14
15 You should have received a copy of the GNU General Public License 15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software 16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 18
19*/ 19*/
20 20
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. */
29 29
30class IRCMessage { 30class IRCMessage {
31public: 31public:
32 /* Parse an IRC message and create the IRCMessage object */ 32 /* Parse an IRC message and create the IRCMessage object */
33 IRCMessage(QString line); 33 IRCMessage(QString line);
34 34
35 /* Return the IRC message prefix (usually sender etc) */ 35 /* Return the IRC message prefix (usually sender etc) */
36 QString prefix(); 36 QString prefix();
37 /* Check if this IRCMessage's command is literal or numerical */ 37 /* Check if this IRCMessage's command is literal or numerical */
38 bool isNumerical(); 38 bool isNumerical();
39 /* CHeck if this IRCMessage is a CTCP message */ 39 /* CHeck if this IRCMessage is a CTCP message */
40 bool isCTCP(); 40 bool isCTCP();
41 /* Return the IRC command (literal commands) */ 41 /* Return the IRC command (literal commands) */
42 QString command(); 42 QString command();
43 /* Return the CTCP command */ 43 /* Return the CTCP command */
44 QString ctcpCommand(); 44 QString ctcpCommand();
45 /* Return the CTCP destination if applicable (channel/person) */ 45 /* Return the CTCP destination if applicable (channel/person) */
46 QString ctcpDestination(); 46 QString ctcpDestination();
47 /* Return the IRC command (numerical commands) */ 47 /* Return the IRC command (numerical commands) */
48 unsigned short commandNumber(); 48 unsigned short commandNumber();
49 /* Return the trailing parameter string */ 49 /* Return the trailing parameter string */
50 QString trailing(); 50 QString trailing();
51 /* Return the complete parameter string */ 51 /* Return the complete parameter string */
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;
58 QString m_ctcpCommand; 60 QString m_ctcpCommand;
59 QString m_ctcpDestination; 61 QString m_ctcpDestination;
60 unsigned short m_commandNumber; 62 unsigned short m_commandNumber;
61 QString m_allParameters; 63 QString m_allParameters;
62 QString m_trailing; 64 QString m_trailing;
63 QStringList m_parameters; 65 QStringList m_parameters;
64 bool m_isNumerical; 66 bool m_isNumerical;
65 bool m_ctcp; 67 bool m_ctcp;
66}; 68};
67 69
68#endif 70#endif
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,114 +1,177 @@
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
5/* Lookup table for literal commands */ 7/* Lookup table for literal commands */
6IRCLiteralMessageParserStruct IRCMessageParser::literalParserProcTable[] = { 8IRCLiteralMessageParserStruct IRCMessageParser::literalParserProcTable[] = {
7 { "PING", FUNC(parseLiteralPing) }, 9 { "PING", FUNC(parseLiteralPing) },
8 { "NOTICE", FUNC(parseLiteralNotice) }, 10 { "NOTICE", FUNC(parseLiteralNotice) },
9 { "JOIN", FUNC(parseLiteralJoin) }, 11 { "JOIN", FUNC(parseLiteralJoin) },
10 { "PRIVMSG", FUNC(parseLiteralPrivMsg) }, 12 { "PRIVMSG", FUNC(parseLiteralPrivMsg) },
11 { "NICK", FUNC(parseLiteralNick) }, 13 { "NICK", FUNC(parseLiteralNick) },
12 { "PART", FUNC(parseLiteralPart) }, 14 { "PART", FUNC(parseLiteralPart) },
13 { "QUIT", FUNC(parseLiteralQuit) }, 15 { "QUIT", FUNC(parseLiteralQuit) },
14 { "ERROR", FUNC(parseLiteralError) }, 16 { "ERROR", FUNC(parseLiteralError) },
15 { "ERROR:", FUNC(parseLiteralError) }, 17 { "ERROR:", FUNC(parseLiteralError) },
16 { "MODE", FUNC(parseLiteralMode) }, 18 { "MODE", FUNC(parseLiteralMode) },
17 { "KICK", FUNC(parseLiteralKick) }, 19 { "KICK", FUNC(parseLiteralKick) },
18 { "TOPIC", FUNC(parseLiteralTopic) }, 20 { "TOPIC", FUNC(parseLiteralTopic) },
19 { 0 , 0 } 21 { 0 , 0 }
20}; 22};
21 23
22/* Lookup table for literal commands */ 24/* Lookup table for literal commands */
23IRCCTCPMessageParserStruct IRCMessageParser::ctcpParserProcTable[] = { 25IRCCTCPMessageParserStruct IRCMessageParser::ctcpParserProcTable[] = {
24 { "PING", FUNC(parseCTCPPing) }, 26 { "PING", FUNC(parseCTCPPing) },
25 { "VERSION", FUNC(parseCTCPVersion) }, 27 { "VERSION", FUNC(parseCTCPVersion) },
26 { "ACTION", FUNC(parseCTCPAction) }, 28 { "ACTION", FUNC(parseCTCPAction) },
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
63IRCMessageParser::IRCMessageParser(IRCSession *session) { 84IRCMessageParser::IRCMessageParser(IRCSession *session) {
64 m_session = session; 85 m_session = session;
65} 86}
66 87
67void IRCMessageParser::parse(IRCMessage *message) { 88void IRCMessageParser::parse(IRCMessage *message) {
68 /* Find out what kind of message we have here and call the appropriate handler using 89 /* Find out what kind of message we have here and call the appropriate handler using
69 the parser tables. If no handler can be found, print out an error message */ 90 the parser tables. If no handler can be found, print out an error 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 }
77 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Received unhandled numeric command: %1").arg( QString::number(message->commandNumber()) ))); 98 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Received unhandled numeric command: %1").arg( QString::number(message->commandNumber()) )));
78 } else if (message->isCTCP()) { 99 } else if (message->isCTCP()) {
79 for (int i=0; ctcpParserProcTable[i].commandName; i++) { 100 for (int i=0; ctcpParserProcTable[i].commandName; i++) {
80 if (message->ctcpCommand() == ctcpParserProcTable[i].commandName) { 101 if (message->ctcpCommand() == ctcpParserProcTable[i].commandName) {
81 (this->*(ctcpParserProcTable[i].proc))(message); 102 (this->*(ctcpParserProcTable[i].proc))(message);
82 return; 103 return;
83 } 104 }
84 } 105 }
85 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Received unhandled ctcp command: %1").arg( message->ctcpCommand())) ); 106 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Received unhandled ctcp command: %1").arg( message->ctcpCommand())) );
86 } else { 107 } else {
87 for (int i=0; literalParserProcTable[i].commandName; i++) { 108 for (int i=0; literalParserProcTable[i].commandName; i++) {
88 if (message->command() == literalParserProcTable[i].commandName) { 109 if (message->command() == literalParserProcTable[i].commandName) {
89 (this->*(literalParserProcTable[i].proc))(message); 110 (this->*(literalParserProcTable[i].proc))(message);
90 return; 111 return;
91 } 112 }
92 } 113 }
93 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Received unhandled literal command: %1").arg( message->command()) )); 114 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Received unhandled literal command: %1").arg( message->command()) ));
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) {
102 m_session->m_connection->sendLine("PONG " + message->allParameters()); 165 m_session->m_connection->sendLine("PONG " + message->allParameters());
103} 166}
104 167
105void IRCMessageParser::parseLiteralNotice(IRCMessage *message) { 168void IRCMessageParser::parseLiteralNotice(IRCMessage *message) {
106 emit outputReady(IRCOutput(OUTPUT_SERVERMESSAGE, message->allParameters())); 169 emit outputReady(IRCOutput(OUTPUT_SERVERMESSAGE, message->allParameters()));
107} 170}
108 171
109void IRCMessageParser::parseLiteralJoin(IRCMessage *message) { 172void IRCMessageParser::parseLiteralJoin(IRCMessage *message) {
110 QString channelName = message->param(0).lower(); 173 QString channelName = message->param(0).lower();
111 IRCPerson mask(message->prefix()); 174 IRCPerson mask(message->prefix());
112 IRCChannel *channel = m_session->getChannel(channelName); 175 IRCChannel *channel = m_session->getChannel(channelName);
113 if (!channel) { 176 if (!channel) {
114 /* We joined */ 177 /* We joined */
@@ -196,65 +259,65 @@ void IRCMessageParser::parseLiteralPrivMsg(IRCMessage *message) {
196 IRCOutput output(OUTPUT_CHANPRIVMSG, message->param(1)); 259 IRCOutput output(OUTPUT_CHANPRIVMSG, message->param(1));
197 output.addParam(channel); 260 output.addParam(channel);
198 output.addParam(person); 261 output.addParam(person);
199 emit outputReady(output); 262 emit outputReady(output);
200 } else { 263 } else {
201 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Channel message with unknown sender"))); 264 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Channel message with unknown sender")));
202 } 265 }
203 } else { 266 } else {
204 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Channel message with unknown channel %1").arg(message->param(0).lower()) )); 267 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Channel message with unknown channel %1").arg(message->param(0).lower()) ));
205 } 268 }
206 } else { 269 } else {
207 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Received PRIVMSG of unknown type"))); 270 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Received PRIVMSG of unknown type")));
208 } 271 }
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);
231 for (;it.current(); ++it) { 294 for (;it.current(); ++it) {
232 IRCChannelPerson *chanperson = it.current()->getPerson(mask.nick()); 295 IRCChannelPerson *chanperson = it.current()->getPerson(mask.nick());
233 it.current()->removePerson(chanperson); 296 it.current()->removePerson(chanperson);
234 chanperson->person->setNick(message->param(0)); 297 chanperson->person->setNick(message->param(0));
235 it.current()->addPerson(chanperson); 298 it.current()->addPerson(chanperson);
236 IRCOutput output(OUTPUT_NICKCHANGE, tr("%1 is now known as %2").arg( mask.nick() ).arg( message->param(0))); 299 IRCOutput output(OUTPUT_NICKCHANGE, tr("%1 is now known as %2").arg( mask.nick() ).arg( message->param(0)));
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) {
248 IRCPerson mask(message->prefix()); 311 IRCPerson mask(message->prefix());
249 IRCPerson *person = m_session->getPerson(mask.nick()); 312 IRCPerson *person = m_session->getPerson(mask.nick());
250 if (person) { 313 if (person) {
251 QList<IRCChannel> channels; 314 QList<IRCChannel> channels;
252 m_session->getChannelsByPerson(person, channels); 315 m_session->getChannelsByPerson(person, channels);
253 QListIterator<IRCChannel> it(channels); 316 QListIterator<IRCChannel> it(channels);
254 for (;it.current(); ++it) { 317 for (;it.current(); ++it) {
255 IRCChannelPerson *chanperson = it.current()->getPerson(mask.nick()); 318 IRCChannelPerson *chanperson = it.current()->getPerson(mask.nick());
256 it.current()->removePerson(chanperson); 319 it.current()->removePerson(chanperson);
257 delete chanperson; 320 delete chanperson;
258 } 321 }
259 m_session->removePerson(person); 322 m_session->removePerson(person);
260 IRCOutput output(OUTPUT_QUIT, tr("%1 has quit (%2)" ).arg( mask.nick() ).arg( message->param(0) )); 323 IRCOutput output(OUTPUT_QUIT, tr("%1 has quit (%2)" ).arg( mask.nick() ).arg( message->param(0) ));
@@ -311,33 +374,33 @@ void IRCMessageParser::parseCTCPPing(IRCMessage *message) {
311 /* Person not yet known, create and add to the current session */ 374 /* Person not yet known, create and add to the current session */
312 person = new IRCPerson(message->prefix()); 375 person = new IRCPerson(message->prefix());
313 m_session->addPerson(person); 376 m_session->addPerson(person);
314 } 377 }
315 IRCOutput output(OUTPUT_QUERYACTION, tr("Received a CTCP PING from ")+ mask.nick() ); 378 IRCOutput output(OUTPUT_QUERYACTION, tr("Received a CTCP PING from ")+ mask.nick() );
316 output.addParam(person); 379 output.addParam(person);
317 emit outputReady(output); 380 emit outputReady(output);
318 } else { 381 } else {
319 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("CTCP PING with bad recipient"))); 382 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("CTCP PING with bad recipient")));
320 } 383 }
321 } 384 }
322 385
323} 386}
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
331void IRCMessageParser::parseCTCPAction(IRCMessage *message) { 394void IRCMessageParser::parseCTCPAction(IRCMessage *message) {
332 IRCPerson mask(message->prefix()); 395 IRCPerson mask(message->prefix());
333 QString dest = message->ctcpDestination(); 396 QString dest = message->ctcpDestination();
334 if (dest.startsWith("#")) { 397 if (dest.startsWith("#")) {
335 IRCChannel *channel = m_session->getChannel(dest.lower()); 398 IRCChannel *channel = m_session->getChannel(dest.lower());
336 if (channel) { 399 if (channel) {
337 IRCChannelPerson *person = channel->getPerson(mask.nick()); 400 IRCChannelPerson *person = channel->getPerson(mask.nick());
338 if (person) { 401 if (person) {
339 IRCOutput output(OUTPUT_CHANACTION, "*" + mask.nick() + message->param(0)); 402 IRCOutput output(OUTPUT_CHANACTION, "*" + mask.nick() + message->param(0));
340 output.addParam(channel); 403 output.addParam(channel);
341 output.addParam(person); 404 output.addParam(person);
342 emit outputReady(output); 405 emit outputReady(output);
343 } else { 406 } else {
@@ -450,41 +513,32 @@ void IRCMessageParser::parseLiteralKick(IRCMessage *message) {
450 } else { 513 } else {
451 /* someone else got kicked */ 514 /* someone else got kicked */
452 channel->removePerson(person); 515 channel->removePerson(person);
453 IRCOutput output(OUTPUT_OTHERKICK, person->person->nick() + tr(" was kicked from ") + channel->channelname() + tr(" by ") + mask.nick()+ " (" + message->param(2) + ")"); 516 IRCOutput output(OUTPUT_OTHERKICK, person->person->nick() + tr(" was kicked from ") + channel->channelname() + tr(" by ") + mask.nick()+ " (" + message->param(2) + ")");
454 output.addParam(channel); 517 output.addParam(channel);
455 output.addParam(person); 518 output.addParam(person);
456 emit outputReady(output); 519 emit outputReady(output);
457 } 520 }
458 } else { 521 } else {
459 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Unknown person kick - desynchronized?"))); 522 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Unknown person kick - desynchronized?")));
460 } 523 }
461 } else { 524 } else {
462 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Unknown channel kick - desynchronized?"))); 525 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Unknown channel kick - desynchronized?")));
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());
478 if (channel != 0) { 532 if (channel != 0) {
479 QString people = message->param(3); 533 QString people = message->param(3);
480 QTextIStream stream(&people); 534 QTextIStream stream(&people);
481 QString temp; 535 QString temp;
482 536
483 while (!stream.atEnd()) { 537 while (!stream.atEnd()) {
484 stream >> temp; 538 stream >> temp;
485 539
486 char flagch = temp.at(0).latin1(); 540 char flagch = temp.at(0).latin1();
487 int flag = 0; 541 int flag = 0;
488 QString nick; 542 QString nick;
489 /* Parse person flags */ 543 /* Parse person flags */
490 if (flagch == '@' || flagch == '+' || flagch=='%' || flagch == '*') { 544 if (flagch == '@' || flagch == '+' || flagch=='%' || flagch == '*') {
@@ -519,32 +573,36 @@ void IRCMessageParser::parseNumericalNames(IRCMessage *message) {
519void IRCMessageParser::parseNumericalEndOfNames(IRCMessage *message) { 573void IRCMessageParser::parseNumericalEndOfNames(IRCMessage *message) {
520 /* Done syncing to channel */ 574 /* Done syncing to channel */
521 IRCChannel *channel = m_session->getChannel(message->param(1).lower()); 575 IRCChannel *channel = m_session->getChannel(message->param(1).lower());
522 if (channel) { 576 if (channel) {
523 channel->setHasPeople(TRUE); 577 channel->setHasPeople(TRUE);
524 /* Yes, we want the names before anything happens inside the GUI */ 578 /* Yes, we want the names before anything happens inside the GUI */
525 IRCOutput output(OUTPUT_SELFJOIN, tr("You joined channel ") + channel->channelname()); 579 IRCOutput output(OUTPUT_SELFJOIN, tr("You joined channel ") + channel->channelname());
526 output.addParam(channel); 580 output.addParam(channel);
527 emit outputReady(output); 581 emit outputReady(output);
528 } else { 582 } else {
529 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Server message with unknown channel"))); 583 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Server message with unknown channel")));
530 } 584 }
531} 585}
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}
538 596
539void IRCMessageParser::parseNumericalNoSuchNick(IRCMessage *) { 597void IRCMessageParser::parseNumericalNoSuchNick(IRCMessage *) {
540 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("No such nickname"))); 598 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("No such nickname")));
541} 599}
542 600
543void IRCMessageParser::parseNumericalTopic(IRCMessage *message) { 601void IRCMessageParser::parseNumericalTopic(IRCMessage *message) {
544 IRCChannel *channel = m_session->getChannel(message->param(1).lower()); 602 IRCChannel *channel = m_session->getChannel(message->param(1).lower());
545 if (channel) { 603 if (channel) {
546 IRCOutput output(OUTPUT_TOPIC, tr("Topic for channel " + channel->channelname() + " is \"" + message->param(2) + "\"")); 604 IRCOutput output(OUTPUT_TOPIC, tr("Topic for channel " + channel->channelname() + " is \"" + message->param(2) + "\""));
547 output.addParam(channel); 605 output.addParam(channel);
548 emit outputReady(output); 606 emit outputReady(output);
549 } else { 607 } else {
550 IRCOutput output(OUTPUT_TOPIC, tr("Topic for channel " + message->param(1) + " is \"" + message->param(2) + "\"")); 608 IRCOutput output(OUTPUT_TOPIC, tr("Topic for channel " + message->param(1) + " is \"" + message->param(2) + "\""));
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
@@ -33,61 +33,65 @@ typedef void (IRCMessageParser::*IRCMessageParseProc)(IRCMessage *);
33 33
34/* Struct representing a literal command handler */ 34/* Struct representing a literal command handler */
35typedef struct IRCLiteralMessageParserStruct { 35typedef struct IRCLiteralMessageParserStruct {
36 char *commandName; 36 char *commandName;
37 IRCMessageParseProc proc; 37 IRCMessageParseProc proc;
38}; 38};
39 39
40/* Struct representing a ctcp command handler */ 40/* Struct representing a ctcp command handler */
41typedef struct IRCCTCPMessageParserStruct { 41typedef struct IRCCTCPMessageParserStruct {
42 char *commandName; 42 char *commandName;
43 IRCMessageParseProc proc; 43 IRCMessageParseProc proc;
44}; 44};
45 45
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
52class IRCMessageParser : public QObject { 54class IRCMessageParser : public QObject {
53 Q_OBJECT 55 Q_OBJECT
54public: 56public:
55 /* Create an IRCMessageParser object */ 57 /* Create an IRCMessageParser object */
56 IRCMessageParser(IRCSession *session); 58 IRCMessageParser(IRCSession *session);
57 /* Parse a server message and take the appropriate actions */ 59 /* Parse a server message and take the appropriate actions */
58 void parse(IRCMessage *message); 60 void parse(IRCMessage *message);
59signals: 61signals:
60 /* Used to send commands to the UI (such as displaying text etc) */ 62 /* Used to send commands to the UI (such as displaying text etc) */
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);
68 void parseLiteralPrivMsg(IRCMessage *message); 69 void parseLiteralPrivMsg(IRCMessage *message);
69 void parseLiteralNick(IRCMessage *message); 70 void parseLiteralNick(IRCMessage *message);
70 void parseLiteralPart(IRCMessage *message); 71 void parseLiteralPart(IRCMessage *message);
71 void parseLiteralQuit(IRCMessage *message); 72 void parseLiteralQuit(IRCMessage *message);
72 void parseLiteralError(IRCMessage *message); 73 void parseLiteralError(IRCMessage *message);
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);
81 void parseNumericalNoSuchNick(IRCMessage *message); 85 void parseNumericalNoSuchNick(IRCMessage *message);
82 void parseNumericalTopic(IRCMessage *message); 86 void parseNumericalTopic(IRCMessage *message);
83 void parseNumericalTopicWhoTime(IRCMessage *message); 87 void parseNumericalTopicWhoTime(IRCMessage *message);
84 void parseCTCPPing(IRCMessage *message); 88 void parseCTCPPing(IRCMessage *message);
85 void parseCTCPVersion(IRCMessage *message); 89 void parseCTCPVersion(IRCMessage *message);
86 void parseCTCPAction(IRCMessage *message); 90 void parseCTCPAction(IRCMessage *message);
87protected: 91protected:
88 IRCSession *m_session; 92 IRCSession *m_session;
89 /* Parser tables */ 93 /* Parser tables */
90 static IRCLiteralMessageParserStruct literalParserProcTable[]; 94 static IRCLiteralMessageParserStruct literalParserProcTable[];
91 static IRCNumericalMessageParserStruct numericalParserProcTable[]; 95 static IRCNumericalMessageParserStruct numericalParserProcTable[];
92 static IRCCTCPMessageParserStruct ctcpParserProcTable[]; 96 static IRCCTCPMessageParserStruct ctcpParserProcTable[];
93}; 97};
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,17 +1,20 @@
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;
5} 8}
6 9
7/* Setter implementations */ 10/* Setter implementations */
8 11
9void IRCServer::setHostname(QString hostname) { 12void IRCServer::setHostname(QString hostname) {
10 m_hostname = hostname; 13 m_hostname = hostname;
11} 14}
12 15
13void IRCServer::setName(QString name) { 16void IRCServer::setName(QString name) {
14 m_name = name; 17 m_name = name;
15} 18}
16 19
17void IRCServer::setPort(int port) { 20void IRCServer::setPort(int port) {
@@ -36,39 +39,45 @@ void IRCServer::setRealname(QString realname) {
36 39
37void IRCServer::setChannels(QString channels) { 40void IRCServer::setChannels(QString channels) {
38 m_channels = channels; 41 m_channels = channels;
39} 42}
40 43
41/* Getter implementations */ 44/* Getter implementations */
42 45
43QString IRCServer::hostname() { 46QString IRCServer::hostname() {
44 return m_hostname; 47 return m_hostname;
45} 48}
46 49
47QString IRCServer::name() { 50QString IRCServer::name() {
48 return m_name; 51 return m_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() {
56 return m_username; 62 return m_username;
57} 63}
58 64
59QString IRCServer::password() { 65QString IRCServer::password() {
60 return m_password; 66 return m_password;
61} 67}
62 68
63QString IRCServer::nick() { 69QString IRCServer::nick() {
64 return m_nick; 70 return m_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() {
72 return m_channels; 81 return m_channels;
73} 82}
74 83
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
@@ -45,38 +45,38 @@ IRCServerEditor::IRCServerEditor(IRCServer server, QWidget* parent, const char*
45 label = new QLabel(tr("Channels :"), this); 45 label = new QLabel(tr("Channels :"), this);
46 m_channels = new QLineEdit(server.channels(), this); 46 m_channels = new QLineEdit(server.channels(), this);
47 QWhatsThis::add(m_channels, tr("Comma-Separated list of all channels you would like to join automatically")); 47 QWhatsThis::add(m_channels, tr("Comma-Separated list of all channels you would like to join automatically"));
48 layout->addWidget(label, 6, 0); 48 layout->addWidget(label, 6, 0);
49 layout->addWidget(m_channels, 6, 1); 49 layout->addWidget(m_channels, 6, 1);
50 setCaption(tr("Edit server information")); 50 setCaption(tr("Edit server information"));
51 51
52 QPEApplication::showDialog( this ); 52 QPEApplication::showDialog( this );
53} 53}
54 54
55 55
56void IRCServerEditor::accept() { 56void IRCServerEditor::accept() {
57 if (m_name->text().length()==0) 57 if (m_name->text().length()==0)
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());
70 for (QStringList::Iterator it = channels.begin(); it != channels.end(); ++it) { 70 for (QStringList::Iterator it = channels.begin(); it != channels.end(); ++it) {
71 QString channelName = (*it).stripWhiteSpace(); 71 QString channelName = (*it).stripWhiteSpace();
72 if (!channelName.startsWith("#") && !channelName.startsWith("+")) { 72 if (!channelName.startsWith("#") && !channelName.startsWith("+")) {
73 QMessageBox::critical(this, tr("Error"), tr("The channel list needs to contain a\ncomma separated list of channel\n names which start with either '#' or '+'")); 73 QMessageBox::critical(this, tr("Error"), tr("The channel list needs to contain a\ncomma separated list of channel\n names which start with either '#' or '+'"));
74 return; 74 return;
75 } 75 }
76 } 76 }
77 QDialog::accept(); 77 QDialog::accept();
78 } 78 }
79} 79}
80 80
81IRCServer IRCServerEditor::getServer() { 81IRCServer IRCServerEditor::getServer() {
82 IRCServer server; 82 IRCServer server;
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
@@ -4,50 +4,51 @@
4#include "ircservertab.h" 4#include "ircservertab.h"
5#include "ircmessageparser.h" 5#include "ircmessageparser.h"
6 6
7 7
8bool IRCServerTab::containsPing( const QString& text, IRCServerTab* tab ) { 8bool IRCServerTab::containsPing( const QString& text, IRCServerTab* tab ) {
9 return (text.contains(IRCMessageParser::tr("Received a CTCP PING from "))) || 9 return (text.contains(IRCMessageParser::tr("Received a CTCP PING from "))) ||
10 (text.find("ping") != -1 && text.find( tab->server()->nick() != -1)); 10 (text.find("ping") != -1 && text.find( tab->server()->nick() != -1));
11} 11}
12 12
13 13
14IRCServerTab::IRCServerTab(IRCServer server, MainWindow *mainWindow, QWidget *parent, const char *name, WFlags f) : IRCTab(parent, name, f) { 14IRCServerTab::IRCServerTab(IRCServer server, MainWindow *mainWindow, QWidget *parent, const char *name, WFlags f) : IRCTab(parent, name, f) {
15 m_server = server; 15 m_server = server;
16 m_session = new IRCSession(&m_server); 16 m_session = new IRCSession(&m_server);
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);
24 m_textview->setTextFormat(RichText); 24 m_textview->setTextFormat(RichText);
25 QWhatsThis::add(m_textview, tr("Server messages")); 25 QWhatsThis::add(m_textview, tr("Server messages"));
26 m_layout->add(m_textview); 26 m_layout->add(m_textview);
27 m_field = new IRCHistoryLineEdit(this); 27 m_field = new IRCHistoryLineEdit(this);
28 connect(m_field, SIGNAL(nextTab()), this, SIGNAL(nextTab())); 28 connect(m_field, SIGNAL(nextTab()), this, SIGNAL(nextTab()));
29 connect(m_field, SIGNAL(prevTab()), this, SIGNAL(prevTab())); 29 connect(m_field, SIGNAL(prevTab()), this, SIGNAL(prevTab()));
30 connect(m_field, SIGNAL(closeTab()), this, SIGNAL(closeTab())); 30 connect(m_field, SIGNAL(closeTab()), this, SIGNAL(closeTab()));
31 connect(this, SIGNAL(editFocus()), m_field, SLOT(setEditFocus())); 31 connect(this, SIGNAL(editFocus()), m_field, SLOT(setEditFocus()));
32 32
33 QWhatsThis::add(m_field, tr("Type commands here. A list of available commands can be found inside the OpieIRC help")); 33 QWhatsThis::add(m_field, tr("Type commands here. A list of available commands can be found inside the OpieIRC help"));
34 m_layout->add(m_field); 34 m_layout->add(m_field);
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();
41 m_field->setActiveWindow(); 42 m_field->setActiveWindow();
42 43
43} 44}
44 45
45void IRCServerTab::scrolling(){ 46void IRCServerTab::scrolling(){
46 m_textview->ensureVisible(0, m_textview->contentsHeight()); 47 m_textview->ensureVisible(0, m_textview->contentsHeight());
47} 48}
48 49
49 50
50void IRCServerTab::appendText(QString text) { 51void IRCServerTab::appendText(QString text) {
51 /* not using append because it creates layout problems */ 52 /* not using append because it creates layout problems */
52 QString txt = m_textview->text() + IRCTab::appendTimestamp( text ); 53 QString txt = m_textview->text() + IRCTab::appendTimestamp( text );
53 54
@@ -100,33 +101,39 @@ IRCServer *IRCServerTab::server() {
100 101
101void IRCServerTab::settingsChanged() { 102void IRCServerTab::settingsChanged() {
102 m_textview->setText("<qt bgcolor=\"" + m_backgroundColor + "\"/>"); 103 m_textview->setText("<qt bgcolor=\"" + m_backgroundColor + "\"/>");
103 m_lines = 0; 104 m_lines = 0;
104} 105}
105 106
106void IRCServerTab::executeCommand(IRCTab *tab, QString line) { 107void IRCServerTab::executeCommand(IRCTab *tab, QString line) {
107 QTextIStream stream(&line); 108 QTextIStream stream(&line);
108 QString command; 109 QString command;
109 stream >> command; 110 stream >> command;
110 command = command.upper().right(command.length()-1); 111 command = command.upper().right(command.length()-1);
111 112
112 //JOIN 113 //JOIN
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>");
120 } 127 }
121 } 128 }
122 129
123 //KICK 130 //KICK
124 else if (command == "KICK"){ 131 else if (command == "KICK"){
125 QString nickname; 132 QString nickname;
126 stream >> nickname; 133 stream >> nickname;
127 if (nickname.length() > 0) { 134 if (nickname.length() > 0) {
128 if (line.length() > 7 + nickname.length()) { 135 if (line.length() > 7 + nickname.length()) {
129 QString text = line.right(line.length()-nickname.length()-7); 136 QString text = line.right(line.length()-nickname.length()-7);
130 IRCPerson person; 137 IRCPerson person;
131 person.setNick(nickname); 138 person.setNick(nickname);
132 m_session->kick(((IRCChannelTab *)tab)->channel(), &person, text); 139 m_session->kick(((IRCChannelTab *)tab)->channel(), &person, text);
@@ -332,62 +339,76 @@ void IRCServerTab::display(IRCOutput output) {
332 } 339 }
333 break; 340 break;
334 case OUTPUT_CHANACTION: { 341 case OUTPUT_CHANACTION: {
335 IRCChannelTab *channelTab = getTabForChannel((IRCChannel *)output.getParam(0)); 342 IRCChannelTab *channelTab = getTabForChannel((IRCChannel *)output.getParam(0));
336 channelTab->appendText("<font color=\"" + m_otherColor + "\">"+output.htmlMessage()+"</font><br>"); 343 channelTab->appendText("<font color=\"" + m_otherColor + "\">"+output.htmlMessage()+"</font><br>");
337 } 344 }
338 break; 345 break;
339 case OUTPUT_TOPIC: { 346 case OUTPUT_TOPIC: {
340 IRCChannel *channel = (IRCChannel *) output.getParam(0); 347 IRCChannel *channel = (IRCChannel *) output.getParam(0);
341 if (channel) { 348 if (channel) {
342 IRCChannelTab *channelTab = getTabForChannel(channel); 349 IRCChannelTab *channelTab = getTabForChannel(channel);
343 if (channelTab) { 350 if (channelTab) {
344 channelTab->appendText("<font color=\"" + m_notificationColor + "\">"+output.htmlMessage()+"</font><br>"); 351 channelTab->appendText("<font color=\"" + m_notificationColor + "\">"+output.htmlMessage()+"</font><br>");
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: {
352 QString nick = ((IRCPerson *)output.getParam(0))->nick(); 359 QString nick = ((IRCPerson *)output.getParam(0))->nick();
353 QListIterator<IRCChannelTab> it(m_channelTabs); 360 QListIterator<IRCChannelTab> it(m_channelTabs);
354 for (; it.current(); ++it) { 361 for (; it.current(); ++it) {
355 if (it.current()->list()->hasPerson(nick)) { 362 if (it.current()->list()->hasPerson(nick)) {
356 it.current()->appendText("<font color=\"" + m_notificationColor + "\">"+output.htmlMessage()+"</font><br>"); 363 it.current()->appendText("<font color=\"" + m_notificationColor + "\">"+output.htmlMessage()+"</font><br>");
357 it.current()->list()->update(); 364 it.current()->list()->update();
358 } 365 }
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: {
378 IRCChannelTab *channelTab = getTabForChannel((IRCChannel *)output.getParam(0)); 388 IRCChannelTab *channelTab = getTabForChannel((IRCChannel *)output.getParam(0));
379 channelTab->appendText("<font color=\"" + m_notificationColor + "\">"+output.htmlMessage()+"</font><br>"); 389 channelTab->appendText("<font color=\"" + m_notificationColor + "\">"+output.htmlMessage()+"</font><br>");
380 channelTab->list()->update(); 390 channelTab->list()->update();
381 } 391 }
382 break; 392 break;
383 case OUTPUT_CTCP: 393 case OUTPUT_CTCP:
384 appendText("<font color=\"" + m_notificationColor + "\">" + output.htmlMessage() + "</font><br>"); 394 appendText("<font color=\"" + m_notificationColor + "\">" + output.htmlMessage() + "</font><br>");
385 break; 395 break;
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
@@ -49,32 +49,33 @@ public:
49 void removeChannelTab(IRCChannelTab *tab); 49 void removeChannelTab(IRCChannelTab *tab);
50 void removeQueryTab(IRCQueryTab *tab); 50 void removeQueryTab(IRCQueryTab *tab);
51 /* Return tabs from the internal tab lists */ 51 /* Return tabs from the internal tab lists */
52 IRCChannelTab *getTabForChannel(IRCChannel *channel); 52 IRCChannelTab *getTabForChannel(IRCChannel *channel);
53 IRCQueryTab *getTabForQuery(IRCPerson *person); 53 IRCQueryTab *getTabForQuery(IRCPerson *person);
54 /* Add tabs to the internal tab lists */ 54 /* Add tabs to the internal tab lists */
55 void addQueryTab(IRCQueryTab *tab); 55 void addQueryTab(IRCQueryTab *tab);
56 /* Execute a user command such as /join, /msg etc */ 56 /* Execute a user command such as /join, /msg etc */
57 void executeCommand(IRCTab *tab, QString line); 57 void executeCommand(IRCTab *tab, QString line);
58protected: 58protected:
59 void appendText(QString text); 59 void appendText(QString text);
60public slots: 60public slots:
61 void scrolling(); 61 void scrolling();
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:
68 int m_lines; 69 int m_lines;
69 bool m_close; 70 bool m_close;
70 IRCServer m_server; 71 IRCServer m_server;
71 IRCSession *m_session; 72 IRCSession *m_session;
72 MainWindow *m_mainWindow; 73 MainWindow *m_mainWindow;
73 QTextView *m_textview; 74 QTextView *m_textview;
74 IRCHistoryLineEdit *m_field; 75 IRCHistoryLineEdit *m_field;
75 /* Channel tabs associated with this server tab */ 76 /* Channel tabs associated with this server tab */
76 QList<IRCChannelTab> m_channelTabs; 77 QList<IRCChannelTab> m_channelTabs;
77 /* Query tabs associated with this server tab */ 78 /* Query tabs associated with this server tab */
78 QList<IRCQueryTab> m_queryTabs; 79 QList<IRCQueryTab> m_queryTabs;
79}; 80};
80 81
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
@@ -12,106 +12,152 @@ IRCSession::IRCSession(IRCServer *server) {
12} 12}
13 13
14IRCSession::~IRCSession() { 14IRCSession::~IRCSession() {
15 /* We want this to get deleted automatically */ 15 /* We want this to get deleted automatically */
16 m_channels.setAutoDelete(TRUE); 16 m_channels.setAutoDelete(TRUE);
17 m_people.setAutoDelete(TRUE); 17 m_people.setAutoDelete(TRUE);
18 18
19 delete m_parser; 19 delete m_parser;
20 delete m_connection; 20 delete m_connection;
21} 21}
22 22
23void IRCSession::beginSession() { 23void IRCSession::beginSession() {
24 m_connection->doConnect(); 24 m_connection->doConnect();
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(){
32 m_connection->sendLine("QUIT :[OI] I'm too good to need a reason"); 32 m_connection->sendLine("QUIT :[OI] I'm too good to need a reason");
33} 33}
34 34
35void IRCSession::quit(QString message){ 35void IRCSession::quit(QString message){
36 m_connection->sendLine("QUIT :" + message); 36 m_connection->sendLine("QUIT :" + message);
37} 37}
38 38
39void IRCSession::topic(IRCChannel *channel, QString message){ 39void IRCSession::topic(IRCChannel *channel, QString message){
40 m_connection->sendLine("TOPIC :" + channel->channelname() + " " + message); 40 m_connection->sendLine("TOPIC :" + channel->channelname() + " " + message);
41} 41}
42 42
43void IRCSession::mode(IRCChannel *channel, QString message){ 43void IRCSession::mode(IRCChannel *channel, QString message){
44 m_connection->sendLine("MODE " + channel->channelname() + " " + message); 44 m_connection->sendLine("MODE " + channel->channelname() + " " + message);
45} 45}
46 46
47void IRCSession::mode(IRCPerson *person, QString message){ 47void IRCSession::mode(IRCPerson *person, QString message){
48 m_connection->sendLine("MODE " + person->nick() + " " + message); 48 m_connection->sendLine("MODE " + person->nick() + " " + message);
49} 49}
50 50
51void IRCSession::mode(QString message){ 51void IRCSession::mode(QString message){
52 m_connection->sendLine("MODE " + message); 52 m_connection->sendLine("MODE " + message);
53} 53}
54 54
55void IRCSession::raw(QString message){ 55void IRCSession::raw(QString message){
56 m_connection->sendLine(message); 56 m_connection->sendLine(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) {
72 m_connection->sendLine("PRIVMSG " + person->nick() + " :" + message); 72 m_connection->sendLine("PRIVMSG " + person->nick() + " :" + message);
73} 73}
74 74
75void IRCSession::sendMessage(IRCChannel *channel, QString message) { 75void IRCSession::sendMessage(IRCChannel *channel, QString message) {
76 m_connection->sendLine("PRIVMSG " + channel->channelname() + " :" + message); 76 m_connection->sendLine("PRIVMSG " + channel->channelname() + " :" + message);
77} 77}
78 78
79void IRCSession::sendAction(IRCChannel *channel, QString message) { 79void IRCSession::sendAction(IRCChannel *channel, QString message) {
80 m_connection->sendLine("PRIVMSG " + channel->channelname() + " :\001ACTION " + message + "\001"); 80 m_connection->sendLine("PRIVMSG " + channel->channelname() + " :\001ACTION " + message + "\001");
81} 81}
82 82
83void IRCSession::sendAction(IRCPerson *person, QString message) { 83void IRCSession::sendAction(IRCPerson *person, QString message) {
84 m_connection->sendLine("PRIVMSG " + person->nick() + " :\001ACTION " + message + "\001"); 84 m_connection->sendLine("PRIVMSG " + person->nick() + " :\001ACTION " + message + "\001");
85} 85}
86 86
87bool IRCSession::isSessionActive() { 87bool 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}
97 101
98void IRCSession::part(IRCChannel *channel) { 102void 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);
105 for (; it.current(); ++it) { 151 for (; it.current(); ++it) {
106 if (it.current()->channelname() == channelname) { 152 if (it.current()->channelname() == channelname) {
107 return it.current(); 153 return it.current();
108 } 154 }
109 } 155 }
110 return 0; 156 return 0;
111} 157}
112 158
113IRCPerson *IRCSession::getPerson(QString nickname) { 159IRCPerson *IRCSession::getPerson(QString nickname) {
114 QListIterator<IRCPerson> it(m_people); 160 QListIterator<IRCPerson> it(m_people);
115 for (; it.current(); ++it) { 161 for (; it.current(); ++it) {
116 if (it.current()->nick() == nickname) { 162 if (it.current()->nick() == nickname) {
117 return it.current(); 163 return it.current();
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
@@ -44,41 +44,48 @@ public:
44 44
45 void join(QString channel); 45 void join(QString channel);
46 void quit(QString message); 46 void quit(QString message);
47 void quit(); 47 void quit();
48 void raw(QString message); 48 void raw(QString message);
49 void topic(IRCChannel *channel, QString message); 49 void topic(IRCChannel *channel, QString message);
50 void mode(IRCChannel *channel, QString message); 50 void mode(IRCChannel *channel, QString message);
51 void mode(IRCPerson *person, QString message); 51 void mode(IRCPerson *person, QString message);
52 void mode(QString message); 52 void mode(QString message);
53 void part(IRCChannel *channel); 53 void part(IRCChannel *channel);
54 void op(IRCChannel *channel, IRCPerson *person); 54 void op(IRCChannel *channel, IRCPerson *person);
55 void kick(IRCChannel *channel, IRCPerson *person); 55 void kick(IRCChannel *channel, IRCPerson *person);
56 void kick(IRCChannel *channel, IRCPerson *person, QString message); 56 void kick(IRCChannel *channel, IRCPerson *person, QString message);
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:
67 void addPerson(IRCPerson *person); 71 void addPerson(IRCPerson *person);
68 void addChannel(IRCChannel *channel); 72 void addChannel(IRCChannel *channel);
69 void removeChannel(IRCChannel *channel); 73 void removeChannel(IRCChannel *channel);
70 void removePerson(IRCPerson *person); 74 void removePerson(IRCPerson *person);
71 void getChannelsByPerson(IRCPerson *person, QList<IRCChannel> &channels); 75 void getChannelsByPerson(IRCPerson *person, QList<IRCChannel> &channels);
72protected slots: 76protected 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 */