00001 #include <qtextstream.h>
00002 #include <qwhatsthis.h>
00003
00004 #include "ircservertab.h"
00005 #include "ircmessageparser.h"
00006 #include "ircchannelperson.h"
00007
00008
00009 bool IRCServerTab::containsPing( const QString& text, IRCServerTab* tab ) {
00010 return (text.contains(IRCMessageParser::tr("Received a CTCP PING from "))) ||
00011 (text.find("ping") != -1 && text.find( tab->server()->nick() != -1));
00012 }
00013
00014
00015 IRCServerTab::IRCServerTab(IRCServer server, MainWindow *mainWindow, QWidget *parent, const char *name, WFlags f) : IRCTab(parent, name, f) {
00016 m_server = server;
00017 m_session = new IRCSession(this, &m_server);
00018 m_mainWindow = mainWindow;
00019 m_close = FALSE;
00020 m_lines = 0;
00021 m_description->setText(tr("Connecting to")+" <b>" + server.hostname() + ":" + QString::number(server.port()) + "</b>");
00022 m_textview = new QTextView(this);
00023 m_textview->setHScrollBarMode(QScrollView::AlwaysOff);
00024 m_textview->setVScrollBarMode(QScrollView::AlwaysOn);
00025 m_textview->setTextFormat(RichText);
00026 QWhatsThis::add(m_textview, tr("Server messages"));
00027 m_layout->add(m_textview);
00028 m_field = new IRCHistoryLineEdit(this);
00029 connect(m_field, SIGNAL(nextTab()), this, SIGNAL(nextTab()));
00030 connect(m_field, SIGNAL(prevTab()), this, SIGNAL(prevTab()));
00031 connect(m_field, SIGNAL(closeTab()), this, SIGNAL(closeTab()));
00032 connect(this, SIGNAL(editFocus()), m_field, SLOT(setEditFocus()));
00033
00034 QWhatsThis::add(m_field, tr("Type commands here. A list of available commands can be found inside the OpieIRC help"));
00035 m_layout->add(m_field);
00036 connect(m_field, SIGNAL(returnPressed()), this, SLOT(processCommand()));
00037 connect(m_session, SIGNAL(outputReady(IRCOutput)), this, SLOT(display(IRCOutput)));
00038 connect(m_mainWindow, SIGNAL(updateScroll()), this, SLOT(scrolling()));
00039 connect(m_session, SIGNAL(updateChannels()), this, SLOT(slotUpdateChannels()));
00040 settingsChanged();
00041
00042 m_field->setFocus();
00043 m_field->setActiveWindow();
00044
00045 }
00046
00047 void IRCServerTab::scrolling(){
00048 m_textview->ensureVisible(0, m_textview->contentsHeight());
00049 }
00050
00051
00052 void IRCServerTab::appendText(QString text) {
00053
00054 QString txt = m_textview->text() + IRCTab::appendTimestamp( text );
00055
00056
00057
00058 if (m_maxLines > 0 && m_lines >= m_maxLines) {
00059 int firstBreak = txt.find('\n');
00060 if (firstBreak != -1) {
00061 txt = "<qt bgcolor=\"" + m_backgroundColor + "\"/>" + txt.right(txt.length() - (firstBreak + 1));
00062 }
00063 } else {
00064 m_lines++;
00065 }
00066 m_textview->setText(txt);
00067 m_textview->ensureVisible(0, m_textview->contentsHeight());
00068 emit changed(this);
00069 }
00070
00071 IRCServerTab::~IRCServerTab() {
00072 delete m_session;
00073 }
00074
00075 void IRCServerTab::removeChannelTab(IRCChannelTab *tab) {
00076 m_channelTabs.remove(tab);
00077 }
00078
00079 void IRCServerTab::removeQueryTab(IRCQueryTab *tab) {
00080 m_queryTabs.remove(tab);
00081 }
00082
00083 void IRCServerTab::addQueryTab(IRCQueryTab *tab) {
00084 m_queryTabs.append(tab);
00085 }
00086
00087 QString IRCServerTab::title() {
00088 return "Server";
00089 }
00090
00091 IRCSession *IRCServerTab::session() {
00092 return m_session;
00093 }
00094
00095
00096
00097
00098
00099 IRCServer *IRCServerTab::server() {
00100 return &m_server;
00101 }
00102
00103 void IRCServerTab::settingsChanged() {
00104 m_textview->setText("<qt bgcolor=\"" + m_backgroundColor + "\"/>");
00105 m_lines = 0;
00106 }
00107
00108 void IRCServerTab::executeCommand(IRCTab *tab, QString line) {
00109 QTextIStream stream(&line);
00110 QString command;
00111 stream >> command;
00112 command = command.upper().right(command.length()-1);
00113
00114
00115 if (command == "JOIN" || command == "J") {
00116 QString channel;
00117 stream >> channel;
00118
00119 if (channel.length() > 0 && channel.length() < 200 &&
00120 channel.find(",") == -1 && channel.find('\007') == -1) {
00121
00122 if (!channel.startsWith("#") && !channel.startsWith("&")
00123 && !channel.startsWith("+") && !channel.startsWith("!")) {
00124 channel = channel.prepend("#");
00125 }
00126 m_session->join(channel);
00127 } else {
00128 tab->appendText("<font color=\"" + m_errorColor + "\">Unknown channel format!</font><br>");
00129 }
00130 }
00131
00132
00133 else if (command == "KICK"){
00134 QString nickname;
00135 stream >> nickname;
00136 if (nickname.length() > 0) {
00137 if (line.length() > 7 + nickname.length()) {
00138 QString text = line.right(line.length()-nickname.length()-7);
00139 IRCPerson person;
00140 person.setNick(nickname);
00141 m_session->kick(((IRCChannelTab *)tab)->channel(), &person, text);
00142 } else {
00143 IRCPerson person;
00144 person.setNick(nickname);
00145 m_session->kick(((IRCChannelTab *)tab)->channel(), &person);
00146 }
00147 }
00148 }
00149
00150 else if (command == "OP"){
00151 QString nickname;
00152 stream >> nickname;
00153 if (nickname.length() > 0) {
00154 QString text = line.right(line.length()-nickname.length()-5);
00155 IRCPerson person;
00156 person.setNick(nickname);
00157 m_session->op(((IRCChannelTab *)tab)->channel(), &person);
00158 }
00159 }
00160
00161
00162 else if (command == "MODE"){
00163 QString text = line.right(line.length()-6);
00164 if (text.length() > 0) {
00165 m_session->mode(text);
00166 } else {
00167 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>");
00168 }
00169 }
00170
00171 else if (command == "RAW"){
00172 QString text = line.right(line.length()-5);
00173 if (text.length() > 0) {
00174 m_session->raw(text);
00175 }
00176 }
00177 else if (command == "SUSPEND"){
00178 QString text = line.right(line.length()-9);
00179 if (text.upper() == "ON") {
00180 QCopEnvelope( "QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::Enable;
00181 }
00182 else if (text.upper() == "OFF"){
00183 QCopEnvelope( "QPE/System", "setScreenSaverMode(int)" ) << QPEApplication::Disable;
00184 } else {
00185 tab->appendText("<font color=\"" + m_errorColor + "\">Line: "+ line +"</font><br>Text: "+text);
00186 }
00187 }
00188
00189 else if (command == "QUIT"){
00190 QString text = line.right(line.length()-6);
00191 if (text.length() > 0) {
00192 m_session->quit(text);
00193 } else {
00194 m_session->quit();
00195 }
00196 }
00197
00198
00199 else if (command == "ME") {
00200 QString text = line.right(line.length()-4);
00201 if (text.length() > 0) {
00202 if (tab->isA("IRCChannelTab")) {
00203 tab->appendText("<font color=\"" + m_selfColor + "\">*" + IRCOutput::toHTML(m_server.nick()) + " " + IRCOutput::toHTML(text) + "</font><br>");
00204 m_session->sendAction(((IRCChannelTab *)tab)->channel(), text);
00205 } else if (tab->isA("IRCQueryTab")) {
00206 tab->appendText("<font color=\"" + m_selfColor + "\">*" + IRCOutput::toHTML(m_server.nick()) + " " + IRCOutput::toHTML(text) + "</font><br>");
00207 m_session->sendAction(((IRCQueryTab *)tab)->person(), text);
00208 } else {
00209 tab->appendText("<font color=\"" + m_errorColor + "\">Invalid tab for this command</font><br>");
00210 }
00211 }
00212 }
00213
00214 else if (command == "MSG") {
00215 QString nickname;
00216 stream >> nickname;
00217 if (nickname.length() > 0) {
00218 if (line.length() > 6 + nickname.length()) {
00219 QString text = line.right(line.length()-nickname.length()-6);
00220 IRCPerson person;
00221 person.setNick(nickname);
00222 tab->appendText("<font color=\"" + m_textColor + "\">></font><font color=\"" + m_otherColor + "\">"+IRCOutput::toHTML(nickname)+"</font><font color=\"" + m_textColor + "\">< "+IRCOutput::toHTML(text)+"</font><br>");
00223 m_session->sendMessage(&person, text);
00224 }
00225 }
00226 }
00227 else {
00228 tab->appendText("<font color=\"" + m_errorColor + "\">Unknown command</font><br>");
00229 }
00230 }
00231
00232 void IRCServerTab::processCommand() {
00233 QString text = m_field->text();
00234 if (text.startsWith("/") && !text.startsWith("//")) {
00235
00236 executeCommand(this, text);
00237 }
00238 m_field->clear();
00239 }
00240
00241 void IRCServerTab::doConnect() {
00242 m_session->beginSession();
00243 }
00244
00245 void IRCServerTab::remove() {
00246
00247 if (m_session->isSessionActive()) {
00248
00249 m_close = TRUE;
00250 m_session->endSession();
00251 } else {
00252
00253 m_channelTabs.first();
00254 while (m_channelTabs.current() != 0) {
00255 m_mainWindow->killTab(m_channelTabs.current(), true);
00256 }
00257 m_queryTabs.first();
00258 while (m_queryTabs.current() != 0) {
00259 m_mainWindow->killTab(m_queryTabs.current(), true);
00260 }
00261 m_mainWindow->killTab(this);
00262 }
00263 }
00264
00265 IRCChannelTab *IRCServerTab::getTabForChannel(IRCChannel *channel) {
00266 QListIterator<IRCChannelTab> it(m_channelTabs);
00267
00268 for (; it.current(); ++it) {
00269 if (it.current()->channel() == channel)
00270 return it.current();
00271 }
00272 return 0;
00273 }
00274
00275 IRCQueryTab *IRCServerTab::getTabForQuery(IRCPerson *person) {
00276 QListIterator<IRCQueryTab> it(m_queryTabs);
00277
00278 for (; it.current(); ++it) {
00279 if (it.current()->person()->nick() == person->nick())
00280 return it.current();
00281 }
00282 return 0;
00283 }
00284
00285 void IRCServerTab::display(IRCOutput output) {
00286
00287
00288 switch (output.type()) {
00289 case OUTPUT_CONNCLOSE:
00290 if (m_close) {
00291 m_channelTabs.first();
00292 while (m_channelTabs.current() != 0) {
00293 m_mainWindow->killTab(m_channelTabs.current(), true);
00294 }
00295 m_queryTabs.first();
00296 while (m_queryTabs.current() != 0) {
00297 m_mainWindow->killTab(m_queryTabs.current(), true);
00298 }
00299 m_mainWindow->killTab(this);
00300 } else {
00301 appendText("<font color=\"" + m_errorColor + "\">" + output.htmlMessage() +"</font><br>");
00302 QListIterator<IRCChannelTab> it(m_channelTabs);
00303 for (; it.current(); ++it) {
00304 it.current()->appendText("<font color=\"" + m_serverColor + "\">" + output.htmlMessage() +"</font><br>");
00305 }
00306 }
00307 break;
00308 case OUTPUT_SELFJOIN: {
00309 IRCChannelTab *channeltab = new IRCChannelTab((IRCChannel *)output.getParam(0), this, m_mainWindow, (QWidget *)parent());
00310 m_channelTabs.append(channeltab);
00311 m_mainWindow->addTab(channeltab);
00312 }
00313 break;
00314 case OUTPUT_CHANPRIVMSG: {
00315 IRCChannelTab *channelTab = getTabForChannel((IRCChannel *)output.getParam(0));
00316 channelTab->appendText("<font color=\"" + m_textColor + "\"><</font><font color=\"" + m_otherColor + "\">"+IRCOutput::toHTML(((IRCChannelPerson *)output.getParam(1))->nick())+"</font><font color=\"" + m_textColor + "\">> " + output.htmlMessage()+"</font><br>");
00317 }
00318 break;
00319 case OUTPUT_QUERYACTION:
00320 case OUTPUT_QUERYPRIVMSG: {
00321 IRCQueryTab *queryTab = getTabForQuery((IRCPerson *)output.getParam(0));
00322 if (!queryTab) {
00323 queryTab = new IRCQueryTab((IRCPerson *)output.getParam(0), this, m_mainWindow, (QWidget *)parent());
00324 m_queryTabs.append(queryTab);
00325 m_mainWindow->addTab(queryTab);
00326 }
00327 queryTab->display(output);
00328 }
00329 break;
00330 case OUTPUT_SELFPART: {
00331 IRCChannelTab *channelTab = getTabForChannel((IRCChannel *)output.getParam(0));
00332 if (channelTab)
00333 m_mainWindow->killTab(channelTab, true);
00334 }
00335 break;
00336 case OUTPUT_SELFKICK: {
00337 appendText("<font color=\"" + m_errorColor + "\">" + output.htmlMessage() + "</font><br>");
00338 IRCChannelTab *channelTab = getTabForChannel((IRCChannel *)output.getParam(0));
00339 if (channelTab)
00340 m_mainWindow->killTab(channelTab, true);
00341 }
00342 break;
00343 case OUTPUT_CHANACTION: {
00344 IRCChannelTab *channelTab = getTabForChannel((IRCChannel *)output.getParam(0));
00345 channelTab->appendText("<font color=\"" + m_otherColor + "\">"+output.htmlMessage()+"</font><br>");
00346 }
00347 break;
00348 case OUTPUT_TOPIC: {
00349 IRCChannel *channel = (IRCChannel *) output.getParam(0);
00350 if (channel) {
00351 IRCChannelTab *channelTab = getTabForChannel(channel);
00352 if (channelTab) {
00353 channelTab->appendText("<font color=\"" + m_notificationColor + "\">"+output.htmlMessage()+"</font><br>");
00354 return;
00355 }
00356 }
00357 IRCChannelTab::enqueue(channel->channelname(), "<font color=\"" + m_notificationColor + "\">"+output.htmlMessage()+"</font><br>");
00358 }
00359 break;
00360 case OUTPUT_QUIT: {
00361 QString nick = ((IRCPerson *)output.getParam(0))->nick();
00362 QListIterator<IRCChannelTab> it(m_channelTabs);
00363 for (; it.current(); ++it) {
00364 if (it.current()->list()->hasPerson(nick)) {
00365 it.current()->appendText("<font color=\"" + m_notificationColor + "\">"+output.htmlMessage()+"</font><br>");
00366 it.current()->list()->update();
00367 }
00368 }
00369 }
00370 break;
00371 case OUTPUT_NICKCHANGE: {
00372 QString *nick = static_cast<QString*>(output.getParam(0));
00373 if(!nick) {
00374 appendText("<font color=\"" + m_notificationColor + "\">"+output.htmlMessage()+"</font><br>");
00375 break;
00376 }
00377 QListIterator<IRCChannelTab> it(m_channelTabs);
00378 for (; it.current(); ++it) {
00379 if (it.current()->list()->hasPerson(*nick)) {
00380 it.current()->appendText("<font color=\"" + m_notificationColor + "\">"+output.htmlMessage()+"</font><br>");
00381 }
00382 }
00383 delete nick;
00384 }
00385 break;
00386 case OUTPUT_OTHERJOIN:
00387 case OUTPUT_OTHERKICK:
00388 case OUTPUT_CHANPERSONMODE:
00389 case OUTPUT_OTHERPART: {
00390 IRCChannelTab *channelTab = getTabForChannel((IRCChannel *)output.getParam(0));
00391 channelTab->appendText("<font color=\"" + m_notificationColor + "\">"+output.htmlMessage()+"</font><br>");
00392 channelTab->list()->update();
00393 }
00394 break;
00395 case OUTPUT_CTCP:
00396 appendText("<font color=\"" + m_notificationColor + "\">" + output.htmlMessage() + "</font><br>");
00397 break;
00398 case OUTPUT_ERROR:
00399 appendText("<font color=\"" + m_errorColor + "\">" + output.htmlMessage() + "</font><br>");
00400 break;
00401 case OUTPUT_TITLE:
00402 m_description->setText(output.message());
00403 break;
00404 default:
00405 appendText("<font color=\"" + m_serverColor + "\">" + output.htmlMessage() + "</font><br>");
00406 break;
00407 }
00408 }
00409
00410 void IRCServerTab::slotUpdateChannels() {
00411 QListIterator<IRCChannelTab> it(m_channelTabs);
00412 for (; it.current(); ++it) {
00413 it.current()->list()->update();
00414 }
00415 }
00416
00417 MainWindow *IRCServerTab::mainwindow() {
00418 return m_mainWindow;
00419 }
00420