From 8836fdc8e4107437e5fff0e10e18d581297d59e4 Mon Sep 17 00:00:00 2001 From: Manuel Nickschas Date: Wed, 27 Jun 2007 21:48:19 +0000 Subject: [PATCH] Still working on the authentification stuff. Technically, now even in the monolithic build the client connects to the internal core (still using the possible shortcuts, of course). It should also be able to disconnect, although not all is cleaned up yet in the process. After this is done, one will be able to disconnect the client from the internal core and connect to a remote core, and vice versa. This made a lot of changes to the init process necessary, so I have changed quite a bit of stuff around. You should refrain from building core and client separately now, even though it probably compiles. It is not tested yet, and the GUI stuff is still missing anyways. --- src/CMakeLists.txt | 12 +-- src/client/client.cpp | 108 +++++++++++++++----- src/client/client.h | 17 +++- src/client/clientproxy.h | 1 + src/common/CMakeLists.txt | 4 +- src/common/main.cpp | 48 +++++---- src/common/proxy_common.h | 2 +- src/common/quasselui.h | 14 ++- src/core/core.cpp | 44 +++++--- src/core/core.h | 10 ++ src/core/coreproxy.cpp | 1 + src/core/coreproxy.h | 1 + src/core/sqlitestorage.cpp | 1 - src/qtgui/coreconnectdlg.cpp | 14 +-- src/qtgui/mainwin.cpp | 55 ++++++++-- src/qtgui/mainwin.h | 41 ++++++-- src/qtgui/ui/coreconnectdlg.ui | 177 ++++++++++++++++++++------------- src/qtgui/ui/mainwin.ui | 35 +++++++ 18 files changed, 424 insertions(+), 161 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9fc218e6..7e0244ff 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -20,13 +20,13 @@ IF(BUILD MATCHES "mono" OR BUILD MATCHES "all") SET(BUILD_MONO true) MESSAGE("Building monolithic Quassel.") ENDIF(BUILD MATCHES "mono" OR BUILD MATCHES "all") -IF(NOT BUILD_MONO AND NOT BUILD_CORE AND NOT BUILD_GUI) +IF(NOT BUILD_MONO AND NOT BUILD_CORE AND NOT BUILD_QTGUI) MESSAGE(FATAL_ERROR "\nYou have not selected which parts of Quassel I should build. Aborting.\nRun 'cmake -DBUILD=', where contains one or more of 'core', 'gui' or 'monolithic', or 'all' to build everything.\n") -ENDIF(NOT BUILD_MONO AND NOT BUILD_CORE AND NOT BUILD_GUI) +ENDIF(NOT BUILD_MONO AND NOT BUILD_CORE AND NOT BUILD_QTGUI) -IF(BUILD_CORE OR BUILD_QTGUI) - MESSAGE(FATAL_ERROR "\nBuilding of standalone core or GUI not supported at this time. Please check back later.\n") -ENDIF(BUILD_CORE OR BUILD_QTGUI) +#IF(BUILD_CORE OR BUILD_QTGUI) +# MESSAGE(FATAL_ERROR "\nBuilding of standalone core or GUI not supported at this time. Please check back later.\n") +#ENDIF(BUILD_CORE OR BUILD_QTGUI) SET(CMAKE_BUILD_TYPE Debug) @@ -96,7 +96,7 @@ IF(BUILD_QTGUI OR BUILD_MONO) # OK, now we need QtGui! ENDIF(BUILD_MONO) IF(BUILD_QTGUI) - ADD_EXECUTABLE(quasselclient ${quassel_gui_SRCS} ${_RCCS}) + ADD_EXECUTABLE(quasselclient ${quassel_qtgui_SRCS} ${_RCCS}) TARGET_LINK_LIBRARIES(quasselclient common client qtgui ${QT_LIBRARIES}) SET(TARGET_LIST ${TARGET_LIST} quasselclient) ENDIF(BUILD_QTGUI) diff --git a/src/client/client.cpp b/src/client/client.cpp index 8b954d39..30eeb51d 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -26,13 +26,14 @@ Client * Client::instanceptr = 0; +bool Client::connectedToCore = false; Client::ClientMode Client::clientMode; QHash Client::buffers; QHash Client::bufferIds; QHash > Client::nicks; -QHash Client::connected; +QHash Client::netConnected; QHash Client::ownNick; -QList Client::coreBuffers; +//QList Client::coreBuffers; Client *Client::instance() { @@ -58,6 +59,7 @@ Client::Client() { // TODO: make this configurable (allow monolithic client to connect to remote cores) if(Global::runMode == Global::Monolithic) clientMode = LocalCore; else clientMode = RemoteCore; + connectedToCore = false; } void Client::init(AbstractUi *ui) { @@ -92,20 +94,18 @@ void Client::init() { connect(clientProxy, SIGNAL(csUpdateBufferId(BufferId)), this, SLOT(updateBufferId(BufferId))); connect(this, SIGNAL(sendInput(BufferId, QString)), clientProxy, SLOT(gsUserInput(BufferId, QString))); connect(this, SIGNAL(requestBacklog(BufferId, QVariant, QVariant)), clientProxy, SLOT(gsRequestBacklog(BufferId, QVariant, QVariant))); + connect(this, SIGNAL(requestNetworkStates()), clientProxy, SLOT(gsRequestNetworkStates())); - syncToCore(); + connect(mainUi, SIGNAL(connectToCore(const VarMap &)), this, SLOT(connectToCore(const VarMap &))); + connect(mainUi, SIGNAL(disconnectFromCore()), this, SLOT(disconnectFromCore())); + connect(this, SIGNAL(connected()), mainUi, SLOT(connectedToCore())); + connect(this, SIGNAL(disconnected()), mainUi, SLOT(disconnectedFromCore())); layoutTimer = new QTimer(this); layoutTimer->setInterval(0); layoutTimer->setSingleShot(false); connect(layoutTimer, SIGNAL(timeout()), this, SLOT(layoutMsg())); - /* make lookups by id faster */ - foreach(BufferId id, coreBuffers) { - bufferIds[id.uid()] = id; // make lookups by id faster - buffer(id); // create all buffers, so we see them in the network views - emit requestBacklog(id, -1, -1); // TODO: use custom settings for backlog request - } } Client::~Client() { @@ -120,12 +120,71 @@ BufferTreeModel *Client::bufferModel() { return instance()->_bufferModel; } +bool Client::isConnected() { return connectedToCore; } + +void Client::connectToCore(const VarMap &conn) { + // TODO implement SSL + if(isConnected()) { + qDebug() << "Already connected to core!"; + return; + } + if(conn["Host"].toString().isEmpty()) { + clientMode = LocalCore; + syncToCore(); // TODO send user and pw from conn info + } else { + clientMode = RemoteCore; + socket.connectToHost(conn["Host"].toString(), conn["Port"].toUInt()); + } +} + +void Client::disconnectFromCore() { + if(clientMode == RemoteCore) { + socket.close(); + } else { + disconnectFromLocalCore(); + coreDisconnected(); + } + // TODO clear internal data +} + void Client::coreConnected() { + syncToCore(); } void Client::coreDisconnected() { + connectedToCore = false; + emit disconnected(); +} + +void Client::syncToCore() { + VarMap state; + if(clientMode == LocalCore) { + state = connectToLocalCore("Default", "password").toMap(); // TODO make this configurable + } else { + } + + VarMap data = state["CoreData"].toMap(); + foreach(QString key, data.keys()) { + Global::updateData(key, data[key]); + } + //if(!Global::data("CoreReady").toBool()) { + // qFatal("Something is wrong, getting invalid data from core!"); + //} + + VarMap sessionState = state["SessionState"].toMap(); + QList coreBuffers = sessionState["Buffers"].toList(); + /* make lookups by id faster */ + foreach(QVariant vid, coreBuffers) { + BufferId id = vid.value(); + bufferIds[id.uid()] = id; // make lookups by id faster + buffer(id); // create all buffers, so we see them in the network views + //emit requestBacklog(id, -1, -1); // TODO: use custom settings for backlog request + } + connectedToCore = true; + emit connected(); + emit requestNetworkStates(); } void Client::updateCoreData(UserId, QString key) { @@ -146,15 +205,6 @@ void Client::recvProxySignal(ClientSignal sig, QVariant arg1, QVariant arg2, QVa writeDataToDevice(&socket, QVariant(sigdata)); } -void Client::connectToCore(QString host, quint16 port) { - // TODO implement SSL - socket.connectToHost(host, port); -} - -void Client::disconnectFromCore() { - socket.close(); -} - void Client::serverError(QAbstractSocket::SocketError) { emit coreConnectionError(socket.errorString()); } @@ -174,7 +224,7 @@ void Client::serverHasData() { } void Client::networkConnected(QString net) { - connected[net] = true; + netConnected[net] = true; BufferId id = statusBufferId(net); Buffer *b = buffer(id); b->setActive(true); @@ -189,7 +239,7 @@ void Client::networkDisconnected(QString net) { //b->displayMsg(Message(id, Message::Server, tr("Server disconnected."))); FIXME b->setActive(false); } - connected[net] = false; + netConnected[net] = false; } void Client::updateBufferId(BufferId id) { @@ -224,8 +274,12 @@ Buffer * Client::buffer(BufferId id) { return buffers[id]; } +QList Client::allBufferIds() { + return buffers.keys(); +} + void Client::recvNetworkState(QString net, QVariant state) { - connected[net] = true; + netConnected[net] = true; setOwnNick(net, state.toMap()["OwnNick"].toString()); buffer(statusBufferId(net))->setActive(true); VarMap t = state.toMap()["Topics"].toMap(); @@ -289,7 +343,7 @@ void Client::userInput(BufferId id, QString msg) { void Client::setTopic(QString net, QString buf, QString topic) { BufferId id = bufferId(net, buf); - if(!connected[id.network()]) return; + if(!netConnected[id.network()]) return; Buffer *b = buffer(id); b->setTopic(topic); //if(!b->isActive()) { @@ -299,7 +353,7 @@ void Client::setTopic(QString net, QString buf, QString topic) { } void Client::addNick(QString net, QString nick, VarMap props) { - if(!connected[net]) return; + if(!netConnected[net]) return; nicks[net][nick] = props; VarMap chans = props["Channels"].toMap(); QStringList c = chans.keys(); @@ -309,7 +363,7 @@ void Client::addNick(QString net, QString nick, VarMap props) { } void Client::renameNick(QString net, QString oldnick, QString newnick) { - if(!connected[net]) return; + if(!netConnected[net]) return; QStringList chans = nicks[net][oldnick]["Channels"].toMap().keys(); foreach(QString c, chans) { buffer(bufferId(net, c))->renameNick(oldnick, newnick); @@ -318,7 +372,7 @@ void Client::renameNick(QString net, QString oldnick, QString newnick) { } void Client::updateNick(QString net, QString nick, VarMap props) { - if(!connected[net]) return; + if(!netConnected[net]) return; QStringList oldchans = nicks[net][nick]["Channels"].toMap().keys(); QStringList newchans = props["Channels"].toMap().keys(); foreach(QString c, newchans) { @@ -332,7 +386,7 @@ void Client::updateNick(QString net, QString nick, VarMap props) { } void Client::removeNick(QString net, QString nick) { - if(!connected[net]) return; + if(!netConnected[net]) return; VarMap chans = nicks[net][nick]["Channels"].toMap(); foreach(QString bufname, chans.keys()) { buffer(bufferId(net, bufname))->removeNick(nick); @@ -341,7 +395,7 @@ void Client::removeNick(QString net, QString nick) { } void Client::setOwnNick(QString net, QString nick) { - if(!connected[net]) return; + if(!netConnected[net]) return; ownNick[net] = nick; foreach(BufferId id, buffers.keys()) { if(id.network() == net) { diff --git a/src/client/client.h b/src/client/client.h index eee57fd5..9bc40345 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -40,6 +40,7 @@ class Client : public QObject { static void init(AbstractUi *); static void destroy(); + static QList allBufferIds(); static Buffer *buffer(BufferId); static BufferId statusBufferId(QString net); static BufferId bufferId(QString net, QString buf); @@ -48,6 +49,8 @@ class Client : public QObject { static AbstractUiMsg *layoutMsg(const Message &); + static bool isConnected(); + signals: void sendInput(BufferId, QString message); void showBuffer(Buffer *); @@ -57,13 +60,18 @@ class Client : public QObject { void bufferDestroyed(Buffer *); void backlogReceived(Buffer *, QList); void requestBacklog(BufferId, QVariant, QVariant); + void requestNetworkStates(); void recvPartialItem(quint32 avail, quint32 size); void coreConnectionError(QString errorMsg); + void connected(); + void disconnected(); + public slots: //void selectBuffer(Buffer *); - void connectToCore(QString host, quint16 port); + //void connectToLocalCore(); + void connectToCore(const VarMap &); void disconnectFromCore(); private slots: @@ -100,6 +108,8 @@ class Client : public QObject { static Client *instanceptr; void syncToCore(); + QVariant connectToLocalCore(QString user, QString passwd); // defined in main.cpp + void disconnectFromLocalCore(); // defined in main.cpp enum ClientMode { LocalCore, RemoteCore }; static ClientMode clientMode; @@ -111,12 +121,13 @@ class Client : public QObject { QTcpSocket socket; quint32 blockSize; + static bool connectedToCore; static QHash buffers; static QHash bufferIds; static QHash > nicks; - static QHash connected; + static QHash netConnected; static QHash ownNick; - static QList coreBuffers; + //static QList coreBuffers; QTimer *layoutTimer; QList layoutQueue; diff --git a/src/client/clientproxy.h b/src/client/clientproxy.h index 28fbfff4..abe7ca46 100644 --- a/src/client/clientproxy.h +++ b/src/client/clientproxy.h @@ -42,6 +42,7 @@ class ClientProxy : public QObject { inline void gsRequestConnect(QStringList networks) { send(GS_REQUEST_CONNECT, networks); } inline void gsImportBacklog() { send(GS_IMPORT_BACKLOG); } inline void gsRequestBacklog(BufferId id, QVariant v1, QVariant v2) { send(GS_REQUEST_BACKLOG, QVariant::fromValue(id), v1, v2); } + inline void gsRequestNetworkStates() { send(GS_REQUEST_NETWORK_STATES); } inline void gsGeneric(ClientSignal sig, QVariant v1 = QVariant(), QVariant v2 = QVariant(), QVariant v3 = QVariant()) { send(sig, v1, v2, v3); } diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 7f465520..55457d2f 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -1,6 +1,6 @@ SET(common_SRCS global.cpp logger.cpp util.cpp message.cpp settings.cpp) -SET(common_HDRS util.h message.h settings.h quasselui.h) -SET(common_MOCS global.h logger.h) +SET(common_HDRS util.h message.h settings.h) +SET(common_MOCS global.h logger.h quasselui.h) QT4_WRAP_CPP(_MOC ${common_MOCS}) ADD_LIBRARY(common ${_MOC} ${common_SRCS} ${common_HDRS}) diff --git a/src/common/main.cpp b/src/common/main.cpp index 48760d2d..a35ab4cb 100644 --- a/src/common/main.cpp +++ b/src/common/main.cpp @@ -22,6 +22,7 @@ #include "global.h" #include "settings.h" +#include "quasselui.h" #if defined BUILD_CORE #include @@ -58,27 +59,28 @@ int main(int argc, char **argv) { Global::runMode = Global::Monolithic; QApplication app(argc, argv); #endif - + //AbstractUi *foo = new AbstractUi(); + //foo->init(); QCoreApplication::setOrganizationDomain("quassel-irc.org"); QCoreApplication::setApplicationName("Quassel IRC"); QCoreApplication::setOrganizationName("Quassel IRC Development Team"); Global::quasselDir = QDir::homePath() + "/.quassel"; - Core::instance(); -#ifdef BUILD_MONO - QObject::connect(Core::localSession(), SIGNAL(proxySignal(CoreSignal, QVariant, QVariant, QVariant)), ClientProxy::instance(), SLOT(recv(CoreSignal, QVariant, QVariant, QVariant))); - QObject::connect(ClientProxy::instance(), SIGNAL(send(ClientSignal, QVariant, QVariant, QVariant)), Core::localSession(), SLOT(processSignal(ClientSignal, QVariant, QVariant, QVariant))); +#ifndef BUILD_QTGUI + Core::instance(); // create and init the core #endif Settings::init(); #ifndef BUILD_CORE Style::init(); - MainWin *mainWin = new MainWin(); - Client::init(mainWin); - mainWin->init(); -#else - Core::instance(); // create and init the core object + AbstractUi foo; // This avoids an annoying linker error (bug?) where AbstractUi's vtable is not found. + // Yes, it's fugly. Yes, I'd like an alternative. + QtGui *gui = new QtGui(); + Client::init(gui); + gui->init(); +//#else +// Core::instance(); // create and init the core object #endif int exitCode = app.exec(); @@ -87,7 +89,7 @@ int main(int argc, char **argv) { // the mainWin has to be deleted before the Core // if not Quassel will crash on exit under certain conditions since the gui // still wants to access clientdata - delete mainWin; + delete gui; Client::destroy(); #endif #ifndef BUILD_QTGUI @@ -97,11 +99,23 @@ int main(int argc, char **argv) { return exitCode; } -#ifndef BUILD_CORE -void Client::syncToCore() { - //Q_ASSERT(Global::data("CoreReady").toBool()); - coreBuffers = Core::localSession()->buffers(); - // NOTE: We don't need to request server states, because in the monolithic version there can't be - // any servers connected at this stage... +#ifdef BUILD_QTGUI +QVariant Client::connectToLocalCore(QString, QString) { return QVariant(); } +void Client::disconnectFromLocalCore() {} +#elif defined BUILD_MONO + +QVariant Client::connectToLocalCore(QString user, QString passwd) { + // TODO catch exceptions + QVariant reply = Core::connectLocalClient(user, passwd); + QObject::connect(Core::localSession(), SIGNAL(proxySignal(CoreSignal, QVariant, QVariant, QVariant)), ClientProxy::instance(), SLOT(recv(CoreSignal, QVariant, QVariant, QVariant))); + QObject::connect(ClientProxy::instance(), SIGNAL(send(ClientSignal, QVariant, QVariant, QVariant)), Core::localSession(), SLOT(processSignal(ClientSignal, QVariant, QVariant, QVariant))); + return reply; } + +void Client::disconnectFromLocalCore() { + disconnect(Core::localSession(), 0, ClientProxy::instance(), 0); + disconnect(ClientProxy::instance(), 0, Core::localSession(), 0); + Core::disconnectLocalClient(); +} + #endif diff --git a/src/common/proxy_common.h b/src/common/proxy_common.h index 30421e71..2eacb0df 100644 --- a/src/common/proxy_common.h +++ b/src/common/proxy_common.h @@ -22,7 +22,7 @@ #define _PROXY_COMMON_H_ enum ClientSignal { GS_CLIENT_INIT, GS_USER_INPUT, GS_REQUEST_CONNECT, GS_UPDATE_GLOBAL_DATA, GS_IMPORT_BACKLOG, - GS_REQUEST_BACKLOG + GS_REQUEST_BACKLOG, GS_REQUEST_NETWORK_STATES }; diff --git a/src/common/quasselui.h b/src/common/quasselui.h index 1b8c7a0e..0925b2ee 100644 --- a/src/common/quasselui.h +++ b/src/common/quasselui.h @@ -21,6 +21,7 @@ #ifndef _QUASSELUI_H_ #define _QUASSELUI_H_ +#include #include "message.h" class AbstractUiMsg { @@ -36,13 +37,22 @@ class AbstractUiMsg { }; -class AbstractUi { +class AbstractUi : public QObject { + Q_OBJECT public: + static void foo() {}; virtual ~AbstractUi() {}; - virtual AbstractUiMsg *layoutMsg(const Message &) = 0; + virtual void init() {}; // called after the client is initialized + virtual AbstractUiMsg *layoutMsg(const Message &) { return 0; } + protected slots: + virtual void connectedToCore() {} + virtual void disconnectedFromCore() {} + signals: + void connectToCore(const VarMap &connInfo); + void disconnectFromCore(); }; diff --git a/src/core/core.cpp b/src/core/core.cpp index 1df55da2..f9bc84fa 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -43,7 +43,7 @@ void Core::destroy() { } Core::Core() { - qDebug() << "core"; + } void Core::init() { @@ -55,6 +55,8 @@ void Core::init() { connect(Global::instance(), SIGNAL(dataPutLocally(UserId, QString)), this, SLOT(updateGlobalData(UserId, QString))); connect(&server, SIGNAL(newConnection()), this, SLOT(incomingConnection())); //startListening(); // FIXME + guiUser = 0; + /* if(Global::runMode == Global::Monolithic) { // TODO Make GUI user configurable try { guiUser = storage->validateUser("Default", "password"); @@ -65,7 +67,7 @@ void Core::init() { Global::setGuiUser(guiUser); createSession(guiUser); } else guiUser = 0; - + */ // Read global settings from config file QSettings s; s.beginGroup("Global"); @@ -173,36 +175,53 @@ void Core::clientDisconnected() { // TODO remove unneeded sessions - if necessary/possible... } +QVariant Core::connectLocalClient(QString user, QString passwd) { + UserId uid = instance()->storage->validateUser(user, passwd); + QVariant reply = instance()->initSession(uid); + instance()->guiUser = uid; + Global::setGuiUser(uid); + qDebug() << "Local client connected."; + return reply; +} + +QVariant Core::disconnectLocalClient() { + qDebug() << "Local client disconnected."; + instance()->guiUser = 0; + Global::setGuiUser(0); +} + void Core::processClientInit(QTcpSocket *socket, const QVariant &v) { VarMap msg = v.toMap(); if(msg["GUIProtocol"].toUInt() != GUI_PROTOCOL) { //qWarning() << "Client version mismatch."; throw Exception("GUI client version mismatch"); } - // Auth + // Auth UserId uid = storage->validateUser(msg["User"].toString(), msg["Password"].toString()); // throws exception if this failed + VarMap reply = initSession(uid).toMap(); + validClients[socket] = uid; + QList sigdata; + sigdata.append(CS_CORE_STATE); sigdata.append(QVariant(reply)); sigdata.append(QVariant()); sigdata.append(QVariant()); + writeDataToDevice(socket, QVariant(sigdata)); +} +QVariant Core::initSession(UserId uid) { // Find or create session for validated user CoreSession *sess; if(sessions.contains(uid)) sess = sessions[uid]; else { sess = createSession(uid); - validClients[socket] = uid; + //validClients[socket] = uid; } VarMap reply; VarMap coreData; - // FIXME QStringList dataKeys = Global::keys(uid); - QString key; - foreach(key, dataKeys) { - coreData[key] = Global::data(key); + foreach(QString key, dataKeys) { + coreData[key] = Global::data(uid, key); } reply["CoreData"] = coreData; reply["SessionState"] = sess->sessionState(); - QList sigdata; - sigdata.append(CS_CORE_STATE); sigdata.append(QVariant(reply)); sigdata.append(QVariant()); sigdata.append(QVariant()); - writeDataToDevice(socket, QVariant(sigdata)); - sess->sendServerStates(); + return reply; } void Core::processClientUpdate(QTcpSocket *socket, QString key, const QVariant &data) { @@ -263,6 +282,7 @@ CoreSession::CoreSession(UserId uid, Storage *_storage) : user(uid), storage(_st connect(coreProxy, SIGNAL(gsUserInput(BufferId, QString)), this, SLOT(msgFromGui(BufferId, QString))); connect(coreProxy, SIGNAL(gsImportBacklog()), storage, SLOT(importOldBacklog())); connect(coreProxy, SIGNAL(gsRequestBacklog(BufferId, QVariant, QVariant)), this, SLOT(sendBacklog(BufferId, QVariant, QVariant))); + connect(coreProxy, SIGNAL(gsRequestNetworkStates()), this, SLOT(sendServerStates())); connect(this, SIGNAL(displayMsg(Message)), coreProxy, SLOT(csDisplayMsg(Message))); connect(this, SIGNAL(displayStatusMsg(QString, QString)), coreProxy, SLOT(csDisplayStatusMsg(QString, QString))); connect(this, SIGNAL(backlogData(BufferId, QList, bool)), coreProxy, SLOT(csBacklogData(BufferId, QList, bool))); diff --git a/src/core/core.h b/src/core/core.h index 126e3a57..aec04693 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -43,6 +43,9 @@ class Core : public QObject { static CoreSession * localSession(); static CoreSession * createSession(UserId); + static QVariant connectLocalClient(QString user, QString passwd); + static QVariant disconnectLocalClient(); + private slots: void recvProxySignal(CoreSignal, QVariant, QVariant, QVariant); bool startListening(uint port = 4242); @@ -58,6 +61,13 @@ class Core : public QObject { void init(); static Core *instanceptr; + //! Initiate a session for the user with the given credentials if one does not already exist. + /** This function is called during the init process for a new client. If there is no session for the + * given user, one is created. + * \param userId The user + * \return A QVariant containing the session data, e.g. global data and buffers + */ + QVariant initSession(UserId userId); void processClientInit(QTcpSocket *socket, const QVariant &v); void processClientUpdate(QTcpSocket *socket, QString key, const QVariant &data); diff --git a/src/core/coreproxy.cpp b/src/core/coreproxy.cpp index ee9ea2d1..84c427c9 100644 --- a/src/core/coreproxy.cpp +++ b/src/core/coreproxy.cpp @@ -68,6 +68,7 @@ void CoreProxy::recv(ClientSignal sig, QVariant arg1, QVariant arg2, QVariant ar case GS_REQUEST_CONNECT: emit gsRequestConnect(arg1.toStringList()); break; case GS_IMPORT_BACKLOG: emit gsImportBacklog(); break; case GS_REQUEST_BACKLOG: emit gsRequestBacklog(arg1.value(), arg2, arg3); break; + case GS_REQUEST_NETWORK_STATES: emit gsRequestNetworkStates(); break; //default: qWarning() << "Unknown signal in CoreProxy::recv: " << sig; default: emit gsGeneric(sig, arg1, arg2, arg3); } diff --git a/src/core/coreproxy.h b/src/core/coreproxy.h index 071f651c..737d061a 100644 --- a/src/core/coreproxy.h +++ b/src/core/coreproxy.h @@ -65,6 +65,7 @@ class CoreProxy : public QObject { void gsRequestConnect(QStringList networks); void gsImportBacklog(); void gsRequestBacklog(BufferId, QVariant, QVariant); + void gsRequestNetworkStates(); void gsGeneric(ClientSignal, QVariant, QVariant, QVariant); diff --git a/src/core/sqlitestorage.cpp b/src/core/sqlitestorage.cpp index af5767dd..00dc4c03 100644 --- a/src/core/sqlitestorage.cpp +++ b/src/core/sqlitestorage.cpp @@ -386,7 +386,6 @@ QList SqliteStorage::requestMsgs(BufferId buffer, int lastmsgs, int off msg.msgId = requestMsgsQuery->value(0).toUInt(); messagelist << msg; } - return messagelist; } diff --git a/src/qtgui/coreconnectdlg.cpp b/src/qtgui/coreconnectdlg.cpp index d51bb5d8..102c3cc5 100644 --- a/src/qtgui/coreconnectdlg.cpp +++ b/src/qtgui/coreconnectdlg.cpp @@ -29,6 +29,7 @@ CoreConnectDlg::CoreConnectDlg(QWidget *parent) : QDialog(parent) { ui.progressBar->hide(); coreState = 0; QSettings s; + /* connect(ui.hostName, SIGNAL(textChanged(QString)), this, SLOT(hostEditChanged(QString))); connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(hostSelected())); @@ -39,31 +40,32 @@ CoreConnectDlg::CoreConnectDlg(QWidget *parent) : QDialog(parent) { if(s.value("GUI/CoreAutoConnect").toBool()) { hostSelected(); } + */ } -void CoreConnectDlg::setStartState() { +void CoreConnectDlg::setStartState() { /* ui.hostName->show(); ui.hostPort->show(); ui.hostLabel->show(); ui.portLabel->show(); ui.statusText->setText(tr("Connect to Quassel Core running on:")); ui.buttonBox->button(QDialogButtonBox::Ok)->show(); ui.hostName->setEnabled(true); ui.hostPort->setEnabled(true); - ui.hostName->setSelection(0, ui.hostName->text().length()); + ui.hostName->setSelection(0, ui.hostName->text().length()); */ } void CoreConnectDlg::hostEditChanged(QString txt) { ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(txt.length()); } -void CoreConnectDlg::hostSelected() { +void CoreConnectDlg::hostSelected() { /* ui.hostName->hide(); ui.hostPort->hide(); ui.hostLabel->hide(); ui.portLabel->hide(); ui.statusText->setText(tr("Connecting to %1:%2" ).arg(ui.hostName->text()).arg(ui.hostPort->value())); ui.buttonBox->button(QDialogButtonBox::Ok)->hide(); connect(ClientProxy::instance(), SIGNAL(coreConnected()), this, SLOT(coreConnected())); connect(ClientProxy::instance(), SIGNAL(coreConnectionError(QString)), this, SLOT(coreConnectionError(QString))); Client::instance()->connectToCore(ui.hostName->text(), ui.hostPort->value()); - +*/ } -void CoreConnectDlg::coreConnected() { +void CoreConnectDlg::coreConnected() { /* ui.hostLabel->hide(); ui.hostName->hide(); ui.portLabel->hide(); ui.hostPort->hide(); ui.statusText->setText(tr("Synchronizing...")); QSettings s; @@ -75,7 +77,7 @@ void CoreConnectDlg::coreConnected() { ui.progressBar->show(); VarMap initmsg; initmsg["GUIProtocol"] = GUI_PROTOCOL; - // FIXME guiProxy->send(GS_CLIENT_INIT, QVariant(initmsg)); + // FIXME guiProxy->send(GS_CLIENT_INIT, QVariant(initmsg)); */ } void CoreConnectDlg::coreConnectionError(QString err) { diff --git a/src/qtgui/mainwin.cpp b/src/qtgui/mainwin.cpp index 772acab3..bb193cf5 100644 --- a/src/qtgui/mainwin.cpp +++ b/src/qtgui/mainwin.cpp @@ -36,27 +36,55 @@ #include "settingsdlg.h" #include "settingspages.h" -MainWin::MainWin() : QMainWindow() { - ui.setupUi(this); +QtGui::QtGui() : AbstractUi() { + mainWin = new MainWin(this); + connect(mainWin, SIGNAL(connectToCore(const VarMap &)), this, SIGNAL(connectToCore(const VarMap &))); + connect(mainWin, SIGNAL(disconnectFromCore()), this, SIGNAL(disconnectFromCore())); - //widget = 0; - //qDebug() << "Available DB drivers: " << QSqlDatabase::drivers (); +} + +QtGui::~QtGui() { + delete mainWin; +} + +void QtGui::init() { + mainWin->init(); +} + +AbstractUiMsg *QtGui::layoutMsg(const Message &msg) { + return mainWin->layoutMsg(msg); +} + +void QtGui::connectedToCore() { + mainWin->connectedToCore(); +} + +void QtGui::disconnectedFromCore() { + mainWin->disconnectedFromCore(); +} + +MainWin::MainWin(QtGui *_gui, QWidget *parent) : QMainWindow(parent), gui(_gui) { + ui.setupUi(this); setWindowTitle("Quassel IRC"); //setWindowTitle("Κυασελ Εγαρζη"); setWindowIcon(QIcon(":/qirc-icon.png")); setWindowIconText("Quassel IRC"); - //workspace = new QWorkspace(this); - //setCentralWidget(workspace); statusBar()->showMessage(tr("Waiting for core...")); } void MainWin::init() { + connect(this, SIGNAL(requestBacklog(BufferId, QVariant, QVariant)), ClientProxy::instance(), SLOT(gsRequestBacklog(BufferId, QVariant, QVariant))); ui.bufferWidget->init(); show(); - //syncToCore(); + + VarMap connInfo; + connInfo["User"] = "Default"; + connInfo["Password"] = "password"; + connectToCore(connInfo); + statusBar()->showMessage(tr("Ready.")); systray = new QSystemTrayIcon(this); systray->setIcon(QIcon(":/qirc-icon.png")); @@ -92,6 +120,7 @@ void MainWin::init() { } } */ + } MainWin::~MainWin() { @@ -124,7 +153,7 @@ void MainWin::setupMenus() { void MainWin::setupViews() { - BufferTreeModel *model = Client::bufferModel(); // FIXME Where is the delete for that? :p + BufferTreeModel *model = Client::bufferModel(); connect(model, SIGNAL(bufferSelected(Buffer *)), this, SLOT(showBuffer(Buffer *))); addBufferView(tr("All Buffers"), model, BufferViewFilter::AllNets, QStringList()); @@ -153,6 +182,16 @@ void MainWin::addBufferView(const QString &viewname, QAbstractItemModel *model, netViews.append(dock); } +void MainWin::connectedToCore() { + foreach(BufferId id, Client::allBufferIds()) { + emit requestBacklog(id, 100, -1); + } +} + +void MainWin::disconnectedFromCore() { + +} + AbstractUiMsg *MainWin::layoutMsg(const Message &msg) { return new ChatLine(msg); } diff --git a/src/qtgui/mainwin.h b/src/qtgui/mainwin.h index e46e233e..eed60f78 100644 --- a/src/qtgui/mainwin.h +++ b/src/qtgui/mainwin.h @@ -24,7 +24,6 @@ #include #include "ui_mainwin.h" -#include "quasselui.h" //#include "global.h" #include "message.h" #include "chatwidget.h" @@ -35,17 +34,32 @@ class ServerListDlg; class CoreConnectDlg; class Buffer; class SettingsDlg; +class MainWin; -//!\brief The main window and central object of Quassel GUI. -/** In addition to displaying the main window including standard stuff like a menubar, - * dockwidgets and of course the chat window, this class also stores all data it - * receives from the core, and it maintains a list of all known nicks. - */ -class MainWin : public QMainWindow, public AbstractUi { +class QtGui : public AbstractUi { Q_OBJECT public: - MainWin(); + QtGui(); + ~QtGui(); + void init(); + AbstractUiMsg *layoutMsg(const Message &); + + protected slots: + void connectedToCore(); + void disconnectedFromCore(); + + private: + MainWin *mainWin; +}; + + +//!\brief The main window of Quassel's QtGui. +class MainWin : public QMainWindow { + Q_OBJECT + + public: + MainWin(QtGui *gui, QWidget *parent = 0); virtual ~MainWin(); void init(); @@ -56,7 +70,9 @@ class MainWin : public QMainWindow, public AbstractUi { protected: void closeEvent(QCloseEvent *event); - //void importOldBacklog(); + protected slots: + void connectedToCore(); + void disconnectedFromCore(); private slots: @@ -69,15 +85,21 @@ class MainWin : public QMainWindow, public AbstractUi { void importBacklog(); signals: + void connectToCore(const VarMap &connInfo); + void disconnectFromCore(); + void requestBacklog(BufferId, QVariant, QVariant); void importOldBacklog(); private: Ui::MainWin ui; + QtGui *gui; void setupMenus(); void setupViews(); void setupSettingsDlg(); + void enableMenus(); + QSystemTrayIcon *systray; ServerListDlg *serverListDlg; @@ -88,6 +110,7 @@ class MainWin : public QMainWindow, public AbstractUi { QList netViews; + friend class QtGui; }; #endif diff --git a/src/qtgui/ui/coreconnectdlg.ui b/src/qtgui/ui/coreconnectdlg.ui index 12b0be03..1311565b 100644 --- a/src/qtgui/ui/coreconnectdlg.ui +++ b/src/qtgui/ui/coreconnectdlg.ui @@ -5,14 +5,12 @@ 0 0 - 499 - 144 + 498 + 270 - - 5 - 3 + 0 0 @@ -21,64 +19,112 @@ Connect to Quassel Core - :/default/server.png + false - - 9 - - - 6 - - - - Connect to Quassel Core running on: + + + Core Connection Settings + + + + + + + + + + <html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Bitstream Vera Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Host:</span></p></body></html> + + + + + + + quassel.mindpool.net:4242 + + + + + + + <html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Bitstream Vera Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">User:</span></p></body></html> + + + + + + + quasseluser + + + + + + + <html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Bitstream Vera Sans'; font-size:11pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Password:</span></p></body></html> + + + + + + + QLineEdit::Password + + + + + + + Edit... + + + + + + + New... + + + + + + + Remember + + + + + + - - - 0 + + + Qt::Vertical - - 6 + + + 20 + 40 + - - - - Host - - - - - - - - - - Port - - - - - - - 65535 - - - 1024 - - - 4242 - - - - + @@ -91,25 +137,21 @@ - - - Qt::Vertical + + + 6 - - - 20 - 53 - + + 0 - - - - - + 0 - - 6 + + 0 + + + 0 @@ -148,8 +190,9 @@ + - + diff --git a/src/qtgui/ui/mainwin.ui b/src/qtgui/ui/mainwin.ui index ea93b308..82c7e6e9 100644 --- a/src/qtgui/ui/mainwin.ui +++ b/src/qtgui/ui/mainwin.ui @@ -53,6 +53,15 @@ Connection + + + Connect to Core + + + + + + @@ -95,8 +104,14 @@ + + + Core + + + @@ -191,6 +206,26 @@ Import Backlog + + + Connect + + + + + Disconnect + + + + + Internal + + + + + Disconnect from Core + + -- 2.20.1