From e368a1672c4f917bfa6adb52dae3b5ebfcd0db18 Mon Sep 17 00:00:00 2001 From: Manuel Nickschas Date: Wed, 18 Oct 2006 14:47:55 +0000 Subject: [PATCH] Big refactoring completed. Everything prepared for the separation of core and gui. Building separate components does not work yet, but the monolithic build should be able to go online again. Note that there are more significant changes in the framework to expect. --- CMakeLists.txt | 20 +++-- core/CMakeLists.txt | 4 +- core/core.cpp | 14 +++- core/core.h | 6 +- gui/CMakeLists.txt | 6 +- gui/channelwidget.cpp | 13 +++- gui/channelwidget.h | 1 + gui/guiproxy.cpp | 32 ++++++++ gui/guiproxy.h | 57 ++++++++++++++ gui/mainwin.cpp | 8 +- gui/serverlist.cpp | 6 +- main/CMakeLists.txt | 6 ++ main/logger.cpp | 51 +++++++++++++ main/logger.h | 41 ++++++++++ main/main_core.cpp | 31 +++++--- main/main_gui.cpp | 57 ++++++++++++++ main/main_mono.cpp | 34 ++++----- main/proxy_common.h | 33 ++++++++ {core => main}/quassel.cpp | 34 ++++++++- {core => main}/quassel.h | 34 ++++++--- network/CMakeLists.txt | 4 +- network/builtin_cmds.cpp | 2 +- network/message.cpp | 2 + network/server.cpp | 153 +++++++++++++++++++++++++------------ network/server.h | 53 +++++-------- 25 files changed, 550 insertions(+), 152 deletions(-) create mode 100644 gui/guiproxy.cpp create mode 100644 gui/guiproxy.h create mode 100644 main/CMakeLists.txt create mode 100644 main/logger.cpp create mode 100644 main/logger.h create mode 100644 main/main_gui.cpp create mode 100644 main/proxy_common.h rename {core => main}/quassel.cpp (75%) rename {core => main}/quassel.h (76%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 959790e9..77c3b413 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,8 +26,9 @@ ENDIF(NOT BUILD_MONO AND NOT BUILD_CORE AND NOT BUILD_GUI) # Define files SET(quassel_mono_SRCS main/main_mono.cpp) SET(quassel_core_SRCS main/main_core.cpp) +#SET(quassel_gui_SRCS main/main_gui.cpp ${common_SRCS}) SET(quassel_RCCS images/icons.qrc) -SET(quassel_DIRS gui core network) +SET(quassel_DIRS main gui core network) # Build correct absolute paths for subdirs to include SET(SDIRS "") @@ -45,13 +46,15 @@ SET(QT_USE_QTNETWORK true) SET(QT_DONT_USE_QTGUI true) # This is added later if GUI is requested INCLUDE(${QT_USE_FILE}) -ADD_SUBDIRECTORY(network) -ADD_SUBDIRECTORY(core) +ADD_SUBDIRECTORY(main) QT4_ADD_RESOURCES(_RCCS ${quassel_RCCS}) IF(BUILD_CORE) + ADD_DEFINITIONS(-DBUILD_CORE) + ADD_SUBDIRECTORY(network) + ADD_SUBDIRECTORY(core) ADD_EXECUTABLE(quasselcore ${quassel_core_SRCS} ${_RCCS}) - TARGET_LINK_LIBRARIES(quasselcore core network ${QT_LIBRARIES}) + TARGET_LINK_LIBRARIES(quasselcore core network main ${QT_LIBRARIES}) ENDIF(BUILD_CORE) IF(BUILD_GUI OR BUILD_MONO) # OK, now we need QtGui! @@ -62,14 +65,19 @@ IF(BUILD_GUI OR BUILD_MONO) # OK, now we need QtGui! INCLUDE(${QT_USE_FILE}) IF(BUILD_MONO) + ADD_DEFINITIONS(-DBUILD_MONO) ADD_SUBDIRECTORY(gui) + ADD_SUBDIRECTORY(network) + ADD_SUBDIRECTORY(core) ADD_EXECUTABLE(quassel ${quassel_mono_SRCS} ${_RCCS}) - TARGET_LINK_LIBRARIES(quassel gui core network ${QT_LIBRARIES}) + TARGET_LINK_LIBRARIES(quassel gui core network main ${QT_LIBRARIES}) ENDIF(BUILD_MONO) IF(BUILD_GUI) + ADD_DEFINITIONS(-DBUILD_GUI) ADD_SUBDIRECTORY(gui) - MESSAGE(FATAL_ERROR "Client mode not yet supported.") + ADD_EXECUTABLE(quasselgui ${quassel_gui_SRCS} ${_RCCS}) + TARGET_LINK_LIBRARIES(quasselgui gui main ${QT_LIBRARIES}) ENDIF(BUILD_GUI) ENDIF(BUILD_GUI OR BUILD_MONO) diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index c2fa0b62..2d5a7061 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -1,6 +1,6 @@ -SET(core_SRCS logger.cpp quassel.cpp core.cpp) +SET(core_SRCS core.cpp) SET(core_HDRS ) -SET(core_MOCS logger.h core.h quassel.h) +SET(core_MOCS core.h) QT4_WRAP_CPP(_MOC ${core_MOCS}) ADD_LIBRARY(core ${_MOC} ${core_SRCS} ${core_HDRS}) diff --git a/core/core.cpp b/core/core.cpp index f5c06fd6..b7f0e39c 100644 --- a/core/core.cpp +++ b/core/core.cpp @@ -20,12 +20,18 @@ #include "core.h" #include "server.h" +#include "quassel.h" #include -void Core::init() { - Server::init(); - +Core * Core::init() { + if(core) return core; + QSettings s; + VarMap identities = s.value("Network/Identities").toMap(); + qDebug() << identities; + //VarMap networks = s.value("Network/ + quassel->putData("Identities", identities); + return new Core(); } void Core::run() { @@ -54,3 +60,5 @@ void Core::storeIdentities(VarMap identities) { QSettings s; s.setValue("Network/Identities", identities); } + +Core *core; diff --git a/core/core.h b/core/core.h index 7cfecece..f9cd9f16 100644 --- a/core/core.h +++ b/core/core.h @@ -27,14 +27,12 @@ #include "server.h" -typedef QMap VarMap; - class Core : public QThread { Q_OBJECT public: - static void init(); + static Core * init(); static VarMap loadNetworks(); static void storeNetworks(VarMap); static VarMap loadIdentities(); @@ -54,4 +52,6 @@ class Core : public QThread { }; +extern Core *core; + #endif diff --git a/gui/CMakeLists.txt b/gui/CMakeLists.txt index 35eebf6d..b622620a 100644 --- a/gui/CMakeLists.txt +++ b/gui/CMakeLists.txt @@ -1,12 +1,12 @@ -SET(gui_SRCS channelwidget.cpp mainwin.cpp serverlist.cpp) +SET(gui_SRCS channelwidget.cpp mainwin.cpp serverlist.cpp guiproxy.cpp) SET(gui_HDRS ) -SET(gui_MOCS channelwidget.h mainwin.h serverlist.h) +SET(gui_MOCS channelwidget.h mainwin.h serverlist.h guiproxy.h) SET(gui_UICS channelwidget.ui identitiesdlg.ui identitieseditdlg.ui networkeditdlg.ui nickeditdlg.ui serverlistdlg.ui) QT4_WRAP_UI(_UIC ${gui_UICS}) QT4_WRAP_CPP(_MOC ${gui_MOCS}) -# We need to workaround a dependency bug with out-of-source builds... +# We need to work around a dependency bug with out-of-source builds... SET_SOURCE_FILES_PROPERTIES(${gui_SRCS} PROPERTIES OBJECT_DEPENDS "${_UIC}") INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) diff --git a/gui/channelwidget.cpp b/gui/channelwidget.cpp index 320cef34..71a40755 100644 --- a/gui/channelwidget.cpp +++ b/gui/channelwidget.cpp @@ -19,6 +19,7 @@ ***************************************************************************/ #include "channelwidget.h" +#include "guiproxy.h" #include #include @@ -40,14 +41,22 @@ ChannelWidget::ChannelWidget(QWidget *parent) : QWidget(parent) { */ //connect(&core, SIGNAL(outputLine( const QString& )), ui.textBrowser, SLOT(insertPlainText(const QString &))); //connect(ui.lineEdit, SIGNAL( - connect(&core, SIGNAL(outputLine( const QString& )), ui.textBrowser, SLOT(insertPlainText(const QString &))); + connect(&core, SIGNAL(outputLine( const QString& )), this, SLOT(lineReceived(const QString &))); connect(ui.lineEdit, SIGNAL(returnPressed()), this, SLOT(enterPressed())); connect(this, SIGNAL(inputLine( const QString& )), &core, SLOT(inputLine( const QString& ))); + + connect(this, SIGNAL(inputLine(QString)), guiProxy, SLOT(gsUserInput(QString))); + core.start(); - core.connectToIrc("irc.quakenet.org", 6668); + core.connectToIrc("irc.moep.net", 6668); } void ChannelWidget::enterPressed() { emit inputLine(ui.lineEdit->text()); ui.lineEdit->clear(); } + +void ChannelWidget::lineReceived(QString s) { + ui.textBrowser->insertPlainText(s + "\n"); + ui.textBrowser->ensureCursorVisible(); +} diff --git a/gui/channelwidget.h b/gui/channelwidget.h index a9f768f6..b5cc2d49 100644 --- a/gui/channelwidget.h +++ b/gui/channelwidget.h @@ -36,6 +36,7 @@ class ChannelWidget : public QWidget { private slots: void enterPressed(); + void lineReceived(QString); private: Ui::ChannelWidget ui; diff --git a/gui/guiproxy.cpp b/gui/guiproxy.cpp new file mode 100644 index 00000000..4da47a48 --- /dev/null +++ b/gui/guiproxy.cpp @@ -0,0 +1,32 @@ +/*************************************************************************** + * Copyright (C) 2005/06 by The Quassel Team * + * devel@quassel-irc.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "guiproxy.h" + +GUIProxy * GUIProxy::init() { + if(guiProxy) return guiProxy; + return new GUIProxy; +} + +void GUIProxy::gsUserInput(QString s) { + send(GS_USER_INPUT, s); +} + +GUIProxy *guiProxy; diff --git a/gui/guiproxy.h b/gui/guiproxy.h new file mode 100644 index 00000000..37bfd149 --- /dev/null +++ b/gui/guiproxy.h @@ -0,0 +1,57 @@ +/*************************************************************************** + * Copyright (C) 2005/06 by The Quassel Team * + * devel@quassel-irc.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _GUIPROXY_H_ +#define _GUIPROXY_H_ + +#include "../main/proxy_common.h" + +#include +#include + +/** This class is the GUI side of the proxy. The GUI connects its signals and slots to it, + * and the calls are marshalled and sent to (or received and unmarshalled from) the CoreProxy. + * The connection function is defined in main/main_gui.cpp or main/main_mono.cpp. + */ +class GUIProxy : public QObject { + Q_OBJECT + + private: + void send(GUISignal, QVariant arg1 = QVariant(), QVariant arg2 = QVariant(), QVariant arg3 = QVariant()); + void recv(CoreSignal, QVariant arg1 = QVariant(), QVariant arg2 = QVariant(), QVariant arg3 = QVariant()); + + public: + static GUIProxy * init(); + + public slots: + void gsUserInput(QString); + + + signals: + void psCoreMessage(QString); + + +}; + +extern GUIProxy *guiProxy; + + + +#endif diff --git a/gui/mainwin.cpp b/gui/mainwin.cpp index 92316907..d67309d4 100644 --- a/gui/mainwin.cpp +++ b/gui/mainwin.cpp @@ -32,11 +32,11 @@ MainWin::MainWin() : QMainWindow() { setWindowTitle("Quassel IRC"); setWindowIcon(QIcon(":/default/tux.png")); setWindowIconText("Quassel IRC"); - workspace = new QWorkspace(this); - setCentralWidget(workspace); + //workspace = new QWorkspace(this); + //setCentralWidget(workspace); ChannelWidget *cw = new ChannelWidget(this); - workspace->addWindow(cw); - //setCentralWidget(cw); + //workspace->addWindow(cw); + setCentralWidget(cw); serverListDlg = new ServerListDlg(this); serverListDlg->setVisible(serverListDlg->showOnStartup()); //showServerList(); diff --git a/gui/serverlist.cpp b/gui/serverlist.cpp index b194c606..f6192501 100644 --- a/gui/serverlist.cpp +++ b/gui/serverlist.cpp @@ -117,7 +117,8 @@ void ServerListDlg::loadIdentities() { //QSettings s; //s.beginGroup("Identities"); //identities = s.value("Network/Identities").toMap(); - identities = GuiProxy::loadIdentities(); + //identities = GuiProxy::loadIdentities(); + identities = quassel->getData("Identities").toMap(); while(!identities.contains("Default")) { identities = VarMap(); editIdentities(); @@ -127,7 +128,8 @@ void ServerListDlg::loadIdentities() { void ServerListDlg::storeIdentities() { //QSettings s; //s.setValue("Network/Identities", identities); - GuiProxy::storeIdentities(identities); + //GuiProxy::storeIdentities(identities); + quassel->putData("Identities", identities); } void ServerListDlg::editIdentities() { diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt new file mode 100644 index 00000000..268a0276 --- /dev/null +++ b/main/CMakeLists.txt @@ -0,0 +1,6 @@ +SET(main_SRCS quassel.cpp logger.cpp) +SET(main_HDRS ) +SET(main_MOCS quassel.h logger.h) + +QT4_WRAP_CPP(_MOC ${main_MOCS}) +ADD_LIBRARY(main ${_MOC} ${main_SRCS} ${main_HDRS}) diff --git a/main/logger.cpp b/main/logger.cpp new file mode 100644 index 00000000..cad728c2 --- /dev/null +++ b/main/logger.cpp @@ -0,0 +1,51 @@ +/*************************************************************************** + * Copyright (C) 2005 by The Quassel Team * + * devel@quassel-irc.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "quassel.h" +#include "logger.h" + +#include + + + +Logger::~Logger() { + //qInstallMsgHandler(0); +} + +void messageHandler(QtMsgType type, const char *msg) { + switch (type) { + case QtDebugMsg: + std::cerr << "[DEBUG] " << msg << "\n"; + break; + case QtWarningMsg: + std::cerr << "[WARNING] " << msg << "\n"; + break; + case QtCriticalMsg: + std::cerr << "[CRITICAL] " << msg << "\n"; + break; + case QtFatalMsg: + std::cerr << "[FATAL] " << msg << "\n"; + abort(); // deliberately core dump + } +} + +Logger::Logger() { + //qInstallMsgHandler(messageHandler); +} diff --git a/main/logger.h b/main/logger.h new file mode 100644 index 00000000..ba8eba42 --- /dev/null +++ b/main/logger.h @@ -0,0 +1,41 @@ +/*************************************************************************** + * Copyright (C) 2005 by The Quassel Team * + * devel@quassel-irc.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _LOGGER_H_ +#define _LOGGER_H_ + +#include + +class Logger : public QObject { + Q_OBJECT + + public: + Logger(); + virtual ~Logger(); + + + + private: + //void messageHandler(QtMsgType type, const char *msg); +}; + + + +#endif diff --git a/main/main_core.cpp b/main/main_core.cpp index 25264857..b7d33a43 100644 --- a/main/main_core.cpp +++ b/main/main_core.cpp @@ -22,29 +22,36 @@ #include #include "quassel.h" -#include "logger.h" -#include "proxy.h" +#include "core.h" int main(int argc, char **argv) { - - Quassel::init(); - Logger *logger = new Logger(); - Quassel::setLogger(logger); - QCoreApplication app(argc, argv); - QCoreApplication::setOrganizationDomain("quassel-irc.org"); QCoreApplication::setApplicationName("Quassel IRC"); QCoreApplication::setOrganizationName("The Quassel Team"); - return app.exec(); + Quassel::runMode = Quassel::CoreOnly; + quassel = Quassel::init(); + core = Core::init(); + //coreProxy = CoreProxy::init(); + + //Logger *logger = new Logger(); + //Quassel::setLogger(logger); + + int exitCode = app.exec(); + delete quassel; + return exitCode; } -QVariant proxyConnect(uint func, QVariant arg) { +Core *core = 0; + +//GUIProxy::send(uint func, QVariant arg) { + /* switch(func) { case LOAD_IDENTITIES: return (QVariant) CoreProxy::loadIdentities(); case STORE_IDENTITIES: CoreProxy::storeIdentities(arg.toMap()); return 0; } - return 0; -} + */ + +//} diff --git a/main/main_gui.cpp b/main/main_gui.cpp new file mode 100644 index 00000000..80e2f504 --- /dev/null +++ b/main/main_gui.cpp @@ -0,0 +1,57 @@ +/*************************************************************************** + * Copyright (C) 2005 by The Quassel Team * + * devel@quassel-irc.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include + +#include + +#include "quassel.h" +#include "guiproxy.h" + +#include "mainwin.h" + +int main(int argc, char **argv) { + QApplication app(argc, argv); + QApplication::setOrganizationDomain("quassel-irc.org"); + QApplication::setApplicationName("Quassel IRC"); + QApplication::setOrganizationName("The Quassel Team"); + + Quassel::runMode = Quassel::GUIOnly; + quassel = Quassel::init(); + guiProxy = GUIProxy::init(); + + MainWin mainWin; + mainWin.show(); + int exitCode = app.exec(); + delete guiProxy; + delete quassel; +} + +void GUIProxy::send(GUISignal sig, QVariant arg1, QVariant arg2, QVariant arg3) { + + + +} + +void GUIProxy::recv(CoreSignal sig, QVariant arg1, QVariant arg2, QVariant arg3) { + + + +} diff --git a/main/main_mono.cpp b/main/main_mono.cpp index b935a128..49078c1e 100644 --- a/main/main_mono.cpp +++ b/main/main_mono.cpp @@ -24,37 +24,37 @@ #include "core.h" #include "quassel.h" -#include "logger.h" -#include "proxy.h" +#include "guiproxy.h" #include "mainwin.h" int main(int argc, char **argv) { - - Quassel::init(); - Logger *logger = new Logger(); - Quassel::setLogger(logger); - QApplication app(argc, argv); - QApplication::setOrganizationDomain("quassel-irc.org"); QApplication::setApplicationName("Quassel IRC"); QApplication::setOrganizationName("The Quassel Team"); - Core::init(); + Quassel::runMode = Quassel::Monolithic; + quassel = Quassel::init(); + core = Core::init(); + guiProxy = GUIProxy::init(); + // coreProxy = CoreProxy::init(); MainWin mainWin; mainWin.show(); - return app.exec(); + int exitCode = app.exec(); + delete guiProxy; + delete quassel; } -QVariant proxyConnect(uint func, QVariant arg) { - using namespace Proxy; +void GUIProxy::send(GUISignal sig, QVariant arg1, QVariant arg2, QVariant arg3) { + + + +} + +void GUIProxy::recv(CoreSignal sig, QVariant arg1, QVariant arg2, QVariant arg3) { + - switch(func) { - case LOAD_IDENTITIES: return (QVariant) CoreProxy::loadIdentities(); - case STORE_IDENTITIES: CoreProxy::storeIdentities(arg.toMap()); return 0; - } - return 0; } diff --git a/main/proxy_common.h b/main/proxy_common.h new file mode 100644 index 00000000..5f90c9e8 --- /dev/null +++ b/main/proxy_common.h @@ -0,0 +1,33 @@ +/*************************************************************************** + * Copyright (C) 2005/06 by The Quassel Team * + * devel@quassel-irc.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef _PROXY_COMMON_H_ +#define _PROXY_COMMON_H_ + +enum GUISignal { GS_USER_INPUT + +}; + +enum CoreSignal { GS_CORE_MESSAGE + +}; + + +#endif diff --git a/core/quassel.cpp b/main/quassel.cpp similarity index 75% rename from core/quassel.cpp rename to main/quassel.cpp index b650b210..6e90e13f 100644 --- a/core/quassel.cpp +++ b/main/quassel.cpp @@ -20,22 +20,45 @@ #include "quassel.h" #include "logger.h" -#include "proxy.h" +//#include "proxy.h" +#include "core.h" #include #include -void Quassel::init() { - Core::init(); +extern void messageHandler(QtMsgType type, const char *msg); +Quassel * Quassel::init() { + if(quassel) return quassel; + qInstallMsgHandler(messageHandler); + quassel = new Quassel(); //initIconMap(); + return quassel; } +/* void Quassel::setLogger(Logger *) { }; +*/ + +QVariant Quassel::getData(QString key) { + mutex.lock(); + QVariant d = data[key]; + mutex.unlock(); + qDebug() << "getData("< Quassel::data; diff --git a/core/quassel.h b/main/quassel.h similarity index 76% rename from core/quassel.h rename to main/quassel.h index a054e088..b3c942ba 100644 --- a/core/quassel.h +++ b/main/quassel.h @@ -21,35 +21,51 @@ #ifndef _QUASSEL_H_ #define _QUASSEL_H_ -class Logger; +class Quassel; -#include -#include +#include +//#include +/* Some global stuff */ +typedef QMap VarMap; +extern Quassel *quassel; /** * A static class containing global data. * This is used in both core and GUI modules. Where appropriate, accessors are thread-safe * to account for that fact. */ -class Quassel { +class Quassel : public QObject { Q_OBJECT public: - static void init(); - static Logger *getLogger(); - static void setLogger(Logger *); + static Quassel * init(); + //static Logger *getLogger(); + //static void setLogger(Logger *); // static QIcon *getIcon(QString symbol); + QVariant getData(QString key); + + public slots: + void putData(QString key, const QVariant &data); + + signals: + void dataChanged(QString key, const QVariant &data); + + public: + enum RunMode { Monolithic, GUIOnly, CoreOnly }; + static RunMode runMode; + private: static void initIconMap(); - static Logger *logger; + //static Logger *logger; // static QString iconPath; static QHash iconMap; - + static QMutex mutex; + static QHash data; }; class Exception { diff --git a/network/CMakeLists.txt b/network/CMakeLists.txt index 4dbbcfb1..e43d6bca 100644 --- a/network/CMakeLists.txt +++ b/network/CMakeLists.txt @@ -1,5 +1,5 @@ -SET(network_SRCS message.cpp builtin_cmds.cpp builtin_handlers.cpp server.cpp) -SET(network_HDRS message.h cmdcodes.h) +SET(network_SRCS server.cpp) +SET(network_HDRS ) SET(network_MOCS server.h) QT4_WRAP_CPP(_MOC ${network_MOCS}) diff --git a/network/builtin_cmds.cpp b/network/builtin_cmds.cpp index 7bbe48c4..2e72c9de 100644 --- a/network/builtin_cmds.cpp +++ b/network/builtin_cmds.cpp @@ -19,7 +19,7 @@ ***************************************************************************/ #include -#include "message.h" +//#include "message.h" #include "cmdcodes.h" /** This macro marks strings as translateable for Qt's linguist tools */ diff --git a/network/message.cpp b/network/message.cpp index 2bfd915d..b2e6f880 100644 --- a/network/message.cpp +++ b/network/message.cpp @@ -18,6 +18,8 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ +/* OBSOLETE CODE! */ + #include "message.h" #include diff --git a/network/server.cpp b/network/server.cpp index d55a9a71..f97e1aed 100644 --- a/network/server.cpp +++ b/network/server.cpp @@ -22,64 +22,46 @@ #include "server.h" #include "cmdcodes.h" +#include + Server::Server() { - socket = new QTcpSocket(); } Server::~Server() { - delete socket; + } void Server::init() { - Message::init(&dispatchServerMsg, &dispatchUserMsg); + //Message::init(&dispatchServerMsg, &dispatchUserMsg); } void Server::run() { - connect(socket, SIGNAL(connected()), this, SLOT(socketConnected())); - connect(socket, SIGNAL(disconnected()), this, SLOT(socketDisconnected())); - connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError))); - connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(socketStateChanged(QAbstractSocket::SocketState))); - connect(socket, SIGNAL(readyRead()), this, SLOT(socketHasData())); - - stream.setDevice(socket); - //connectToIrc("irc.quakenet.org", 6667); - exec(); -} + connect(&socket, SIGNAL(connected()), this, SLOT(socketConnected())); + connect(&socket, SIGNAL(disconnected()), this, SLOT(socketDisconnected())); + connect(&socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError))); + connect(&socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(socketStateChanged(QAbstractSocket::SocketState))); + connect(&socket, SIGNAL(readyRead()), this, SLOT(socketHasData())); -/* -QAbstractSocket::SocketState TcpConnection::state( ) const { - return socket.state(); + exec(); } -*/ void Server::connectToIrc( const QString & host, quint16 port ) { qDebug() << "Connecting..."; - socket->connectToHost(host, port); + socket.connectToHost(host, port); } void Server::disconnectFromIrc( ) { - socket->disconnectFromHost(); -} - -void Server::putRawLine( const QString &s ) { - qDebug() << "Sent: " << s; - stream << s << "\r\n" << flush; - //Message::createFromServerString(this, s); + socket.disconnectFromHost(); } -void Server::socketHasData( ) { - while(socket->canReadLine()) { - QString s = stream.readLine(); +void Server::socketHasData() { + while(socket.canReadLine()) { + QString s = socket.readLine().trimmed(); qDebug() << "Read: " << s; emit recvRawServerMsg(s); - Message *msg = Message::createFromServerString(this, s); - if(msg) { - try { handleServerMsg(msg); } catch(Exception e) { - emit recvLine(e.msg() + "\n"); - } - } - delete msg; + //Message *msg = Message::createFromServerString(this, s); + handleServerMsg(s); } } @@ -90,7 +72,8 @@ void Server::socketError( QAbstractSocket::SocketError err ) { void Server::socketConnected( ) { qDebug() << "Socket connected!"; - //emit connected(); + putRawLine("NICK :Sput|QuasselDev"); + putRawLine("USER Sputnick 8 * :Using Quassel IRC (WiP Version)"); } void Server::socketDisconnected( ) { @@ -102,7 +85,78 @@ void Server::socketStateChanged(QAbstractSocket::SocketState state) { qDebug() << "Socket state changed: " << state; } -/** Handle a message sent by the IRC server that does not have a custom handler. */ +void Server::putRawLine(QString s) { + qDebug() << "SentRaw: " << s; + s += "\r\n"; + socket.write(s.toAscii()); +} + +void Server::putCmd(QString cmd, QStringList params, QString prefix) { + QString m; + if(!prefix.isEmpty()) m += ":" + prefix + " "; + m += cmd.toUpper(); + for(int i = 0; i < params.size() - 1; i++) { + m += " " + params[i]; + } + if(!params.isEmpty()) m += " :" + params.last(); + qDebug() << "SentCmd: " << m; + m += "\r\n"; + socket.write(m.toAscii()); +} + +/** Handle a raw message string sent by the server. We try to find a suitable handler, otherwise we call a default handler. */ +void Server::handleServerMsg(QString msg) { + try { + if(msg.isEmpty()) { + qWarning() << "Received empty string from server!"; + return; + } + // OK, first we split the raw message into its various parts... + 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; + } + // 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"; + if(!QMetaObject::invokeMethod(this, hname.toAscii(), Q_ARG(QString, prefix), Q_ARG(QStringList, params))) { + // Ok. Default handler it is. + defaultHandlerForServer(cmd, prefix, params); + } + } catch(Exception e) { + emit recvLine(e.msg()); + } +} + +void Server::defaultHandlerForServer(QString cmd, QString prefix, QStringList params) { + uint num = cmd.toUInt(); + if(num) { + recvLine(cmd + " " + params.join(" ")); + } else { + recvLine(QString("Unknown: ") + cmd + " " + params.join(" ")); + } +} + +void Server::handleUserMsg(QString usrMsg) { + +} + +/* void Server::handleServerMsg(Message *msg) { int cmdCode = msg->getCmdCode(); QString prefix = msg->getPrefix(); @@ -111,11 +165,8 @@ void Server::handleServerMsg(Message *msg) { switch(-cmdCode) { case CMD_PING: // PING [] - if(params.size() == 1) { - putRawLine(QString("PONG :") + params[0]); - } else if(params.size() == 2) { - putRawLine(QString("PONG ") + params[0] + " :" + params[1]); - } else throw ParseError(msg); + if(params.size() < 1 || params.size() > 2) throw ParseError(msg); + putCmd("PONG", params); break; default: @@ -133,19 +184,25 @@ void Server::handleServerMsg(Message *msg) { throw UnknownCmdError(msg); } } +*/ + +void Server::handleNoticeFromServer(QString prefix, QStringList params) { + recvLine(params.join(" ")); -QString Server::handleUserMsg(Message *msg) { - return ""; +} + +void Server::handlePingFromServer(QString prefix, QStringList params) { + putCmd("PONG", params); } /* Exception classes for message handling */ -Server::ParseError::ParseError(Message *msg) { - _msg = QString("Command Parse Error: ") + msg->getCmd() + msg->getParams().join(" "); +Server::ParseError::ParseError(QString cmd, QString prefix, QStringList params) { + _msg = QString("Command Parse Error: ") + cmd + params.join(" "); } -Server::UnknownCmdError::UnknownCmdError(Message *msg) { - _msg = QString("Unknown Command: ") + msg->getCmd(); +Server::UnknownCmdError::UnknownCmdError(QString cmd, QString prefix, QStringList params) { + _msg = QString("Unknown Command: ") + cmd; } diff --git a/network/server.h b/network/server.h index 5eecb31b..b0077c19 100644 --- a/network/server.h +++ b/network/server.h @@ -22,13 +22,14 @@ #define _SERVER_H_ #include +#include #include #include "quassel.h" -#include "message.h" #define DEFAULT_PORT 6667 + /** * This is a server object, managing a single connection to an IRC server, handling the associated channels and so on. * We have this run in its own thread mainly to not block other server objects or the core if something goes wrong, @@ -52,7 +53,8 @@ class Server : public QThread { void connectToIrc(const QString &host, quint16 port = DEFAULT_PORT); void disconnectFromIrc(); - void putRawLine(const QString &input /*, Buffer *source = 0 */); + void putRawLine(QString input); + void putCmd(QString cmd, QStringList params, QString prefix = 0); signals: //void outputLine(const QString & /*, Buffer *target = 0 */); @@ -67,53 +69,34 @@ class Server : public QThread { void socketDisconnected(); 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); + private: - QTcpSocket *socket; + QTcpSocket socket; QTextStream stream; - void handleServerMsg(Message *); - QString handleUserMsg(Message *); - static inline void dispatchServerMsg(Message *msg) { msg->getServer()->handleServerMsg(msg); } - static inline void dispatchUserMsg(Message *msg) { msg->getServer()->handleUserMsg(msg); } + void handleServerMsg(QString rawMsg); + void handleUserMsg(QString usrMsg); + //static inline void dispatchServerMsg(Message *msg) { msg->getServer()->handleServerMsg(msg); } + //static inline void dispatchUserMsg(Message *msg) { msg->getServer()->handleUserMsg(msg); } class ParseError : public Exception { public: - ParseError(Message *msg); + ParseError(QString cmd, QString prefix, QStringList params); }; class UnknownCmdError : public Exception { public: - UnknownCmdError(Message *msg); + UnknownCmdError(QString cmd, QString prefix, QStringList params); }; }; class Buffer {}; -/* -class TcpConnection : public QThread { - Q_OBJECT - - - public: - void run(); - QAbstractSocket::SocketState state() const; - - public slots: - void connectToHost(const QString &host, quint16 port = DEFAULT_PORT); - void disconnectFromHost(); - void sendLine(const QString &); - - signals: - void recvLine(QString); - void error(QAbstractSocket::SocketError); - void connected(); - void disconnected(); - void stateChanged(QAbstractSocket::SocketState); - - private: - QTcpSocket socket; - QTextStream stream; -}; -*/ #endif -- 2.20.1