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
@@ -1,65 +1,65 @@
1#include <qpe/resource.h> 1#include <qpe/resource.h>
2#include "ircchannellist.h" 2#include "ircchannellist.h"
3 3
4IRCChannelList::IRCChannelList(IRCChannel *channel, QWidget *parent, const char *name, WFlags f) : QListBox(parent, name, f) { 4IRCChannelList::IRCChannelList(IRCChannel *channel, QWidget *parent, const char *name, WFlags f) : QListBox(parent, name, f) {
5 m_channel = channel; 5 m_channel = channel;
6} 6}
7 7
8void IRCChannelList::update() { 8void IRCChannelList::update() {
9 QPixmap op = Resource::loadPixmap("opieirc/op"); 9 QPixmap op = Resource::loadPixmap("opieirc/op");
10 QPixmap hop = Resource::loadPixmap("opieirc/hop"); 10 QPixmap hop = Resource::loadPixmap("opieirc/hop");
11 QPixmap voice = Resource::loadPixmap("opieirc/voice"); 11 QPixmap voice = Resource::loadPixmap("opieirc/voice");
12 QListIterator<IRCChannelPerson> it = m_channel->people(); 12 QListIterator<IRCChannelPerson> it = m_channel->people();
13 clear(); 13 clear();
14 for (; it.current(); ++it) { 14 for (; it.current(); ++it) {
15 IRCChannelPerson *person = it.current(); 15 IRCChannelPerson *person = it.current();
16 if (person->flags & PERSON_FLAG_OP) { 16 if (person->flags & PERSON_FLAG_OP) {
17 insertItem(op, "1" + person->person->nick()); 17 insertItem(op, "1" + person->person->nick());
18 } else if (person->flags & PERSON_FLAG_HALFOP) { 18 } else if (person->flags & PERSON_FLAG_HALFOP) {
19 insertItem(op, "2" + person->person->nick()); 19 insertItem(op, "2" + person->person->nick());
20 } else if (person->flags & PERSON_FLAG_VOICE) { 20 } else if (person->flags & PERSON_FLAG_VOICE) {
21 insertItem(voice, "3" + person->person->nick()); 21 insertItem(voice, "3" + person->person->nick());
22 } else { 22 } else {
23 insertItem("4" + person->person->nick()); 23 insertItem("4" + person->person->nick());
24 } 24 }
25 } 25 }
26 sort(); 26 sort();
27 adjustNicks(); 27 adjustNicks();
28} 28}
29 29
30 30
31bool IRCChannelList::hasPerson(QString nick) { 31bool IRCChannelList::hasPerson(QString nick) {
32 for (unsigned int i=0; i<count(); i++) { 32 for (unsigned int i=0; i<count(); i++) {
33 if (text(i) == nick) 33 if (text(i) == nick)
34 return TRUE; 34 return TRUE;
35 } 35 }
36 return FALSE; 36 return FALSE;
37} 37}
38 38
39bool IRCChannelList::removePerson(QString nick) { 39bool IRCChannelList::removePerson(QString nick) {
40 for (unsigned int i=0; i<count(); i++) { 40 for (unsigned int i=0; i<count(); i++) {
41 if (text(i) == nick){ 41 if (text(i) == nick){
42 removeItem(i); 42 removeItem(i);
43 return TRUE; 43 return TRUE;
44 } 44 }
45 } 45 }
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,119 +1,128 @@
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()));
25 m_list = new IRCChannelList(m_channel, hbox); 28 m_list = new IRCChannelList(m_channel, hbox);
26 m_list->update(); 29 m_list->update();
27 m_list->setMaximumWidth(LISTWIDTH); 30 m_list->setMaximumWidth(LISTWIDTH);
28 m_field = new IRCHistoryLineEdit(this); 31 m_field = new IRCHistoryLineEdit(this);
29 connect(m_field, SIGNAL(nextTab()), this, SIGNAL(nextTab())); 32 connect(m_field, SIGNAL(nextTab()), this, SIGNAL(nextTab()));
30 connect(m_field, SIGNAL(prevTab()), this, SIGNAL(prevTab())); 33 connect(m_field, SIGNAL(prevTab()), this, SIGNAL(prevTab()));
31 connect(m_field, SIGNAL(closeTab()), this, SLOT(remove())); 34 connect(m_field, SIGNAL(closeTab()), this, SLOT(remove()));
32 connect(this, SIGNAL(editFocus()), m_field, SLOT(setEditFocus())); 35 connect(this, SIGNAL(editFocus()), m_field, SLOT(setEditFocus()));
33 36
34 QWhatsThis::add(m_field, tr("Type your message here to participate in the channel discussion")); 37 QWhatsThis::add(m_field, tr("Type your message here to participate in the channel discussion"));
35 m_popup = new QPopupMenu(m_list); 38 m_popup = new QPopupMenu(m_list);
36 m_lines = 0; 39 m_lines = 0;
37 /* Required so that embedded-style "right" clicks work */ 40 /* Required so that embedded-style "right" clicks work */
38 QPEApplication::setStylusOperation(m_list->viewport(), QPEApplication::RightOnHold); 41 QPEApplication::setStylusOperation(m_list->viewport(), QPEApplication::RightOnHold);
39 connect(m_list, SIGNAL(mouseButtonPressed(int,QListBoxItem*,const QPoint&)), this, SLOT(mouseButtonPressed(int,QListBoxItem*,const QPoint&))); 42 connect(m_list, SIGNAL(mouseButtonPressed(int,QListBoxItem*,const QPoint&)), this, SLOT(mouseButtonPressed(int,QListBoxItem*,const QPoint&)));
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++;
72 } 81 }
73 m_textview->ensureVisible(0, m_textview->contentsHeight()); 82 m_textview->ensureVisible(0, m_textview->contentsHeight());
74 m_textview->setText(txt); 83 m_textview->setText(txt);
75 m_textview->ensureVisible(0, m_textview->contentsHeight()); 84 m_textview->ensureVisible(0, m_textview->contentsHeight());
76 85
77 int p1, p2; 86 int p1, p2;
78 if ( text.contains( IRCMessageParser::tr("Received a CTCP PING from ") ) ) 87 if ( text.contains( IRCMessageParser::tr("Received a CTCP PING from ") ) )
79 emit ping( title() ); 88 emit ping( title() );
80 else if ( (p1 = text.find("ping", 0, false) )!= -1 && (p2 = text.find( m_parentTab->server()->nick(), 0,false )) != -1 ) { 89 else if ( (p1 = text.find("ping", 0, false) )!= -1 && (p2 = text.find( m_parentTab->server()->nick(), 0,false )) != -1 ) {
81 int col = text.findRev("color", -1, false); 90 int col = text.findRev("color", -1, false);
82 if ( col < p2 ) 91 if ( col < p2 )
83 emit ping( title() ); 92 emit ping( title() );
84 93
85 } 94 }
86 95
87 emit changed(this); 96 emit changed(this);
88} 97}
89 98
90IRCChannelTab::~IRCChannelTab() { 99IRCChannelTab::~IRCChannelTab() {
91 m_parentTab->removeChannelTab(this); 100 m_parentTab->removeChannelTab(this);
92} 101}
93 102
94void IRCChannelTab::processCommand() { 103void IRCChannelTab::processCommand() {
95 QString text = m_field->text(); 104 QString text = m_field->text();
96 if (text.length()>0) { 105 if (text.length()>0) {
97 if (session()->isSessionActive()) { 106 if (session()->isSessionActive()) {
98 if (text.startsWith("/") && !text.startsWith("//")) { 107 if (text.startsWith("/") && !text.startsWith("//")) {
99 /* Command mode */ 108 /* Command mode */
100 m_parentTab->executeCommand(this, text);; 109 m_parentTab->executeCommand(this, text);;
101 } else { 110 } else {
102 if (text.startsWith("//")) 111 if (text.startsWith("//"))
103 text = text.right(text.length()-1); 112 text = text.right(text.length()-1);
104 session()->sendMessage(m_channel, m_field->text()); 113 session()->sendMessage(m_channel, m_field->text());
105 appendText("<font color=\"" + m_textColor + "\">&lt;</font><font color=\"" + m_selfColor + "\">"+m_parentTab->server()->nick()+"</font><font color=\"" + m_textColor + "\">&gt; "+IRCOutput::toHTML(m_field->text())+"</font><br>"); 114 appendText("<font color=\"" + m_textColor + "\">&lt;</font><font color=\"" + m_selfColor + "\">"+m_parentTab->server()->nick()+"</font><font color=\"" + m_textColor + "\">&gt; "+IRCOutput::toHTML(m_field->text())+"</font><br>");
106 } 115 }
107 } else { 116 } else {
108 appendText("<font color=\"" + m_errorColor + "\">"+tr("Disconnected")+"</font><br>"); 117 appendText("<font color=\"" + m_errorColor + "\">"+tr("Disconnected")+"</font><br>");
109 } 118 }
110 } 119 }
111 m_field->clear(); 120 m_field->clear();
112} 121}
113 122
114void IRCChannelTab::settingsChanged() { 123void IRCChannelTab::settingsChanged() {
115 m_textview->setText("<qt bgcolor=\"" + m_backgroundColor + "\"/>"); 124 m_textview->setText("<qt bgcolor=\"" + m_backgroundColor + "\"/>");
116 m_lines = 0; 125 m_lines = 0;
117} 126}
118 127
119void IRCChannelTab::toggleList() { 128void IRCChannelTab::toggleList() {
@@ -121,71 +130,79 @@ void IRCChannelTab::toggleList() {
121 m_list->setMaximumWidth(0); 130 m_list->setMaximumWidth(0);
122 m_listButton->setText("<"); 131 m_listButton->setText("<");
123 } else { 132 } else {
124 m_list->setMaximumWidth(LISTWIDTH); 133 m_list->setMaximumWidth(LISTWIDTH);
125 m_listButton->setText(">"); 134 m_listButton->setText(">");
126 } 135 }
127 m_listVisible = !m_listVisible; 136 m_listVisible = !m_listVisible;
128} 137}
129 138
130void IRCChannelTab::mouseButtonPressed(int mouse, QListBoxItem *, const QPoint &point) { 139void IRCChannelTab::mouseButtonPressed(int mouse, QListBoxItem *, const QPoint &point) {
131 switch (mouse) { 140 switch (mouse) {
132 case 1: 141 case 1:
133 break; 142 break;
134 case 2: 143 case 2:
135 m_popup->popup(point); 144 m_popup->popup(point);
136 break; 145 break;
137 }; 146 };
138} 147}
139 148
140void IRCChannelTab::popupQuery( QListBoxItem *item) { 149void IRCChannelTab::popupQuery( QListBoxItem *item) {
141 if (item) { 150 if (item) {
142 IRCPerson *person = session()->getPerson(item->text()); 151 IRCPerson *person = session()->getPerson(item->text());
143 if (person) { 152 if (person) {
144 IRCQueryTab *tab = m_parentTab->getTabForQuery(person); 153 IRCQueryTab *tab = m_parentTab->getTabForQuery(person);
145 if (!tab) { 154 if (!tab) {
146 tab = new IRCQueryTab(person, m_parentTab, m_mainWindow, (QWidget *)parent()); 155 tab = new IRCQueryTab(person, m_parentTab, m_mainWindow, (QWidget *)parent());
147 m_parentTab->addQueryTab(tab); 156 m_parentTab->addQueryTab(tab);
148 m_mainWindow->addTab(tab); 157 m_mainWindow->addTab(tab);
149 } 158 }
150 } 159 }
151 } 160 }
152} 161}
153 162
154void IRCChannelTab::popupQuery() { 163void IRCChannelTab::popupQuery() {
155 if ( m_list->currentItem() != -1 ) 164 if ( m_list->currentItem() != -1 )
156 popupQuery( m_list->item(m_list->currentItem())); 165 popupQuery( m_list->item(m_list->currentItem()));
157} 166}
158 167
159void IRCChannelTab::popupPing() { 168void IRCChannelTab::popupPing() {
160 //HAHA, no wonder these don't work 169 //HAHA, no wonder these don't work
161} 170}
162 171
163void IRCChannelTab::popupVersion() { 172void IRCChannelTab::popupVersion() {
164} 173}
165 174
166void IRCChannelTab::popupWhois() { 175void IRCChannelTab::popupWhois() {
167} 176}
168 177
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
@@ -1,75 +1,78 @@
1/* 1/*
2 OpieIRC - An embedded IRC client 2 OpieIRC - An embedded IRC client
3 Copyright (C) 2002 Wenzel Jakob 3 Copyright (C) 2002 Wenzel Jakob
4 4
5 This program is free software; you can redistribute it and/or modify 5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by 6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or 7 the Free Software Foundation; either version 2 of the License, or
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 __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,122 +1,151 @@
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(":")) {
18 /* extract the prefix */ 21 /* extract the prefix */
19 m_prefix = temp.right(temp.length()-1); 22 m_prefix = temp.right(temp.length()-1);
20 stream >> temp; 23 stream >> temp;
21 m_command = temp.upper(); 24 m_command = temp.upper();
22 m_allParameters = line.right(line.length() - m_prefix.length() - m_command.length() - 3); 25 m_allParameters = line.right(line.length() - m_prefix.length() - m_command.length() - 3);
23 } else { 26 } else {
24 m_command = temp.upper(); 27 m_command = temp.upper();
25 m_allParameters = line.right(line.length() - m_command.length() - 1); 28 m_allParameters = line.right(line.length() - m_command.length() - 1);
26 } 29 }
27 30
28 /* Create a list of all parameters */ 31 /* Create a list of all parameters */
29 while(!(stream.atEnd())) { 32 while(!(stream.atEnd())) {
30 stream >> temp; 33 stream >> temp;
31 if (temp.startsWith(":")) { 34 if (temp.startsWith(":")) {
32 /* last parameter */ 35 /* last parameter */
33 m_trailing = line.right(line.length() - line.find(QChar(':'), 1) - 1); 36 m_trailing = line.right(line.length() - line.find(QChar(':'), 1) - 1);
34 m_parameters << m_trailing; 37 m_parameters << m_trailing;
35 break; 38 break;
36 } else { 39 } else {
37 m_parameters << temp; 40 m_parameters << temp;
38 } 41 }
39 } 42 }
40 43
41 44
42 m_commandNumber = m_command.toInt(&m_isNumerical); 45 m_commandNumber = m_command.toInt(&m_isNumerical);
43 /* Is this a CTCP command */ 46 /* Is this a CTCP command */
44 if ((m_command == "PRIVMSG" || m_command == "NOTICE") && m_trailing.length()>0 && m_trailing.left(1) == QChar(1)) { 47 if ((m_command == "PRIVMSG" || m_command == "NOTICE") && m_trailing.length()>0 && m_trailing.left(1) == QChar(1)) {
45 m_ctcp = TRUE; 48 m_ctcp = TRUE;
46 /* Strip CTCP \001 characters */ 49 /* Strip CTCP \001 characters */
47 m_allParameters = m_allParameters.replace(QRegExp(QChar(1)), ""); 50 m_allParameters = m_allParameters.replace(QRegExp(QChar(1)), "");
48 QTextIStream ctcpStream(&m_allParameters); 51 QTextIStream ctcpStream(&m_allParameters);
49 if (m_command == "PRIVMSG") 52 if (m_command == "PRIVMSG")
50 ctcpStream >> m_ctcpDestination; 53 ctcpStream >> m_ctcpDestination;
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
103unsigned short IRCMessage::commandNumber() { 132unsigned short IRCMessage::commandNumber() {
104 return m_commandNumber; 133 return m_commandNumber;
105} 134}
106 135
107bool IRCMessage::isNumerical() { 136bool IRCMessage::isNumerical() {
108 return m_isNumerical; 137 return m_isNumerical;
109} 138}
110 139
111bool IRCMessage::isCTCP() { 140bool IRCMessage::isCTCP() {
112 return m_ctcp; 141 return m_ctcp;
113} 142}
114 143
115QString IRCMessage::trailing() { 144QString IRCMessage::trailing() {
116 return m_trailing; 145 return m_trailing;
117} 146}
118 147
119QString IRCMessage::allParameters() { 148QString IRCMessage::allParameters() {
120 return m_allParameters; 149 return m_allParameters;
121} 150}
122 151
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
@@ -1,68 +1,70 @@
1/* 1/*
2 OpieIRC - An embedded IRC client 2 OpieIRC - An embedded IRC client
3 Copyright (C) 2002 Wenzel Jakob 3 Copyright (C) 2002 Wenzel Jakob
4 4
5 This program is free software; you can redistribute it and/or modify 5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by 6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or 7 the Free Software Foundation; either version 2 of the License, or
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,391 +1,454 @@
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 */
115 if (mask.nick() == m_session->m_server->nick()) { 178 if (mask.nick() == m_session->m_server->nick()) {
116 channel = new IRCChannel(channelName); 179 channel = new IRCChannel(channelName);
117 m_session->addChannel(channel); 180 m_session->addChannel(channel);
118 } else { 181 } else {
119 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Nonexistant channel join - desynchronized?"))); 182 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Nonexistant channel join - desynchronized?")));
120 } 183 }
121 } else { 184 } else {
122 /* Someone else joined */ 185 /* Someone else joined */
123 if (mask.nick() != m_session->m_server->nick()) { 186 if (mask.nick() != m_session->m_server->nick()) {
124 if (!channel->getPerson(mask.nick())) { 187 if (!channel->getPerson(mask.nick())) {
125 IRCChannelPerson *chanperson = new IRCChannelPerson(); 188 IRCChannelPerson *chanperson = new IRCChannelPerson();
126 IRCPerson *person = m_session->getPerson(mask.nick()); 189 IRCPerson *person = m_session->getPerson(mask.nick());
127 if (!person) { 190 if (!person) {
128 person = new IRCPerson(message->prefix()); 191 person = new IRCPerson(message->prefix());
129 m_session->addPerson(person); 192 m_session->addPerson(person);
130 } 193 }
131 chanperson->flags = 0; 194 chanperson->flags = 0;
132 chanperson->person = person; 195 chanperson->person = person;
133 channel->addPerson(chanperson); 196 channel->addPerson(chanperson);
134 IRCOutput output(OUTPUT_OTHERJOIN ,tr("%1 joined channel %2").arg( mask.nick() ).arg( channelName )); 197 IRCOutput output(OUTPUT_OTHERJOIN ,tr("%1 joined channel %2").arg( mask.nick() ).arg( channelName ));
135 output.addParam(channel); 198 output.addParam(channel);
136 output.addParam(chanperson); 199 output.addParam(chanperson);
137 emit outputReady(output); 200 emit outputReady(output);
138 } else { 201 } else {
139 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Person has already joined the channel - desynchronized?"))); 202 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Person has already joined the channel - desynchronized?")));
140 } 203 }
141 } else { 204 } else {
142 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("You already joined the channel - desynchronized?"))); 205 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("You already joined the channel - desynchronized?")));
143 } 206 }
144 } 207 }
145} 208}
146 209
147void IRCMessageParser::parseLiteralPart(IRCMessage *message) { 210void IRCMessageParser::parseLiteralPart(IRCMessage *message) {
148 QString channelName = message->param(0).lower(); 211 QString channelName = message->param(0).lower();
149 IRCChannel *channel = m_session->getChannel(channelName); 212 IRCChannel *channel = m_session->getChannel(channelName);
150 IRCPerson mask(message->prefix()); 213 IRCPerson mask(message->prefix());
151 if (channel) { 214 if (channel) {
152 if (mask.nick() == m_session->m_server->nick()) { 215 if (mask.nick() == m_session->m_server->nick()) {
153 m_session->removeChannel(channel); 216 m_session->removeChannel(channel);
154 IRCOutput output(OUTPUT_SELFPART, tr("You left channel %1").arg( channelName )); 217 IRCOutput output(OUTPUT_SELFPART, tr("You left channel %1").arg( channelName ));
155 output.addParam(channel); 218 output.addParam(channel);
156 emit outputReady(output); 219 emit outputReady(output);
157 delete channel; 220 delete channel;
158 } else { 221 } else {
159 IRCChannelPerson *person = channel->getPerson(mask.nick()); 222 IRCChannelPerson *person = channel->getPerson(mask.nick());
160 if (person) { 223 if (person) {
161 channel->removePerson(person); 224 channel->removePerson(person);
162 IRCOutput output(OUTPUT_OTHERPART, tr("%1 left channel %2").arg( mask.nick() ).arg( channelName) ); 225 IRCOutput output(OUTPUT_OTHERPART, tr("%1 left channel %2").arg( mask.nick() ).arg( channelName) );
163 output.addParam(channel); 226 output.addParam(channel);
164 output.addParam(person); 227 output.addParam(person);
165 emit outputReady(output); 228 emit outputReady(output);
166 delete person; 229 delete person;
167 } else { 230 } else {
168 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Parting person not found - desynchronized?"))); 231 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Parting person not found - desynchronized?")));
169 } 232 }
170 } 233 }
171 } else { 234 } else {
172 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Channel for part not found - desynchronized?"))); 235 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Channel for part not found - desynchronized?")));
173 } 236 }
174} 237}
175 238
176void IRCMessageParser::parseLiteralPrivMsg(IRCMessage *message) { 239void IRCMessageParser::parseLiteralPrivMsg(IRCMessage *message) {
177 if (m_session->m_server->nick().lower() == message->param(0).lower() ) { 240 if (m_session->m_server->nick().lower() == message->param(0).lower() ) {
178 /* IRC Query message detected, verify sender and display it */ 241 /* IRC Query message detected, verify sender and display it */
179 IRCPerson mask(message->prefix()); 242 IRCPerson mask(message->prefix());
180 IRCPerson *person = m_session->getPerson(mask.nick()); 243 IRCPerson *person = m_session->getPerson(mask.nick());
181 if (!person) { 244 if (!person) {
182 /* Person not yet known, create and add to the current session */ 245 /* Person not yet known, create and add to the current session */
183 person = new IRCPerson(message->prefix()); 246 person = new IRCPerson(message->prefix());
184 m_session->addPerson(person); 247 m_session->addPerson(person);
185 } 248 }
186 IRCOutput output(OUTPUT_QUERYPRIVMSG, message->param(1)); 249 IRCOutput output(OUTPUT_QUERYPRIVMSG, message->param(1));
187 output.addParam(person); 250 output.addParam(person);
188 emit outputReady(output); 251 emit outputReady(output);
189 } else if (message->param(0).at(0) == '#' || message->param(0).at(0) == '+') { 252 } else if (message->param(0).at(0) == '#' || message->param(0).at(0) == '+') {
190 /* IRC Channel message detected, verify sender, channel and display it */ 253 /* IRC Channel message detected, verify sender, channel and display it */
191 IRCChannel *channel = m_session->getChannel(message->param(0).lower()); 254 IRCChannel *channel = m_session->getChannel(message->param(0).lower());
192 if (channel) { 255 if (channel) {
193 IRCPerson mask(message->prefix()); 256 IRCPerson mask(message->prefix());
194 IRCChannelPerson *person = channel->getPerson(mask.nick()); 257 IRCChannelPerson *person = channel->getPerson(mask.nick());
195 if (person) { 258 if (person) {
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) ));
261 output.addParam(person); 324 output.addParam(person);
262 emit outputReady(output); 325 emit outputReady(output);
263 delete person; 326 delete person;
264 } else { 327 } else {
265 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Unknown person quit - desynchronized?"))); 328 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Unknown person quit - desynchronized?")));
266 } 329 }
267} 330}
268 331
269void IRCMessageParser::parseLiteralTopic(IRCMessage *message) { 332void IRCMessageParser::parseLiteralTopic(IRCMessage *message) {
270 IRCPerson mask(message->prefix()); 333 IRCPerson mask(message->prefix());
271 IRCChannel *channel = m_session->getChannel(message->param(0).lower()); 334 IRCChannel *channel = m_session->getChannel(message->param(0).lower());
272 if (channel) { 335 if (channel) {
273 IRCOutput output(OUTPUT_TOPIC, mask.nick() + tr(" changed topic to ") + "\"" + message->param(1) + "\""); 336 IRCOutput output(OUTPUT_TOPIC, mask.nick() + tr(" changed topic to ") + "\"" + message->param(1) + "\"");
274 output.addParam(channel); 337 output.addParam(channel);
275 emit outputReady(output); 338 emit outputReady(output);
276 } else { 339 } else {
277 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Unknown channel topic - desynchronized?"))); 340 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Unknown channel topic - desynchronized?")));
278 } 341 }
279} 342}
280 343
281void IRCMessageParser::parseLiteralError(IRCMessage *message) { 344void IRCMessageParser::parseLiteralError(IRCMessage *message) {
282 emit outputReady(IRCOutput(OUTPUT_ERROR, message->allParameters())); 345 emit outputReady(IRCOutput(OUTPUT_ERROR, message->allParameters()));
283} 346}
284 347
285void IRCMessageParser::parseCTCPPing(IRCMessage *message) { 348void IRCMessageParser::parseCTCPPing(IRCMessage *message) {
286 IRCPerson mask(message->prefix()); 349 IRCPerson mask(message->prefix());
287 m_session->m_connection->sendCTCP(mask.nick(), "PING " + message->allParameters()); 350 m_session->m_connection->sendCTCP(mask.nick(), "PING " + message->allParameters());
288 emit outputReady(IRCOutput(OUTPUT_CTCP, tr("Received a CTCP PING from ")+mask.nick())); 351 emit outputReady(IRCOutput(OUTPUT_CTCP, tr("Received a CTCP PING from ")+mask.nick()));
289 352
290 //IRCPerson mask(message->prefix()); 353 //IRCPerson mask(message->prefix());
291 QString dest = message->ctcpDestination(); 354 QString dest = message->ctcpDestination();
292 if (dest.startsWith("#")) { 355 if (dest.startsWith("#")) {
293 IRCChannel *channel = m_session->getChannel(dest.lower()); 356 IRCChannel *channel = m_session->getChannel(dest.lower());
294 if (channel) { 357 if (channel) {
295 IRCChannelPerson *person = channel->getPerson(mask.nick()); 358 IRCChannelPerson *person = channel->getPerson(mask.nick());
296 if (person) { 359 if (person) {
297 IRCOutput output(OUTPUT_CHANACTION, tr("Received a CTCP PING from ")+ mask.nick()) ; 360 IRCOutput output(OUTPUT_CHANACTION, tr("Received a CTCP PING from ")+ mask.nick()) ;
298 output.addParam(channel); 361 output.addParam(channel);
299 output.addParam(person); 362 output.addParam(person);
300 emit outputReady(output); 363 emit outputReady(output);
301 } else { 364 } else {
302 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("CTCP PING with unknown person - Desynchronized?"))); 365 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("CTCP PING with unknown person - Desynchronized?")));
303 } 366 }
304 } else { 367 } else {
305 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("CTCP PING with unknown channel - Desynchronized?"))); 368 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("CTCP PING with unknown channel - Desynchronized?")));
306 } 369 }
307 } else { 370 } else {
308 if (message->ctcpDestination() == m_session->m_server->nick()) { 371 if (message->ctcpDestination() == m_session->m_server->nick()) {
309 IRCPerson *person = m_session->getPerson(mask.nick()); 372 IRCPerson *person = m_session->getPerson(mask.nick());
310 if (!person) { 373 if (!person) {
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 {
344 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("CTCP ACTION with unknown person - Desynchronized?"))); 407 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("CTCP ACTION with unknown person - Desynchronized?")));
345 } 408 }
346 } else { 409 } else {
347 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("CTCP ACTION with unknown channel - Desynchronized?"))); 410 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("CTCP ACTION with unknown channel - Desynchronized?")));
348 } 411 }
349 } else { 412 } else {
350 if (message->ctcpDestination() == m_session->m_server->nick()) { 413 if (message->ctcpDestination() == m_session->m_server->nick()) {
351 IRCPerson *person = m_session->getPerson(mask.nick()); 414 IRCPerson *person = m_session->getPerson(mask.nick());
352 if (!person) { 415 if (!person) {
353 /* Person not yet known, create and add to the current session */ 416 /* Person not yet known, create and add to the current session */
354 person = new IRCPerson(message->prefix()); 417 person = new IRCPerson(message->prefix());
355 m_session->addPerson(person); 418 m_session->addPerson(person);
356 } 419 }
357 IRCOutput output(OUTPUT_QUERYACTION, "*" + mask.nick() + message->param(0)); 420 IRCOutput output(OUTPUT_QUERYACTION, "*" + mask.nick() + message->param(0));
358 output.addParam(person); 421 output.addParam(person);
359 emit outputReady(output); 422 emit outputReady(output);
360 } else { 423 } else {
361 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("CTCP ACTION with bad recipient"))); 424 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("CTCP ACTION with bad recipient")));
362 } 425 }
363 } 426 }
364} 427}
365 428
366void IRCMessageParser::parseLiteralMode(IRCMessage *message) { 429void IRCMessageParser::parseLiteralMode(IRCMessage *message) {
367 IRCPerson mask(message->prefix()); 430 IRCPerson mask(message->prefix());
368 431
369 if (message->param(0).startsWith("#")) { 432 if (message->param(0).startsWith("#")) {
370 IRCChannel *channel = m_session->getChannel(message->param(0).lower()); 433 IRCChannel *channel = m_session->getChannel(message->param(0).lower());
371 if (channel) { 434 if (channel) {
372 QString temp, parameters = message->allParameters().right(message->allParameters().length() - channel->channelname().length() - 1); 435 QString temp, parameters = message->allParameters().right(message->allParameters().length() - channel->channelname().length() - 1);
373 QTextIStream stream(&parameters); 436 QTextIStream stream(&parameters);
374 bool set = FALSE; 437 bool set = FALSE;
375 while (!stream.atEnd()) { 438 while (!stream.atEnd()) {
376 stream >> temp; 439 stream >> temp;
377 if (temp.startsWith("+")) { 440 if (temp.startsWith("+")) {
378 set = TRUE; 441 set = TRUE;
379 temp = temp.right(1); 442 temp = temp.right(1);
380 } else if (temp.startsWith("-")) { 443 } else if (temp.startsWith("-")) {
381 set = FALSE; 444 set = FALSE;
382 temp = temp.right(1); 445 temp = temp.right(1);
383 } else { 446 } else {
384 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Mode change has unknown type"))); 447 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Mode change has unknown type")));
385 return; 448 return;
386 } 449 }
387 if (temp == "o") { 450 if (temp == "o") {
388 stream >> temp; 451 stream >> temp;
389 IRCChannelPerson *person = channel->getPerson(temp); 452 IRCChannelPerson *person = channel->getPerson(temp);
390 if (person) { 453 if (person) {
391 if (set) { 454 if (set) {
@@ -402,158 +465,153 @@ void IRCMessageParser::parseLiteralMode(IRCMessage *message) {
402 emit outputReady(output); 465 emit outputReady(output);
403 } 466 }
404 } else { 467 } else {
405 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Mode change with unknown person - Desynchronized?"))); 468 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Mode change with unknown person - Desynchronized?")));
406 } 469 }
407 } else if (temp == "v") { 470 } else if (temp == "v") {
408 stream >> temp; 471 stream >> temp;
409 IRCChannelPerson *person = channel->getPerson(temp); 472 IRCChannelPerson *person = channel->getPerson(temp);
410 if (person) { 473 if (person) {
411 if (set) { 474 if (set) {
412 person->flags |= PERSON_FLAG_VOICE; 475 person->flags |= PERSON_FLAG_VOICE;
413 IRCOutput output(OUTPUT_CHANPERSONMODE, mask.nick() + tr(" gives voice to " + person->person->nick())); 476 IRCOutput output(OUTPUT_CHANPERSONMODE, mask.nick() + tr(" gives voice to " + person->person->nick()));
414 output.addParam(channel); 477 output.addParam(channel);
415 output.addParam(person); 478 output.addParam(person);
416 emit outputReady(output); 479 emit outputReady(output);
417 } else { 480 } else {
418 person->flags &= 0xFFFF - PERSON_FLAG_VOICE; 481 person->flags &= 0xFFFF - PERSON_FLAG_VOICE;
419 IRCOutput output(OUTPUT_CHANPERSONMODE, mask.nick() + tr(" removes voice from " + person->person->nick())); 482 IRCOutput output(OUTPUT_CHANPERSONMODE, mask.nick() + tr(" removes voice from " + person->person->nick()));
420 output.addParam(channel); 483 output.addParam(channel);
421 output.addParam(person); 484 output.addParam(person);
422 emit outputReady(output); 485 emit outputReady(output);
423 } 486 }
424 } else { 487 } else {
425 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Mode change with unknown person - Desynchronized?"))); 488 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Mode change with unknown person - Desynchronized?")));
426 } 489 }
427 } else { 490 } else {
428 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Mode change with unknown flag"))); 491 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Mode change with unknown flag")));
429 } 492 }
430 } 493 }
431 } else { 494 } else {
432 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Mode change with unknown kannel - Desynchronized?"))); 495 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Mode change with unknown kannel - Desynchronized?")));
433 } 496 }
434 } else { 497 } else {
435 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("User modes not supported yet"))); 498 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("User modes not supported yet")));
436 } 499 }
437} 500}
438 501
439void IRCMessageParser::parseLiteralKick(IRCMessage *message) { 502void IRCMessageParser::parseLiteralKick(IRCMessage *message) {
440 IRCPerson mask(message->prefix()); 503 IRCPerson mask(message->prefix());
441 IRCChannel *channel = m_session->getChannel(message->param(0).lower()); 504 IRCChannel *channel = m_session->getChannel(message->param(0).lower());
442 if (channel) { 505 if (channel) {
443 IRCChannelPerson *person = channel->getPerson(message->param(1)); 506 IRCChannelPerson *person = channel->getPerson(message->param(1));
444 if (person) { 507 if (person) {
445 if (person->person->nick() == m_session->m_server->nick()) { 508 if (person->person->nick() == m_session->m_server->nick()) {
446 m_session->removeChannel(channel); 509 m_session->removeChannel(channel);
447 IRCOutput output(OUTPUT_SELFKICK, tr("You were kicked from ") + channel->channelname() + tr(" by ") + mask.nick() + " (" + message->param(2) + ")"); 510 IRCOutput output(OUTPUT_SELFKICK, tr("You were kicked from ") + channel->channelname() + tr(" by ") + mask.nick() + " (" + message->param(2) + ")");
448 output.addParam(channel); 511 output.addParam(channel);
449 emit outputReady(output); 512 emit outputReady(output);
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 == '*') {
491 545
492 nick = temp.right(temp.length()-1); 546 nick = temp.right(temp.length()-1);
493 switch (flagch) { 547 switch (flagch) {
494 case '@': flag = PERSON_FLAG_OP; break; 548 case '@': flag = PERSON_FLAG_OP; break;
495 case '+': flag = PERSON_FLAG_VOICE; break; 549 case '+': flag = PERSON_FLAG_VOICE; break;
496 case '%': flag = PERSON_FLAG_HALFOP; break; 550 case '%': flag = PERSON_FLAG_HALFOP; break;
497 default : flag = 0; break; 551 default : flag = 0; break;
498 } 552 }
499 } else { 553 } else {
500 nick = temp; 554 nick = temp;
501 } 555 }
502 556
503 IRCChannelPerson *chan_person = new IRCChannelPerson(); 557 IRCChannelPerson *chan_person = new IRCChannelPerson();
504 IRCPerson *person = m_session->getPerson(nick); 558 IRCPerson *person = m_session->getPerson(nick);
505 if (person == 0) { 559 if (person == 0) {
506 person = new IRCPerson(); 560 person = new IRCPerson();
507 person->setNick(nick); 561 person->setNick(nick);
508 m_session->addPerson(person); 562 m_session->addPerson(person);
509 } 563 }
510 chan_person->person = person; 564 chan_person->person = person;
511 chan_person->flags = flag; 565 chan_person->flags = flag;
512 channel->addPerson(chan_person); 566 channel->addPerson(chan_person);
513 } 567 }
514 } else { 568 } else {
515 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Server message with unknown channel"))); 569 emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Server message with unknown channel")));
516 } 570 }
517} 571}
518 572
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) + "\""));
551 output.addParam(0); 609 output.addParam(0);
552 emit outputReady(output); 610 emit outputReady(output);
553 } 611 }
554} 612}
555 613
556void IRCMessageParser::parseNumericalTopicWhoTime(IRCMessage *) { 614void IRCMessageParser::parseNumericalTopicWhoTime(IRCMessage *) {
557} 615}
558 616
559 617
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
@@ -1,95 +1,99 @@
1/* 1/*
2 OpieIRC - An embedded IRC client 2 OpieIRC - An embedded IRC client
3 Copyright (C) 2002 Wenzel Jakob 3 Copyright (C) 2002 Wenzel Jakob
4 4
5 This program is free software; you can redistribute it and/or modify 5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by 6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or 7 the Free Software Foundation; either version 2 of the License, or
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 __IRCMESSAGEPARSER_H 21#ifndef __IRCMESSAGEPARSER_H
22#define __IRCMESSAGEPARSER_H 22#define __IRCMESSAGEPARSER_H
23 23
24#include "ircsession.h" 24#include "ircsession.h"
25 25
26/* Macro to facilitate the parser table's creation */ 26/* Macro to facilitate the parser table's creation */
27#define FUNC(__proc) &IRCMessageParser::__proc 27#define FUNC(__proc) &IRCMessageParser::__proc
28 28
29class IRCMessageParser; 29class IRCMessageParser;
30 30
31/* Typedef representing a parser function */ 31/* Typedef representing a parser function */
32typedef void (IRCMessageParser::*IRCMessageParseProc)(IRCMessage *); 32typedef 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};
94 98
95#endif /* __IRCMESSAGEPARSER_H */ 99#endif /* __IRCMESSAGEPARSER_H */
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,74 +1,83 @@
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) {
18 m_port = port; 21 m_port = port;
19} 22}
20 23
21void IRCServer::setUsername(QString username) { 24void IRCServer::setUsername(QString username) {
22 m_username = username; 25 m_username = username;
23} 26}
24 27
25void IRCServer::setPassword(QString password) { 28void IRCServer::setPassword(QString password) {
26 m_password = password; 29 m_password = password;
27} 30}
28 31
29void IRCServer::setNick(QString nick) { 32void IRCServer::setNick(QString nick) {
30 m_nick = nick; 33 m_nick = nick;
31} 34}
32 35
33void IRCServer::setRealname(QString realname) { 36void IRCServer::setRealname(QString realname) {
34 m_realname = realname; 37 m_realname = realname;
35} 38}
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
@@ -1,92 +1,92 @@
1#include "ircservereditor.h" 1#include "ircservereditor.h"
2 2
3/* OPIE */ 3/* OPIE */
4#include <qpe/qpeapplication.h> 4#include <qpe/qpeapplication.h>
5 5
6/* QT */ 6/* QT */
7#include <qmessagebox.h> 7#include <qmessagebox.h>
8#include <qlayout.h> 8#include <qlayout.h>
9#include <qlabel.h> 9#include <qlabel.h>
10#include <qwhatsthis.h> 10#include <qwhatsthis.h>
11 11
12IRCServerEditor::IRCServerEditor(IRCServer server, QWidget* parent, const char* name, bool modal, WFlags) : QDialog(parent, name, modal, WStyle_ContextHelp) { 12IRCServerEditor::IRCServerEditor(IRCServer server, QWidget* parent, const char* name, bool modal, WFlags) : QDialog(parent, name, modal, WStyle_ContextHelp) {
13 QGridLayout *layout = new QGridLayout(this, 7, 2, 5, 5); 13 QGridLayout *layout = new QGridLayout(this, 7, 2, 5, 5);
14 QLabel *label = new QLabel(tr("Profile name :"), this); 14 QLabel *label = new QLabel(tr("Profile name :"), this);
15 m_name = new QLineEdit(server.name(), this); 15 m_name = new QLineEdit(server.name(), this);
16 QWhatsThis::add(m_name, tr("The name of this server profile in the overview")); 16 QWhatsThis::add(m_name, tr("The name of this server profile in the overview"));
17 layout->addWidget(label, 0, 0); 17 layout->addWidget(label, 0, 0);
18 layout->addWidget(m_name, 0, 1); 18 layout->addWidget(m_name, 0, 1);
19 label = new QLabel(tr("Hostname :"), this); 19 label = new QLabel(tr("Hostname :"), this);
20 m_hostname = new QLineEdit(server.hostname(), this); 20 m_hostname = new QLineEdit(server.hostname(), this);
21 QWhatsThis::add(m_hostname, tr("The server to connect to - can be any valid host name or IP address")); 21 QWhatsThis::add(m_hostname, tr("The server to connect to - can be any valid host name or IP address"));
22 layout->addWidget(label, 1, 0); 22 layout->addWidget(label, 1, 0);
23 layout->addWidget(m_hostname, 1, 1); 23 layout->addWidget(m_hostname, 1, 1);
24 label = new QLabel(tr("Port :"), this); 24 label = new QLabel(tr("Port :"), this);
25 m_port = new QLineEdit(QString::number(server.port()), this); 25 m_port = new QLineEdit(QString::number(server.port()), this);
26 QWhatsThis::add(m_port, tr("The server port to connect to. Usually 6667")); 26 QWhatsThis::add(m_port, tr("The server port to connect to. Usually 6667"));
27 layout->addWidget(label, 2, 0); 27 layout->addWidget(label, 2, 0);
28 layout->addWidget(m_port, 2, 1); 28 layout->addWidget(m_port, 2, 1);
29 label = new QLabel(tr("Nickname :"), this); 29 label = new QLabel(tr("Nickname :"), this);
30 m_nickname = new QLineEdit(server.nick(), this); 30 m_nickname = new QLineEdit(server.nick(), this);
31 QWhatsThis::add(m_nickname, tr("Your nick name on the IRC network")); 31 QWhatsThis::add(m_nickname, tr("Your nick name on the IRC network"));
32 layout->addWidget(label, 3, 0); 32 layout->addWidget(label, 3, 0);
33 layout->addWidget(m_nickname, 3, 1); 33 layout->addWidget(m_nickname, 3, 1);
34 label = new QLabel(tr("Realname :"), this); 34 label = new QLabel(tr("Realname :"), this);
35 m_realname = new QLineEdit(server.realname(), this); 35 m_realname = new QLineEdit(server.realname(), this);
36 QWhatsThis::add(m_realname, tr("Your real name")); 36 QWhatsThis::add(m_realname, tr("Your real name"));
37 layout->addWidget(label, 4, 0); 37 layout->addWidget(label, 4, 0);
38 layout->addWidget(m_realname, 4, 1); 38 layout->addWidget(m_realname, 4, 1);
39 label = new QLabel(tr("Password :"), this); 39 label = new QLabel(tr("Password :"), this);
40 m_password = new QLineEdit(server.password(), this); 40 m_password = new QLineEdit(server.password(), this);
41 m_password->setEchoMode( QLineEdit::Password ); 41 m_password->setEchoMode( QLineEdit::Password );
42 QWhatsThis::add(m_password, tr("Password to connect to the server (if required)")); 42 QWhatsThis::add(m_password, tr("Password to connect to the server (if required)"));
43 layout->addWidget(label, 5, 0); 43 layout->addWidget(label, 5, 0);
44 layout->addWidget(m_password, 5, 1); 44 layout->addWidget(m_password, 5, 1);
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;
83 server.setName(m_name->text()); 83 server.setName(m_name->text());
84 server.setHostname(m_hostname->text()); 84 server.setHostname(m_hostname->text());
85 server.setPort(m_port->text().toInt()); 85 server.setPort(m_port->text().toInt());
86 server.setNick(m_nickname->text()); 86 server.setNick(m_nickname->text());
87 server.setRealname(m_realname->text()); 87 server.setRealname(m_realname->text());
88 server.setUsername(m_nickname->text()); 88 server.setUsername(m_nickname->text());
89 server.setPassword(m_password->text()); 89 server.setPassword(m_password->text());
90 server.setChannels(m_channels->text()); 90 server.setChannels(m_channels->text());
91 return server; 91 return server;
92} 92}
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
@@ -1,180 +1,187 @@
1#include <qtextstream.h> 1#include <qtextstream.h>
2#include <qwhatsthis.h> 2#include <qwhatsthis.h>
3 3
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
54 55
55 56
56 if (m_maxLines > 0 && m_lines >= m_maxLines) { 57 if (m_maxLines > 0 && m_lines >= m_maxLines) {
57 int firstBreak = txt.find('\n'); 58 int firstBreak = txt.find('\n');
58 if (firstBreak != -1) { 59 if (firstBreak != -1) {
59 txt = "<qt bgcolor=\"" + m_backgroundColor + "\"/>" + txt.right(txt.length() - (firstBreak + 1)); 60 txt = "<qt bgcolor=\"" + m_backgroundColor + "\"/>" + txt.right(txt.length() - (firstBreak + 1));
60 } 61 }
61 } else { 62 } else {
62 m_lines++; 63 m_lines++;
63 } 64 }
64 m_textview->setText(txt); 65 m_textview->setText(txt);
65 m_textview->ensureVisible(0, m_textview->contentsHeight()); 66 m_textview->ensureVisible(0, m_textview->contentsHeight());
66 emit changed(this); 67 emit changed(this);
67} 68}
68 69
69IRCServerTab::~IRCServerTab() { 70IRCServerTab::~IRCServerTab() {
70 delete m_session; 71 delete m_session;
71} 72}
72 73
73void IRCServerTab::removeChannelTab(IRCChannelTab *tab) { 74void IRCServerTab::removeChannelTab(IRCChannelTab *tab) {
74 m_channelTabs.remove(tab); 75 m_channelTabs.remove(tab);
75} 76}
76 77
77void IRCServerTab::removeQueryTab(IRCQueryTab *tab) { 78void IRCServerTab::removeQueryTab(IRCQueryTab *tab) {
78 m_queryTabs.remove(tab); 79 m_queryTabs.remove(tab);
79} 80}
80 81
81void IRCServerTab::addQueryTab(IRCQueryTab *tab) { 82void IRCServerTab::addQueryTab(IRCQueryTab *tab) {
82 m_queryTabs.append(tab); 83 m_queryTabs.append(tab);
83} 84}
84 85
85QString IRCServerTab::title() { 86QString IRCServerTab::title() {
86 return "Server"; 87 return "Server";
87} 88}
88 89
89IRCSession *IRCServerTab::session() { 90IRCSession *IRCServerTab::session() {
90 return m_session; 91 return m_session;
91} 92}
92/* 93/*
93QString *IRCServerTab::mynick() { 94QString *IRCServerTab::mynick() {
94 return (*m_server->nick()); 95 return (*m_server->nick());
95} */ 96} */
96 97
97IRCServer *IRCServerTab::server() { 98IRCServer *IRCServerTab::server() {
98 return &m_server; 99 return &m_server;
99} 100}
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);
133 } else { 140 } else {
134 IRCPerson person; 141 IRCPerson person;
135 person.setNick(nickname); 142 person.setNick(nickname);
136 m_session->kick(((IRCChannelTab *)tab)->channel(), &person); 143 m_session->kick(((IRCChannelTab *)tab)->channel(), &person);
137 } 144 }
138 } 145 }
139 } 146 }
140 147
141 else if (command == "OP"){ 148 else if (command == "OP"){
142 QString nickname; 149 QString nickname;
143 stream >> nickname; 150 stream >> nickname;
144 if (nickname.length() > 0) { 151 if (nickname.length() > 0) {
145 QString text = line.right(line.length()-nickname.length()-5); 152 QString text = line.right(line.length()-nickname.length()-5);
146 IRCPerson person; 153 IRCPerson person;
147 person.setNick(nickname); 154 person.setNick(nickname);
148 m_session->op(((IRCChannelTab *)tab)->channel(), &person); 155 m_session->op(((IRCChannelTab *)tab)->channel(), &person);
149 } 156 }
150 } 157 }
151 158
152 //SEND MODES 159 //SEND MODES
153 else if (command == "MODE"){ 160 else if (command == "MODE"){
154 QString text = line.right(line.length()-6); 161 QString text = line.right(line.length()-6);
155 if (text.length() > 0) { 162 if (text.length() > 0) {
156 m_session->mode(text); 163 m_session->mode(text);
157 } else { 164 } else {
158 tab->appendText("<font color=\"" + m_errorColor + "\">/mode channel {[+|-]|o|p|s|i|t|n|b|v} [limit] [user] [ban mask]<br>/mode nickname {[+|-]|i|w|s|o}</font><br>"); 165 tab->appendText("<font color=\"" + m_errorColor + "\">/mode channel {[+|-]|o|p|s|i|t|n|b|v} [limit] [user] [ban mask]<br>/mode nickname {[+|-]|i|w|s|o}</font><br>");
159 } 166 }
160 } 167 }
161 //SEND RAW MESSAGE TO SERVER, COMPLETELY UNCHECKED - anything in the RFC...or really anything you want 168 //SEND RAW MESSAGE TO SERVER, COMPLETELY UNCHECKED - anything in the RFC...or really anything you want
162 else if (command == "RAW"){ 169 else if (command == "RAW"){
163 QString text = line.right(line.length()-5); 170 QString text = line.right(line.length()-5);
164 if (text.length() > 0) { 171 if (text.length() > 0) {
165 m_session->raw(text); 172 m_session->raw(text);
166 } 173 }
167 } 174 }
168 else if (command == "SUSPEND"){ 175 else if (command == "SUSPEND"){
169 QString text = line.right(line.length()-9); 176 QString text = line.right(line.length()-9);
170 if (text.upper() == "ON") { 177 if (text.upper() == "ON") {
171 QCopEnvelope( "QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::Enable; 178 QCopEnvelope( "QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::Enable;
172 } 179 }
173 else if (text.upper() == "OFF"){ 180 else if (text.upper() == "OFF"){
174 QCopEnvelope( "QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::Disable; 181 QCopEnvelope( "QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::Disable;
175 } else { 182 } else {
176 tab->appendText("<font color=\"" + m_errorColor + "\">Line: "+ line +"</font><br>Text: "+text); 183 tab->appendText("<font color=\"" + m_errorColor + "\">Line: "+ line +"</font><br>Text: "+text);
177 } 184 }
178 } 185 }
179 186
180 else if (command == "QUIT"){ 187 else if (command == "QUIT"){
@@ -284,110 +291,124 @@ void IRCServerTab::display(IRCOutput output) {
284 m_mainWindow->killTab(m_channelTabs.current(), true); 291 m_mainWindow->killTab(m_channelTabs.current(), true);
285 } 292 }
286 m_queryTabs.first(); 293 m_queryTabs.first();
287 while (m_queryTabs.current() != 0) { 294 while (m_queryTabs.current() != 0) {
288 m_mainWindow->killTab(m_queryTabs.current(), true); 295 m_mainWindow->killTab(m_queryTabs.current(), true);
289 } 296 }
290 m_mainWindow->killTab(this); 297 m_mainWindow->killTab(this);
291 } else { 298 } else {
292 appendText("<font color=\"" + m_errorColor + "\">" + output.htmlMessage() +"</font><br>"); 299 appendText("<font color=\"" + m_errorColor + "\">" + output.htmlMessage() +"</font><br>");
293 QListIterator<IRCChannelTab> it(m_channelTabs); 300 QListIterator<IRCChannelTab> it(m_channelTabs);
294 for (; it.current(); ++it) { 301 for (; it.current(); ++it) {
295 it.current()->appendText("<font color=\"" + m_serverColor + "\">" + output.htmlMessage() +"</font><br>"); 302 it.current()->appendText("<font color=\"" + m_serverColor + "\">" + output.htmlMessage() +"</font><br>");
296 } 303 }
297 } 304 }
298 break; 305 break;
299 case OUTPUT_SELFJOIN: { 306 case OUTPUT_SELFJOIN: {
300 IRCChannelTab *channeltab = new IRCChannelTab((IRCChannel *)output.getParam(0), this, m_mainWindow, (QWidget *)parent()); 307 IRCChannelTab *channeltab = new IRCChannelTab((IRCChannel *)output.getParam(0), this, m_mainWindow, (QWidget *)parent());
301 m_channelTabs.append(channeltab); 308 m_channelTabs.append(channeltab);
302 m_mainWindow->addTab(channeltab); 309 m_mainWindow->addTab(channeltab);
303 } 310 }
304 break; 311 break;
305 case OUTPUT_CHANPRIVMSG: { 312 case OUTPUT_CHANPRIVMSG: {
306 IRCChannelTab *channelTab = getTabForChannel((IRCChannel *)output.getParam(0)); 313 IRCChannelTab *channelTab = getTabForChannel((IRCChannel *)output.getParam(0));
307 channelTab->appendText("<font color=\"" + m_textColor + "\">&lt;</font><font color=\"" + m_otherColor + "\">"+IRCOutput::toHTML(((IRCChannelPerson *)output.getParam(1))->person->nick())+"</font><font color=\"" + m_textColor + "\">&gt; " + output.htmlMessage()+"</font><br>"); 314 channelTab->appendText("<font color=\"" + m_textColor + "\">&lt;</font><font color=\"" + m_otherColor + "\">"+IRCOutput::toHTML(((IRCChannelPerson *)output.getParam(1))->person->nick())+"</font><font color=\"" + m_textColor + "\">&gt; " + output.htmlMessage()+"</font><br>");
308 } 315 }
309 break; 316 break;
310 case OUTPUT_QUERYACTION: 317 case OUTPUT_QUERYACTION:
311 case OUTPUT_QUERYPRIVMSG: { 318 case OUTPUT_QUERYPRIVMSG: {
312 IRCQueryTab *queryTab = getTabForQuery((IRCPerson *)output.getParam(0)); 319 IRCQueryTab *queryTab = getTabForQuery((IRCPerson *)output.getParam(0));
313 if (!queryTab) { 320 if (!queryTab) {
314 queryTab = new IRCQueryTab((IRCPerson *)output.getParam(0), this, m_mainWindow, (QWidget *)parent()); 321 queryTab = new IRCQueryTab((IRCPerson *)output.getParam(0), this, m_mainWindow, (QWidget *)parent());
315 m_queryTabs.append(queryTab); 322 m_queryTabs.append(queryTab);
316 m_mainWindow->addTab(queryTab); 323 m_mainWindow->addTab(queryTab);
317 } 324 }
318 queryTab->display(output); 325 queryTab->display(output);
319 } 326 }
320 break; 327 break;
321 case OUTPUT_SELFPART: { 328 case OUTPUT_SELFPART: {
322 IRCChannelTab *channelTab = getTabForChannel((IRCChannel *)output.getParam(0)); 329 IRCChannelTab *channelTab = getTabForChannel((IRCChannel *)output.getParam(0));
323 if (channelTab) 330 if (channelTab)
324 m_mainWindow->killTab(channelTab, true); 331 m_mainWindow->killTab(channelTab, true);
325 } 332 }
326 break; 333 break;
327 case OUTPUT_SELFKICK: { 334 case OUTPUT_SELFKICK: {
328 appendText("<font color=\"" + m_errorColor + "\">" + output.htmlMessage() + "</font><br>"); 335 appendText("<font color=\"" + m_errorColor + "\">" + output.htmlMessage() + "</font><br>");
329 IRCChannelTab *channelTab = getTabForChannel((IRCChannel *)output.getParam(0)); 336 IRCChannelTab *channelTab = getTabForChannel((IRCChannel *)output.getParam(0));
330 if (channelTab) 337 if (channelTab)
331 m_mainWindow->killTab(channelTab, true); 338 m_mainWindow->killTab(channelTab, true);
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
@@ -1,81 +1,82 @@
1/* 1/*
2 OpieIRC - An embedded IRC client 2 OpieIRC - An embedded IRC client
3 Copyright (C) 2002 Wenzel Jakob 3 Copyright (C) 2002 Wenzel Jakob
4 4
5 This program is free software; you can redistribute it and/or modify 5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by 6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or 7 the Free Software Foundation; either version 2 of the License, or
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 __IRCSERVERTAB_H 21#ifndef __IRCSERVERTAB_H
22#define __IRCSERVERTAB_H 22#define __IRCSERVERTAB_H
23#include <qpe/qpeapplication.h> 23#include <qpe/qpeapplication.h>
24#include <qpe/qcopenvelope_qws.h> 24#include <qpe/qcopenvelope_qws.h>
25#include "irctab.h" 25#include "irctab.h"
26#include "ircsession.h" 26#include "ircsession.h"
27#include "mainwindow.h" 27#include "mainwindow.h"
28#include "ircchanneltab.h" 28#include "ircchanneltab.h"
29#include "ircquerytab.h" 29#include "ircquerytab.h"
30#include "ircmisc.h" 30#include "ircmisc.h"
31 31
32 32
33class IRCServerTab : public IRCTab { 33class IRCServerTab : public IRCTab {
34 Q_OBJECT 34 Q_OBJECT
35public: 35public:
36 static bool containsPing(const QString& text, IRCServerTab *tab); 36 static bool containsPing(const QString& text, IRCServerTab *tab);
37 37
38 /* IRCTab implementation */ 38 /* IRCTab implementation */
39 IRCServerTab(IRCServer server, MainWindow *mainWindow, QWidget *parent = 0, const char *name = 0, WFlags f = 0); 39 IRCServerTab(IRCServer server, MainWindow *mainWindow, QWidget *parent = 0, const char *name = 0, WFlags f = 0);
40 ~IRCServerTab(); 40 ~IRCServerTab();
41 QString title(); 41 QString title();
42 IRCSession *session(); 42 IRCSession *session();
43 IRCServer *server(); 43 IRCServer *server();
44 44
45 /* Start the server session */ 45 /* Start the server session */
46 void doConnect(); 46 void doConnect();
47// QString *mynick(); 47// QString *mynick();
48 /* Remove tabs from the internal tab lists */ 48 /* Remove tabs from the internal tab lists */
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
81#endif /* __IRCSERVERTAB_H */ 82#endif /* __IRCSERVERTAB_H */
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
@@ -1,150 +1,196 @@
1#include "ircsession.h" 1#include "ircsession.h"
2#include "ircmessageparser.h" 2#include "ircmessageparser.h"
3#include "ircversion.h" 3#include "ircversion.h"
4 4
5IRCSession::IRCSession(IRCServer *server) { 5IRCSession::IRCSession(IRCServer *server) {
6 m_server = server; 6 m_server = server;
7 m_connection = new IRCConnection(m_server); 7 m_connection = new IRCConnection(m_server);
8 m_parser = new IRCMessageParser(this); 8 m_parser = new IRCMessageParser(this);
9 connect(m_connection, SIGNAL(messageArrived(IRCMessage*)), this, SLOT(handleMessage(IRCMessage*))); 9 connect(m_connection, SIGNAL(messageArrived(IRCMessage*)), this, SLOT(handleMessage(IRCMessage*)));
10 connect(m_parser, SIGNAL(outputReady(IRCOutput)), this, SIGNAL(outputReady(IRCOutput))); 10 connect(m_parser, SIGNAL(outputReady(IRCOutput)), this, SIGNAL(outputReady(IRCOutput)));
11 connect(m_connection, SIGNAL(outputReady(IRCOutput)), this, SIGNAL(outputReady(IRCOutput))); 11 connect(m_connection, SIGNAL(outputReady(IRCOutput)), this, SIGNAL(outputReady(IRCOutput)));
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();
118 } 164 }
119 } 165 }
120 return 0; 166 return 0;
121} 167}
122 168
123void IRCSession::getChannelsByPerson(IRCPerson *person, QList<IRCChannel> &channels) { 169void IRCSession::getChannelsByPerson(IRCPerson *person, QList<IRCChannel> &channels) {
124 QListIterator<IRCChannel> it(m_channels); 170 QListIterator<IRCChannel> it(m_channels);
125 for (; it.current(); ++it) { 171 for (; it.current(); ++it) {
126 if (it.current()->getPerson(person->nick()) != 0) { 172 if (it.current()->getPerson(person->nick()) != 0) {
127 channels.append(it.current()); 173 channels.append(it.current());
128 } 174 }
129 } 175 }
130} 176}
131 177
132void IRCSession::addPerson(IRCPerson *person) { 178void IRCSession::addPerson(IRCPerson *person) {
133 m_people.append(person); 179 m_people.append(person);
134} 180}
135 181
136void IRCSession::addChannel(IRCChannel *channel) { 182void IRCSession::addChannel(IRCChannel *channel) {
137 m_channels.append(channel); 183 m_channels.append(channel);
138} 184}
139 185
140void IRCSession::removeChannel(IRCChannel *channel) { 186void IRCSession::removeChannel(IRCChannel *channel) {
141 m_channels.remove(channel); 187 m_channels.remove(channel);
142} 188}
143 189
144void IRCSession::removePerson(IRCPerson *person) { 190void IRCSession::removePerson(IRCPerson *person) {
145 m_people.remove(person); 191 m_people.remove(person);
146} 192}
147 193
148void IRCSession::handleMessage(IRCMessage *message) { 194void IRCSession::handleMessage(IRCMessage *message) {
149 m_parser->parse(message); 195 m_parser->parse(message);
150} 196}
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
@@ -1,84 +1,91 @@
1/* 1/*
2 OpieIRC - An embedded IRC client 2 OpieIRC - An embedded IRC client
3 Copyright (C) 2002 Wenzel Jakob 3 Copyright (C) 2002 Wenzel Jakob
4 4
5 This program is free software; you can redistribute it and/or modify 5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by 6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or 7 the Free Software Foundation; either version 2 of the License, or
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 __IRCSESSION_H 21#ifndef __IRCSESSION_H
22#define __IRCSESSION_H 22#define __IRCSESSION_H
23 23
24#include <qstring.h> 24#include <qstring.h>
25#include <qlist.h> 25#include <qlist.h>
26#include "ircserver.h" 26#include "ircserver.h"
27#include "ircconnection.h" 27#include "ircconnection.h"
28#include "ircmessage.h" 28#include "ircmessage.h"
29#include "ircchannel.h" 29#include "ircchannel.h"
30#include "ircoutput.h" 30#include "ircoutput.h"
31 31
32class IRCMessageParser; 32class IRCMessageParser;
33 33
34/* The IRCSession stores all information relating to the connection 34/* The IRCSession stores all information relating to the connection
35 to one IRC server. IRCSession makes it possible to run multiple 35 to one IRC server. IRCSession makes it possible to run multiple
36 IRC server connections from within the same program */ 36 IRC server connections from within the same program */
37 37
38class IRCSession : public QObject { 38class IRCSession : public QObject {
39friend class IRCMessageParser; 39friend class IRCMessageParser;
40 Q_OBJECT 40 Q_OBJECT
41public: 41public:
42 IRCSession(IRCServer *server); 42 IRCSession(IRCServer *server);
43 ~IRCSession(); 43 ~IRCSession();
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 */