From: Manuel Nickschas Date: Tue, 7 Aug 2007 19:20:00 +0000 (+0000) Subject: Yay! After months, distributed client/core operation is working again! X-Git-Tag: 0.1.0~173 X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=commitdiff_plain;h=2039f5e28eeb431e394f1c2468a26218bd926538 Yay! After months, distributed client/core operation is working again! There is still some work left concerning menu states, progress bar, and the dialog, and also we don't have user management yet (so you have to use user "Default" and password "password" for both internal and external cores), but basically it's working. This also (finally!) closes BR #17. --- diff --git a/Quassel.kdevelop.filelist b/Quassel.kdevelop.filelist index 07efc40b..e9088246 100644 --- a/Quassel.kdevelop.filelist +++ b/Quassel.kdevelop.filelist @@ -101,3 +101,5 @@ src/client/clientsettings.h src/client/clientsettings.cpp src/qtgui/guisettings.h src/qtgui/guisettings.cpp +src/common/ircuser.h +src/common/ircuser.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7e0244ff..07d2f2ff 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -29,6 +29,7 @@ ENDIF(NOT BUILD_MONO AND NOT BUILD_CORE AND NOT BUILD_QTGUI) #ENDIF(BUILD_CORE OR BUILD_QTGUI) SET(CMAKE_BUILD_TYPE Debug) +SET(GCC_WARN "-Wall -Wextra -ansi -Wno-unused-parameter") # may not be portable! # Define files SET(quassel_mono_SRCS common/build_mono.cpp) @@ -57,6 +58,8 @@ SET(QT_USE_QTUITOOLS true) SET(QT_DONT_USE_QTGUI true) # This is added later if GUI is requested INCLUDE(${QT_USE_FILE}) +ADD_DEFINITIONS(${GCC_WARN}) + # Define subdirs. CMake complains if a directory is added twice, so make sure this # does not happen in any combination of the requested targets. @@ -70,8 +73,6 @@ ENDIF(BUILD_MONO AND NOT BUILD_CORE) QT4_ADD_RESOURCES(_RCCS ${quassel_RCCS}) -ADD_DEFINITIONS(-Wall -Wextra -ansi) # may not be portable! - SET(TARGET_LIST ) IF(BUILD_CORE) diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt index 159b4f1a..d35378e9 100644 --- a/src/client/CMakeLists.txt +++ b/src/client/CMakeLists.txt @@ -3,5 +3,6 @@ SET(client_HDRS ) SET(client_MOCS buffer.h buffertreemodel.h client.h clientproxy.h clientsettings.h treemodel.h) QT4_WRAP_CPP(_MOC ${client_MOCS}) + ADD_LIBRARY(client ${client_SRCS} ${_MOC}) TARGET_LINK_LIBRARIES(client common) \ No newline at end of file diff --git a/src/client/client.cpp b/src/client/client.cpp index c115068f..9257594f 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -73,14 +73,15 @@ void Client::init() { blockSize = 0; connect(&socket, SIGNAL(readyRead()), this, SLOT(serverHasData())); - connect(&socket, SIGNAL(connected()), this, SLOT(coreConnected())); - connect(&socket, SIGNAL(disconnected()), this, SLOT(coreDisconnected())); + connect(&socket, SIGNAL(connected()), this, SLOT(coreSocketConnected())); + connect(&socket, SIGNAL(disconnected()), this, SLOT(coreSocketDisconnected())); connect(&socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(serverError(QAbstractSocket::SocketError))); connect(this, SIGNAL(sendSessionData(const QString &, const QVariant &)), clientProxy, SLOT(gsSessionDataChanged(const QString &, const QVariant &))); connect(clientProxy, SIGNAL(csSessionDataChanged(const QString &, const QVariant &)), this, SLOT(recvSessionData(const QString &, const QVariant &))); connect(clientProxy, SIGNAL(send(ClientSignal, QVariant, QVariant, QVariant)), this, SLOT(recvProxySignal(ClientSignal, QVariant, QVariant, QVariant))); + connect(clientProxy, SIGNAL(csCoreState(QVariant)), this, SLOT(recvCoreState(const QVariant &))); connect(clientProxy, SIGNAL(csServerState(QString, QVariant)), this, SLOT(recvNetworkState(QString, QVariant))); connect(clientProxy, SIGNAL(csServerConnected(QString)), this, SLOT(networkConnected(QString))); connect(clientProxy, SIGNAL(csServerDisconnected(QString)), this, SLOT(networkDisconnected(QString))); @@ -133,7 +134,8 @@ void Client::connectToCore(const VarMap &conn) { } if(conn["Host"].toString().isEmpty()) { clientMode = LocalCore; - syncToCore(); + QVariant state = connectToLocalCore(coreConnectionInfo["User"].toString(), coreConnectionInfo["Password"].toString()); + syncToCore(state); } else { clientMode = RemoteCore; emit coreConnectionMsg(tr("Connecting...")); @@ -146,7 +148,7 @@ void Client::disconnectFromCore() { socket.close(); } else { disconnectFromLocalCore(); - coreDisconnected(); + coreSocketDisconnected(); } /* Clear internal data. Hopefully nothing relies on it at this point. */ coreConnectionInfo.clear(); @@ -158,26 +160,28 @@ void Client::disconnectFromCore() { qDebug() << "foobar"; } -void Client::coreConnected() { - syncToCore(); - +void Client::coreSocketConnected() { + VarMap clientInit; + clientInit["GuiProtocol"] = GUI_PROTOCOL; + clientInit["User"] = coreConnectionInfo["User"].toString(); + clientInit["Password"] = coreConnectionInfo["Password"].toString(); + writeDataToDevice(&socket, clientInit); } -void Client::coreDisconnected() { +void Client::coreSocketDisconnected() { connectedToCore = false; emit disconnected(); } -void Client::syncToCore() { - VarMap state; - if(clientMode == LocalCore) { - state = connectToLocalCore(coreConnectionInfo["User"].toString(), coreConnectionInfo["Password"].toString()).toMap(); - } else { - // TODO connect to remote cores - } +void Client::recvCoreState(const QVariant &state) { + syncToCore(state); - VarMap sessionState = state["SessionState"].toMap(); +} + +void Client::syncToCore(const QVariant &coreState) { + VarMap sessionState = coreState.toMap()["SessionState"].toMap(); VarMap sessData = sessionState["SessionData"].toMap(); + foreach(QString key, sessData.keys()) { recvSessionData(key, sessData[key]); } diff --git a/src/client/client.h b/src/client/client.h index caa21b92..cb031ac9 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -59,6 +59,9 @@ class Client : public QObject { static QVariant retrieveSessionData(const QString &key, const QVariant &def = QVariant()); static QStringList sessionDataKeys(); + enum ClientMode { LocalCore, RemoteCore }; + static ClientMode clientMode; + signals: void sendInput(BufferId, QString message); void showBuffer(Buffer *); @@ -89,13 +92,14 @@ class Client : public QObject { void disconnectFromCore(); private slots: + void recvCoreState(const QVariant &state); void recvSessionData(const QString &key, const QVariant &data); void recvProxySignal(ClientSignal sig, QVariant arg1, QVariant arg2, QVariant arg3); void serverError(QAbstractSocket::SocketError); void serverHasData(); - void coreConnected(); - void coreDisconnected(); + void coreSocketConnected(); + void coreSocketDisconnected(); void userInput(BufferId, QString); void networkConnected(QString); @@ -120,13 +124,10 @@ class Client : public QObject { void init(); static Client *instanceptr; - void syncToCore(); + void syncToCore(const QVariant &coreState); QVariant connectToLocalCore(QString user, QString passwd); // defined in main.cpp void disconnectFromLocalCore(); // defined in main.cpp - enum ClientMode { LocalCore, RemoteCore }; - static ClientMode clientMode; - AbstractUi *mainUi; ClientProxy *clientProxy; BufferTreeModel *_bufferModel; diff --git a/src/common/global.cpp b/src/common/global.cpp index a0c94bb3..cbde79cd 100644 --- a/src/common/global.cpp +++ b/src/common/global.cpp @@ -48,8 +48,6 @@ void Global::initIconMap() { /**************************************************************************************/ - - BufferId::BufferId(uint _id, QString _net, QString _buf, uint _gid) : id(_id), gid(_gid), net(_net), buf(_buf) { @@ -62,14 +60,15 @@ QString BufferId::buffer() const { QDataStream &operator<<(QDataStream &out, const BufferId &bufferId) { out << bufferId.id << bufferId.gid << bufferId.net.toUtf8() << bufferId.buf.toUtf8(); + return out; } QDataStream &operator>>(QDataStream &in, BufferId &bufferId) { QByteArray n, b; - BufferId i; in >> bufferId.id >> bufferId.gid >> n >> b; bufferId.net = QString::fromUtf8(n); bufferId.buf = QString::fromUtf8(b); + return in; } uint qHash(const BufferId &bid) { diff --git a/src/common/main.cpp b/src/common/main.cpp index c47d8b74..fea9d2cc 100644 --- a/src/common/main.cpp +++ b/src/common/main.cpp @@ -22,6 +22,7 @@ #if defined BUILD_CORE #include +#include #include "core.h" #elif defined BUILD_QTGUI @@ -45,6 +46,11 @@ #endif int main(int argc, char **argv) { + qRegisterMetaType("Message"); + qRegisterMetaType("BufferId"); + qRegisterMetaTypeStreamOperators("Message"); + qRegisterMetaTypeStreamOperators("BufferId"); + #if defined BUILD_CORE Global::runMode = Global::CoreOnly; QCoreApplication app(argc, argv); diff --git a/src/common/message.cpp b/src/common/message.cpp index 8b9f1584..837dc35a 100644 --- a/src/common/message.cpp +++ b/src/common/message.cpp @@ -22,10 +22,6 @@ #include QDataStream &operator<<(QDataStream &out, const Message &msg) { - /* - out << (quint32)msg.timeStamp.toTime_t() << (quint8)msg.type << (quint8)msg.flags - << msg.target.toUtf8() << msg.sender.toUtf8() << msg.text.toUtf8(); - */ out << (quint32)msg.timeStamp.toTime_t() << (quint8)msg.type << (quint8)msg.flags << msg.buffer << msg.sender.toUtf8() << msg.text.toUtf8(); return out; @@ -34,13 +30,13 @@ QDataStream &operator<<(QDataStream &out, const Message &msg) { QDataStream &operator>>(QDataStream &in, Message &msg) { quint8 t, f; quint32 ts; - QByteArray s, m, targ; + QByteArray s, m; BufferId buf; in >> ts >> t >> f >> buf >> s >> m; msg.type = (Message::Type)t; msg.flags = (quint8)f; + msg.buffer = buf; msg.timeStamp = QDateTime::fromTime_t(ts); - //msg.target = QString::fromUtf8(targ); msg.sender = QString::fromUtf8(s); msg.text = QString::fromUtf8(m); return in; diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 1f0effef..b7d3be82 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -4,3 +4,4 @@ SET(core_MOCS core.h coreproxy.h coresession.h server.h serverinfo.h sqlitestora QT4_WRAP_CPP(_MOC ${core_MOCS}) ADD_LIBRARY(core ${core_SRCS} ${_MOC}) +TARGET_LINK_LIBRARIES(core common) diff --git a/src/core/core.cpp b/src/core/core.cpp index b3e6d032..98aa4979 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -48,20 +48,8 @@ void Core::init() { //SqliteStorage::init(); storage = new SqliteStorage(); connect(&server, SIGNAL(newConnection()), this, SLOT(incomingConnection())); - //startListening(); // FIXME + startListening(); // FIXME make configurable guiUser = 0; - /* - if(Global::runMode == Global::Monolithic) { // TODO Make GUI user configurable - try { - guiUser = storage->validateUser("Default", "password"); - } catch(Storage::AuthError) { - guiUser = storage->addUser("Default", "password"); - } - Q_ASSERT(guiUser); - Global::setGuiUser(guiUser); - createSession(guiUser); - } else guiUser = 0; - */ } Core::~Core() { @@ -168,16 +156,16 @@ void Core::disconnectLocalClient() { void Core::processClientInit(QTcpSocket *socket, const QVariant &v) { VarMap msg = v.toMap(); - if(msg["GUIProtocol"].toUInt() != GUI_PROTOCOL) { + if(msg["GuiProtocol"].toUInt() != GUI_PROTOCOL) { //qWarning() << "Client version mismatch."; throw Exception("GUI client version mismatch"); } // Auth UserId uid = storage->validateUser(msg["User"].toString(), msg["Password"].toString()); // throws exception if this failed - VarMap reply = initSession(uid).toMap(); + QVariant reply = initSession(uid); validClients[socket] = uid; QList sigdata; - sigdata.append(CS_CORE_STATE); sigdata.append(QVariant(reply)); sigdata.append(QVariant()); sigdata.append(QVariant()); + sigdata.append(CS_CORE_STATE); sigdata.append(reply); sigdata.append(QVariant()); sigdata.append(QVariant()); writeDataToDevice(socket, QVariant(sigdata)); } diff --git a/src/core/coreproxy.h b/src/core/coreproxy.h index 187ddefa..9a48fe0f 100644 --- a/src/core/coreproxy.h +++ b/src/core/coreproxy.h @@ -27,8 +27,7 @@ //#include #include -//#include -//#include +#include /** This class is the Core side of the proxy. The Core connects its signals and slots to it, * and the calls are marshalled and sent to (or received and unmarshalled from) the GuiProxy. @@ -45,7 +44,7 @@ class CoreProxy : public QObject { inline void csServerConnected(QString net) { send(CS_SERVER_CONNECTED, net); } inline void csServerDisconnected(QString net) { send(CS_SERVER_DISCONNECTED, net); } inline void csServerState(QString net, VarMap data) { send(CS_SERVER_STATE, net, data); } - inline void csDisplayMsg(Message msg) { send(CS_DISPLAY_MSG, QVariant::fromValue(msg)); } + inline void csDisplayMsg(Message msg) { send(CS_DISPLAY_MSG, QVariant::fromValue(msg));} inline void csDisplayStatusMsg(QString net, QString msg) { send(CS_DISPLAY_STATUS_MSG, net, msg); } inline void csModeSet(QString net, QString target, QString mode) { send(CS_MODE_SET, net, target, mode); } inline void csTopicSet(QString net, QString buf, QString topic) { send(CS_TOPIC_SET, net, buf, topic); } diff --git a/src/core/coresession.cpp b/src/core/coresession.cpp index ec12da7b..8e1fe93f 100644 --- a/src/core/coresession.cpp +++ b/src/core/coresession.cpp @@ -147,7 +147,7 @@ void CoreSession::recvMessageFromServer(Message::Type type, QString target, QStr buf = storage->getBufferId(user, s->getNetwork(), target); } Message msg(buf, type, text, sender, flags); - msg.msgId = storage->logMessage(msg); //qDebug() << msg.msgId; + msg.msgId = storage->logMessage(msg); Q_ASSERT(msg.msgId); emit displayMsg(msg); } diff --git a/src/core/coresession.h b/src/core/coresession.h index e9631312..54af24ed 100644 --- a/src/core/coresession.h +++ b/src/core/coresession.h @@ -82,10 +82,11 @@ class CoreSession : public QObject { void serverDisconnected(QString net); private: + UserId user; + CoreProxy *coreProxy; Storage *storage; QHash servers; - UserId user; VarMap sessionData; QMutex mutex; diff --git a/src/qtgui/coreconnectdlg.cpp b/src/qtgui/coreconnectdlg.cpp index 401809f6..3b3bb249 100644 --- a/src/qtgui/coreconnectdlg.cpp +++ b/src/qtgui/coreconnectdlg.cpp @@ -31,13 +31,15 @@ CoreConnectDlg::CoreConnectDlg(QWidget *parent, bool /*doAutoConnect*/) : QDialo setAttribute(Qt::WA_DeleteOnClose); coreState = 0; + /* We show ui.internalCore in any case, because we might want to run as monolithic client anyway at another time if(Global::runMode == Global::Monolithic) { connect(ui.internalCore, SIGNAL(toggled(bool)), ui.hostEdit, SLOT(setDisabled(bool))); connect(ui.internalCore, SIGNAL(toggled(bool)), ui.port, SLOT(setDisabled(bool))); ui.internalCore->setChecked(true); } else { - ui.internalCore->hide(); + //ui.internalCore->hide(); } + */ connect(ui.newAccount, SIGNAL(clicked()), this, SLOT(createAccount())); connect(ui.delAccount, SIGNAL(clicked()), this, SLOT(removeAccount())); connect(ui.buttonBox1, SIGNAL(accepted()), this, SLOT(doConnect())); @@ -115,8 +117,7 @@ void CoreConnectDlg::setAccountEditEnabled(bool en) { ui.delAccount->setEnabled(en); ui.internalCore->setEnabled(en); ui.rememberPasswd->setEnabled(en); - //ui.autoConnect->setEnabled(en); - ui.autoConnect->setEnabled(false); // FIXME temporär + ui.autoConnect->setEnabled(en); ui.buttonBox1->button(QDialogButtonBox::Ok)->setEnabled(en && checkInputValid()); } @@ -190,6 +191,7 @@ void CoreConnectDlg::removeAccount() { bool CoreConnectDlg::willDoInternalAutoConnect() { AccountSettings s; + if(Global::runMode != Global::Monolithic) return false; if(ui.autoConnect->isChecked() && s.autoConnectAccount() == curacc && ui.internalCore->isChecked()) { return true; } @@ -209,12 +211,16 @@ void CoreConnectDlg::doConnect() { VarMap conninfo; ui.stackedWidget->setCurrentIndex(1); if(ui.internalCore->isChecked()) { + if(Global::runMode != Global::Monolithic) { + coreConnectionError(tr("Can't connect to internal core, since we are running as a standalone GUI!")); + return; + } ui.connectionGroupBox->setTitle(tr("Connecting to internal core")); ui.connectionProgress->hide(); } else { ui.connectionGroupBox->setTitle(tr("Connecting to %1").arg(ui.hostEdit->text())); conninfo["Host"] = ui.hostEdit->text(); - conninfo["Post"] = ui.port->value(); + conninfo["Port"] = ui.port->value(); } conninfo["User"] = ui.userEdit->text(); conninfo["Password"] = ui.passwdEdit->text();