and we already sorta use this feature. Implemented /say, /quote and /join. Made output
prettier. However, this is all still pretty much work in progress and I guess there are
still some Q_ASSERTs triggering where they shouldn't.
if(core) qFatal("Trying to instantiate more than one Core object!");
connect(coreProxy, SIGNAL(gsRequestConnect(QStringList)), this, SLOT(connectToIrc(QStringList)));
- connect(coreProxy, SIGNAL(gsUserInput(QString)), this, SLOT(inputLine(QString)));
- connect(this, SIGNAL(sendMessage(QString, QString, QString)), coreProxy, SLOT(csSendMessage(QString, QString, QString)));
+ connect(coreProxy, SIGNAL(gsUserInput(QString, QString, QString)), this, SIGNAL(msgFromGUI(QString, QString, QString)));
+ connect(this, SIGNAL(sendMessage(QString, QString, Message)), coreProxy, SLOT(csSendMessage(QString, QString, Message)));
connect(this, SIGNAL(sendStatusMsg(QString, QString)), coreProxy, SLOT(csSendStatusMsg(QString, QString)));
// Read global settings from config file
s.setValue(QString("Global/")+key, data);
}
-// temp
-void Core::inputLine(QString s) {
- emit msgFromGUI("", "", s);
-
-}
-
void Core::connectToIrc(QStringList networks) {
foreach(QString net, networks) {
if(servers.contains(net)) {
connect(this, SIGNAL(connectToIrc(QString)), server, SLOT(connectToIrc(QString)));
connect(this, SIGNAL(disconnectFromIrc(QString)), server, SLOT(disconnectFromIrc(QString)));
connect(this, SIGNAL(msgFromGUI(QString, QString, QString)), server, SLOT(userInput(QString, QString, QString)));
- connect(server, SIGNAL(sendMessage(QString, QString)), this, SLOT(recvMessageFromServer(QString, QString)));
+ connect(server, SIGNAL(sendMessage(QString, Message)), this, SLOT(recvMessageFromServer(QString, Message)));
connect(server, SIGNAL(sendStatusMsg(QString)), this, SLOT(recvStatusMsgFromServer(QString)));
+ connect(server, SIGNAL(setTopic(QString, QString, QString)), coreProxy, SLOT(csSetTopic(QString, QString, QString)));
+ connect(server, SIGNAL(setNicks(QString, QString, QStringList)), coreProxy, SLOT(csSetNicks(QString, QString, QStringList)));
// add error handling
server->start();
}
}
-void Core::recvMessageFromServer(QString buf, QString msg) {
+void Core::recvMessageFromServer(QString buf, Message msg) {
Q_ASSERT(sender());
QString net = qobject_cast<Server*>(sender())->getNetwork();
emit sendMessage(net, buf, msg);
void Core::recvStatusMsgFromServer(QString msg) {
Q_ASSERT(sender());
QString net = qobject_cast<Server*>(sender())->getNetwork();
- qDebug() << "sent status:"<<msg;
emit sendStatusMsg(net, msg);
}
//~Core();
public slots:
- void inputLine(QString); // temp
void connectToIrc(QStringList);
signals:
- void outputLine(const QString &); // temp
void msgFromGUI(QString network, QString channel, QString message);
- void sendMessage(QString network, QString channel, QString message);
+ void sendMessage(QString network, QString channel, Message message);
void sendStatusMsg(QString, QString);
void connectToIrc(QString net);
private slots:
void globalDataUpdated(QString);
void recvStatusMsgFromServer(QString msg);
- void recvMessageFromServer(QString buffer, QString msg);
+ void recvMessageFromServer(QString buffer, Message msg);
private:
QHash<QString, Server *> servers;
//qDebug() << "[CORE] Received signal" << sig << ":" << arg1<<arg2<<arg3;
switch(sig) {
case GS_UPDATE_GLOBAL_DATA: emit gsPutGlobalData(arg1.toString(), arg2); break;
- case GS_USER_INPUT: emit gsUserInput(arg1.toString()); break;
+ case GS_USER_INPUT: emit gsUserInput(arg1.toString(), arg2.toString(), arg3.toString()); break;
case GS_REQUEST_CONNECT: emit gsRequestConnect(arg1.toStringList()); break;
default: qWarning() << "Unknown signal in CoreProxy::recv: " << sig;
}
#define _COREPROXY_H_
#include "proxy_common.h"
+#include "message.h"
#include <QtCore>
#include <QTcpSocket>
public slots:
inline void csUpdateGlobalData(QString key, QVariant data) { send(CS_UPDATE_GLOBAL_DATA, key, data); }
- inline void csSendMessage(QString net, QString chan, QString msg) { send(CS_SEND_MESSAGE, net, chan, msg); }
+ inline void csSendMessage(QString net, QString buf, Message msg) { send(CS_SEND_MESSAGE, net, buf, QVariant::fromValue(msg)); }
inline void csSendStatusMsg(QString net, QString msg) { send(CS_SEND_STATUS_MSG, net, msg); }
+ inline void csSetTopic(QString net, QString buf, QString topic) { send(CS_SET_TOPIC, net, buf, topic); }
+ inline void csSetNicks(QString net, QString buf, QStringList nicks) { send(CS_SET_NICKS, net, buf, nicks); }
signals:
void gsPutGlobalData(QString, QVariant);
- void gsUserInput(QString);
+ void gsUserInput(QString, QString, QString);
void gsRequestConnect(QStringList networks);
private:
SET(gui_SRCS channelwidget.cpp mainwin.cpp serverlist.cpp identities.cpp coreconnectdlg.cpp guiproxy.cpp)
SET(gui_HDRS )
SET(gui_MOCS channelwidget.h mainwin.h serverlist.h identities.h coreconnectdlg.h guiproxy.h)
-SET(gui_UICS channelwidget.ui identitiesdlg.ui identitieseditdlg.ui networkeditdlg.ui nickeditdlg.ui serverlistdlg.ui servereditdlg.ui coreconnectdlg.ui)
+SET(gui_UICS channelwidget.ui identitiesdlg.ui identitieseditdlg.ui networkeditdlg.ui
+ nickeditdlg.ui serverlistdlg.ui servereditdlg.ui coreconnectdlg.ui ircwidget.ui)
QT4_WRAP_UI(_UIC ${gui_UICS})
QT4_WRAP_CPP(_MOC ${gui_MOCS})
#include <QtGui>
#include <iostream>
-ChannelWidget::ChannelWidget(QWidget *parent) : QWidget(parent) {
+ChannelWidget::ChannelWidget(QString netname, QString bufname, QWidget *parent) : QWidget(parent) {
ui.setupUi(this);
- //ui.inputEdit->grabKeyboard();
-
-/* //ui.splitter->
- ui.textBrowser->setHtml("[17:21] <em>--> Dante has joined #quassel (~hurz@p1af2242.dip.t-dialin.net)</em><br>"
- "[17:21] <em>--> Sput has joined #quassel (~Sput42@vincent.mindpool.net)</em><br>"
- "[17:23] <<b>Dante</b>> Das sieht ja soweit schonmal Klasse aus!<br>"
- "[17:23] <<b>Sput</b>> Find ich auch... schade dass es noch nix tut :p<br>"
- "[17:24] <<b>Dante</b>> Das wird sich ja gottseidank bald ändern.<br>"
- "[17:24] <<b>Sput</b>> Wollen wir's hoffen :D"
- );
- ui.listWidget->addItem("@Dante");
- ui.listWidget->addItem("@Sput");
- */
- //connect(&core, SIGNAL(outputLine( const QString& )), ui.textBrowser, SLOT(insertPlainText(const QString &)));
- //connect(ui.lineEdit, SIGNAL(
- //connect(&core, SIGNAL(outputLine( const QString& )), this, SLOT(lineReceived(const QString &)));
+ _networkName = netname;
+ _bufferName = bufname;
connect(ui.inputEdit, SIGNAL(returnPressed()), this, SLOT(enterPressed()));
- //connect(this, SIGNAL(inputLine( const QString& )), &core, SLOT(inputLine( const QString& )));
+ //ui.inputEdit->setFocus();
- connect(this, SIGNAL(inputLine(QString)), guiProxy, SLOT(gsUserInput(QString)));
- connect(guiProxy, SIGNAL(csSendMessage(QString, QString, QString)), this, SLOT(msgReceived(QString, QString, QString)));
- connect(guiProxy, SIGNAL(csSendStatusMsg(QString, QString)), this, SLOT(statusMsgReceived(QString, QString)));
- ui.inputEdit->setFocus();
+ // Define standard colors
+ stdCol = QColor("black");
+ noticeCol = QColor("darkblue");
+ serverCol = QColor("darkblue");
+ errorCol = QColor("red");
+ joinCol = QColor("green");
+ quitCol = QColor("firebrick");
+ partCol = QColor("firebrick");
+
}
void ChannelWidget::enterPressed() {
- emit inputLine(ui.inputEdit->text());
+ emit sendMessage(networkName(), bufferName(), ui.inputEdit->text());
ui.inputEdit->clear();
}
-void ChannelWidget::msgReceived(QString net, QString chan, QString msg) {
- ui.chatWidget->insertPlainText(QString("[%1:%2] %3\n").arg(net).arg(chan).arg(msg));
+void ChannelWidget::recvMessage(Message msg) {
+ QString s;
+ QColor c = stdCol;
+ switch(msg.type) {
+ case Message::Server:
+ c = serverCol; s = msg.msg;
+ break;
+ case Message::Error:
+ c = errorCol; s = msg.msg;
+ break;
+ default:
+ c = stdCol; s = QString("[%1] %2").arg(msg.sender).arg(msg.msg);
+ break;
+ }
+ ui.chatWidget->setTextColor(c);
+ ui.chatWidget->insertPlainText(QString("%1\n").arg(s));
ui.chatWidget->ensureCursorVisible();
}
-void ChannelWidget::statusMsgReceived(QString net, QString msg) {
- msgReceived(net, "STATUS", msg);
+void ChannelWidget::recvStatusMsg(QString msg) {
+ ui.chatWidget->insertPlainText(QString("[STATUS] %1").arg(msg));
+ ui.chatWidget->ensureCursorVisible();
+}
+
+void ChannelWidget::setTopic(QString topic) {
+ ui.topicEdit->setText(topic);
+}
+
+void ChannelWidget::setNicks(QStringList nicks) {
+
+
+}
+
+/**********************************************************************************************/
+
+
+IrcWidget::IrcWidget(QWidget *parent) : QWidget(parent) {
+ ui.setupUi(this);
+ ui.tabWidget->removeTab(0);
+
+ connect(guiProxy, SIGNAL(csSendMessage(QString, QString, Message)), this, SLOT(recvMessage(QString, QString, Message)));
+ connect(guiProxy, SIGNAL(csSendStatusMsg(QString, QString)), this, SLOT(recvStatusMsg(QString, QString)));
+ connect(guiProxy, SIGNAL(csSetTopic(QString, QString, QString)), this, SLOT(setTopic(QString, QString, QString)));
+ connect(guiProxy, SIGNAL(csSetNicks(QString, QString, QStringList)), this, SLOT(setNicks(QString, QString, QStringList)));
+ connect(this, SIGNAL(sendMessage( QString, QString, QString )), guiProxy, SLOT(gsUserInput(QString, QString, QString)));
+}
+
+ChannelWidget * IrcWidget::getBuffer(QString net, QString buf) {
+ QString key = net + buf;
+ if(!buffers.contains(key)) {
+ ChannelWidget *cw = new ChannelWidget(net, buf);
+ connect(cw, SIGNAL(sendMessage(QString, QString, QString)), this, SLOT(userInput(QString, QString, QString)));
+ ui.tabWidget->addTab(cw, net+buf);
+ ui.tabWidget->setCurrentWidget(cw);
+ //cw->setFocus();
+ buffers[key] = cw;
+ }
+ return buffers[key];
+}
+
+
+void IrcWidget::recvMessage(QString net, QString buf, Message msg) {
+ ChannelWidget *cw = getBuffer(net, buf);
+ cw->recvMessage(msg);
+}
+
+void IrcWidget::recvStatusMsg(QString net, QString msg) {
+ recvMessage(net, "", QString("[STATUS] %1").arg(msg));
+
}
+
+void IrcWidget::userInput(QString net, QString buf, QString msg) {
+ emit sendMessage(net, buf, msg);
+}
+
+void IrcWidget::setTopic(QString net, QString buf, QString topic) {
+ ChannelWidget *cw = getBuffer(net, buf);
+ cw->setTopic(topic);
+}
+
+void IrcWidget::setNicks(QString net, QString buf, QStringList nicks) {
+ ChannelWidget *cw = getBuffer(net, buf);
+ cw->setNicks(nicks);
+}
+
#define _CHANNELWIDGET_H_
#include "ui_channelwidget.h"
+#include "ui_ircwidget.h"
+
+#include "message.h"
class ChannelWidget : public QWidget {
Q_OBJECT
public:
- ChannelWidget(QWidget *parent = 0);
+ ChannelWidget(QString netname, QString bufname, QWidget *parent = 0);
+ QString bufferName() { return _bufferName; }
+ QString networkName() { return _networkName; }
signals:
- void requestConnect(QString, quint16);
- void inputLine(QString);
+ void sendMessage(QString, QString, QString);
+
+ public slots:
+ void recvMessage(Message);
+ void recvStatusMsg(QString msg);
+ void setTopic(QString);
+ void setNicks(QStringList);
private slots:
void enterPressed();
- void msgReceived(QString, QString, QString);
- void statusMsgReceived(QString net, QString msg);
private:
Ui::ChannelWidget ui;
+ QColor stdCol, errorCol, noticeCol, joinCol, quitCol, partCol, serverCol;
+ QString _networkName;
+ QString _bufferName;
};
+/** Temporary widget for displaying a set of ChannelWidgets. */
+class IrcWidget : public QWidget {
+ Q_OBJECT
+
+ public:
+ IrcWidget(QWidget *parent = 0);
+
+ public slots:
+ void recvMessage(QString network, QString buffer, Message message);
+ void recvStatusMsg(QString network, QString message);
+ void setTopic(QString, QString, QString);
+ void setNicks(QString, QString, QStringList);
+
+ signals:
+ void sendMessage(QString network, QString buffer, QString message);
+
+ private slots:
+ void userInput(QString, QString, QString);
+
+ private:
+ Ui::IrcWidget ui;
+ QHash<QString, ChannelWidget *> buffers;
+
+ ChannelWidget * getBuffer(QString net, QString buf);
+};
#endif
<ui version="4.0" >
<class>ChannelWidget</class>
<widget class="QWidget" name="ChannelWidget" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>713</width>
+ <height>519</height>
+ </rect>
+ </property>
<property name="sizePolicy" >
<sizepolicy>
<hsizetype>3</hsizetype>
<number>6</number>
</property>
<item>
- <widget class="QLineEdit" name="topicEdit" />
+ <widget class="QLineEdit" name="topicEdit" >
+ <property name="focusPolicy" >
+ <enum>Qt::ClickFocus</enum>
+ </property>
+ <property name="readOnly" >
+ <bool>true</bool>
+ </property>
+ </widget>
</item>
<item>
<widget class="QToolButton" name="chanSettingsButton" >
<verstretch>0</verstretch>
</sizepolicy>
</property>
+ <property name="font" >
+ <font>
+ <family>Monospace</family>
+ </font>
+ </property>
</widget>
<widget class="QTreeWidget" name="nickTree" >
<property name="sizePolicy" >
</layout>
</widget>
<tabstops>
+ <tabstop>inputEdit</tabstop>
+ <tabstop>ownNick</tabstop>
+ <tabstop>nickTree</tabstop>
<tabstop>topicEdit</tabstop>
<tabstop>chanSettingsButton</tabstop>
+ <tabstop>chatWidget</tabstop>
</tabstops>
<resources/>
<connections/>
#include "guiproxy.h"
#include "util.h"
+#include "message.h"
void GUIProxy::recv(CoreSignal sig, QVariant arg1, QVariant arg2, QVariant arg3) {
//qDebug() << "[GUI] Received signal:" << sig <<arg1<<arg2<<arg3;
case CS_CORE_STATE: emit csCoreState(arg1); break;
case CS_UPDATE_GLOBAL_DATA: emit csUpdateGlobalData(arg1.toString(), arg2); break;
//case CS_GLOBAL_DATA_CHANGED: emit csGlobalDataChanged(arg1.toString()); break;
- case CS_SEND_MESSAGE: emit csSendMessage(arg1.toString(), arg2.toString(), arg3.toString()); break;
+ case CS_SEND_MESSAGE: emit csSendMessage(arg1.toString(), arg2.toString(), arg3.value<Message>()); break;
case CS_SEND_STATUS_MSG: emit csSendStatusMsg(arg1.toString(), arg2.toString()); break;
+ case CS_SET_TOPIC: emit csSetTopic(arg1.toString(), arg2.toString(), arg3.toString()); break;
+ case CS_SET_NICKS: emit csSetNicks(arg1.toString(), arg2.toString(), arg3.toStringList()); break;
default: qWarning() << "Unknown signal in GUIProxy::recv: " << sig;
}
#define _GUIPROXY_H_
#include "proxy_common.h"
+#include "message.h"
#include <QObject>
#include <QVariant>
GUIProxy();
public slots:
- inline void gsUserInput(QString s) { send(GS_USER_INPUT, s); }
- inline void gsRequestConnect(QStringList networks) { send(GS_REQUEST_CONNECT, networks); }
+ inline void gsUserInput(QString net, QString buf, QString msg) { send(GS_USER_INPUT, net, buf, msg); }
+ inline void gsRequestConnect(QStringList networks) { send(GS_REQUEST_CONNECT, networks); }
void connectToCore(QString host, quint16 port);
void disconnectFromCore();
signals:
void csCoreState(QVariant);
- void csSendMessage(QString, QString, QString);
+ void csSendMessage(QString, QString, Message);
void csSendStatusMsg(QString, QString);
void csUpdateGlobalData(QString key, QVariant data);
void csGlobalDataChanged(QString key);
+ void csSetTopic(QString, QString, QString);
+ void csSetNicks(QString, QString, QStringList);
void coreConnected();
void coreDisconnected();
--- /dev/null
+<ui version="4.0" >
+ <class>IrcWidget</class>
+ <widget class="QWidget" name="IrcWidget" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>733</width>
+ <height>531</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QTabWidget" name="tabWidget" >
+ <property name="tabPosition" >
+ <enum>QTabWidget::South</enum>
+ </property>
+ <property name="tabShape" >
+ <enum>QTabWidget::Rounded</enum>
+ </property>
+ <property name="currentIndex" >
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="tab" >
+ <attribute name="title" >
+ <string>No connection</string>
+ </attribute>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
move(s.value("MainWinPos", QPoint(50, 50)).toPoint());
s.endGroup();
- workspace = new QWorkspace(this);
- setCentralWidget(workspace);
- //ChannelWidget *cw = new ChannelWidget(this);
- //workspace->addWindow(cw);
- //setCentralWidget(cw);
+ //workspace = new QWorkspace(this);
+ //setCentralWidget(workspace);
statusBar()->showMessage(tr("Waiting for core..."));
setEnabled(false);
show();
setupMenus();
//identitiesAct = settingsMenu->addAction(QIcon(":/default/identity.png"), tr("&Identities..."), serverListDlg, SLOT(editIdentities()));
//showServerList();
- ChannelWidget *cw = new ChannelWidget(this);
- //setCentralWidget(cw);
- workspace->addWindow(cw);
- cw->showMaximized();
- //setEnabled(true);
+ IrcWidget *cw = new IrcWidget(this);
+ setCentralWidget(cw);
+ //workspace->addWindow(cw);
+ //cw->showMaximized();
statusBar()->showMessage(tr("Ready."));
- //QSystemTrayIcon *systray = new QSystemTrayIcon(QIcon(":/qirc-icon.png"));
- //systray->showMessage("Quassel", "Started!");
+ cw->setFocus();
}
void MainWin::syncToCore() {
#include "global.h"
#include "logger.h"
#include "core.h"
+#include "message.h"
-#include <QString>
-#include <QStringList>
+#include <QtCore>
#include <QDomDocument>
extern void messageHandler(QtMsgType type, const char *msg);
Global::Global() {
if(global) qFatal("Trying to instantiate more than one Global object!");
qInstallMsgHandler(messageHandler);
+ qRegisterMetaType<Message>("Message");
//initIconMap();
}
};
enum CoreSignal { CS_CORE_STATE, CS_SEND_MESSAGE, CS_SEND_STATUS_MSG, CS_UPDATE_GLOBAL_DATA,
+ CS_SET_TOPIC, CS_SET_NICKS,
};
-SET(network_SRCS server.cpp buffer.cpp)
-SET(network_HDRS )
+SET(network_SRCS server.cpp buffer.cpp message.cpp)
+SET(network_HDRS message.h)
SET(network_MOCS server.h buffer.h)
QT4_WRAP_CPP(_MOC ${network_MOCS})
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+
+#include "buffer.h"
+
+Buffer::Buffer(QString n) {
+ _name = n;
+
+
+
+}
+
class Buffer : public QObject {
Q_OBJECT
+ public:
+ Buffer(QString name);
+ QString name() { return _name; }
+ QString topic() { return _topic; }
+ public slots:
+ //void setNicks(QStringList nicks);
+ //void addNick(QString nick);
+ //void removeNick(QString nick);
+
+ signals:
+
+ private:
+ QString _name;
+ QString _topic;
+ QStringList nicks;
};
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
-/* OBSOLETE CODE! */
-
#include "message.h"
-#include <QtDebug>
-
-extern BuiltinCmd builtins[];
-
-recvHandlerType Message::defaultRecvHandler;
-sendHandlerType Message::defaultSendHandler;
-QHash<QString, CmdType> Message::cmdTypes;
-
-Message::Message(Server *srv, Buffer *buf, QString _cmd, QString _prefix, QStringList _params)
- : server(srv), buffer(buf), cmd(_cmd), prefix(_prefix), params(_params) {
-
- // Check if it's a registered cmd (or a numeric reply with a custom entry)
- if(cmdTypes.contains(cmd)) {
- CmdType c = cmdTypes[cmd];
- recvHandler = ( c.recvHandler ? c.recvHandler : defaultRecvHandler);
- sendHandler = ( c.sendHandler ? c.sendHandler : defaultSendHandler);
- cmdCode = - c.cmdCode; // named commands have a _negative_ code!
- } else {
- int t = cmd.toInt();
- if(t) {
- cmdCode = t;
- recvHandler = defaultRecvHandler;
- sendHandler = defaultSendHandler;
- } else {
- // Unknown cmd!
- qWarning() << "Unknown command: " << cmd;
- cmdCode = 0;
- }
- }
-}
-
-void Message::init(recvHandlerType _r, sendHandlerType _s) {
- defaultRecvHandler = _r;
- defaultSendHandler = _s;
-
- // Register builtin commands
- for(int i = 0; ; i++) {
- if(builtins[i].cmd.isEmpty()) break;
- CmdType c;
- c.cmdCode = builtins[i].cmdCode;
- c.cmd = builtins[i].cmd.toUpper();
- c.cmdDescr = builtins[i].cmdDescr;
- c.args = builtins[i].args;
- c.argsDescr = builtins[i].argsDescr;
- c.recvHandler = ( builtins[i].recvHandler ? builtins[i].recvHandler : defaultRecvHandler);
- c.sendHandler = ( builtins[i].sendHandler ? builtins[i].sendHandler : defaultSendHandler);
- cmdTypes.insert(c.cmd, c);
- }
-
-}
-
-recvHandlerType Message::getRecvHandler() {
- CmdType c = cmdTypes[cmd];
- if(c.recvHandler) return c.recvHandler;
- qDebug() << "No recvHandler defined for " << cmd << "!";
- return 0;
-}
+#include <QDataStream>
-sendHandlerType Message::getSendHandler() {
- CmdType c = cmdTypes[cmd];
- if(c.sendHandler) return c.sendHandler;
- qDebug() << "No sendHandler defined for " << cmd << "!";
- return 0;
+QDataStream &operator<<(QDataStream &out, const Message &msg) {
+ out << (quint8)msg.type << (quint8)msg.flags << msg.sender << msg.msg;
+ return out;
}
-/** This parses a raw string as sent by the server and constructs a message object which is then returned.
- */
-Message * Message::createFromServerString(Server *srv, QString msg) {
- if(msg.isEmpty()) {
- qWarning() << "Received empty message from server!";
- return 0;
- }
- QString prefix;
- QString cmd;
- QStringList params;
- if(msg[0] == ':') {
- msg.remove(0,1);
- prefix = msg.section(' ', 0, 0);
- msg = msg.section(' ', 1);
- }
- cmd = msg.section(' ', 0, 0).toUpper();
- msg = msg.section(' ', 1);
- QString left = msg.section(':', 0, 0);
- QString trailing = msg.section(':', 1);
- if(!left.isEmpty()) {
- params << left.split(' ', QString::SkipEmptyParts);
- }
- if(!trailing.isEmpty()) {
- params << trailing;
- }
- return new Message(srv, 0, cmd, prefix, params);
- //qDebug() << "prefix: " << prefix << " cmd: " << cmd << " params: " << params;
+QDataStream &operator>>(QDataStream &in, Message &msg) {
+ quint8 t, f;
+ in >> t >> f >> msg.sender >> msg.msg;
+ msg.type = (Message::Type)t;
+ msg.flags = (Message::Flags)f;
+ return in;
}
#ifndef _MESSAGE_H_
#define _MESSAGE_H_
-#include <QHash>
-#include <QString>
-#include <QStringList>
+#include <QtCore>
-class Server;
-class Buffer;
-class Message;
+struct Message {
-typedef void (*sendHandlerType)(Message *); // handler for commands sent by the user
-typedef void (*recvHandlerType)(Message *); // handler for incoming messages
+ /** The different types a message can have for display */
+ enum Type { Msg, Notice, Action, Nick, Mode, Join, Part, Quit, Kick, Kill, Server, Info, Error };
+ enum Flags { None = 0, Self = 1, Highlight = 2 };
-/**
- * This contains information that depends (solely) on the message type, such as the handler function and help texts.
- * Most of these are defined at compile time, but more may be added at runtime.
- */
-struct CmdType {
- int cmdCode;
- QString cmd;
- QString cmdDescr;
- QString args;
- QString argsDescr;
- recvHandlerType recvHandler;
- sendHandlerType sendHandler;
+ Type type;
+ Flags flags;
+ QString sender;
+ QString msg;
-};
-
-/**
- *
-*/
-class Message {
- public:
- Message(Server *server, Buffer *buffer, QString cmd, QString prefix, QStringList args = QStringList());
-
- virtual ~Message() {};
-
- static void init(recvHandlerType defaultRevcHandler, sendHandlerType defaultSendHandler);
- static Message * createFromServerString(Server *server, QString srvMsg);
- //static Message * createFromUserString(Server *server, Buffer *buffer, QString usrMsg);
- //static registerCmd();
- //static unregisterCmd();
+ Message(QString _msg = "", QString _sender = "", Type _type = Msg, Flags _flags = None)
+ : msg(_msg), sender(_sender), type(_type), flags(_flags) {};
- inline Server * getServer() { return server; }
- inline Buffer * getBuffer() { return buffer; }
- inline int getCmdCode() { return cmdCode; }
- inline QString getPrefix() { return prefix; }
- inline QString getCmd() { return cmd; }
- inline QStringList getParams() { return params; }
- inline recvHandlerType getRecvHandler();
- inline sendHandlerType getSendHandler();
-
- protected:
- Server *server;
- Buffer *buffer;
- int cmdCode;
- QString prefix;
- QString cmd;
- QStringList params;
- recvHandlerType recvHandler;
- sendHandlerType sendHandler;
- static recvHandlerType defaultRecvHandler;
- static sendHandlerType defaultSendHandler;
-
- static QHash<QString, CmdType> cmdTypes;
};
-
-/** This is only used to have a nice way for defining builtin commands.
- * We create an array of these in builtin_cmds.cpp and read this to fill our
- * command hash.
- */
-struct BuiltinCmd {
- int cmdCode;
- QString cmd;
- QString cmdDescr;
- QString args;
- QString argsDescr;
- recvHandlerType recvHandler;
- sendHandlerType sendHandler;
-};
+Q_DECLARE_METATYPE(Message)
#endif
#include "global.h"
#include "server.h"
#include "cmdcodes.h"
+#include "message.h"
#include <QMetaObject>
void Server::socketHasData() {
while(socket.canReadLine()) {
QString s = socket.readLine().trimmed();
- //qDebug() << "Read: " << s;
+ qDebug() << "Read: " << s;
emit recvRawServerMsg(s);
//Message *msg = Message::createFromServerString(this, s);
handleServerMsg(s);
}
void Server::socketError( QAbstractSocket::SocketError err ) {
- qDebug() << "Socket Error!";
+ //qDebug() << "Socket Error!";
//emit error(err);
}
}
void Server::socketDisconnected( ) {
- qDebug() << "Socket disconnected!";
- //emit disconnected();
+ //qDebug() << "Socket disconnected!";
+ emit disconnected();
}
void Server::socketStateChanged(QAbstractSocket::SocketState state) {
- qDebug() << "Socket state changed: " << state;
+ //qDebug() << "Socket state changed: " << state;
}
void Server::userInput(QString net, QString buf, QString msg) {
- putRawLine(msg);
+ if(net != network) return; // not me!
+ msg = msg.trimmed(); // remove whitespace from start and end
+ if(msg.isEmpty()) return;
+ if(!msg.startsWith('/')) {
+ msg = QString("/SAY ") + msg;
+ }
+ handleUserMsg(buf, msg);
}
void Server::putRawLine(QString s) {
// Now we try to find a handler for this message. BTW, I do love the Trolltech guys ;-)
QString hname = cmd.toLower();
hname[0] = hname[0].toUpper();
- hname = "handle" + hname + "FromServer";
+ hname = "handleServer" + hname;
if(!QMetaObject::invokeMethod(this, hname.toAscii(), Q_ARG(QString, prefix), Q_ARG(QStringList, params))) {
// Ok. Default handler it is.
- defaultHandlerForServer(cmd, prefix, params);
+ defaultServerHandler(cmd, prefix, params);
}
} catch(Exception e) {
- emit sendStatusMsg(e.msg());
+ emit sendMessage("", Message(e.msg(), "", Message::Error));
}
}
-void Server::defaultHandlerForServer(QString cmd, QString prefix, QStringList params) {
+void Server::defaultServerHandler(QString cmd, QString prefix, QStringList params) {
uint num = cmd.toUInt();
if(num) {
- emit sendMessage("", cmd + " " + params.join(" "));
+ if(params.count() > 0) {
+ if(params[0] == currentNick) params.removeFirst(); // remove nick if it is first arg
+ else qWarning((QString("First param NOT nick: %1:%2 %3").arg(prefix).arg(cmd).arg(params.join(" "))).toAscii());
+ }
+ // A lot of server messages don't really need their own handler because they don't do much.
+ // Catch and handle these here.
+ switch(num) {
+ // Welcome, status, info messages. Just display these.
+ case 2: case 3: case 4: case 5: case 251: case 252: case 253: case 254: case 255: case 372: case 375:
+ emit sendMessage("", Message(params.join(" "), prefix, Message::Server));
+ break;
+ // Ignore these commands.
+ case 376:
+ break;
+
+ // Everything else will be marked in red, so we can add them somewhere.
+ default:
+ emit sendMessage("", Message(cmd + " " + params.join(" "), prefix, Message::Error));
+ }
+ //qDebug() << prefix <<":"<<cmd<<params;
} else {
- emit sendMessage("", QString("Unknown: ") + cmd + " " + params.join(" "));
+ emit sendMessage("", Message(QString("Unknown: ") + cmd + " " + params.join(" "), prefix, Message::Error));
+ //qDebug() << prefix <<":"<<cmd<<params;
+ }
+}
+
+void Server::handleUserMsg(QString bufname, QString usrMsg) {
+ try {
+ Buffer *buffer = 0;
+ if(!bufname.isEmpty()) {
+ Q_ASSERT(buffers.contains(bufname));
+ buffer = buffers[bufname];
+ }
+ QString cmd = usrMsg.section(' ', 0, 0).remove(0, 1).toUpper();
+ QString msg = usrMsg.section(' ', 1).trimmed();
+ QString hname = cmd.toLower();
+ hname[0] = hname[0].toUpper();
+ hname = "handleUser" + hname;
+ if(!QMetaObject::invokeMethod(this, hname.toAscii(), Q_ARG(QString, msg), Q_ARG(Buffer*, buffer))) {
+ // Ok. Default handler it is.
+ defaultUserHandler(cmd, msg, buffer);
+ }
+ } catch(Exception e) {
+ emit sendMessage("", Message(e.msg(), "", Message::Error));
}
}
-void Server::handleUserMsg(QString usrMsg) {
+void Server::defaultUserHandler(QString cmd, QString msg, Buffer *buf) {
+ emit sendMessage("", Message(QString("Error: %1 %2").arg(cmd).arg(msg), "", Message::Error));
+
+}
+
+/**********************************************************************************/
+
+/*
+void Server::handleUser(QString msg, Buffer *buf) {
+
+
+}
+*/
+
+void Server::handleUserJoin(QString msg, Buffer *buf) {
+ putCmd("JOIN", QStringList(msg));
+
+}
+
+void Server::handleUserQuote(QString msg, Buffer *buf) {
+ putRawLine(msg);
+}
+void Server::handleUserSay(QString msg, Buffer *buf) {
+ if(!buf) return; // server buffer
+ QStringList params;
+ params << buf->name() << msg;
+ putCmd("PRIVMSG", params);
}
-void Server::handleNoticeFromServer(QString prefix, QStringList params) {
- sendMessage("", params.join(" "));
+/**********************************************************************************/
+void Server::handleServerJoin(QString prefix, QStringList params) {
+ Q_ASSERT(params.count() == 1);
+ QString bufname = params[0];
+ if(!buffers.contains(bufname)) {
+ Buffer *buf = new Buffer(bufname);
+ buffers[bufname] = buf;
+ }
+ // handle user joins!
+}
+void Server::handleServerNotice(QString prefix, QStringList params) {
+ Message msg(params[1], prefix, Message::Notice);
+ if(prefix == currentServer) emit sendMessage("", Message(params[1], prefix, Message::Server));
+ else emit sendMessage("", Message(params[1], prefix, Message::Notice));
}
-void Server::handlePingFromServer(QString prefix, QStringList params) {
+void Server::handleServerPing(QString prefix, QStringList params) {
putCmd("PONG", params);
}
+void Server::handleServerPrivmsg(QString prefix, QStringList params) {
+ emit sendMessage(params[0], Message(params[1], prefix, Message::Msg));
+
+}
+
+/* RPL_WELCOME */
+void Server::handleServer001(QString prefix, QStringList params) {
+ currentServer = prefix;
+ currentNick = params[0];
+ emit sendMessage("", Message(params[1], prefix, Message::Server));
+}
+
+/* RPL_NOTOPIC */
+void Server::handleServer331(QString prefix, QStringList params) {
+ if(params[0] == currentNick) params.removeFirst();
+ emit setTopic(network, params[0], "");
+}
+
+/* RPL_TOPIC */
+void Server::handleServer332(QString prefix, QStringList params) {
+ if(params[0] == currentNick) params.removeFirst();
+ emit setTopic(network, params[0], params[1]);
+}
+
+/***********************************************************************************/
+
/* Exception classes for message handling */
Server::ParseError::ParseError(QString cmd, QString prefix, QStringList params) {
_msg = QString("Command Parse Error: ") + cmd + params.join(" ");
#include "global.h"
#include "buffer.h"
+#include "message.h"
#define DEFAULT_PORT 6667
-/*! \file */
-/*! \class Server
+/*!
* This is a server object, managing a single connection to an IRC server, handling the associated channels and so on.
* We have this running in its own thread mainly to not block other server objects or the core if something goes wrong,
* e.g. if some scripts starts running wild...
signals:
void recvRawServerMsg(QString);
void sendStatusMsg(QString);
- void sendMessage(QString buffer, QString msg);
+ void sendMessage(QString buffer, Message msg);
void disconnected();
+ void setTopic(QString network, QString buffer, QString topic);
+ void setNicks(QString network, QString buffer, QStringList nicks);
+
+
private slots:
void run();
void socketHasData();
void socketStateChanged(QAbstractSocket::SocketState);
/* Message Handlers */
- /* handleXxxxFromServer(QString prefix, QStringList params); */
- void handleNoticeFromServer(QString, QStringList);
- void handlePingFromServer(QString, QStringList);
- void defaultHandlerForServer(QString cmd, QString prefix, QStringList params);
+ /* handleUser(QString, Buffer *) */
+ void handleUserJoin(QString, Buffer *);
+ void handleUserQuote(QString, Buffer *);
+ void handleUserSay(QString, Buffer *);
+
+
+ /* handleServer(QString, QStringList); */
+ void handleServerJoin(QString, QStringList);
+ void handleServerNotice(QString, QStringList);
+ void handleServerPing(QString, QStringList);
+ void handleServerPrivmsg(QString, QStringList);
+
+ void handleServer001(QString, QStringList); // RPL_WELCOME
+ void handleServer331(QString, QStringList); // RPL_NOTOPIC
+ void handleServer332(QString, QStringList); // RPL_TOPIC
+
+ void defaultServerHandler(QString cmd, QString prefix, QStringList params);
+ void defaultUserHandler(QString cmd, QString msg, Buffer *buf);
private:
QString network;
QTcpSocket socket;
QHash<QString, Buffer*> buffers;
+ QString currentNick;
+ QString currentServer;
+
void handleServerMsg(QString rawMsg);
- void handleUserMsg(QString usrMsg);
+ void handleUserMsg(QString buffer, QString usrMsg);
class ParseError : public Exception {
public: