From 06a03c2c69ee934aaeec83512bae2fffee83a340 Mon Sep 17 00:00:00 2001 From: Manuel Nickschas Date: Wed, 29 Aug 2007 20:44:47 +0000 Subject: [PATCH] YES! We finally have dynamic signals between Core and Client, meaning that arbitrary signals and slots can be attached to the SignalProxy, rather than having hard-coded stuff in the old CoreProxy and ClientProxy classes. This was made possible by integrating QxtRPCPeer from the guys at . Everything should work now as before, except connections to an internal core, which are disabled for the moment. The connection handling had to be completely rewritten, and I still need a QIODevice that can do loopback connections. The code is still a big mess, I am deliberately committing this before clean-up, in case I delete something we still need. Expect a much cleaner version soon. Oh, and VarMap has been substituted by QVariantMap project-wide. We cannot send VarMap through the SignalProxy, and I decided to change the naming consistently everywhere. --- Quassel.kdevelop.filelist | 8 + src/client/buffer.cpp | 6 +- src/client/buffer.h | 10 +- src/client/buffertreemodel.cpp | 9 +- src/client/client.cpp | 203 ++++++--- src/client/client.h | 27 +- src/client/clientproxy.h | 4 +- src/common/global.h | 1 - src/common/main.cpp | 12 +- src/common/quasselui.h | 2 +- src/common/signalproxy.cpp | 21 + src/common/signalproxy.h | 5 +- src/contrib/qxt/CMakeLists.txt | 6 +- src/contrib/qxt/qxtboundcfunction.h | 72 +++ src/contrib/qxt/qxtboundfunction.h | 104 +++++ src/contrib/qxt/qxtboundfunctionbase.h | 53 +++ src/contrib/qxt/qxtglobal.h | 6 +- src/contrib/qxt/qxtmetaobject.cpp | 335 ++++++++++++++ src/contrib/qxt/qxtmetaobject.h | 58 +++ src/contrib/qxt/qxtnull.cpp | 3 + src/contrib/qxt/qxtnull.h | 64 +++ src/contrib/qxt/qxtnullable.h | 145 ++++++ src/contrib/qxt/qxtpimpl.h | 75 +++- src/contrib/qxt/qxtrpcpeer.cpp | 599 ++++++++++++++++--------- src/contrib/qxt/qxtrpcpeer.h | 150 ++++--- src/core/core.cpp | 35 +- src/core/core.h | 4 +- src/core/coreproxy.h | 6 +- src/core/coresession.cpp | 106 +++-- src/core/coresession.h | 24 +- src/core/server.cpp | 52 +-- src/core/server.h | 14 +- src/core/serverinfo.h | 4 +- src/core/sqlitestorage.cpp | 1 + src/qtgui/bufferwidget.cpp | 6 +- src/qtgui/bufferwidget.h | 4 +- src/qtgui/coreconnectdlg.cpp | 17 +- src/qtgui/coreconnectdlg.h | 2 +- src/qtgui/identities.cpp | 20 +- src/qtgui/identities.h | 14 +- src/qtgui/mainwin.cpp | 11 +- src/qtgui/mainwin.h | 2 +- src/qtgui/qtgui.cpp | 2 +- src/qtgui/serverlist.cpp | 48 +- src/qtgui/serverlist.h | 20 +- 45 files changed, 1807 insertions(+), 563 deletions(-) create mode 100644 src/contrib/qxt/qxtboundcfunction.h create mode 100644 src/contrib/qxt/qxtboundfunction.h create mode 100644 src/contrib/qxt/qxtboundfunctionbase.h create mode 100644 src/contrib/qxt/qxtmetaobject.cpp create mode 100644 src/contrib/qxt/qxtmetaobject.h create mode 100644 src/contrib/qxt/qxtnull.cpp create mode 100644 src/contrib/qxt/qxtnull.h create mode 100644 src/contrib/qxt/qxtnullable.h diff --git a/Quassel.kdevelop.filelist b/Quassel.kdevelop.filelist index 51259503..584525a4 100644 --- a/Quassel.kdevelop.filelist +++ b/Quassel.kdevelop.filelist @@ -112,3 +112,11 @@ src/core/serverinfo.h src/contrib/qxt/CMakeLists.txt src/common/signalproxy.cpp src/common/signalproxy.h +src/contrib/qxt/qxtboundcfunction.h +src/contrib/qxt/qxtboundfunctionbase.h +src/contrib/qxt/qxtboundfunction.h +src/contrib/qxt/qxtmetaobject.cpp +src/contrib/qxt/qxtmetaobject.h +src/contrib/qxt/qxtnullable.h +src/contrib/qxt/qxtnull.cpp +src/contrib/qxt/qxtnull.h diff --git a/src/client/buffer.cpp b/src/client/buffer.cpp index 7f4d885a..917d71a2 100644 --- a/src/client/buffer.cpp +++ b/src/client/buffer.cpp @@ -85,7 +85,7 @@ QList Buffer::contents() const { return layoutedMsgs; } -VarMap Buffer::nickList() const { +QVariantMap Buffer::nickList() const { return nicks; } @@ -138,13 +138,13 @@ void Buffer::setTopic(QString t) { emit bufferUpdated(this); } -void Buffer::addNick(QString nick, VarMap props) { +void Buffer::addNick(QString nick, QVariantMap props) { if(nick == ownNick()) setActive(true); nicks[nick] = props; emit nickListChanged(nicks); } -void Buffer::updateNick(QString nick, VarMap props) { +void Buffer::updateNick(QString nick, QVariantMap props) { nicks[nick] = props; emit nickListChanged(nicks); } diff --git a/src/client/buffer.h b/src/client/buffer.h index 8e9bf6c0..76b14404 100644 --- a/src/client/buffer.h +++ b/src/client/buffer.h @@ -55,14 +55,14 @@ class Buffer : public QObject { QString displayName() const; BufferId bufferId() const; QList contents() const; - VarMap nickList() const; + QVariantMap nickList() const; QString topic() const; QString ownNick() const; bool isStatusBuffer() const; signals: void userInput(const BufferId &, QString); - void nickListChanged(VarMap nicks); + void nickListChanged(QVariantMap nicks); void topicSet(QString topic); void ownNickSet(QString ownNick); void bufferUpdated(Buffer *); @@ -79,10 +79,10 @@ class Buffer : public QObject { bool layoutMsg(); void setTopic(QString); //void setNicks(QStringList); - void addNick(QString nick, VarMap props); + void addNick(QString nick, QVariantMap props); void renameNick(QString oldnick, QString newnick); void removeNick(QString nick); - void updateNick(QString nick, VarMap props); + void updateNick(QString nick, QVariantMap props); void setOwnNick(QString nick); void processUserInput(QString); @@ -92,7 +92,7 @@ class Buffer : public QObject { bool active; Type type; - VarMap nicks; + QVariantMap nicks; QString _topic; QString _ownNick; QString _networkName, _bufferName; diff --git a/src/client/buffertreemodel.cpp b/src/client/buffertreemodel.cpp index 54ef7a87..c6fb9964 100644 --- a/src/client/buffertreemodel.cpp +++ b/src/client/buffertreemodel.cpp @@ -20,8 +20,10 @@ #include // FIXME Dependency on QtGui! -#include "clientproxy.h" +#include "client.h" +//#include "clientproxy.h" #include "buffertreemodel.h" +#include "signalproxy.h" /***************************************** * Fancy Buffer Items @@ -116,8 +118,9 @@ Qt::ItemFlags NetworkTreeItem::flags() const { BufferTreeModel::BufferTreeModel(QObject *parent) : TreeModel(BufferTreeModel::defaultHeader(), parent) { - connect(this, SIGNAL(fakeUserInput(BufferId, QString)), - ClientProxy::instance(), SLOT(gsUserInput(BufferId, QString))); + //connect(this, SIGNAL(fakeUserInput(BufferId, QString)), + // ClientProxy::instance(), SLOT(gsUserInput(BufferId, QString))); + Client::signalProxy()->attachSignal(this, SIGNAL(fakeUserInput(BufferId, QString)), SIGNAL(sendInput(BufferId, QString))); } QListBufferTreeModel::defaultHeader() { diff --git a/src/client/client.cpp b/src/client/client.cpp index 85096c7b..3cb067b9 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -22,18 +22,19 @@ #include "buffer.h" #include "buffertreemodel.h" -#include "clientproxy.h" +//#include "clientproxy.h" #include "quasselui.h" +#include "signalproxy.h" #include "util.h" Client * Client::instanceptr = 0; bool Client::connectedToCore = false; Client::ClientMode Client::clientMode; -VarMap Client::coreConnectionInfo; +QVariantMap Client::coreConnectionInfo; QHash Client::buffers; QHash Client::bufferIds; -QHash > Client::nicks; +QHash > Client::nicks; QHash Client::netConnected; QStringList Client::netsAwaitingInit; QHash Client::ownNick; @@ -50,18 +51,14 @@ void Client::destroy() { } Client::Client() { - clientProxy = ClientProxy::instance(); - - _bufferModel = new BufferTreeModel(this); - - connect(this, SIGNAL(bufferSelected(Buffer *)), _bufferModel, SLOT(selectBuffer(Buffer *))); - connect(this, SIGNAL(bufferUpdated(Buffer *)), _bufferModel, SLOT(bufferUpdated(Buffer *))); - connect(this, SIGNAL(bufferActivity(Buffer::ActivityLevel, Buffer *)), _bufferModel, SLOT(bufferActivity(Buffer::ActivityLevel, Buffer *))); + //clientProxy = ClientProxy::instance(); + _signalProxy = new SignalProxy(SignalProxy::Client, 0, this); // TODO: make this configurable (allow monolithic client to connect to remote cores) - if(Global::runMode == Global::Monolithic) clientMode = LocalCore; - else clientMode = RemoteCore; + //if(Global::runMode == Global::Monolithic) clientMode = LocalCore; + //else clientMode = RemoteCore; connectedToCore = false; + socket = 0; } void Client::init(AbstractUi *ui) { @@ -72,34 +69,61 @@ void Client::init(AbstractUi *ui) { void Client::init() { blockSize = 0; - connect(&socket, SIGNAL(readyRead()), this, SLOT(serverHasData())); - 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))); - connect(clientProxy, SIGNAL(csDisplayMsg(Message)), this, SLOT(recvMessage(const Message &))); - connect(clientProxy, SIGNAL(csDisplayStatusMsg(QString, QString)), this, SLOT(recvStatusMsg(QString, QString))); - connect(clientProxy, SIGNAL(csTopicSet(QString, QString, QString)), this, SLOT(setTopic(QString, QString, QString))); - connect(clientProxy, SIGNAL(csNickAdded(QString, QString, VarMap)), this, SLOT(addNick(QString, QString, VarMap))); - connect(clientProxy, SIGNAL(csNickRemoved(QString, QString)), this, SLOT(removeNick(QString, QString))); - connect(clientProxy, SIGNAL(csNickRenamed(QString, QString, QString)), this, SLOT(renameNick(QString, QString, QString))); - connect(clientProxy, SIGNAL(csNickUpdated(QString, QString, VarMap)), this, SLOT(updateNick(QString, QString, VarMap))); - connect(clientProxy, SIGNAL(csOwnNickSet(QString, QString)), this, SLOT(setOwnNick(QString, QString))); - connect(clientProxy, SIGNAL(csBacklogData(BufferId, const QList &, bool)), this, SLOT(recvBacklogData(BufferId, QList, bool))); - 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())); - - connect(mainUi, SIGNAL(connectToCore(const VarMap &)), this, SLOT(connectToCore(const VarMap &))); + _bufferModel = new BufferTreeModel(this); + + connect(this, SIGNAL(bufferSelected(Buffer *)), _bufferModel, SLOT(selectBuffer(Buffer *))); + connect(this, SIGNAL(bufferUpdated(Buffer *)), _bufferModel, SLOT(bufferUpdated(Buffer *))); + connect(this, SIGNAL(bufferActivity(Buffer::ActivityLevel, Buffer *)), _bufferModel, SLOT(bufferActivity(Buffer::ActivityLevel, Buffer *))); + + //connect(&socket, SIGNAL(readyRead()), this, SLOT(serverHasData())); + //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))); + //connect(clientProxy, SIGNAL(csDisplayMsg(Message)), this, SLOT(recvMessage(const Message &))); + //connect(clientProxy, SIGNAL(csDisplayStatusMsg(QString, QString)), this, SLOT(recvStatusMsg(QString, QString))); + //connect(clientProxy, SIGNAL(csTopicSet(QString, QString, QString)), this, SLOT(setTopic(QString, QString, QString))); + //connect(clientProxy, SIGNAL(csNickAdded(QString, QString, QVariantMap)), this, SLOT(addNick(QString, QString, QVariantMap))); + //connect(clientProxy, SIGNAL(csNickRemoved(QString, QString)), this, SLOT(removeNick(QString, QString))); + //connect(clientProxy, SIGNAL(csNickRenamed(QString, QString, QString)), this, SLOT(renameNick(QString, QString, QString))); + //connect(clientProxy, SIGNAL(csNickUpdated(QString, QString, QVariantMap)), this, SLOT(updateNick(QString, QString, QVariantMap))); + //connect(clientProxy, SIGNAL(csOwnNickSet(QString, QString)), this, SLOT(setOwnNick(QString, QString))); + //connect(clientProxy, SIGNAL(csBacklogData(BufferId, const QList &, bool)), this, SLOT(recvBacklogData(BufferId, QList, bool))); + //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())); + + SignalProxy *p = signalProxy(); + p->attachSignal(this, SIGNAL(sendSessionData(const QString &, const QVariant &)), SIGNAL(clientSessionDataChanged(const QString &, const QVariant &))); + p->attachSlot(SIGNAL(coreSessionDataChanged(const QString &, const QVariant &)), this, SLOT(recvSessionData(const QString &, const QVariant &))); + p->attachSlot(SIGNAL(coreState(const QVariant &)), this, SLOT(recvCoreState(const QVariant &))); + p->attachSlot(SIGNAL(networkState(QString, QVariant)), this, SLOT(recvNetworkState(QString, QVariant))); + p->attachSlot(SIGNAL(networkConnected(QString)), this, SLOT(networkConnected(QString))); + p->attachSlot(SIGNAL(networkDisconnected(QString)), this, SLOT(networkDisconnected(QString))); + p->attachSlot(SIGNAL(displayMsg(const Message &)), this, SLOT(recvMessage(const Message &))); + p->attachSlot(SIGNAL(displayStatusMsg(QString, QString)), this, SLOT(recvStatusMsg(QString, QString))); + p->attachSlot(SIGNAL(topicSet(QString, QString, QString)), this, SLOT(setTopic(QString, QString, QString))); + p->attachSlot(SIGNAL(nickAdded(QString, QString, QVariantMap)), this, SLOT(addNick(QString, QString, QVariantMap))); + p->attachSlot(SIGNAL(nickRemoved(QString, QString)), this, SLOT(removeNick(QString, QString))); + p->attachSlot(SIGNAL(nickRenamed(QString, QString, QString)), this, SLOT(renameNick(QString, QString, QString))); + p->attachSlot(SIGNAL(nickUpdated(QString, QString, QVariantMap)), this, SLOT(updateNick(QString, QString, QVariantMap))); + p->attachSlot(SIGNAL(ownNickSet(QString, QString)), this, SLOT(setOwnNick(QString, QString))); + p->attachSlot(SIGNAL(backlogData(BufferId, const QVariantList &, bool)), this, SLOT(recvBacklogData(BufferId, const QVariantList &, bool))); + p->attachSlot(SIGNAL(bufferIdUpdated(BufferId)), this, SLOT(updateBufferId(BufferId))); + p->attachSignal(this, SIGNAL(sendInput(BufferId, QString))); + //p->attachSignal(this, SIGNAL(requestBacklog(BufferId, QVariant, QVariant)), "requestBacklog"); + p->attachSignal(this, SIGNAL(requestNetworkStates())); + + connect(mainUi, SIGNAL(connectToCore(const QVariantMap &)), this, SLOT(connectToCore(const QVariantMap &))); connect(mainUi, SIGNAL(disconnectFromCore()), this, SLOT(disconnectFromCore())); connect(this, SIGNAL(connected()), mainUi, SLOT(connectedToCore())); connect(this, SIGNAL(disconnected()), mainUi, SLOT(disconnectedFromCore())); @@ -114,8 +138,8 @@ void Client::init() { Client::~Client() { //delete mainUi; //delete _bufferModel; - foreach(Buffer *buf, buffers.values()) delete buf; // this is done by disconnectFromCore()! - ClientProxy::destroy(); + foreach(Buffer *buf, buffers.values()) delete buf; // this is done by disconnectFromCore()! FIXME? + //ClientProxy::destroy(); Q_ASSERT(!buffers.count()); } @@ -123,31 +147,54 @@ BufferTreeModel *Client::bufferModel() { return instance()->_bufferModel; } -bool Client::isConnected() { return connectedToCore; } +SignalProxy *Client::signalProxy() { + return instance()->_signalProxy; +} + +bool Client::isConnected() { + return connectedToCore; +} -void Client::connectToCore(const VarMap &conn) { +void Client::connectToCore(const QVariantMap &conn) { // TODO implement SSL coreConnectionInfo = conn; - if(isConnected()) { + if(isConnected() || socket != 0) { emit coreConnectionError(tr("Already connected to Core!")); return; } if(conn["Host"].toString().isEmpty()) { clientMode = LocalCore; - QVariant state = connectToLocalCore(coreConnectionInfo["User"].toString(), coreConnectionInfo["Password"].toString()); - syncToCore(state); + socket = new QBuffer(this); + connect(socket, SIGNAL(readyRead()), this, SLOT(coreHasData())); + socket->open(QIODevice::ReadWrite); + //QVariant state = connectToLocalCore(coreConnectionInfo["User"].toString(), coreConnectionInfo["Password"].toString()); + //syncToCore(state); + coreSocketConnected(); } else { clientMode = RemoteCore; emit coreConnectionMsg(tr("Connecting...")); - socket.connectToHost(conn["Host"].toString(), conn["Port"].toUInt()); + Q_ASSERT(!socket); + QTcpSocket *sock = new QTcpSocket(this); + socket = sock; + connect(sock, SIGNAL(readyRead()), this, SLOT(coreHasData())); + connect(sock, SIGNAL(connected()), this, SLOT(coreSocketConnected())); + connect(sock, SIGNAL(disconnected()), this, SLOT(coreSocketDisconnected())); + connect(signalProxy(), SIGNAL(peerDisconnected()), this, SLOT(coreSocketDisconnected())); + //connect(sock, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(coreSocketStateChanged(QAbstractSocket::SocketState))); + connect(sock, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(coreSocketError(QAbstractSocket::SocketError))); + sock->connectToHost(conn["Host"].toString(), conn["Port"].toUInt()); } } void Client::disconnectFromCore() { if(clientMode == RemoteCore) { - socket.close(); + socket->close(); + //QAbstractSocket *sock = qobject_cast(socket); + //Q_ASSERT(sock); + //sock->disconnectFromHost(); } else { - disconnectFromLocalCore(); + socket->close(); + //disconnectFromLocalCore(); coreSocketDisconnected(); } } @@ -155,16 +202,18 @@ void Client::disconnectFromCore() { void Client::coreSocketConnected() { connect(this, SIGNAL(recvPartialItem(uint, uint)), this, SIGNAL(coreConnectionProgress(uint, uint))); emit coreConnectionMsg(tr("Synchronizing to core...")); - VarMap clientInit; + QVariantMap clientInit; clientInit["GuiProtocol"] = GUI_PROTOCOL; clientInit["User"] = coreConnectionInfo["User"].toString(); clientInit["Password"] = coreConnectionInfo["Password"].toString(); - writeDataToDevice(&socket, clientInit); + writeDataToDevice(socket, clientInit); } void Client::coreSocketDisconnected() { connectedToCore = false; emit disconnected(); + socket->deleteLater(); + /* Clear internal data. Hopefully nothing relies on it at this point. */ _bufferModel->clear(); // Buffers, if deleted, send a signal that causes their removal from buffers and bufferIds. @@ -182,15 +231,25 @@ void Client::coreSocketDisconnected() { layoutTimer->stop(); } +void Client::coreSocketStateChanged(QAbstractSocket::SocketState state) { qDebug() << state; + if(state == QAbstractSocket::UnconnectedState) coreSocketDisconnected(); +} + void Client::recvCoreState(const QVariant &state) { disconnect(this, SIGNAL(recvPartialItem(uint, uint)), this, SIGNAL(coreConnectionProgress(uint, uint))); + disconnect(socket, 0, this, 0); // rest of communication happens through SignalProxy + signalProxy()->addPeer(socket); syncToCore(state); - } void Client::syncToCore(const QVariant &coreState) { - VarMap sessionState = coreState.toMap()["SessionState"].toMap(); - VarMap sessData = sessionState["SessionData"].toMap(); + if(!coreState.toMap().contains("SessionState")) { + emit coreConnectionError(tr("Invalid data received from core!")); + disconnectFromCore(); + return; + } + QVariantMap sessionState = coreState.toMap()["SessionState"].toMap(); + QVariantMap sessData = sessionState["SessionData"].toMap(); foreach(QString key, sessData.keys()) { recvSessionData(key, sessData[key]); @@ -242,24 +301,26 @@ void Client::recvProxySignal(ClientSignal sig, QVariant arg1, QVariant arg2, QVa QList sigdata; sigdata.append(sig); sigdata.append(arg1); sigdata.append(arg2); sigdata.append(arg3); //qDebug() << "Sending signal: " << sigdata; - writeDataToDevice(&socket, QVariant(sigdata)); + writeDataToDevice(socket, QVariant(sigdata)); } -void Client::serverError(QAbstractSocket::SocketError) { - emit coreConnectionError(socket.errorString()); +void Client::coreSocketError(QAbstractSocket::SocketError) { + emit coreConnectionError(socket->errorString()); } -void Client::serverHasData() { +void Client::coreHasData() { QVariant item; - while(readDataFromDevice(&socket, blockSize, item)) { + if(readDataFromDevice(socket, blockSize, item)) { emit recvPartialItem(1,1); - QList sigdata = item.toList(); - Q_ASSERT(sigdata.size() == 4); - ClientProxy::instance()->recv((CoreSignal)sigdata[0].toInt(), sigdata[1], sigdata[2], sigdata[3]); + //QList sigdata = item.toList(); + //Q_ASSERT(sigdata.size() == 4); + //ClientProxy::instance()->recv((CoreSignal)sigdata[0].toInt(), sigdata[1], sigdata[2], sigdata[3]); + recvCoreState(item); blockSize = 0; + return; } if(blockSize > 0) { - emit recvPartialItem(socket.bytesAvailable(), blockSize); + emit recvPartialItem(socket->bytesAvailable(), blockSize); } } @@ -336,8 +397,8 @@ void Client::recvNetworkState(QString net, QVariant state) { netConnected[net] = true; setOwnNick(net, state.toMap()["OwnNick"].toString()); buffer(statusBufferId(net))->setActive(true); - VarMap t = state.toMap()["Topics"].toMap(); - VarMap n = state.toMap()["Nicks"].toMap(); + QVariantMap t = state.toMap()["Topics"].toMap(); + QVariantMap n = state.toMap()["Nicks"].toMap(); foreach(QVariant v, t.keys()) { QString buf = v.toString(); BufferId id = bufferId(net, buf); @@ -371,7 +432,7 @@ void Client::recvStatusMsg(QString /*net*/, QString /*msg*/) { } -void Client::recvBacklogData(BufferId id, const QList &msgs, bool /*done*/) { +void Client::recvBacklogData(BufferId id, QVariantList msgs, bool /*done*/) { Buffer *b = buffer(id); foreach(QVariant v, msgs) { Message msg = v.value(); @@ -408,10 +469,10 @@ void Client::setTopic(QString net, QString buf, QString topic) { //} } -void Client::addNick(QString net, QString nick, VarMap props) { +void Client::addNick(QString net, QString nick, QVariantMap props) { if(!netConnected[net]) return; nicks[net][nick] = props; - VarMap chans = props["Channels"].toMap(); + QVariantMap chans = props["Channels"].toMap(); QStringList c = chans.keys(); foreach(QString bufname, c) { buffer(bufferId(net, bufname))->addNick(nick, props); @@ -427,7 +488,7 @@ void Client::renameNick(QString net, QString oldnick, QString newnick) { nicks[net][newnick] = nicks[net].take(oldnick); } -void Client::updateNick(QString net, QString nick, VarMap props) { +void Client::updateNick(QString net, QString nick, QVariantMap props) { if(!netConnected[net]) return; QStringList oldchans = nicks[net][nick]["Channels"].toMap().keys(); QStringList newchans = props["Channels"].toMap().keys(); @@ -443,7 +504,7 @@ void Client::updateNick(QString net, QString nick, VarMap props) { void Client::removeNick(QString net, QString nick) { if(!netConnected[net]) return; - VarMap chans = nicks[net][nick]["Channels"].toMap(); + QVariantMap chans = nicks[net][nick]["Channels"].toMap(); foreach(QString bufname, chans.keys()) { buffer(bufferId(net, bufname))->removeNick(nick); } diff --git a/src/client/client.h b/src/client/client.h index a55a92b2..9d7df3ee 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -24,6 +24,7 @@ #include #include #include +#include #include "buffer.h" #include "message.h" @@ -33,6 +34,7 @@ class AbstractUi; class ClientProxy; class BufferTreeModel; class QtGui; +class SignalProxy; class QTimer; @@ -50,6 +52,7 @@ class Client : public QObject { static BufferId bufferId(QString net, QString buf); static BufferTreeModel *bufferModel(); + static SignalProxy *signalProxy(); static AbstractUiMsg *layoutMsg(const Message &); @@ -88,7 +91,7 @@ class Client : public QObject { public slots: //void selectBuffer(Buffer *); //void connectToLocalCore(); - void connectToCore(const VarMap &); + void connectToCore(const QVariantMap &); void disconnectFromCore(); private slots: @@ -96,10 +99,11 @@ class Client : public QObject { 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 coreSocketError(QAbstractSocket::SocketError); + void coreHasData(); void coreSocketConnected(); void coreSocketDisconnected(); + void coreSocketStateChanged(QAbstractSocket::SocketState); void userInput(BufferId, QString); void networkConnected(QString); @@ -108,12 +112,12 @@ class Client : public QObject { void recvMessage(const Message &message); void recvStatusMsg(QString network, QString message); void setTopic(QString net, QString buf, QString); - void addNick(QString net, QString nick, VarMap props); + void addNick(QString net, QString nick, QVariantMap props); void removeNick(QString net, QString nick); void renameNick(QString net, QString oldnick, QString newnick); - void updateNick(QString net, QString nick, VarMap props); + void updateNick(QString net, QString nick, QVariantMap props); void setOwnNick(QString net, QString nick); - void recvBacklogData(BufferId, const QList &, bool); + void recvBacklogData(BufferId, QVariantList, bool); void updateBufferId(BufferId); void removeBuffer(Buffer *); @@ -131,17 +135,18 @@ class Client : public QObject { void disconnectFromLocalCore(); // defined in main.cpp AbstractUi *mainUi; - ClientProxy *clientProxy; + //ClientProxy *clientProxy; + SignalProxy *_signalProxy; BufferTreeModel *_bufferModel; - QTcpSocket socket; + QPointer socket; quint32 blockSize; static bool connectedToCore; - static VarMap coreConnectionInfo; + static QVariantMap coreConnectionInfo; static QHash buffers; static QHash bufferIds; - static QHash > nicks; + static QHash > nicks; static QHash netConnected; static QStringList netsAwaitingInit; static QHash ownNick; @@ -149,7 +154,7 @@ class Client : public QObject { QTimer *layoutTimer; QList layoutQueue; - VarMap sessionData; + QVariantMap sessionData; }; #endif diff --git a/src/client/clientproxy.h b/src/client/clientproxy.h index 4845faf0..e579e121 100644 --- a/src/client/clientproxy.h +++ b/src/client/clientproxy.h @@ -55,10 +55,10 @@ class ClientProxy : public QObject { void csSessionDataChanged(const QString &key, const QVariant &data); void csModeSet(QString, QString, QString); void csTopicSet(QString, QString, QString); - void csNickAdded(QString, QString, VarMap); + void csNickAdded(QString, QString, QVariantMap); void csNickRemoved(QString, QString); void csNickRenamed(QString, QString, QString); - void csNickUpdated(QString, QString, VarMap); + void csNickUpdated(QString, QString, QVariantMap); void csOwnNickSet(QString, QString); void csQueryRequested(QString, QString); void csBacklogData(BufferId, QList, bool); diff --git a/src/common/global.h b/src/common/global.h index c672c402..4ec49eb8 100644 --- a/src/common/global.h +++ b/src/common/global.h @@ -35,7 +35,6 @@ #include /* Some global stuff */ -typedef QMap VarMap; typedef uint UserId; typedef uint MsgId; diff --git a/src/common/main.cpp b/src/common/main.cpp index 86d874b5..4b99a39e 100644 --- a/src/common/main.cpp +++ b/src/common/main.cpp @@ -25,18 +25,19 @@ #include #include #include "core.h" +#include "message.h" #elif defined BUILD_QTGUI #include #include "client.h" -#include "clientproxy.h" +//#include "clientproxy.h" #include "qtgui.h" #include "style.h" #elif defined BUILD_MONO #include #include "client.h" -#include "clientproxy.h" +//#include "clientproxy.h" #include "core.h" #include "coresession.h" #include "qtgui.h" @@ -59,8 +60,10 @@ int main(int argc, char **argv) { signal(SIGTERM, handle_signal); signal(SIGINT, handle_signal); + qRegisterMetaType("QVariant"); qRegisterMetaType("Message"); qRegisterMetaType("BufferId"); + qRegisterMetaTypeStreamOperators("QVariant"); qRegisterMetaTypeStreamOperators("Message"); qRegisterMetaTypeStreamOperators("BufferId"); @@ -115,16 +118,21 @@ 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; + */ + return QVariant(); } 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/quasselui.h b/src/common/quasselui.h index 5cfc5f05..414d5993 100644 --- a/src/common/quasselui.h +++ b/src/common/quasselui.h @@ -49,7 +49,7 @@ class AbstractUi : public QObject { virtual void disconnectedFromCore() {} signals: - void connectToCore(const VarMap &connInfo); + void connectToCore(const QVariantMap &connInfo); void disconnectFromCore(); }; diff --git a/src/common/signalproxy.cpp b/src/common/signalproxy.cpp index bd12b15f..d6c105b3 100644 --- a/src/common/signalproxy.cpp +++ b/src/common/signalproxy.cpp @@ -44,6 +44,7 @@ void SignalProxy::addPeer(QIODevice *dev) { Connection conn; conn.device = dev; conn.peer = new QxtRPCPeer(dev, QxtRPCPeer::Peer, this); + connect(conn.peer, SIGNAL(peerDisconnected()), this, SLOT(socketDisconnected())); foreach(SlotDesc slot, attachedSlots) { conn.peer->attachSlot(slot.rpcFunction, slot.recv, slot.slot); @@ -55,6 +56,20 @@ void SignalProxy::addPeer(QIODevice *dev) { } +void SignalProxy::socketDisconnected() { + for(int i = 0; i < peers.count(); i++) { + Connection conn = peers[i]; + QAbstractSocket *sock = qobject_cast(conn.device); + if(!sock) continue; + if(sock->state() == QAbstractSocket::UnconnectedState) { + peers[i].peer->deleteLater(); peers[i].device->deleteLater(); + peers.removeAt(i); + emit peerDisconnected(); + i--; + } + } +} + void SignalProxy::attachSignal(QObject* sender, const char* signal, const QByteArray& rpcFunction) { foreach(Connection conn, peers) { conn.peer->attachSignal(sender, signal, rpcFunction); @@ -79,3 +94,9 @@ void SignalProxy::detachObject(QObject* obj) { } +void SignalProxy::sendSignal(const char *signal, QVariant p1, QVariant p2, QVariant p3, QVariant p4, QVariant p5, QVariant p6, QVariant p7, QVariant p8, QVariant p9) { + foreach(Connection conn, peers) { + conn.peer->call(signal, p1, p2, p3, p4, p5, p6, p7, p8, p9); + } +} + diff --git a/src/common/signalproxy.h b/src/common/signalproxy.h index 90daddeb..ed8b46b0 100644 --- a/src/common/signalproxy.h +++ b/src/common/signalproxy.h @@ -45,12 +45,13 @@ class SignalProxy : public QObject { void sendSignal(const char *signal, QVariant p1 = QVariant(), QVariant p2 = QVariant(), QVariant p3 = QVariant(), QVariant p4 = QVariant(), QVariant p5 = QVariant(), QVariant p6 = QVariant(), QVariant p7 = QVariant(), QVariant p8 = QVariant(), QVariant p9 = QVariant()); - void detachSender(); + //void detachSender(); signals: - //void peerDisconnected(); + void peerDisconnected(); private slots: + void socketDisconnected(); private: struct Connection { diff --git a/src/contrib/qxt/CMakeLists.txt b/src/contrib/qxt/CMakeLists.txt index 9f3c2f2d..cd8448fd 100644 --- a/src/contrib/qxt/CMakeLists.txt +++ b/src/contrib/qxt/CMakeLists.txt @@ -1,6 +1,6 @@ -SET(qxt_SRCS qxtrpcpeer.cpp) -SET(qxt_HDRS qxtglobal.h qxtpimpl.h) -SET(qxt_MOCS qxtrpcpeer.h) +SET(qxt_SRCS qxtmetaobject.cpp qxtnull.cpp qxtrpcpeer.cpp) +SET(qxt_HDRS qxtboundcfunction.h qxtboundfunctionbase.h qxtboundfunction.h qxtglobal.h qxtpimpl.h qxtmetaobject.h qxtnullable.h qxtnull.h) +SET(qxt_MOCS qxtboundfunction.h qxtrpcpeer.h) QT4_WRAP_CPP(_MOC ${qxt_MOCS}) ADD_LIBRARY(qxt ${qxt_SRCS} ${_MOC}) diff --git a/src/contrib/qxt/qxtboundcfunction.h b/src/contrib/qxt/qxtboundcfunction.h new file mode 100644 index 00000000..02ba5961 --- /dev/null +++ b/src/contrib/qxt/qxtboundcfunction.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) Qxt Foundation. Some rights reserved. +** +** This file is part of the QxtCore module of the Qt eXTension library +** +** This library is free software; you can redistribute it and/or modify it +** under the terms of th Common Public License, version 1.0, as published by +** IBM. +** +** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY +** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY +** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR +** FITNESS FOR A PARTICULAR PURPOSE. +** +** You should have received a copy of the CPL along with this file. +** See the LICENSE file and the cpl1.0.txt file included with the source +** distribution for more information. If you did not receive a copy of the +** license, contact the Qxt Foundation. +** +** +** +****************************************************************************/ + +#ifndef QXTBOUNDCFUNCTION_H +#define QXTBOUNDCFUNCTION_H + +#include +#include +#include +#include +#include +#include +#include +/* +template +class QxtBoundCFunction : public QxtBoundFunctionBase { +public: + FUNCTION funcPtr; + + QxtBoundCFunction(QObject* parent, FUNCTION funcPointer, QGenericArgument* params[argc], QByteArray types[argc]) : QxtBoundFunctionBase(parent, params, types), funcPtr(funcPointer) { + // initializers only, thanks to template magic + } + + virtual bool invokeImpl(Qt::ConnectionType type, QGenericReturnArgument returnValue, QXT_IMPL_10ARGS(QGenericArgument)) { + return qxt_invoke_cfunction_return(funcPtr, returnValue, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); + } +}; + +template +class QxtBoundCFunction : public QxtBoundFunctionBase { +public: + FUNCTION funcPtr; + + QxtBoundCFunction(QObject* parent, FUNCTION funcPointer, QGenericArgument* params[argc], QByteArray types[argc]) : QxtBoundFunctionBase(parent, params, types), funcPtr(funcPointer) { + // initializers only, thanks to template magic + } + + virtual bool invokeImpl(Qt::ConnectionType type, QGenericReturnArgument returnValue, QXT_IMPL_10ARGS(QGenericArgument)) { + return qxt_invoke_cfunction(funcPtr, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); + } +}; + +QGenericArgument* qbcfP[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +QByteArray types[10] = { "", "", "", "", "", "", "", "", "", "" }; + +void testFunction(int a) { a++; return; } +template < typename FP > QxtBoundFunction* testBind(FP fn) { return new QxtBoundCFunction(0, fn, qbcfP, types); } +QxtBoundCFunction qbcf(0, testFunction, qbcfP, types); +QxtBoundFunction* qbf = testBind(testFunction); +*/ +#endif diff --git a/src/contrib/qxt/qxtboundfunction.h b/src/contrib/qxt/qxtboundfunction.h new file mode 100644 index 00000000..80d02941 --- /dev/null +++ b/src/contrib/qxt/qxtboundfunction.h @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) Qxt Foundation. Some rights reserved. +** +** This file is part of the QxtCore module of the Qt eXTension library +** +** This library is free software; you can redistribute it and/or modify it +** under the terms of th Common Public License, version 1.0, as published by +** IBM. +** +** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY +** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY +** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR +** FITNESS FOR A PARTICULAR PURPOSE. +** +** You should have received a copy of the CPL along with this file. +** See the LICENSE file and the cpl1.0.txt file included with the source +** distribution for more information. If you did not receive a copy of the +** license, contact the Qxt Foundation. +** +** +** +****************************************************************************/ + +#ifndef QXTBOUNDFUNCTION_H +#define QXTBOUNDFUNCTION_H + +#include +#include +#include +#include +#include +#include + +class QxtBoundFunction : public QObject +{ + Q_OBJECT +public: + template + inline QxtNullable invoke(QXT_PROTO_10ARGS(QVariant)) + { + if (QThread::currentThread() == parent()->thread()) + return invoke(Qt::DirectConnection, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); +#if QT_VERSION >= 0x040300 + return invoke(Qt::BlockingQueuedConnection, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); +#else + qWarning() << "QxtBoundFunction::invoke: Cannot return a value using a queued connection"; + return QxtNull; +#endif + } + + template + QxtNullable invoke(Qt::ConnectionType type, QXT_PROTO_10ARGS(QVariant)) + { + if (type == Qt::QueuedConnection) + { + qWarning() << "QxtBoundFunction::invoke: Cannot return a value using a queued connection"; + return qxtNull; + } + T retval; + // I know this is a totally ugly function call + if (invoke(type, QGenericReturnArgument(qVariantFromValue(*reinterpret_cast(0)).typeName(), reinterpret_cast(&retval)), + p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)) + { + return retval; + } + else + { + return qxtNull; + } + } + + inline bool invoke(QXT_PROTO_10ARGS(QVariant)) + { + return invoke(Qt::AutoConnection, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); + } + bool invoke(Qt::ConnectionType, QXT_PROTO_10ARGS(QVariant)); + + inline bool invoke(QXT_PROTO_10ARGS(QGenericArgument)) + { + return invoke(Qt::AutoConnection, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); + } + inline bool invoke(Qt::ConnectionType type, QXT_PROTO_10ARGS(QGenericArgument)) { + return invoke(type, QGenericReturnArgument(), p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); + } + + inline bool invoke(QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QVariant)) + { + return invoke(Qt::AutoConnection, returnValue, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); + } + bool invoke(Qt::ConnectionType type, QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QVariant)); + + inline bool invoke(QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument)) + { + return invoke(Qt::AutoConnection, returnValue, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); + } + bool invoke(Qt::ConnectionType type, QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument)); + +protected: + QxtBoundFunction(QObject* parent = 0); + virtual bool invokeImpl(Qt::ConnectionType type, QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument)) = 0; +}; + +#endif diff --git a/src/contrib/qxt/qxtboundfunctionbase.h b/src/contrib/qxt/qxtboundfunctionbase.h new file mode 100644 index 00000000..1be80f0f --- /dev/null +++ b/src/contrib/qxt/qxtboundfunctionbase.h @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) Qxt Foundation. Some rights reserved. +** +** This file is part of the QxtCore module of the Qt eXTension library +** +** This library is free software; you can redistribute it and/or modify it +** under the terms of th Common Public License, version 1.0, as published by +** IBM. +** +** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY +** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY +** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR +** FITNESS FOR A PARTICULAR PURPOSE. +** +** You should have received a copy of the CPL along with this file. +** See the LICENSE file and the cpl1.0.txt file included with the source +** distribution for more information. If you did not receive a copy of the +** license, contact the Qxt Foundation. +** +** +** +****************************************************************************/ + +// This file exists for the convenience of QxtBoundCFunction. +// It is not part of the public API and is subject to change. +// +// We mean it. + +#ifndef QXTBOUNDFUNCTIONBASE_H +#define QXTBOUNDFUNCTIONBASE_H + +#include +#include +#include +#include +#include + +class QxtBoundFunctionBase : public QxtBoundFunction +{ +public: + QByteArray bindTypes[10]; + QGenericArgument arg[10], p[10]; + void* data[10]; + + QxtBoundFunctionBase(QObject* parent, QGenericArgument* params[10], QByteArray types[10]); + virtual ~QxtBoundFunctionBase(); + + int qt_metacall(QMetaObject::Call _c, int _id, void **_a); + bool invokeBase(Qt::ConnectionType type, QGenericReturnArgument returnValue, QXT_PROTO_10ARGS(QGenericArgument)); +}; + +#endif diff --git a/src/contrib/qxt/qxtglobal.h b/src/contrib/qxt/qxtglobal.h index 4a2e6b77..2fff0495 100644 --- a/src/contrib/qxt/qxtglobal.h +++ b/src/contrib/qxt/qxtglobal.h @@ -11,13 +11,13 @@ ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR -** FITNESS FOR A PARTICULAR PURPOSE. +** FITNESS FOR A PARTICULAR PURPOSE. ** ** You should have received a copy of the CPL along with this file. ** See the LICENSE file and the cpl1.0.txt file included with the source ** distribution for more information. If you did not receive a copy of the ** license, contact the Qxt Foundation. -** +** ** ** ****************************************************************************/ @@ -80,7 +80,7 @@ -#define QXT_VERSION ( (2<<16) + (2<<8) + 3 ) +#define QXT_VERSION ( (2<<16) + (2<<8) + 3 ) diff --git a/src/contrib/qxt/qxtmetaobject.cpp b/src/contrib/qxt/qxtmetaobject.cpp new file mode 100644 index 00000000..e6aa03cb --- /dev/null +++ b/src/contrib/qxt/qxtmetaobject.cpp @@ -0,0 +1,335 @@ +/**************************************************************************** +** +** Copyright (C) Qxt Foundation. Some rights reserved. +** +** This file is part of the QxtCore module of the Qt eXTension library +** +** This library is free software; you can redistribute it and/or modify it +** under the terms of th Common Public License, version 1.0, as published by +** IBM. +** +** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY +** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY +** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR +** FITNESS FOR A PARTICULAR PURPOSE. +** +** You should have received a copy of the CPL along with this file. +** See the LICENSE file and the cpl1.0.txt file included with the source +** distribution for more information. If you did not receive a copy of the +** license, contact the Qxt Foundation. +** +** +** +****************************************************************************/ +/** +\class QxtMetaObject QxtMetaObject + +\ingroup core + +\brief provides extensions to QMetaObject + +including QxtMetaObject::bind \n + +*/ +#include "qxtmetaobject.h" +#include "qxtboundfunction.h" +#include "qxtboundcfunction.h" + +#include +#include +#include +#include + +class QxtBoundArgument +{ + // This class intentionally left blank +}; +Q_DECLARE_METATYPE(QxtBoundArgument) + +class QxtBoundFunctionBase; + +QxtBoundFunction::QxtBoundFunction(QObject* parent) : QObject(parent) +{ + // initializer only +} + +#define QXT_ARG(i) ((argCount>i)?QGenericArgument(p ## i .typeName(), p ## i .constData()):QGenericArgument()) +#define QXT_VAR_ARG(i) (p ## i .isValid())?QGenericArgument(p ## i .typeName(), p ## i .constData()):QGenericArgument() +bool QxtBoundFunction::invoke(Qt::ConnectionType type, QXT_IMPL_10ARGS(QVariant)) +{ + return invoke(type, QXT_VAR_ARG(1), QXT_VAR_ARG(2), QXT_VAR_ARG(3), QXT_VAR_ARG(4), QXT_VAR_ARG(5), QXT_VAR_ARG(6), QXT_VAR_ARG(7), QXT_VAR_ARG(8), QXT_VAR_ARG(9), QXT_VAR_ARG(10)); +} + +bool QxtBoundFunction::invoke(Qt::ConnectionType type, QGenericReturnArgument returnValue, QXT_IMPL_10ARGS(QVariant)) +{ + return invoke(type, returnValue, QXT_VAR_ARG(1), QXT_VAR_ARG(2), QXT_VAR_ARG(3), QXT_VAR_ARG(4), QXT_VAR_ARG(5), QXT_VAR_ARG(6), QXT_VAR_ARG(7), QXT_VAR_ARG(8), QXT_VAR_ARG(9), QXT_VAR_ARG(10)); +} + +QxtBoundFunctionBase::QxtBoundFunctionBase(QObject* parent, QGenericArgument* params[10], QByteArray types[10]) : QxtBoundFunction(parent) +{ + for (int i=0; i<10; i++) + { + if (!params[i]) break; + if (QByteArray(params[i]->name()) == "QxtBoundArgument") + { + arg[i] = QGenericArgument("QxtBoundArgument", params[i]->data()); + } + else + { + data[i] = QMetaType::construct(QMetaType::type(params[i]->name()), params[i]->data()); + arg[i] = p[i] = QGenericArgument(params[i]->name(), data[i]); + } + bindTypes[i] = types[i]; + } +} + +QxtBoundFunctionBase::~QxtBoundFunctionBase() +{ + for (int i=0; i<10; i++) + { + if (arg[i].name() == 0) return; + if (QByteArray(arg[i].name()) != "QxtBoundArgument") QMetaType::destroy(QMetaType::type(arg[i].name()), arg[i].data()); + } +} + +int QxtBoundFunctionBase::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + _id = QObject::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + if (_c == QMetaObject::InvokeMetaMethod) + { + if (_id == 0) + { + for (int i = 0; i < 10; i++) + { + if (QByteArray(arg[i].name()) == "QxtBoundArgument") + { + p[i] = QGenericArgument(bindTypes[i].constData(), _a[(quintptr)(arg[i].data())]); + } + } + invokeImpl(Qt::DirectConnection, QGenericReturnArgument(), p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9]); + } + _id = -1; + } + return _id; +} + +bool QxtBoundFunctionBase::invokeBase(Qt::ConnectionType type, QGenericReturnArgument returnValue, QXT_IMPL_10ARGS(QGenericArgument)) +{ + QGenericArgument* args[10] = { &p1, &p2, &p3, &p4, &p5, &p6, &p7, &p8, &p9, &p10 }; + for (int i = 0; i < 10; i++) + { + if (QByteArray(arg[i].name()) == "QxtBoundArgument") + { + p[i] = *args[(quintptr)(arg[i].data())-1]; + } + } + return invokeImpl(type, returnValue, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9]); +} + +bool QxtBoundFunction::invoke(Qt::ConnectionType type, QGenericReturnArgument returnValue, QXT_IMPL_10ARGS(QGenericArgument)) +{ + return reinterpret_cast(this)->invokeBase(type, returnValue, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); +} + +class QxtBoundSlot : public QxtBoundFunctionBase +{ +public: + QByteArray sig; + + QxtBoundSlot(QObject* receiver, const char* invokable, QGenericArgument* params[10], QByteArray types[10]) : QxtBoundFunctionBase(receiver, params, types), sig(invokable) + { + // initializers only + } + + virtual bool invokeImpl(Qt::ConnectionType type, QGenericReturnArgument returnValue, QXT_IMPL_10ARGS(QGenericArgument)) + { + if (!QMetaObject::invokeMethod(parent(), QxtMetaObject::methodName(sig.constData()), type, returnValue, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)) + { + qWarning() << "QxtBoundFunction: call to" << sig << "failed"; + return false; + } + return true; + } +}; + +namespace QxtMetaObject +{ + +/*! +\relates QxtMetaObject + + \fn methodName(const char* method) + + Returns the name of the given method. + + Example usage: + \code + QByteArray method = QxtMetaObject::methodName(" int foo ( int bar, double baz )"); + // method is now "foo" + \endcode + */ +QByteArray methodName(const char* method) +{ + QByteArray name = methodSignature(method); + const int idx = name.indexOf("("); + if (idx != -1) + name.truncate(idx); + return name; +} + +/*! +\relates QxtMetaObject + +\fn methodSignature(const char* method) + +Returns the signature of the given method. + */ +QByteArray methodSignature(const char* method) +{ + QByteArray name = QMetaObject::normalizedSignature(method); + if (name.startsWith("1") || name.startsWith("2")) + return name.mid(1); + return name; +} + +/*! +\relates QxtMetaObject + +\fn bool isSignalOrSlot(const char* method) + +checks if \p method contains parantesis and begins with 1 or 2 */ +bool isSignalOrSlot (const char* method) +{ + QByteArray m(method); + return (m.count() && (m[0] == '1'||m[0] == '2') && m.contains('(') && m.contains(')')); +} + +/** +\relates QxtMetaObject +\fn bind(QObject* recv, const char* invokable, QXT_IMPL_10ARGS(QVariant)) + +creates a QxtBoundFunction from a slot + arguments \n +can be used for QxtMetaObject::connect \ + +\code +QxtMetaObject::connect(\n + this, SIGNAL(init()), \\n + QxtMetaObject::bind(this, SLOT(say(QString)), Q_ARG(QString,"hello"))); +\endcode +\n +\code +QxtMetaObject::connect( \n + this, SIGNAL(init(int i)), \n + QxtMetaObject::bind(this, SLOT(say(QString),int), Q_ARG(QString,"hello"),Q_BIND(1))); +\endcode + + */ +QxtBoundFunction* bind(QObject* recv, const char* invokable, QXT_IMPL_10ARGS(QVariant)) +{ + if (!recv) + { + qWarning() << "QxtMetaObject::bind: cannot connect to null QObject"; + return 0; + } + + QVariant* args[10] = { &p1, &p2, &p3, &p4, &p5, &p6, &p7, &p8, &p9, &p10 }; + QByteArray connSlot("2"), recvSlot(QMetaObject::normalizedSignature(invokable)); + const QMetaObject* meta = recv->metaObject(); + int methodID = meta->indexOfMethod(QxtMetaObject::methodSignature(recvSlot.constData())); + if (methodID == -1) + { + qWarning() << "QxtMetaObject::bind: no such method " << recvSlot; + return 0; + } + QMetaMethod method = meta->method(methodID); + int argCount = method.parameterTypes().count(); + const QList paramTypes = method.parameterTypes(); + + for (int i=0; icanConvert((QVariant::Type)type)) + { + qWarning() << "QxtMetaObject::bind: incompatible parameter list for " << recvSlot; + return 0; + } + } + + return QxtMetaObject::bind(recv, invokable, QXT_ARG(1), QXT_ARG(2), QXT_ARG(3), QXT_ARG(4), QXT_ARG(5), QXT_ARG(6), QXT_ARG(7), QXT_ARG(8), QXT_ARG(9), QXT_ARG(10)); +} + +QxtBoundFunction* bind(QObject* recv, const char* invokable, QXT_IMPL_10ARGS(QGenericArgument)) +{ + if (!recv) + { + qWarning() << "QxtMetaObject::bind: cannot connect to null QObject"; + return 0; + } + + QGenericArgument* args[10] = { &p1, &p2, &p3, &p4, &p5, &p6, &p7, &p8, &p9, &p10 }; + QByteArray connSlot("2"), recvSlot(QMetaObject::normalizedSignature(invokable)), bindTypes[10]; + const QMetaObject* meta = recv->metaObject(); + int methodID = meta->indexOfMethod(QxtMetaObject::methodSignature(recvSlot.constData()).constData()); + if (methodID == -1) + { + qWarning() << "QxtMetaObject::bind: no such method " << recvSlot; + return 0; + } + QMetaMethod method = meta->method(methodID); + int argCount = method.parameterTypes().count(); + + connSlot += QxtMetaObject::methodName(invokable) + "("; + for (int i=0; i<10; i++) + { + if (args[i]->name() == 0) break; // done + if (i >= argCount) + { + qWarning() << "QxtMetaObject::bind: too many arguments passed to " << invokable; + return 0; + } + if (i > 0) connSlot += ","; // argument separator + if (QByteArray(args[i]->name()) == "QxtBoundArgument") + { + Q_ASSERT_X((quintptr)(args[i]->data()) > 0 && (quintptr)(args[i]->data()) <= 10, "QXT_BIND", "invalid argument number"); + connSlot += method.parameterTypes()[i]; + bindTypes[i] = method.parameterTypes()[i]; + } + else + { + connSlot += args[i]->name(); // type name + } + } + connSlot = QMetaObject::normalizedSignature(connSlot += ")"); + + if (!QMetaObject::checkConnectArgs(recvSlot.constData(), connSlot.constData())) + { + qWarning() << "QxtMetaObject::bind: provided parameters " << connSlot.mid(connSlot.indexOf('(')) << " is incompatible with " << invokable; + return 0; + } + + return new QxtBoundSlot(recv, invokable, args, bindTypes); +} + +/** +\relates QxtMetaObject +\fn connect(QObject* sender, const char* signal, QxtBoundFunction* slot, Qt::ConnectionType type) { + +connects a signal to a QxtBoundFunction \n + */ +bool connect(QObject* sender, const char* signal, QxtBoundFunction* slot, Qt::ConnectionType type) +{ + const QMetaObject* meta = sender->metaObject(); + int methodID = meta->indexOfMethod(meta->normalizedSignature(signal).mid(1).constData()); + if (methodID < 0) + { + qWarning() << "QxtMetaObject::connect: no such signal: " << QByteArray(signal).mid(1); + return false; + } + + return QMetaObject::connect(sender, methodID, slot, QObject::staticMetaObject.methodCount(), (int)(type)); +} + +} diff --git a/src/contrib/qxt/qxtmetaobject.h b/src/contrib/qxt/qxtmetaobject.h new file mode 100644 index 00000000..02adaae7 --- /dev/null +++ b/src/contrib/qxt/qxtmetaobject.h @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) Qxt Foundation. Some rights reserved. +** +** This file is part of the QxtCore module of the Qt eXTension library +** +** This library is free software; you can redistribute it and/or modify it +** under the terms of th Common Public License, version 1.0, as published by +** IBM. +** +** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY +** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY +** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR +** FITNESS FOR A PARTICULAR PURPOSE. +** +** You should have received a copy of the CPL along with this file. +** See the LICENSE file and the cpl1.0.txt file included with the source +** distribution for more information. If you did not receive a copy of the +** license, contact the Qxt Foundation. +** +** +** +****************************************************************************/ +#ifndef QXTMETAOBJECT_H +#define QXTMETAOBJECT_H + +#include +#include +#include +#include "qxtnullable.h" +class QByteArray; +class QxtBoundArgument; +class QxtBoundFunction; + +#define QXT_PROTO_10ARGS(T) T p1 = T(), T p2 = T(), T p3 = T(), T p4 = T(), \ + T p5 = T(), T p6 = T(), T p7 = T(), T p8 = T(), T p9 = T(), T p10 = T() +#define QXT_IMPL_10ARGS(T) T p1, T p2, T p3, T p4, T p5, T p6, T p7, T p8, T p9, T p10 +namespace QxtMetaObject +{ +QByteArray methodName(const char* method); +QByteArray methodSignature(const char* method); + +bool isSignalOrSlot (const char* method); + + +QxtBoundFunction* bind(QObject* recv, const char* invokable, QXT_PROTO_10ARGS(QVariant)); +QxtBoundFunction* bind(QObject* recv, const char* invokable, QXT_PROTO_10ARGS(QGenericArgument)); +template +QxtBoundFunction* bindFunction(FP funcPointer, QXT_PROTO_10ARGS(QGenericArgument)); +template +QxtBoundFunction* bindMethod(T recv, FP funcPointer, QXT_PROTO_10ARGS(QGenericArgument)); +bool connect(QObject* sender, const char* signal, QxtBoundFunction* slot, + Qt::ConnectionType type = Qt::AutoConnection); +} + +#define QXT_BIND(i) QGenericArgument("QxtBoundArgument", reinterpret_cast(i)) + +#endif // QXTMETAOBJECT_H diff --git a/src/contrib/qxt/qxtnull.cpp b/src/contrib/qxt/qxtnull.cpp new file mode 100644 index 00000000..967c16f9 --- /dev/null +++ b/src/contrib/qxt/qxtnull.cpp @@ -0,0 +1,3 @@ +#include "qxtnull.h" + +QxtNull qxtNull; // static storage for extern diff --git a/src/contrib/qxt/qxtnull.h b/src/contrib/qxt/qxtnull.h new file mode 100644 index 00000000..c520b66d --- /dev/null +++ b/src/contrib/qxt/qxtnull.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) Qxt Foundation. Some rights reserved. +** +** This file is part of the QxtCore module of the Qt eXTension library +** +** This library is free software; you can redistribute it and/or modify it +** under the terms of th Common Public License, version 1.0, as published by +** IBM. +** +** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY +** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY +** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR +** FITNESS FOR A PARTICULAR PURPOSE. +** +** You should have received a copy of the CPL along with this file. +** See the LICENSE file and the cpl1.0.txt file included with the source +** distribution for more information. If you did not receive a copy of the +** license, contact the Qxt Foundation. +** +** +** +****************************************************************************/ + +#ifndef QXTNULL_DEFINED +#define QXTNULL_DEFINED +#include + +/** +\class QxtNull QxtNull + + +\ingroup core + +\brief An object representing the "null" value for QxtNullable. + +seealso: QxtNullable +*/ + +struct QXT_CORE_EXPORT QxtNull +{ + /** integer cast operator + * In expressions, QxtNull behaves as an integer zero for compatibility with generic functions. + */ + operator int() const + { + return 0; + } + enum { isNull = true }; +}; + +/*! \relates QxtNull + * A predefined null object that can be assigned to any QxtNullable object. + */ +extern QxtNull qxtNull; + +#ifndef QXT_NO_MACROS +/*! \relates QxtNull + * A convenience alias for qxtNull. + */ +#define SKIP qxtNull +#endif + +#endif diff --git a/src/contrib/qxt/qxtnullable.h b/src/contrib/qxt/qxtnullable.h new file mode 100644 index 00000000..f9aa5e37 --- /dev/null +++ b/src/contrib/qxt/qxtnullable.h @@ -0,0 +1,145 @@ +/**************************************************************************** +** +** Copyright (C) Qxt Foundation. Some rights reserved. +** +** This file is part of the QxtCore module of the Qt eXTension library +** +** This library is free software; you can redistribute it and/or modify it +** under the terms of th Common Public License, version 1.0, as published by +** IBM. +** +** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY +** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY +** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR +** FITNESS FOR A PARTICULAR PURPOSE. +** +** You should have received a copy of the CPL along with this file. +** See the LICENSE file and the cpl1.0.txt file included with the source +** distribution for more information. If you did not receive a copy of the +** license, contact the Qxt Foundation. +** +** +** +****************************************************************************/ + +/** +\class QxtNullable QxtNullable +\ingroup core +\brief distinct null value compatible with any data type. + +in general it's a templated abstraction to allow any data type to be +expressed with a null value distinct from any real value. An example +of such a use is for optional arguments. +\n +prepare a function for argument skipping: + +\code +void somefunction( qxtNull(int,a) , qxtNull(int,b) ) +{ + +if (!a.isNull()) + { + int i = a.value(); + //do something with i + } + if (!b.isNull()) + { + int x = b.value(); + //do something with x + } +} +\endcode + +usage: +\code + +somefunction(SKIP,1,2); +somefunction(3,4); +somefunction(3,SKIP,6); +somefunction(1); +\endcode + +*/ + +#ifndef QXTNULLABLE_H +#define QXTNULLABLE_H +#include + +/*! \relates QxtNullable + * defines a skipable argument with type \a t and variable name \a n + */ +#define qxtNull(t,n) QxtNullable n = QxtNullable() + +#include + +template +class QXT_CORE_EXPORT QxtNullable +{ +public: + QxtNullable(QxtNull); + QxtNullable(const T& p); + QxtNullable(); + + ///determinates if the Value is set to something meaningfull + bool isNull() const; + + ///delete Value + void nullify(); + + T& value() const; + operator T() const; + void operator=(const T& p); + +private: + T* val; +}; + +template +QxtNullable::QxtNullable(QxtNull) +{ + val = 0; +} + +template +QxtNullable::QxtNullable(const T& p) +{ + val = const_cast(&p); +} + +template +QxtNullable::QxtNullable() +{ + val = 0; +} + +template +QxtNullable::operator T() const +{ + return *val; +} + +template +T& QxtNullable::value() const +{ + return *val; +} + +template +bool QxtNullable::isNull() const +{ + return (val==0); +} + +template +void QxtNullable::nullify() +{ + val=0; +} + +template +void QxtNullable::operator=(const T& p) +{ + val = const_cast(&p); +} + +#endif diff --git a/src/contrib/qxt/qxtpimpl.h b/src/contrib/qxt/qxtpimpl.h index e1aeaa40..1f7093ab 100644 --- a/src/contrib/qxt/qxtpimpl.h +++ b/src/contrib/qxt/qxtpimpl.h @@ -11,13 +11,13 @@ ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR -** FITNESS FOR A PARTICULAR PURPOSE. +** FITNESS FOR A PARTICULAR PURPOSE. ** ** You should have received a copy of the CPL along with this file. ** See the LICENSE file and the cpl1.0.txt file included with the source ** distribution for more information. If you did not receive a copy of the ** license, contact the Qxt Foundation. -** +** ** ** ****************************************************************************/ @@ -25,7 +25,7 @@ \class QxtPimpl QxtPimpl \ingroup core \brief Hide private details of a class - + Application code generally doesn't have to be concerned about hiding its implementation details, but when writing library code it is important to maintain a constant interface, both source and binary. Maintaining a constant @@ -34,7 +34,7 @@ means moving implementation details into a private class. The PIMPL, or d-pointer, idiom is a common method of implementing this separation. QxtPimpl offers a convenient way to connect the public and private sides of your class. -\section start Getting Started +\section start Getting Started Before you declare the public class, you need to make a forward declaration of the private class. The private class must have the same name as the public class, followed by the word Private. For example, a class named MyTest would @@ -43,14 +43,14 @@ declare the private class with: class MyTestPrivate; \endcode -\subsection pub The Public Class +\subsection pub The Public Class Generally, you shouldn't keep any data members in the public class without a good reason. Functions that are part of the public interface should be declared in the public class, and functions that need to be available to subclasses (for -calling or overriding) should be in the protected section of the public class. +calling or overriding) should be in the protected section of the public class. To connect the private class to the public class, include the QXT_DECLARE_PRIVATE macro in the private section of the public class. In the -example above, the private class is connected as follows: +example above, the private class is connected as follows: \code private: QXT_DECLARE_PRIVATE(MyTest); @@ -58,7 +58,7 @@ private: Additionally, you must include the QXT_INIT_PRIVATE macro in the public class's constructor. Continuing with the MyTest example, your constructor might look -like this: +like this: \code MyTest::MyTest() { // initialization @@ -66,12 +66,12 @@ MyTest::MyTest() { } \endcode -\subsection priv The Private Class +\subsection priv The Private Class As mentioned above, data members should usually be kept in the private class. This allows the memory layout of the private class to change without breaking binary compatibility for the public class. Functions that exist only as implementation details, or functions that need access to private data members, -should be implemented here. +should be implemented here. To define the private class, inherit from the template QxtPrivate class, and include the QXT_DECLARE_PUBLIC macro in its public section. The template @@ -118,7 +118,7 @@ void MyTestPrivate::doQuux() { * * This may be put anywhere in the declaration of the private class. The parameter is the name of the public class. */ -#define QXT_DECLARE_PUBLIC(PUB) friend class PUB; +#define QXT_DECLARE_PUBLIC(PUB) friend class PUB; /*! \relates QxtPimpl * Initializes resources owned by the private class. * @@ -161,29 +161,56 @@ const PUB& qxt_p(); #ifndef QXT_DOXYGEN_RUN template -class QxtPrivate { +class QxtPrivate +{ public: - virtual ~QxtPrivate() {} - inline void QXT_setPublic(PUB* pub) { qxt_p_ptr = pub; } + virtual ~QxtPrivate() + {} + inline void QXT_setPublic(PUB* pub) + { + qxt_p_ptr = pub; + } protected: - inline PUB& qxt_p() { return *qxt_p_ptr; } - inline const PUB& qxt_p() const { return *qxt_p_ptr; } + inline PUB& qxt_p() + { + return *qxt_p_ptr; + } + inline const PUB& qxt_p() const + { + return *qxt_p_ptr; + } private: PUB* qxt_p_ptr; }; template -class QxtPrivateInterface { -friend class QxtPrivate; +class QxtPrivateInterface +{ + friend class QxtPrivate; public: - QxtPrivateInterface() { pvt = new PVT; } - ~QxtPrivateInterface() { delete pvt; } - - inline void setPublic(PUB* pub) { pvt->QXT_setPublic(pub); } - inline PVT& operator()() { return *static_cast(pvt); } - inline const PVT& operator()() const { return *static_cast(pvt); } + QxtPrivateInterface() + { + pvt = new PVT; + } + ~QxtPrivateInterface() + { + delete pvt; + } + + inline void setPublic(PUB* pub) + { + pvt->QXT_setPublic(pub); + } + inline PVT& operator()() + { + return *static_cast(pvt); + } + inline const PVT& operator()() const + { + return *static_cast(pvt); + } private: QxtPrivate* pvt; }; diff --git a/src/contrib/qxt/qxtrpcpeer.cpp b/src/contrib/qxt/qxtrpcpeer.cpp index f9766057..e9860500 100644 --- a/src/contrib/qxt/qxtrpcpeer.cpp +++ b/src/contrib/qxt/qxtrpcpeer.cpp @@ -1,26 +1,26 @@ /**************************************************************************** -** -** Copyright (C) Qxt Foundation. Some rights reserved. -** -** This file is part of the QxtNetwork module of the Qt eXTension library -** -** This library is free software; you can redistribute it and/or modify it -** under the terms of th Common Public License, version 1.0, as published by -** IBM. -** -** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY -** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY -** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR -** FITNESS FOR A PARTICULAR PURPOSE. -** -** You should have received a copy of the CPL along with this file. -** See the LICENSE file and the cpl1.0.txt file included with the source -** distribution for more information. If you did not receive a copy of the -** license, contact the Qxt Foundation. -** -** -** -****************************************************************************/ + ** + ** Copyright (C) Qxt Foundation. Some rights reserved. + ** + ** This file is part of the QxtNetwork module of the Qt eXTension library + ** + ** This library is free software; you can redistribute it and/or modify it + ** under the terms of th Common Public License, version 1.0, as published by + ** IBM. + ** + ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY + ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY + ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR + ** FITNESS FOR A PARTICULAR PURPOSE. + ** + ** You should have received a copy of the CPL along with this file. + ** See the LICENSE file and the cpl1.0.txt file included with the source + ** distribution for more information. If you did not receive a copy of the + ** license, contact the Qxt Foundation. + ** + ** + ** + ****************************************************************************/ #include "qxtrpcpeer.h" #include @@ -30,11 +30,14 @@ #include #include #include - -class QxtIntrospector: public QObject { - // This class MANUALLY implements the necessary parts of QObject. - // Do NOT add the Q_OBJECT macro. As this class isn't intended - // for direct use, it doesn't offer any sort of useful meta-object. +#include "qxtmetaobject.h" +#include + +class QxtIntrospector: public QObject +{ +// This class MANUALLY implements the necessary parts of QObject. +// Do NOT add the Q_OBJECT macro. As this class isn't intended +// for direct use, it doesn't offer any sort of useful meta-object. public: QxtIntrospector(QxtRPCPeer* parent, QObject* source, const char* signal); @@ -47,20 +50,25 @@ private: QList argTypes; }; -struct QxtRPCConnection { +struct QxtRPCConnection +{ QTcpSocket* socket; QByteArray buffer; QString lastMethod; }; -class QxtRPCPeerPrivate : public QxtPrivate { +class QxtRPCPeerPrivate : public QxtPrivate, public QTcpServer +{ public: QXT_DECLARE_PUBLIC(QxtRPCPeer); + void incomingConnection ( int socketDescriptor ); + + void receivePeerSignal(QString fn, QVariant p0 = QVariant(), QVariant p1 = QVariant(), QVariant p2 = QVariant(), QVariant p3 = QVariant(), - QVariant p4 = QVariant(), QVariant p5 = QVariant(), QVariant p6 = QVariant(), QVariant p7 = QVariant(), QVariant p8 = QVariant()) const; + QVariant p4 = QVariant(), QVariant p5 = QVariant(), QVariant p6 = QVariant(), QVariant p7 = QVariant(), QVariant p8 = QVariant()) const; void receiveClientSignal(quint64 id, QString fn, QVariant p0 = QVariant(), QVariant p1 = QVariant(), QVariant p2 = QVariant(), QVariant p3 = QVariant(), - QVariant p4 = QVariant(), QVariant p5 = QVariant(), QVariant p6 = QVariant(), QVariant p7 = QVariant()) const; + QVariant p4 = QVariant(), QVariant p5 = QVariant(), QVariant p6 = QVariant(), QVariant p7 = QVariant()) const; void processInput(QIODevice* socket, QByteArray& buffer); @@ -72,125 +80,170 @@ public: typedef QHash ConnHash; ConnHash m_clients; - QTcpServer* m_server; - QIODevice* m_peer; ///aep: doom + QIODevice* m_peer; QByteArray m_buffer; int m_rpctype; + + + QStack pending_connections; + }; -QxtRPCPeer::QxtRPCPeer(QObject* parent) : QObject(parent) { - QXT_INIT_PRIVATE(QxtRPCPeer); - qxt_d().m_rpctype = Peer; - qxt_d().m_server = new QTcpServer(this); - qxt_d().m_peer = new QTcpSocket(this); - QObject::connect(qxt_d().m_peer, SIGNAL(connected()), this, SIGNAL(peerConnected())); - QObject::connect(qxt_d().m_peer, SIGNAL(disconnected()), this, SIGNAL(peerDisconnected())); - QObject::connect(qxt_d().m_peer, SIGNAL(disconnected()), this, SLOT(disconnectSender())); - QObject::connect(qxt_d().m_peer, SIGNAL(readyRead()), this, SLOT(dataAvailable())); - QObject::connect(qxt_d().m_peer, SIGNAL(error(QAbstractSocket::SocketError)), this, SIGNAL(peerError(QAbstractSocket::SocketError))); - QObject::connect(qxt_d().m_server, SIGNAL(newConnection()), this, SLOT(newConnection())); +QxtRPCPeer::QxtRPCPeer(QObject* parent) : QObject(parent) +{ + QXT_INIT_PRIVATE(QxtRPCPeer); + qxt_d().m_rpctype = Peer; + qxt_d().m_peer = new QTcpSocket(this); + QObject::connect(qxt_d().m_peer, SIGNAL(connected()), this, SIGNAL(peerConnected())); + QObject::connect(qxt_d().m_peer, SIGNAL(disconnected()), this, SIGNAL(peerDisconnected())); + QObject::connect(qxt_d().m_peer, SIGNAL(disconnected()), this, SLOT(disconnectSender())); + QObject::connect(qxt_d().m_peer, SIGNAL(readyRead()), this, SLOT(dataAvailable())); + QObject::connect(qxt_d().m_peer, SIGNAL(error(QAbstractSocket::SocketError)), this, SIGNAL(peerError(QAbstractSocket::SocketError))); } -QxtRPCPeer::QxtRPCPeer(RPCTypes type, QObject* parent) : QObject(parent) { - QXT_INIT_PRIVATE(QxtRPCPeer); - qxt_d().m_rpctype = type; - qxt_d().m_server = new QTcpServer(this); - qxt_d().m_peer = new QTcpSocket(this); - QObject::connect(qxt_d().m_peer, SIGNAL(connected()), this, SIGNAL(peerConnected())); - QObject::connect(qxt_d().m_peer, SIGNAL(disconnected()), this, SIGNAL(peerDisconnected())); - QObject::connect(qxt_d().m_peer, SIGNAL(disconnected()), this, SLOT(disconnectSender())); - QObject::connect(qxt_d().m_peer, SIGNAL(readyRead()), this, SLOT(dataAvailable())); - QObject::connect(qxt_d().m_peer, SIGNAL(error(QAbstractSocket::SocketError)), this, SIGNAL(peerError(QAbstractSocket::SocketError))); - QObject::connect(qxt_d().m_server, SIGNAL(newConnection()), this, SLOT(newConnection())); + +QxtRPCPeer::QxtRPCPeer(RPCTypes type, QObject* parent) : QObject(parent) +{ + QXT_INIT_PRIVATE(QxtRPCPeer); + qxt_d().m_rpctype = type; + qxt_d().m_peer = new QTcpSocket(this); + QObject::connect(qxt_d().m_peer, SIGNAL(connected()), this, SIGNAL(peerConnected())); + QObject::connect(qxt_d().m_peer, SIGNAL(disconnected()), this, SIGNAL(peerDisconnected())); + QObject::connect(qxt_d().m_peer, SIGNAL(disconnected()), this, SLOT(disconnectSender())); + QObject::connect(qxt_d().m_peer, SIGNAL(readyRead()), this, SLOT(dataAvailable())); + QObject::connect(qxt_d().m_peer, SIGNAL(error(QAbstractSocket::SocketError)), this, SIGNAL(peerError(QAbstractSocket::SocketError))); } -QxtRPCPeer::QxtRPCPeer(QIODevice* device, RPCTypes type, QObject* parent) : QObject(parent) { - if (!device->isOpen()) - { - qWarning("QxtRPCPeer::the device you passed is not open!"); - } + +QxtRPCPeer::QxtRPCPeer(QIODevice* device, RPCTypes type, QObject* parent) : QObject(parent) +{ + if (!device->isOpen()) + { + qWarning("QxtRPCPeer::the device you passed is not open!"); + } QXT_INIT_PRIVATE(QxtRPCPeer); qxt_d().m_rpctype = type; - qxt_d().m_server = new QTcpServer(this); qxt_d().m_peer = device; - if (qobject_cast(device)!=0) - { - QObject::connect(qxt_d().m_peer, SIGNAL(connected()), this, SIGNAL(peerConnected())); - QObject::connect(qxt_d().m_peer, SIGNAL(disconnected()), this, SIGNAL(peerDisconnected())); - QObject::connect(qxt_d().m_peer, SIGNAL(disconnected()), this, SLOT(disconnectSender())); - QObject::connect(qxt_d().m_peer, SIGNAL(error(QAbstractSocket::SocketError)), this, SIGNAL(peerError(QAbstractSocket::SocketError))); - } + if (qobject_cast(device)!=0) + { + QObject::connect(qxt_d().m_peer, SIGNAL(connected()), this, SIGNAL(peerConnected())); + QObject::connect(qxt_d().m_peer, SIGNAL(disconnected()), this, SIGNAL(peerDisconnected())); + QObject::connect(qxt_d().m_peer, SIGNAL(disconnected()), this, SLOT(disconnectSender())); + QObject::connect(qxt_d().m_peer, SIGNAL(error(QAbstractSocket::SocketError)), this, SIGNAL(peerError(QAbstractSocket::SocketError))); + } QObject::connect(qxt_d().m_peer, SIGNAL(readyRead()), this, SLOT(dataAvailable())); - QObject::connect(qxt_d().m_server, SIGNAL(newConnection()), this, SLOT(newConnection())); } -void QxtRPCPeer::setRPCType(RPCTypes type) { - if(qxt_d().m_peer->isOpen () || qxt_d().m_server->isListening()) { + +void QxtRPCPeer::setRPCType(RPCTypes type) +{ + if (qxt_d().m_peer->isOpen () || qxt_d().isListening()) + { qWarning() << "QxtRPCPeer: Cannot change RPC types while connected or listening"; return; } qxt_d().m_rpctype = type; } -QxtRPCPeer::RPCTypes QxtRPCPeer::rpcType() const { + +QxtRPCPeer::RPCTypes QxtRPCPeer::rpcType() const +{ return (RPCTypes)(qxt_d().m_rpctype); } -void QxtRPCPeer::connect(QHostAddress addr, int port) { - if(qxt_d().m_rpctype == Server) { + +void QxtRPCPeer::connect(QHostAddress addr, int port) +{ + if (qxt_d().m_rpctype == Server) + { qWarning() << "QxtRPCPeer: Cannot connect outward in Server mode"; return; - } else if(qxt_d().m_peer->isOpen ()) { - qWarning() << "QxtRPCPeer: Already connected"; + } + + QAbstractSocket * sock = qobject_cast(qxt_d().m_peer); + if (!sock) + { + qWarning("QxtRPCPeer: cannot connect a custom QIODevice"); return; } - QTcpSocket * sock = qobject_cast(qxt_d().m_peer); - assert(sock); + + if (sock->state()!=QAbstractSocket::UnconnectedState) + { + qWarning("QxtRPCPeer: Already connected"); + return; + } + sock->connectToHost(addr, port); } -bool QxtRPCPeer::listen(QHostAddress iface, int port) { - if(qxt_d().m_rpctype == Client) { + +bool QxtRPCPeer::listen(QHostAddress iface, int port) +{ + if (qxt_d().m_rpctype == Client) + { qWarning() << "QxtRPCPeer: Cannot listen in Client mode"; return false; - } else if(qxt_d().m_rpctype == Peer && qxt_d().m_peer->isOpen ()) { + } + else if (qxt_d().m_rpctype == Peer && qxt_d().m_peer->isOpen ()) + { qWarning() << "QxtRPCPeer: Cannot listen while connected to a peer"; return false; - } else if(qxt_d().m_server->isListening()) { + } + else if (qxt_d().isListening()) + { qWarning() << "QxtRPCPeer: Already listening"; return false; } - return qxt_d().m_server->listen(iface, port); + return qxt_d().listen(iface, port); } -void QxtRPCPeer::disconnectPeer(quint64 id) { - if(qxt_d().m_rpctype == Server && id==0) { + +void QxtRPCPeer::disconnectPeer(quint64 id) +{ + if (qxt_d().m_rpctype == Server && id==(quint64)-1) + { qWarning() << "QxtRPCPeer: Server mode does not have a peer"; return; - } else if(qxt_d().m_rpctype!= Server && id!=0) { + } + else if (qxt_d().m_rpctype!= Server && id!=(quint64)-1) + { qWarning() << "QxtRPCPeer: Must specify a client ID to disconnect"; return; } QxtRPCConnection* conn; - if(id==0) { + if (id==(quint64)-1) + { qxt_d().m_peer->close(); - } else if((conn = qxt_d().m_clients.take((QObject*)(id)))!= 0) { + ///hackaround for qt bug + QAbstractSocket *s =qobject_cast( qxt_d().m_peer); + if (s) + s->disconnectFromHost(); + + } + else if ((conn = qxt_d().m_clients.take((QObject*)(id)))!= 0) + { conn->socket->disconnectFromHost(); conn->socket->deleteLater(); delete conn; - } else { + } + else + { qWarning() << "QxtRPCPeer: no client with id " << id; } } -void QxtRPCPeer::disconnectAll() { - if(qxt_d().m_rpctype!= Server) + +void QxtRPCPeer::disconnectAll() +{ + if (qxt_d().m_rpctype!= Server) disconnectPeer(); - else { - for(QxtRPCPeerPrivate::ConnHash::const_iterator i = qxt_d().m_clients.constBegin(); i!= qxt_d().m_clients.constEnd(); i++) { + else + { + for (QxtRPCPeerPrivate::ConnHash::const_iterator i = qxt_d().m_clients.constBegin(); i!= qxt_d().m_clients.constEnd(); i++) + { (*i)->socket->deleteLater(); delete *i; } @@ -198,44 +251,69 @@ void QxtRPCPeer::disconnectAll() { } } -void QxtRPCPeer::stopListening() { - if(!qxt_d().m_server->isListening()) { + +void QxtRPCPeer::stopListening() +{ + if (!qxt_d().isListening()) + { qWarning() << "QxtRPCPeer: Not listening"; return; } - qxt_d().m_server->close(); + qxt_d().close(); } -bool QxtRPCPeer::attachSignal(QObject* sender, const char* signal, const QByteArray& rpcFunction) { + +bool QxtRPCPeer::attachSignal(QObject* sender, const char* signal, const QByteArray& rpcFunction) +{ const QMetaObject* meta = sender->metaObject(); QByteArray sig(meta->normalizedSignature(signal).mid(1)); int methodID = meta->indexOfMethod(sig.constData()); - if(methodID == -1 || meta->method(methodID).methodType() != QMetaMethod::Signal) { + if (methodID == -1 || meta->method(methodID).methodType() != QMetaMethod::Signal) + { qWarning() << "QxtRPCPeer::attachSignal: No such signal " << signal; return false; } + + QxtIntrospector* spec = new QxtIntrospector(this, sender, signal); - if(!rpcFunction.isEmpty()) { - spec->rpcFunction = rpcFunction.simplified(); - } else { - spec->rpcFunction = sig; + if (!rpcFunction.isEmpty()) + { + if (QxtMetaObject::isSignalOrSlot(rpcFunction.constData())) + { + spec->rpcFunction = QMetaObject::normalizedSignature(rpcFunction.constData()); + } + else + { + spec->rpcFunction = rpcFunction.simplified(); + } + } + else + { + spec->rpcFunction = QMetaObject::normalizedSignature(signal); } qxt_d().attachedSignals.insertMulti(sender, spec); return true; } -bool QxtRPCPeer::attachSlot(const QByteArray& rpcFunction, QObject* recv, const char* slot) { + +bool QxtRPCPeer::attachSlot(const QByteArray& rpcFunction, QObject* recv, const char* slot) +{ const QMetaObject* meta = recv->metaObject(); int methodID = meta->indexOfMethod(meta->normalizedSignature(slot).mid(1)); - if(methodID == -1 || meta->method(methodID).methodType() == QMetaMethod::Method) { + if (methodID == -1 || meta->method(methodID).methodType() == QMetaMethod::Method) + { qWarning() << "QxtRPCPeer::attachSlot: No such slot " << slot; return false; } QString fn; - if(rpcFunction[0] == '1' && rpcFunction.contains('(') && rpcFunction.contains(')')) { - fn = QMetaObject::normalizedSignature(rpcFunction.mid(1).constData()); - } else { + + if (QxtMetaObject::isSignalOrSlot(rpcFunction.constData())) + { + fn = QMetaObject::normalizedSignature(rpcFunction.constData()); + } + else + { fn = rpcFunction.simplified(); } @@ -243,17 +321,23 @@ bool QxtRPCPeer::attachSlot(const QByteArray& rpcFunction, QObject* recv, const return true; } -void QxtRPCPeer::detachSender() { + +void QxtRPCPeer::detachSender() +{ detachObject(sender()); } -void QxtRPCPeer::detachObject(QObject* obj) { + +void QxtRPCPeer::detachObject(QObject* obj) +{ foreach(QxtIntrospector* i, qxt_d().attachedSignals.values(obj)) i->deleteLater(); qxt_d().attachedSignals.remove(obj); - foreach(QString slot, qxt_d().attachedSlots.keys()) { - for(QList >::iterator i(qxt_d().attachedSlots[slot].begin()); - i!= qxt_d().attachedSlots[slot].end(); ) { - if((*i).first == obj) + foreach(QString slot, qxt_d().attachedSlots.keys()) + { + for (QList >::iterator i(qxt_d().attachedSlots[slot].begin()); + i!= qxt_d().attachedSlots[slot].end(); ) + { + if ((*i).first == obj) i = qxt_d().attachedSlots[slot].erase(i); else i++; @@ -261,130 +345,168 @@ void QxtRPCPeer::detachObject(QObject* obj) { } } -QByteArray QxtRPCPeer::serialize(QString fn, QVariant p1, QVariant p2, QVariant p3, QVariant p4, QVariant p5, QVariant p6, QVariant p7, QVariant p8, QVariant p9) const { + +QByteArray QxtRPCPeer::serialize(QString fn, QVariant p1, QVariant p2, QVariant p3, QVariant p4, QVariant p5, QVariant p6, QVariant p7, QVariant p8, QVariant p9) const +{ QByteArray rv; QDataStream str(&rv, QIODevice::WriteOnly); str << fn; unsigned char ct = 9; - if(p1.isNull()) ct = 0; - else if(p2.isNull()) ct = 1; - else if(p3.isNull()) ct = 2; - else if(p4.isNull()) ct = 3; - else if(p5.isNull()) ct = 4; - else if(p6.isNull()) ct = 5; - else if(p7.isNull()) ct = 6; - else if(p8.isNull()) ct = 7; - else if(p9.isNull()) ct = 8; + if (p1.isNull()) ct = 0; + else if (p2.isNull()) ct = 1; + else if (p3.isNull()) ct = 2; + else if (p4.isNull()) ct = 3; + else if (p5.isNull()) ct = 4; + else if (p6.isNull()) ct = 5; + else if (p7.isNull()) ct = 6; + else if (p8.isNull()) ct = 7; + else if (p9.isNull()) ct = 8; str << ct; - if(ct--) str << p1; - if(ct--) str << p2; - if(ct--) str << p3; - if(ct--) str << p4; - if(ct--) str << p5; - if(ct--) str << p6; - if(ct--) str << p7; - if(ct--) str << p8; - if(ct--) str << p9; + if (ct--) str << p1; + if (ct--) str << p2; + if (ct--) str << p3; + if (ct--) str << p4; + if (ct--) str << p5; + if (ct--) str << p6; + if (ct--) str << p7; + if (ct--) str << p8; + if (ct--) str << p9; rv.replace(QByteArray("\\"), QByteArray("\\\\")); rv.replace(QByteArray("\n"), QByteArray("\\n")); rv.append("\n"); return rv; } -void QxtRPCPeer::call(const char * signal , QVariant p1, QVariant p2, QVariant p3, QVariant p4, QVariant p5, QVariant p6, QVariant p7, QVariant p8, QVariant p9) { + +void QxtRPCPeer::call(const char * signal , QVariant p1, QVariant p2, QVariant p3, QVariant p4, QVariant p5, QVariant p6, QVariant p7, QVariant p8, QVariant p9) +{ QByteArray sig=QMetaObject::normalizedSignature(signal); - if(!qxt_d().m_peer->isOpen ()) - { - qWarning("can't call on a closed device"); - return; - } + QAbstractSocket * sock = qobject_cast(qxt_d().m_peer); + if (!qxt_d().m_peer->isOpen () || ( sock && sock->state()!=QAbstractSocket::ConnectedState )) + { + qWarning("can't call on a closed device"); + return; + } qxt_d().m_peer->write(serialize(sig, p1, p2, p3, p4, p5, p6, p7, p8, p9)); } -void QxtRPCPeer::callClientList(QList ids, QString fn, QVariant p1, QVariant p2, QVariant p3, QVariant p4, QVariant p5, QVariant p6, QVariant p7, QVariant p8) { + +void QxtRPCPeer::callClientList(QList ids, QString fn, QVariant p1, QVariant p2, QVariant p3, QVariant p4, QVariant p5, QVariant p6, QVariant p7, QVariant p8) +{ QByteArray c = serialize(fn, p1, p2, p3, p4, p5, p6, p7, p8, QVariant()); - foreach(quint64 id, ids) { + foreach(quint64 id, ids) + { QxtRPCConnection* conn = qxt_d().m_clients.value((QObject*)(id)); - if(!conn) { + if (!conn) + { qWarning() << "QxtRPCPeer: no client with id" << id; - } else { + } + else + { conn->socket->write(c); } } } -void QxtRPCPeer::callClient(quint64 id, QString fn, QVariant p1, QVariant p2, QVariant p3, QVariant p4, QVariant p5, QVariant p6, QVariant p7, QVariant p8) { + +void QxtRPCPeer::callClient(quint64 id, QString fn, QVariant p1, QVariant p2, QVariant p3, QVariant p4, QVariant p5, QVariant p6, QVariant p7, QVariant p8) +{ callClientList(QList() << id, fn, p1, p2, p3, p4, p5, p6, p7, p8); } -void QxtRPCPeer::callClientsExcept(quint64 id, QString fn, QVariant p1, QVariant p2, QVariant p3, QVariant p4, QVariant p5, QVariant p6, QVariant p7, QVariant p8) { + +void QxtRPCPeer::callClientsExcept(quint64 id, QString fn, QVariant p1, QVariant p2, QVariant p3, QVariant p4, QVariant p5, QVariant p6, QVariant p7, QVariant p8) +{ QList cs = clients(); cs.removeAll(id); callClientList(cs, fn, p1, p2, p3, p4, p5, p6, p7, p8); } +#include #define QXT_ARG(i) ((numParams>i)?QGenericArgument(p ## i .typeName(), p ## i .constData()):QGenericArgument()) -void QxtRPCPeerPrivate::receivePeerSignal(QString fn, QVariant p0, QVariant p1, QVariant p2, QVariant p3, QVariant p4, QVariant p5, QVariant p6, QVariant p7, QVariant p8) const { +void QxtRPCPeerPrivate::receivePeerSignal(QString fn, QVariant p0, QVariant p1, QVariant p2, QVariant p3, QVariant p4, QVariant p5, QVariant p6, QVariant p7, QVariant p8) const +{ QByteArray sig; int numParams; - foreach(QxtRPCPeerPrivate::MethodID i, attachedSlots.value(fn)) { + if(!attachedSlots.value(fn).count()) qDebug() << "no attached slot for signal" << fn;// qDebug() << attachedSlots; + foreach(QxtRPCPeerPrivate::MethodID i, attachedSlots.value(fn)) + { sig = i.first->metaObject()->method(i.second).signature(); sig = sig.left(sig.indexOf('(')); - numParams = i.first->metaObject()->method(i.second).parameterTypes().count(); - QMetaObject::invokeMethod(i.first, sig, QXT_ARG(0), QXT_ARG(1), QXT_ARG(2), QXT_ARG(3), QXT_ARG(4), QXT_ARG(5), QXT_ARG(6), QXT_ARG(7), QXT_ARG(8)); + numParams = i.first->metaObject()->method(i.second).parameterTypes().count(); //qDebug() << "calling" << fn << p0 << p1 << p2; + bool res = QMetaObject::invokeMethod(i.first, sig, QXT_ARG(0), QXT_ARG(1), QXT_ARG(2), QXT_ARG(3), QXT_ARG(4), QXT_ARG(5), QXT_ARG(6), QXT_ARG(7), QXT_ARG(8)); + if(!res) qDebug() << "rpccall failed" << fn << sig << p0 << p1 << p2; } } -void QxtRPCPeerPrivate::receiveClientSignal(quint64 id, QString fn, QVariant p0, QVariant p1, QVariant p2, QVariant p3, QVariant p4, QVariant p5, QVariant p6, QVariant p7) const { + +void QxtRPCPeerPrivate::receiveClientSignal(quint64 id, QString fn, QVariant p0, QVariant p1, QVariant p2, QVariant p3, QVariant p4, QVariant p5, QVariant p6, QVariant p7) const +{ QByteArray sig; int numParams; - foreach(QxtRPCPeerPrivate::MethodID i, attachedSlots.value(fn)) { + foreach(QxtRPCPeerPrivate::MethodID i, attachedSlots.value(fn)) + { sig = i.first->metaObject()->method(i.second).signature(); sig = sig.left(sig.indexOf('(')); numParams = i.first->metaObject()->method(i.second).parameterTypes().count(); QMetaObject::invokeMethod(i.first, sig, Q_ARG(quint64, id), QXT_ARG(0), QXT_ARG(1), QXT_ARG(2), QXT_ARG(3), QXT_ARG(4), QXT_ARG(5), QXT_ARG(6), QXT_ARG(7)); } } + + #undef QXT_ARG -void QxtRPCPeer::newConnection() { - QTcpSocket* next = qxt_d().m_server->nextPendingConnection(); - if(qxt_d().m_rpctype == QxtRPCPeer::Peer) { - if(qxt_d().m_peer->isOpen ()) { +void QxtRPCPeerPrivate::incomingConnection ( int socketDescriptor ) +{ + QTcpSocket* next = qxt_p().incomingConnection(socketDescriptor); + if (m_rpctype == QxtRPCPeer::Peer) + { + if (m_peer->isOpen ()) + { qWarning() << "QxtRPCPeer: Rejected connection from " << next->peerAddress().toString() << "; another peer is connected"; next->disconnectFromHost(); next->deleteLater(); - } else { - qxt_d().m_peer->deleteLater(); - qxt_d().m_peer = next; - QObject::connect(qxt_d().m_peer, SIGNAL(connected()), this, SIGNAL(peerConnected())); - QObject::connect(qxt_d().m_peer, SIGNAL(disconnected()), this, SIGNAL(peerDisconnected())); - QObject::connect(qxt_d().m_peer, SIGNAL(disconnected()), this, SLOT(disconnectSender())); - QObject::connect(qxt_d().m_peer, SIGNAL(readyRead()), this, SLOT(dataAvailable())); - QObject::connect(qxt_d().m_peer, SIGNAL(error(QAbstractSocket::SocketError)), this, SIGNAL(peerError(QAbstractSocket::SocketError))); - emit peerConnected(); } - } else { + else + { + m_peer->deleteLater(); + m_peer = next; + QObject::connect(m_peer, SIGNAL(connected()), &qxt_p(), SIGNAL(peerConnected())); + QObject::connect(m_peer, SIGNAL(disconnected()), &qxt_p(), SIGNAL(peerDisconnected())); + QObject::connect(m_peer, SIGNAL(disconnected()), &qxt_p(), SLOT(disconnectSender())); + QObject::connect(m_peer, SIGNAL(readyRead()), &qxt_p(), SLOT(dataAvailable())); + QObject::connect(m_peer, SIGNAL(error(QAbstractSocket::SocketError)), &qxt_p(), SIGNAL(peerError(QAbstractSocket::SocketError))); + emit qxt_p().peerConnected(); + } + } + else + { QxtRPCConnection* conn = new QxtRPCConnection; conn->socket = next; - qxt_d().m_clients[next] = conn; - QObject::connect(next, SIGNAL(disconnected()), this, SLOT(disconnectSender())); - QObject::connect(next, SIGNAL(readyRead()), this, SLOT(dataAvailable())); - QObject::connect(next, SIGNAL(error(QAbstractSocket::SocketError)), this, SIGNAL(peerError(QAbstractSocket::SocketError))); - emit clientConnected((quint64)(next)); + m_clients[next] = conn; + QObject::connect(next, SIGNAL(disconnected()), &qxt_p(), SLOT(disconnectSender())); + QObject::connect(next, SIGNAL(readyRead()), &qxt_p(), SLOT(dataAvailable())); + QObject::connect(next, SIGNAL(error(QAbstractSocket::SocketError)), &qxt_p(), SIGNAL(peerError(QAbstractSocket::SocketError))); + emit qxt_p().clientConnected((quint64)(next)); } } -void QxtRPCPeer::dataAvailable() { - if(qxt_d().m_rpctype!=QxtRPCPeer::Server && qxt_d().m_peer==sender()) { + +void QxtRPCPeer::dataAvailable() +{ + if (qxt_d().m_rpctype!=QxtRPCPeer::Server && qxt_d().m_peer==sender()) + { qxt_d().m_buffer.append(qxt_d().m_peer->readAll()); qxt_d().processInput(qxt_d().m_peer, qxt_d().m_buffer); return; - } else { + } + else + { QxtRPCConnection* conn = qxt_d().m_clients.value(sender()); - if(!conn) { + if (!conn) + { qWarning() << "QxtRPCPeer: Unrecognized client object connected to dataAvailable"; return; } @@ -395,10 +517,14 @@ void QxtRPCPeer::dataAvailable() { qWarning() << "QxtRPCPeer: Unrecognized peer object connected to dataAvailable"; } -void QxtRPCPeer::disconnectSender() { + +void QxtRPCPeer::disconnectSender() +{ QxtRPCConnection* conn = qxt_d().m_clients.value(sender()); - if(!conn) { - if(qxt_d().m_peer!= qobject_cast(sender())) { + if (!conn) + { + if (qxt_d().m_peer!= qobject_cast(sender())) // SPUT: why not QTcpSocket*? + { qWarning() << "QxtRPCPeer: Unrecognized object connected to disconnectSender"; return; } @@ -417,13 +543,18 @@ void QxtRPCPeer::disconnectSender() { qxt_d().m_clients.remove(sender()); } -void QxtRPCPeerPrivate::processInput(QIODevice* socket, QByteArray& buffer) { - while(qxt_p().canDeserialize(buffer)) { + +void QxtRPCPeerPrivate::processInput(QIODevice* socket, QByteArray& buffer) +{ + while (qxt_p().canDeserialize(buffer)) + { QPair > sig = qxt_p().deserialize(buffer); - if(sig.first.isEmpty()) { - if(sig.second.count()) { + if (sig.first.isEmpty()) + { + if (sig.second.count()) + { qWarning() << "QxtRPCPeer: Invalid data received; disconnecting"; - if(socket == m_peer) + if (socket == m_peer) qxt_p().disconnectPeer(); else qxt_p().disconnectPeer((quint64)(socket)); @@ -431,48 +562,58 @@ void QxtRPCPeerPrivate::processInput(QIODevice* socket, QByteArray& buffer) { } continue; } - while(sig.second.count() < 9) sig.second << QVariant(); - if(socket == m_peer) { + while (sig.second.count() < 9) sig.second << QVariant(); + if (socket == m_peer) + { receivePeerSignal(sig.first, sig.second[0], sig.second[1], sig.second[2], sig.second[3], sig.second[4], sig.second[5], sig.second[6], sig.second[7], sig.second[8]); - } else { + } + else + { receiveClientSignal((quint64)(socket), sig.first, sig.second[0], sig.second[1], sig.second[2], sig.second[3], sig.second[4], sig.second[5], sig.second[6], sig.second[7]); } } } -QList QxtRPCPeer::clients() const { + +QList QxtRPCPeer::clients() const +{ QList rv; QList cs = qxt_d().m_clients.keys(); foreach(QObject* id, cs) rv << (const quint64)(id); return rv; } -QxtIntrospector::QxtIntrospector(QxtRPCPeer* parent, QObject* source, const char* signal): QObject(parent) { + +QxtIntrospector::QxtIntrospector(QxtRPCPeer* parent, QObject* source, const char* signal): QObject(parent) +{ peer = parent; QByteArray sig_ba = QMetaObject::normalizedSignature(QByteArray(signal).mid(1)); - ///FIXME: use normalizedsignature const char * sig=sig_ba.constData(); int idx = source->metaObject()->indexOfSignal(sig); - if(idx<0) - qWarning("no such signal: %s",sig_ba.constData()); + if (idx<0) + qWarning("no such signal: %s",sig_ba.constData()); - // Our "method" will have the first ID not used by the superclass. +// Our "method" will have the first ID not used by the superclass. QMetaObject::connect(source, idx, this, QObject::staticMetaObject.methodCount()); QObject::connect(source, SIGNAL(destroyed()), peer, SLOT(detachSender())); QList p = source->metaObject()->method(idx).parameterTypes(); int ct = p.count(); - for(int i=0; icall(rpcFunction.toUtf8().constData(), v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7], v[8]); } _id -= 1; @@ -480,12 +621,14 @@ int QxtIntrospector::qt_metacall(QMetaObject::Call _c, int _id, void **_a) { return _id; } -QPair > QxtRPCPeer::deserialize(QByteArray& data) { + +QPair > QxtRPCPeer::deserialize(QByteArray& data) +{ QByteArray cmd; int pos = data.indexOf('\n'); cmd = data.left(pos-1); data = data.mid(pos+1); - if(cmd.length()==0) return qMakePair(QString(), QList()); + if (cmd.length()==0) return qMakePair(QString(), QList()); cmd.replace(QByteArray("\\n"), QByteArray("\n")); cmd.replace(QByteArray("\\\\"), QByteArray("\\")); QDataStream str(cmd); @@ -495,23 +638,69 @@ QPair > QxtRPCPeer::deserialize(QByteArray& data) { QVariant t; str >> signal >> argCount; - if(str.status() == QDataStream::ReadCorruptData) { + if (str.status() == QDataStream::ReadCorruptData) + { v << QVariant(); return qMakePair(QString(), v); } - for(int i=0; i> t; v << t; } return qMakePair(signal, v); } -bool QxtRPCPeer::canDeserialize(const QByteArray& buffer) const { - if (buffer.indexOf('\n') == -1) - { - return false; - } + +bool QxtRPCPeer::canDeserialize(const QByteArray& buffer) const +{ + if (buffer.indexOf('\n') == -1) + { + return false; + } return true; - + +} + + + + +QIODevice * QxtRPCPeer::socket() +{ + if (qxt_d().m_rpctype == Server)return 0; + return qxt_d().m_peer; +} + + + + +QTcpSocket * QxtRPCPeer::incomingConnection ( int socketDescriptor ) +{ + QTcpSocket * t = new QTcpSocket; + t->setSocketDescriptor (socketDescriptor); + return t; } + + + + +const QTcpSocket * QxtRPCPeer::clientSocket(quint64 id) const + { + if (qxt_d().m_rpctype != Server) + return 0; + + return qxt_d().m_clients[(QTcpSocket*)(id)]->socket; + } +QList QxtRPCPeer::clients() + { + QList list; + foreach(QObject * o,qxt_d().m_clients.keys ()) + { + list.append((quint64)o); + } + return list; + } + + + diff --git a/src/contrib/qxt/qxtrpcpeer.h b/src/contrib/qxt/qxtrpcpeer.h index 3ff8784a..377e802b 100644 --- a/src/contrib/qxt/qxtrpcpeer.h +++ b/src/contrib/qxt/qxtrpcpeer.h @@ -1,31 +1,26 @@ /**************************************************************************** -** -** Copyright (C) Qxt Foundation. Some rights reserved. -** -** This file is part of the QxtNetwork module of the Qt eXTension library -** -** This library is free software; you can redistribute it and/or modify it -** under the terms of th Common Public License, version 1.0, as published by -** IBM. -** -** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY -** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY -** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR -** FITNESS FOR A PARTICULAR PURPOSE. -** -** You should have received a copy of the CPL along with this file. -** See the LICENSE file and the cpl1.0.txt file included with the source -** distribution for more information. If you did not receive a copy of the -** license, contact the Qxt Foundation. -** -** -** -***************************************************************************** -** -** This file has been modified from its original state to suit the needs of -** Quassel IRC. We have virtualized some methods. -** -*****************************************************************************/ + ** + ** Copyright (C) Qxt Foundation. Some rights reserved. + ** + ** This file is part of the QxtNetwork module of the Qt eXTension library + ** + ** This library is free software; you can redistribute it and/or modify it + ** under the terms of th Common Public License, version 1.0, as published by + ** IBM. + ** + ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY + ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY + ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR + ** FITNESS FOR A PARTICULAR PURPOSE. + ** + ** You should have received a copy of the CPL along with this file. + ** See the LICENSE file and the cpl1.0.txt file included with the source + ** distribution for more information. If you did not receive a copy of the + ** license, contact the Qxt Foundation. + ** + ** + ** + ****************************************************************************/ #ifndef QXTRPCPEER #define QXTRPCPEER @@ -38,7 +33,7 @@ #include #include #include - +class QTcpSocket; class QxtRPCPeerPrivate; /*! * \class QxtRPCPeer QxtRPCPeer @@ -47,49 +42,51 @@ class QxtRPCPeerPrivate; * * QxtRPCPeer is a tool that encapsulates Qt signals and transmits them over a network connection. * The signal is subsequently re-emitted on the receiving end of the connection. - * + * * QxtRPCPeer can operate in peer-to-peer mode (that is, one-to-one) or client-server (that is, one-to-many) mode. * In peer or server mode, QxtRPCPeer can listen for and accept incoming connections. In peer or client mode, * QxtRPCPeer can connect to a listening peer or server. - * + * * All data types used in attached signals and slots must be declared and registered with QMetaType using * Q_DECLARE_METATYPE and qRegisterMetaType, and they must have stream operators registered with qRegisterMetaTypeStreamOperators. * * The limits on the number of parameters passed to call() and related functions are a restriction of Qt, * which limits parameters on a signal or slot to 10. - */ -class QXT_NETWORK_EXPORT QxtRPCPeer : public QObject { -Q_OBJECT + */ +class QXT_NETWORK_EXPORT QxtRPCPeer : public QObject +{ + Q_OBJECT public: /*! * This enum is used with the \a setRPCType() to describe the role played in a connection. It is also returned by \a rpcType(). */ - enum RPCTypes { - Server, /**< Listen for clients and accept multiple connections. */ - Client, /**< Connect to a server. */ - Peer /**< Listen for a connection or connect to a peer. */ + enum RPCTypes + { + Server, /**< Listen for clients and accept multiple connections. */ + Client, /**< Connect to a server. */ + Peer /**< Listen for a connection or connect to a peer. */ }; /*! - * Creates a QxtRPCPeer object with the given parent. Unless changed later, this object will use Peer mode and QTcpSocket for its I/O device. - */ + * Creates a QxtRPCPeer object with the given parent. Unless changed later, this object will use Peer mode and QTcpSocket for its I/O device. + */ QxtRPCPeer(QObject* parent = 0); /*! - * Creates a QxtRPCPeer object with the given parent and type. Unless changed later, this object will use QTcpSocket for its I/O device. - */ + * Creates a QxtRPCPeer object with the given parent and type. Unless changed later, this object will use QTcpSocket for its I/O device. + */ QxtRPCPeer(RPCTypes type, QObject* parent = 0); /*! - * Creates a QxtRPCPeer object with the given parent and type and connects it to the specified I/O device. - * - * Note that the I/O device must already be opened for reading and writing. This constructor cannot be used for Server mode. - */ + * Creates a QxtRPCPeer object with the given parent and type and connects it to the specified I/O device. + * + * Note that the I/O device must already be opened for reading and writing. This constructor cannot be used for Server mode. + */ QxtRPCPeer(QIODevice* device, RPCTypes type = QxtRPCPeer::Peer, QObject* parent = 0); /*! - * Sets the RPC type. + * Sets the RPC type. * * Attempting to change the RPC type while listening or connected will be ignored with a warning. */ @@ -108,7 +105,7 @@ public: void connect(QHostAddress addr, int port = 80); /*! - * Listens on the specified interface on the specified port for connections. + * Listens on the specified interface on the specified port for connections. * * Attempting to listen while in Client mode or while connected in Peer mode will be ignored with a warning. In Peer mode, only one connection * can be active at a time. Additional incoming connections while connected to a peer will be dropped. When a peer connects, the \a peerConnected() @@ -133,14 +130,14 @@ public: * Stops listening for connections. Any connections still open will remain connected. */ void stopListening(); - + /*! * Returns a list of client IDs for all connected clients. */ QList clients() const; /*! - * Attaches the given signal. + * Attaches the given signal. * * When the attached signal is emitted, it will be transmitted to all connected servers, clients, or peers. * If an optional rpcFunction is provided, it will be used in place of the name of the transmitted signal. @@ -151,10 +148,10 @@ public: bool attachSignal(QObject* sender, const char* signal, const QByteArray& rpcFunction = QByteArray()); /*! - * Attaches the given slot. + * Attaches the given slot. * - * When a signal with the name given by rpcFunction is received from the network, the attached slot is executed. - * Use the SLOT() macro to specify the slot, just as you would for QObject::connect(). + * When a signal with the name given by rpcFunction is received from the network, the attached slot is executed. + * Use the SLOT() macro to specify the slot, just as you would for QObject::connect(). * * Like QObject::connect(), attachSignal returns false if the connection cannot be established. * @@ -168,11 +165,18 @@ public: */ void detachObject(QObject* obj); + + /*! + * Returns the current used iodevice (might be asocket or a custom iodevie) in client and peer mode. + * returns 0 for server mode + */ + QIODevice * socket(); + public slots: /*! - * Sends the signal fn with the given parameter list to the server or peer. + * Sends the signal fn with the given parameter list to the server or peer. * - * This function accepts up to 9 QVariant parameters. + * This function accepts up to 9 QVariant parameters. * * The receiver is not obligated to act upon the signal. If no server or peer is connected, the call is ignored. * In particular, this function does nothing in Server mode. @@ -189,17 +193,17 @@ public slots: * is ignored with a warning. */ void callClientList(QList ids, QString fn, QVariant p1 = QVariant(), QVariant p2 = QVariant(), QVariant p3 = QVariant(), QVariant p4 = QVariant(), - QVariant p5 = QVariant(), QVariant p6 = QVariant(), QVariant p7 = QVariant(), QVariant p8 = QVariant()); + QVariant p5 = QVariant(), QVariant p6 = QVariant(), QVariant p7 = QVariant(), QVariant p8 = QVariant()); /*! * Sends the signal fn with the given parameter list to the specified client. * - * This function accepts up to 8 QVariant parameters. - * + * This function accepts up to 8 QVariant parameters. + * * The receiver is not obligated to act upon the signal. If no client with the given ID is connected, the call will be ignored with a warning. */ void callClient(quint64 id, QString fn, QVariant p1 = QVariant(), QVariant p2 = QVariant(), QVariant p3 = QVariant(), QVariant p4 = QVariant(), - QVariant p5 = QVariant(), QVariant p6 = QVariant(), QVariant p7 = QVariant(), QVariant p8 = QVariant()); + QVariant p5 = QVariant(), QVariant p6 = QVariant(), QVariant p7 = QVariant(), QVariant p8 = QVariant()); /*! * Sends the signal fn with the given parameter list to all connected clients except for the client specified. @@ -210,13 +214,28 @@ public slots: * to all other connected clients. */ void callClientsExcept(quint64 id, QString fn, QVariant p1 = QVariant(), QVariant p2 = QVariant(), QVariant p3 = QVariant(), QVariant p4 = QVariant(), - QVariant p5 = QVariant(), QVariant p6 = QVariant(), QVariant p7 = QVariant(), QVariant p8 = QVariant()); + QVariant p5 = QVariant(), QVariant p6 = QVariant(), QVariant p7 = QVariant(), QVariant p8 = QVariant()); /*! * Detaches all signals and slots for the object that emitted the signal connected to detachSender(). */ void detachSender(); + /*! + * gives Access to the socket of the client \n + * usefull to get information about the client, like adress, port, etc..\n + * returns 0 when not in server mode or if the client \p id does not exist. + */ + + const QTcpSocket * clientSocket(quint64 id) const; + + /*! + * returns alist of all clients currently connected \n + * returns an empty List when not in server mode + */ + + QList clients(); + signals: /*! * This signal is emitted after a successful connection to or from a peer or server. @@ -224,7 +243,7 @@ signals: void peerConnected(); /*! - * This signal is emitted after a successful connection from a client. + * This signal is emitted after a successful connection from a client. * * The given ID is used for disconnectPeer(), callClient(), and related functions. */ @@ -275,14 +294,19 @@ protected: */ virtual bool canDeserialize(const QByteArray& buffer) const; -//protected: -// void newConnection(); + + + /*! + * is called in Server mode when a new connection is available. the default implementation returns a new QTCPSocket + * for the \p socketDescriptor + */ + virtual QTcpSocket * incomingConnection ( int socketDescriptor ); + private: QXT_DECLARE_PRIVATE(QxtRPCPeer); private slots: - void newConnection(); void dataAvailable(); void disconnectSender(); }; diff --git a/src/core/core.cpp b/src/core/core.cpp index 98aa4979..dfaa1b72 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -33,6 +33,7 @@ Core * Core::instance() { } void Core::destroy() { + //instanceptr->deleteLater(); delete instanceptr; instanceptr = 0; } @@ -53,9 +54,9 @@ void Core::init() { } Core::~Core() { - foreach(QTcpSocket *sock, validClients.keys()) { - delete sock; - } + //foreach(QTcpSocket *sock, validClients.keys()) { + // delete sock; + //} qDeleteAll(sessions); delete storage; } @@ -77,7 +78,7 @@ CoreSession *Core::createSession(UserId uid) { Q_ASSERT(!core->sessions.contains(uid)); CoreSession *sess = new CoreSession(uid, core->storage); core->sessions[uid] = sess; - connect(sess, SIGNAL(proxySignal(CoreSignal, QVariant, QVariant, QVariant)), core, SLOT(recvProxySignal(CoreSignal, QVariant, QVariant, QVariant))); + //connect(sess, SIGNAL(proxySignal(CoreSignal, QVariant, QVariant, QVariant)), core, SLOT(recvProxySignal(CoreSignal, QVariant, QVariant, QVariant))); return sess; } @@ -110,10 +111,12 @@ void Core::clientHasData() { Q_ASSERT(socket && blockSizes.contains(socket)); quint32 bsize = blockSizes.value(socket); QVariant item; - while(readDataFromDevice(socket, bsize, item)) { + if(readDataFromDevice(socket, bsize, item)) { + /* this is probably obsolete now */ if(validClients.contains(socket)) { - QList sigdata = item.toList(); - sessions[validClients[socket]]->processSignal((ClientSignal)sigdata[0].toInt(), sigdata[1], sigdata[2], sigdata[3]); + Q_ASSERT(false); + //QList sigdata = item.toList(); + //sessions[validClients[socket]]->processSignal((ClientSignal)sigdata[0].toInt(), sigdata[1], sigdata[2], sigdata[3]); } else { // we need to auth the client try { @@ -128,7 +131,7 @@ void Core::clientHasData() { return; } } - blockSizes[socket] = bsize = 0; + blockSizes[socket] = bsize = 0; // FIXME blockSizes aufräum0rn! } blockSizes[socket] = bsize; } @@ -155,7 +158,7 @@ void Core::disconnectLocalClient() { } void Core::processClientInit(QTcpSocket *socket, const QVariant &v) { - VarMap msg = v.toMap(); + QVariantMap msg = v.toMap(); if(msg["GuiProtocol"].toUInt() != GUI_PROTOCOL) { //qWarning() << "Client version mismatch."; throw Exception("GUI client version mismatch"); @@ -163,10 +166,12 @@ void Core::processClientInit(QTcpSocket *socket, const QVariant &v) { // Auth UserId uid = storage->validateUser(msg["User"].toString(), msg["Password"].toString()); // throws exception if this failed QVariant reply = initSession(uid); - validClients[socket] = uid; - QList sigdata; - sigdata.append(CS_CORE_STATE); sigdata.append(reply); sigdata.append(QVariant()); sigdata.append(QVariant()); - writeDataToDevice(socket, QVariant(sigdata)); + validClients[socket] = uid; // still needed? FIXME + //QList sigdata; + //sigdata.append(CS_CORE_STATE); sigdata.append(reply); sigdata.append(QVariant()); sigdata.append(QVariant()); + disconnect(socket, 0, this, 0); + sessions[uid]->addClient(socket); + writeDataToDevice(socket, reply); } QVariant Core::initSession(UserId uid) { @@ -177,11 +182,12 @@ QVariant Core::initSession(UserId uid) { sess = createSession(uid); //validClients[socket] = uid; } - VarMap reply; + QVariantMap reply; reply["SessionState"] = sess->sessionState(); return reply; } +/* void Core::recvProxySignal(CoreSignal sig, QVariant arg1, QVariant arg2, QVariant arg3) { CoreSession *sess = qobject_cast(sender()); Q_ASSERT(sess); @@ -193,3 +199,4 @@ void Core::recvProxySignal(CoreSignal sig, QVariant arg1, QVariant arg2, QVarian if(validClients[socket] == uid) writeDataToDevice(socket, QVariant(sigdata)); } } +*/ diff --git a/src/core/core.h b/src/core/core.h index af5fd92d..eef6a2f0 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -26,7 +26,7 @@ #include #include -#include "coreproxy.h" +#include "global.h" class CoreSession; class Storage; @@ -46,7 +46,7 @@ class Core : public QObject { static void disconnectLocalClient(); private slots: - void recvProxySignal(CoreSignal, QVariant, QVariant, QVariant); + //void recvProxySignal(CoreSignal, QVariant, QVariant, QVariant); bool startListening(uint port = DEFAULT_PORT); void stopListening(); void incomingConnection(); diff --git a/src/core/coreproxy.h b/src/core/coreproxy.h index 9a48fe0f..e8c8e63c 100644 --- a/src/core/coreproxy.h +++ b/src/core/coreproxy.h @@ -43,15 +43,15 @@ class CoreProxy : public QObject { inline void csSessionDataChanged(const QString &key, const QVariant &data) { send(CS_SESSION_DATA_CHANGED, key, data); } 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 csServerState(QString net, QVariantMap data) { send(CS_SERVER_STATE, net, data); } 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); } - inline void csNickAdded(QString net, QString nick, VarMap props) { send(CS_NICK_ADDED, net, nick, props); } + inline void csNickAdded(QString net, QString nick, QVariantMap props) { send(CS_NICK_ADDED, net, nick, props); } inline void csNickRemoved(QString net, QString nick) { send(CS_NICK_REMOVED, net, nick); } inline void csNickRenamed(QString net, QString oldn, QString newn) { send(CS_NICK_RENAMED, net, oldn, newn); } - inline void csNickUpdated(QString net, QString nick, VarMap props) { send(CS_NICK_UPDATED, net, nick, props); } + inline void csNickUpdated(QString net, QString nick, QVariantMap props) { send(CS_NICK_UPDATED, net, nick, props); } inline void csOwnNickSet(QString net, QString nick) { send(CS_OWN_NICK_SET, net, nick); } inline void csQueryRequested(QString net, QString nick) { send(CS_QUERY_REQUESTED, net, nick); } inline void csBacklogData(BufferId id, QList msg, bool done) { send(CS_BACKLOG_DATA, QVariant::fromValue(id), msg, done); } diff --git a/src/core/coresession.cpp b/src/core/coresession.cpp index ccfa2a1b..da8e3c51 100644 --- a/src/core/coresession.cpp +++ b/src/core/coresession.cpp @@ -20,11 +20,12 @@ #include "coresession.h" #include "server.h" +#include "signalproxy.h" #include "storage.h" #include "util.h" -CoreSession::CoreSession(UserId uid, Storage *_storage) : user(uid), storage(_storage) { - coreProxy = new CoreProxy(); +CoreSession::CoreSession(UserId uid, Storage *_storage, QObject *parent) : QObject(parent), user(uid), storage(_storage) { + _signalProxy = new SignalProxy(SignalProxy::Server, 0, this); QSettings s; s.beginGroup(QString("SessionData/%1").arg(user)); @@ -34,24 +35,40 @@ CoreSession::CoreSession(UserId uid, Storage *_storage) : user(uid), storage(_st } mutex.unlock(); - connect(coreProxy, SIGNAL(send(CoreSignal, QVariant, QVariant, QVariant)), this, SIGNAL(proxySignal(CoreSignal, QVariant, QVariant, QVariant))); - connect(coreProxy, SIGNAL(requestServerStates()), this, SIGNAL(serverStateRequested())); - connect(coreProxy, SIGNAL(gsRequestConnect(QStringList)), this, SLOT(connectToIrc(QStringList))); - 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))); - connect(this, SIGNAL(bufferIdUpdated(BufferId)), coreProxy, SLOT(csUpdateBufferId(BufferId))); - connect(storage, SIGNAL(bufferIdUpdated(BufferId)), coreProxy, SLOT(csUpdateBufferId(BufferId))); - connect(this, SIGNAL(sessionDataChanged(const QString &, const QVariant &)), coreProxy, SLOT(csSessionDataChanged(const QString &, const QVariant &))); - connect(coreProxy, SIGNAL(gsSessionDataChanged(const QString &, const QVariant &)), this, SLOT(storeSessionData(const QString &, const QVariant &))); + //connect(coreProxy, SIGNAL(send(CoreSignal, QVariant, QVariant, QVariant)), this, SIGNAL(proxySignal(CoreSignal, QVariant, QVariant, QVariant))); + //connect(coreProxy, SIGNAL(requestServerStates()), this, SIGNAL(serverStateRequested())); + //connect(coreProxy, SIGNAL(gsRequestConnect(QStringList)), this, SLOT(connectToIrc(QStringList))); + //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))); + //connect(this, SIGNAL(bufferIdUpdated(BufferId)), coreProxy, SLOT(csUpdateBufferId(BufferId))); + //connect(storage, SIGNAL(bufferIdUpdated(BufferId)), coreProxy, SLOT(csUpdateBufferId(BufferId))); + //connect(this, SIGNAL(sessionDataChanged(const QString &, const QVariant &)), coreProxy, SLOT(csSessionDataChanged(const QString &, const QVariant &))); + //connect(coreProxy, SIGNAL(gsSessionDataChanged(const QString &, const QVariant &)), this, SLOT(storeSessionData(const QString &, const QVariant &))); + + SignalProxy *p = signalProxy(); + + p->attachSlot(SIGNAL(requestNetworkStates()), this, SIGNAL(serverStateRequested())); + p->attachSlot(SIGNAL(requestConnect(QString)), this, SLOT(connectToNetwork(QString))); + p->attachSlot(SIGNAL(sendInput(BufferId, QString)), this, SLOT(msgFromGui(BufferId, QString))); + p->attachSlot(SIGNAL(importOldBacklog()), storage, SLOT(importOldBacklog())); + p->attachSlot(SIGNAL(requestBacklog(BufferId, QVariant, QVariant)), this, SLOT(sendBacklog(BufferId, QVariant, QVariant))); + p->attachSlot(SIGNAL(requestNetworkStates()), this, SLOT(sendServerStates())); + p->attachSignal(this, SIGNAL(displayMsg(Message))); + p->attachSignal(this, SIGNAL(displayStatusMsg(QString, QString))); + p->attachSignal(this, SIGNAL(backlogData(BufferId, QVariantList, bool))); + p->attachSignal(this, SIGNAL(bufferIdUpdated(BufferId))); + p->attachSignal(storage, SIGNAL(bufferIdUpdated(BufferId))); + p->attachSignal(this, SIGNAL(sessionDataChanged(const QString &, const QVariant &)), SIGNAL(coreSessionDataChanged(const QString &, const QVariant &))); + p->attachSlot(SIGNAL(clientSessionDataChanged(const QString &, const QVariant &)), this, SLOT(storeSessionData(const QString &, const QVariant &))); /* Autoconnect. (When) do we actually do this? QStringList list; - VarMap networks = retrieveSessionData("Networks").toMap(); + QVariantMap networks = retrieveSessionData("Networks").toMap(); foreach(QString net, networks.keys()) { if(networks[net].toMap()["AutoConnect"].toBool()) { list << net; @@ -69,9 +86,11 @@ UserId CoreSession::userId() const { return user; } +/* void CoreSession::processSignal(ClientSignal sig, QVariant arg1, QVariant arg2, QVariant arg3) { coreProxy->recv(sig, arg1, arg2, arg3); } +*/ void CoreSession::storeSessionData(const QString &key, const QVariant &data) { QSettings s; @@ -94,7 +113,8 @@ QVariant CoreSession::retrieveSessionData(const QString &key, const QVariant &de return data; } -void CoreSession::connectToIrc(QStringList networks) { +void CoreSession::connectToNetwork(QString network) { + QStringList networks; networks << network; // FIXME obsolete crap foreach(QString net, networks) { if(servers.contains(net)) { @@ -108,21 +128,34 @@ void CoreSession::connectToIrc(QStringList networks) { connect(server, SIGNAL(connected(QString)), this, SLOT(serverConnected(QString))); connect(server, SIGNAL(disconnected(QString)), this, SLOT(serverDisconnected(QString))); - connect(server, SIGNAL(serverState(QString, VarMap)), coreProxy, SLOT(csServerState(QString, VarMap))); - //connect(server, SIGNAL(displayMsg(Message)), this, SLOT(recvMessageFromServer(Message))); + //connect(server, SIGNAL(serverState(QString, QVariantMap)), coreProxy, SLOT(csServerState(QString, QVariantMap))); + ////connect(server, SIGNAL(displayMsg(Message)), this, SLOT(recvMessageFromServer(Message))); connect(server, SIGNAL(displayMsg(Message::Type, QString, QString, QString, quint8)), this, SLOT(recvMessageFromServer(Message::Type, QString, QString, QString, quint8))); connect(server, SIGNAL(displayStatusMsg(QString)), this, SLOT(recvStatusMsgFromServer(QString))); - connect(server, SIGNAL(modeSet(QString, QString, QString)), coreProxy, SLOT(csModeSet(QString, QString, QString))); - connect(server, SIGNAL(topicSet(QString, QString, QString)), coreProxy, SLOT(csTopicSet(QString, QString, QString))); - connect(server, SIGNAL(nickAdded(QString, QString, VarMap)), coreProxy, SLOT(csNickAdded(QString, QString, VarMap))); - connect(server, SIGNAL(nickRenamed(QString, QString, QString)), coreProxy, SLOT(csNickRenamed(QString, QString, QString))); - connect(server, SIGNAL(nickRemoved(QString, QString)), coreProxy, SLOT(csNickRemoved(QString, QString))); - connect(server, SIGNAL(nickUpdated(QString, QString, VarMap)), coreProxy, SLOT(csNickUpdated(QString, QString, VarMap))); - connect(server, SIGNAL(ownNickSet(QString, QString)), coreProxy, SLOT(csOwnNickSet(QString, QString))); - connect(server, SIGNAL(queryRequested(QString, QString)), coreProxy, SLOT(csQueryRequested(QString, QString))); + //connect(server, SIGNAL(modeSet(QString, QString, QString)), coreProxy, SLOT(csModeSet(QString, QString, QString))); + //connect(server, SIGNAL(topicSet(QString, QString, QString)), coreProxy, SLOT(csTopicSet(QString, QString, QString))); + //connect(server, SIGNAL(nickAdded(QString, QString, QVariantMap)), coreProxy, SLOT(csNickAdded(QString, QString, QVariantMap))); + //connect(server, SIGNAL(nickRenamed(QString, QString, QString)), coreProxy, SLOT(csNickRenamed(QString, QString, QString))); + //connect(server, SIGNAL(nickRemoved(QString, QString)), coreProxy, SLOT(csNickRemoved(QString, QString))); + //connect(server, SIGNAL(nickUpdated(QString, QString, QVariantMap)), coreProxy, SLOT(csNickUpdated(QString, QString, QVariantMap))); + //connect(server, SIGNAL(ownNickSet(QString, QString)), coreProxy, SLOT(csOwnNickSet(QString, QString))); + //connect(server, SIGNAL(queryRequested(QString, QString)), coreProxy, SLOT(csQueryRequested(QString, QString))); + //// TODO add error handling + //connect(server, SIGNAL(connected(QString)), coreProxy, SLOT(csServerConnected(QString))); + //connect(server, SIGNAL(disconnected(QString)), coreProxy, SLOT(csServerDisconnected(QString))); + + SignalProxy *p = signalProxy(); + p->attachSignal(server, SIGNAL(serverState(QString, QVariantMap)), SIGNAL(networkState(QString, QVariantMap))); + p->attachSignal(server, SIGNAL(modeSet(QString, QString, QString))); + p->attachSignal(server, SIGNAL(nickAdded(QString, QString, QVariantMap))); + p->attachSignal(server, SIGNAL(nickRenamed(QString, QString, QString))); + p->attachSignal(server, SIGNAL(nickRemoved(QString, QString))); + p->attachSignal(server, SIGNAL(nickUpdated(QString, QString, QVariantMap))); + p->attachSignal(server, SIGNAL(ownNickSet(QString, QString))); + p->attachSignal(server, SIGNAL(queryRequested(QString, QString))); // TODO add error handling - connect(server, SIGNAL(connected(QString)), coreProxy, SLOT(csServerConnected(QString))); - connect(server, SIGNAL(disconnected(QString)), coreProxy, SLOT(csServerDisconnected(QString))); + p->attachSignal(server, SIGNAL(connected(QString)), SIGNAL(networkConnected(QString))); + p->attachSignal(server, SIGNAL(disconnected(QString)), SIGNAL(networkDisconnected(QString))); server->start(); servers[net] = server; @@ -131,6 +164,14 @@ void CoreSession::connectToIrc(QStringList networks) { } } +void CoreSession::addClient(QIODevice *device) { + signalProxy()->addPeer(device); +} + +SignalProxy *CoreSession::signalProxy() const { + return _signalProxy; +} + void CoreSession::serverConnected(QString net) { storage->getBufferId(userId(), net); // create status buffer } @@ -138,7 +179,8 @@ void CoreSession::serverConnected(QString net) { void CoreSession::serverDisconnected(QString net) { delete servers[net]; servers.remove(net); - coreProxy->csServerDisconnected(net); + //coreProxy->csServerDisconnected(net); + signalProxy()->sendSignal(SIGNAL(networkDisconnected(QString)), net); // FIXME does this work? } void CoreSession::msgFromGui(BufferId bufid, QString msg) { @@ -176,7 +218,7 @@ QList CoreSession::buffers() const { QVariant CoreSession::sessionState() { - VarMap v; + QVariantMap v; QList bufs; foreach(BufferId id, storage->requestBuffers(user)) { bufs.append(QVariant::fromValue(id)); } v["Buffers"] = bufs; diff --git a/src/core/coresession.h b/src/core/coresession.h index 54af24ed..73204f64 100644 --- a/src/core/coresession.h +++ b/src/core/coresession.h @@ -25,16 +25,18 @@ #include #include -#include "coreproxy.h" +//#include "coreproxy.h" +#include "message.h" class Server; +class SignalProxy; class Storage; class CoreSession : public QObject { Q_OBJECT public: - CoreSession(UserId, Storage *); + CoreSession(UserId, Storage *, QObject *parent = 0); ~CoreSession(); QList buffers() const; @@ -45,21 +47,24 @@ class CoreSession : public QObject { //! Store a piece session-wide data and distribute it to connected clients. void storeSessionData(const QString &key, const QVariant &data); + void addClient(QIODevice *connection); + public: //! Retrieve a piece of session-wide data. QVariant retrieveSessionData(const QString &key, const QVariant &def = QVariant()); - CoreProxy *proxy(); + //CoreProxy *proxy(); + SignalProxy *signalProxy() const; public slots: - void connectToIrc(QStringList); - void processSignal(ClientSignal, QVariant, QVariant, QVariant); + void connectToNetwork(QString); + //void processSignal(ClientSignal, QVariant, QVariant, QVariant); void sendBacklog(BufferId, QVariant, QVariant); void msgFromGui(BufferId, QString message); void sendServerStates(); signals: - void proxySignal(CoreSignal, QVariant arg1 = QVariant(), QVariant arg2 = QVariant(), QVariant arg3 = QVariant()); + //void proxySignal(CoreSignal, QVariant arg1 = QVariant(), QVariant arg2 = QVariant(), QVariant arg3 = QVariant()); void msgFromGui(QString net, QString buf, QString message); void displayMsg(Message message); @@ -69,7 +74,7 @@ class CoreSession : public QObject { void disconnectFromIrc(QString net); void serverStateRequested(); - void backlogData(BufferId, QList, bool done); + void backlogData(BufferId, QVariantList, bool done); void bufferIdUpdated(BufferId); void sessionDataChanged(const QString &key); @@ -84,11 +89,12 @@ class CoreSession : public QObject { private: UserId user; - CoreProxy *coreProxy; + //CoreProxy *coreProxy; + SignalProxy *_signalProxy; Storage *storage; QHash servers; - VarMap sessionData; + QVariantMap sessionData; QMutex mutex; }; diff --git a/src/core/server.cpp b/src/core/server.cpp index 6bccd564..60accee1 100644 --- a/src/core/server.cpp +++ b/src/core/server.cpp @@ -57,8 +57,8 @@ void Server::run() { } void Server::sendState() { - VarMap s; - VarMap n, t; + QVariantMap s; + QVariantMap n, t; foreach(QString key, nicks.keys()) { n[key] = nicks[key]; } foreach(QString key, topics.keys()) { t[key] = topics[key];} s["Nicks"] = n; @@ -124,7 +124,7 @@ QString Server::updateNickFromMask(QString mask) { QString host = hostFromMask(mask); QString nick = nickFromMask(mask); if(nicks.contains(nick) && !user.isEmpty() && !host.isEmpty()) { - VarMap n = nicks[nick]; + QVariantMap n = nicks[nick]; if(n["User"].toString() != user || n["Host"].toString() != host) { if(!n["User"].toString().isEmpty() || !n["Host"].toString().isEmpty()) qWarning(QString("Strange: Hostmask for nick %1 has changed!").arg(nick).toAscii()); @@ -551,18 +551,18 @@ void Server::handleServerJoin(QString prefix, QStringList params) { topics[params[0]] = ""; emit topicSet(network, params[0], ""); } //else { - VarMap n; + QVariantMap n; if(nicks.contains(nick)) { n = nicks[nick]; - VarMap chans = n["Channels"].toMap(); + QVariantMap chans = n["Channels"].toMap(); // Q_ASSERT(!chans.keys().contains(params[0])); TODO uncomment - chans[params[0]] = VarMap(); + chans[params[0]] = QVariantMap(); n["Channels"] = chans; - nicks[nick] = n; + nicks[nick] = n; qDebug() << network << nick << n; emit nickUpdated(network, nick, n); } else { - VarMap chans; - chans[params[0]] = VarMap(); + QVariantMap chans; + chans[params[0]] = QVariantMap(); n["Channels"] = chans; n["User"] = userFromMask(prefix); n["Host"] = hostFromMask(prefix); @@ -577,8 +577,8 @@ void Server::handleServerKick(QString prefix, QStringList params) { QString kicker = updateNickFromMask(prefix); QString nick = params[1]; Q_ASSERT(nicks.contains(nick)); - VarMap n = nicks[nick]; - VarMap chans = n["Channels"].toMap(); + QVariantMap n = nicks[nick]; + QVariantMap chans = n["Channels"].toMap(); Q_ASSERT(chans.contains(params[0])); chans.remove(params[0]); QString msg = nick; @@ -612,7 +612,7 @@ void Server::handleServerMode(QString prefix, QStringList params) { Q_ASSERT(params.count() > m); QString nick = params[p++]; if(nicks.contains(nick)) { // sometimes, a server might try to set a MODE on a nick that is no longer there - VarMap n = nicks[nick]; VarMap clist = n["Channels"].toMap(); VarMap chan = clist[params[0]].toMap(); + QVariantMap n = nicks[nick]; QVariantMap clist = n["Channels"].toMap(); QVariantMap chan = clist[params[0]].toMap(); QString mstr = chan["Mode"].toString(); add ? mstr += modes[m] : mstr.remove(modes[m]); chan["Mode"] = mstr; clist[params[0]] = chan; n["Channels"] = clist; nicks[nick] = n; @@ -627,7 +627,7 @@ void Server::handleServerMode(QString prefix, QStringList params) { emit displayMsg(Message::Mode, params[0], params.join(" "), prefix); } else { //Q_ASSERT(nicks.contains(params[0])); - //VarMap n = nicks[params[0]].toMap(); + //QVariantMap n = nicks[params[0]].toMap(); //QString mode = n["Mode"].toString(); emit displayMsg(Message::Mode, "", params.join(" ")); } @@ -636,9 +636,9 @@ void Server::handleServerMode(QString prefix, QStringList params) { void Server::handleServerNick(QString prefix, QStringList params) { QString oldnick = updateNickFromMask(prefix); QString newnick = params[0]; - VarMap v = nicks.take(oldnick); + QVariantMap v = nicks.take(oldnick); nicks[newnick] = v; - VarMap chans = v["Channels"].toMap(); + QVariantMap chans = v["Channels"].toMap(); foreach(QString c, chans.keys()) { if(oldnick != ownNick) { emit displayMsg(Message::Nick, c, newnick, prefix); } else { emit displayMsg(Message::Nick, c, newnick, newnick); } @@ -659,8 +659,8 @@ void Server::handleServerNotice(QString prefix, QStringList params) { void Server::handleServerPart(QString prefix, QStringList params) { QString nick = updateNickFromMask(prefix); Q_ASSERT(nicks.contains(nick)); - VarMap n = nicks[nick]; - VarMap chans = n["Channels"].toMap(); + QVariantMap n = nicks[nick]; + QVariantMap chans = n["Channels"].toMap(); Q_ASSERT(chans.contains(params[0])); chans.remove(params[0]); QString msg; @@ -713,7 +713,7 @@ void Server::handleServerPrivmsg(QString prefix, QStringList params) { void Server::handleServerQuit(QString prefix, QStringList params) { QString nick = updateNickFromMask(prefix); Q_ASSERT(nicks.contains(nick)); - VarMap chans = nicks[nick]["Channels"].toMap(); + QVariantMap chans = nicks[nick]["Channels"].toMap(); QString msg; if(params.count()) msg = params[0]; foreach(QString c, chans.keys()) { @@ -736,11 +736,11 @@ void Server::handleServer001(QString prefix, QStringList params) { // there should be only one param: "Welcome to the Internet Relay Network !@" currentServer = prefix; ownNick = params[0].section(' ', -1, -1).section('!', 0, 0); - VarMap n; - n["Channels"] = VarMap(); + QVariantMap n; + n["Channels"] = QVariantMap(); nicks[ownNick] = n; emit ownNickSet(network, ownNick); - emit nickAdded(network, ownNick, VarMap()); + emit nickAdded(network, ownNick, QVariantMap()); emit displayMsg(Message::Server, "", params[0], prefix); // send performlist QStringList performList = networkSettings["Perform"].toString().split( "\n" ); @@ -763,7 +763,7 @@ void Server::handleServer005(QString prefix, QStringList params) { serverSupports[key] = val; // handle some special cases if(key == "PREFIX") { - VarMap foo; QString modes, prefixes; + QVariantMap foo; QString modes, prefixes; Q_ASSERT(val.contains(')') && val.startsWith('(')); int m = 1, p; for(p = 2; p < val.length(); p++) if(val[p] == ')') break; @@ -813,16 +813,16 @@ void Server::handleServer353(QString prefix, QStringList params) { if(prefixes[i] == nick[0]) { mode = serverSupports["PrefixModes"].toString()[i]; break; } nick.remove(0,1); } - VarMap c; c["Mode"] = mode; c["Prefix"] = pfx; + QVariantMap c; c["Mode"] = mode; c["Prefix"] = pfx; if(nicks.contains(nick)) { - VarMap n = nicks[nick]; - VarMap chans = n["Channels"].toMap(); + QVariantMap n = nicks[nick]; + QVariantMap chans = n["Channels"].toMap(); chans[buf] = c; n["Channels"] = chans; nicks[nick] = n; emit nickUpdated(network, nick, n); } else { - VarMap n; VarMap c; VarMap chans; + QVariantMap n; QVariantMap c; QVariantMap chans; c["Mode"] = mode; chans[buf] = c; n["Channels"] = chans; diff --git a/src/core/server.h b/src/core/server.h index dd8aac9b..360bed85 100644 --- a/src/core/server.h +++ b/src/core/server.h @@ -66,7 +66,7 @@ class Server : public QThread { //void exitThread(); signals: - void serverState(QString net, VarMap data); + void serverState(QString net, QVariantMap data); void recvRawServerMsg(QString); void displayStatusMsg(QString); //void displayMsg(Message msg); @@ -74,10 +74,10 @@ class Server : public QThread { void connected(QString network); void disconnected(QString network); - void nickAdded(QString network, QString nick, VarMap props); + void nickAdded(QString network, QString nick, QVariantMap props); void nickRenamed(QString network, QString oldnick, QString newnick); void nickRemoved(QString network, QString nick); - void nickUpdated(QString network, QString nick, VarMap props); + void nickUpdated(QString network, QString nick, QVariantMap props); void modeSet(QString network, QString target, QString mode); void topicSet(QString network, QString buffer, QString topic); void ownNickSet(QString network, QString newNick); @@ -152,11 +152,11 @@ class Server : public QThread { QString ownNick; QString currentServer; - VarMap networkSettings; - VarMap identity; - QHash nicks; // stores all known nicks for the server + QVariantMap networkSettings; + QVariantMap identity; + QHash nicks; // stores all known nicks for the server QHash topics; // stores topics for each buffer - VarMap serverSupports; // stores results from RPL_ISUPPORT + QVariantMap serverSupports; // stores results from RPL_ISUPPORT void handleServerMsg(QByteArray rawMsg); void handleUserInput(QString buffer, QString usrMsg); diff --git a/src/core/serverinfo.h b/src/core/serverinfo.h index 22421ec1..958c90af 100644 --- a/src/core/serverinfo.h +++ b/src/core/serverinfo.h @@ -71,8 +71,8 @@ private: QString currentServer_; QString ownNick_; - //VarMap networkSettings; - //VarMap identity; + //QVariantMap networkSettings; + //QVariantMap identity; QHash ircUsers_; // stores all known nicks for the server QHash topics_; // stores topics for each buffer diff --git a/src/core/sqlitestorage.cpp b/src/core/sqlitestorage.cpp index dda91b4d..86bf9881 100644 --- a/src/core/sqlitestorage.cpp +++ b/src/core/sqlitestorage.cpp @@ -109,6 +109,7 @@ SqliteStorage::SqliteStorage() { } SqliteStorage::~SqliteStorage() { + //logDb.close(); delete logMessageQuery; delete addSenderQuery; delete getLastMessageIdQuery; diff --git a/src/qtgui/bufferwidget.cpp b/src/qtgui/bufferwidget.cpp index f1a8946c..2deb46b3 100644 --- a/src/qtgui/bufferwidget.cpp +++ b/src/qtgui/bufferwidget.cpp @@ -65,7 +65,7 @@ void BufferWidget::setBuffer(Buffer *buf) { s->topic = buf->topic(); updateNickList(s, buf->nickList()); s->splitter->restoreState(s->splitterState); - connect(buf, SIGNAL(nickListChanged(VarMap)), this, SLOT(updateNickList(VarMap))); + connect(buf, SIGNAL(nickListChanged(QVariantMap)), this, SLOT(updateNickList(QVariantMap))); connect(s->nickTree, SIGNAL(itemExpanded(QTreeWidgetItem *)), this, SLOT(itemExpansionChanged(QTreeWidgetItem*))); connect(s->nickTree, SIGNAL(itemCollapsed(QTreeWidgetItem *)), this, SLOT(itemExpansionChanged(QTreeWidgetItem*))); } else { @@ -180,14 +180,14 @@ void BufferWidget::setTopic(QString topic) { } -void BufferWidget::updateNickList(VarMap nicks) { +void BufferWidget::updateNickList(QVariantMap nicks) { Buffer *buf = qobject_cast(sender()); Q_ASSERT(buf); updateNickList(states[buf], nicks); } // TODO Use 005 -void BufferWidget::updateNickList(BufferState *state, VarMap nicks) { +void BufferWidget::updateNickList(BufferState *state, QVariantMap nicks) { emit nickListUpdated(nicks.keys()); QTreeWidget *tree = state->nickTree; if(!tree) return; diff --git a/src/qtgui/bufferwidget.h b/src/qtgui/bufferwidget.h index 2024588b..251643f5 100644 --- a/src/qtgui/bufferwidget.h +++ b/src/qtgui/bufferwidget.h @@ -68,8 +68,8 @@ class BufferWidget : public QWidget { void updateTitle(); //void displayMsg(Message); - void updateNickList(BufferState *state, VarMap nicks); - void updateNickList(VarMap nicks); + void updateNickList(BufferState *state, QVariantMap nicks); + void updateNickList(QVariantMap nicks); void setOwnNick(QString ownNick); void setTopic(QString topic); void setActive(bool act = true); diff --git a/src/qtgui/coreconnectdlg.cpp b/src/qtgui/coreconnectdlg.cpp index d845f00d..9992496c 100644 --- a/src/qtgui/coreconnectdlg.cpp +++ b/src/qtgui/coreconnectdlg.cpp @@ -20,7 +20,7 @@ #include #include "coreconnectdlg.h" -#include "clientproxy.h" +//#include "clientproxy.h" #include "global.h" #include "client.h" #include "clientsettings.h" @@ -126,7 +126,7 @@ void CoreConnectDlg::setAccountEditEnabled(bool en) { void CoreConnectDlg::accountChanged(const QString &text) { AccountSettings s; if(!curacc.isEmpty()) { - VarMap oldAcc; + QVariantMap oldAcc; oldAcc["User"] = ui.userEdit->text(); oldAcc["Host"] = ui.hostEdit->text(); oldAcc["Port"] = ui.port->value(); @@ -138,7 +138,7 @@ void CoreConnectDlg::accountChanged(const QString &text) { if(!text.isEmpty()) { // empty text: just save stuff curacc = text; s.setLastAccount(curacc); - VarMap newAcc = s.value(curacc, "AccountData").toMap(); + QVariantMap newAcc = s.value(curacc, "AccountData").toMap(); ui.userEdit->setText(newAcc["User"].toString()); ui.hostEdit->setText(newAcc["Host"].toString()); ui.port->setValue(newAcc["Port"].toInt()); @@ -170,7 +170,7 @@ void CoreConnectDlg::createAccount() { QMessageBox::warning(this, tr("Account name already exists!"), tr("An account named '%1' already exists, and account names must be unique!").arg(accname)); return; } - VarMap defdata; + QVariantMap defdata; ui.accountList->addItem(accname); ui.accountList->setCurrentIndex(ui.accountList->findText(accname)); setAccountEditEnabled(true); @@ -210,9 +210,12 @@ void CoreConnectDlg::doAutoConnect() { void CoreConnectDlg::doConnect() { accountChanged(); // save current account info - VarMap conninfo; + QVariantMap conninfo; ui.stackedWidget->setCurrentIndex(1); if(ui.internalCore->isChecked()) { + // FIXME + coreConnectionError(tr("Can't connect to internal core at the moment [serious breakage due to switch to dynamic signals]. Please check back later.")); + return; if(Global::runMode != Global::Monolithic) { coreConnectionError(tr("Can't connect to internal core, since we are running as a standalone GUI!")); return; @@ -278,7 +281,7 @@ void CoreConnectDlg::coreConnected() { /* connect(ClientProxy::instance(), SIGNAL(recvPartialItem(quint32, quint32)), this, SLOT(updateProgressBar(quint32, quint32))); connect(ClientProxy::instance(), SIGNAL(csCoreState(QVariant)), this, SLOT(recvCoreState(QVariant))); ui.progressBar->show(); - VarMap initmsg; + QVariantMap initmsg; initmsg["GUIProtocol"] = GUI_PROTOCOL; // FIXME guiProxy->send(GS_CLIENT_INIT, QVariant(initmsg)); */ ui.connectionStatus->setText(tr("Connected to core.")); @@ -289,7 +292,7 @@ void CoreConnectDlg::coreConnectionError(QString err) { ui.stackedWidget->setCurrentIndex(0); show(); // just in case we started hidden QMessageBox::warning(this, tr("Connection Error"), tr("Could not connect to Quassel Core!
\n") + err, QMessageBox::Retry); - disconnect(ClientProxy::instance(), 0, this, 0); + //disconnect(ClientProxy::instance(), 0, this, 0); FIXME? //ui.autoConnect->setChecked(false); setStartState(); } diff --git a/src/qtgui/coreconnectdlg.h b/src/qtgui/coreconnectdlg.h index 384e2579..9f988a3f 100644 --- a/src/qtgui/coreconnectdlg.h +++ b/src/qtgui/coreconnectdlg.h @@ -61,7 +61,7 @@ class CoreConnectDlg: public QDialog { void cancelConnect(); void setStartState(); - VarMap accountData; + QVariantMap accountData; QString curacc; }; diff --git a/src/qtgui/identities.cpp b/src/qtgui/identities.cpp index f1cc27cd..a168b2f9 100644 --- a/src/qtgui/identities.cpp +++ b/src/qtgui/identities.cpp @@ -32,7 +32,7 @@ IdentitiesDlg::IdentitiesDlg(QWidget *parent, QString selected) : QDialog(parent nameMapping[name] = name; } if(identities.size() == 0) { - VarMap id = createDefaultIdentity(); + QVariantMap id = createDefaultIdentity(); id["IdName"] = "Default"; identities["Default"] = id; nameMapping["Default"] = "Default"; @@ -68,8 +68,8 @@ void IdentitiesDlg::globalDataUpdated(QString key) { } } -VarMap IdentitiesDlg::createDefaultIdentity() { - VarMap id; +QVariantMap IdentitiesDlg::createDefaultIdentity() { + QVariantMap id; id["RealName"] = "foo"; id["Ident"] = ""; id["NickList"] = QStringList(); @@ -98,7 +98,7 @@ QString IdentitiesDlg::getCurIdentity() { } void IdentitiesDlg::updateWidgets() { - VarMap id = identities[getCurIdentity()].toMap(); + QVariantMap id = identities[getCurIdentity()].toMap(); ui.realNameEdit->setText(id["RealName"].toString()); ui.identEdit->setText(id["Ident"].toString()); ui.nickList->clear(); @@ -128,7 +128,7 @@ void IdentitiesDlg::updateWidgets() { } void IdentitiesDlg::updateIdentity(QString idName) { - VarMap id; + QVariantMap id; id["RealName"] = ui.realNameEdit->text(); id["Ident"] = ui.identEdit->text(); QStringList nicks; @@ -239,9 +239,9 @@ void IdentitiesDlg::accept() { if(result.length() == 0) { Client::storeSessionData("Identities", identities); // We have to care about renamed identities and update the network list appropriately... - VarMap networks = Client::retrieveSessionData("Networks").toMap(); + QVariantMap networks = Client::retrieveSessionData("Networks").toMap(); foreach(QString netname, networks.keys()) { - VarMap net = networks[netname].toMap(); + QVariantMap net = networks[netname].toMap(); if(nameMapping.contains(net["Identity"].toString())) { net["Identity"] = nameMapping[net["Identity"].toString()]; } else net["Identity"] = "Default"; @@ -260,7 +260,7 @@ QString IdentitiesDlg::checkValidity() { QString reason; foreach(QString name, identities.keys()) { QString r; - VarMap id = identities[name].toMap(); + QVariantMap id = identities[name].toMap(); if(name == "Default") name = tr("Default Identity"); if(id["RealName"].toString().isEmpty()) { r += tr(" You have not set a real name."); @@ -297,7 +297,7 @@ void IdentitiesDlg::editIdentities() { /******************************************************************************/ -IdentitiesEditDlg::IdentitiesEditDlg(QWidget *parent, VarMap _identities, QMap _mapping, VarMap templ, QString selected) +IdentitiesEditDlg::IdentitiesEditDlg(QWidget *parent, QVariantMap _identities, QMap _mapping, QVariantMap templ, QString selected) : QDialog(parent) { ui.setupUi(this); identities = _identities; @@ -331,7 +331,7 @@ IdentitiesEditDlg::IdentitiesEditDlg(QWidget *parent, VarMap _identities, QMap getNameMapping() { return nameMapping; } public slots: @@ -58,12 +58,12 @@ class IdentitiesDlg : public QDialog { private: Ui::IdentitiesDlg ui; - VarMap identities; + QVariantMap identities; QMap nameMapping; QString lastIdentity; QString checkValidity(); - VarMap createDefaultIdentity(); + QVariantMap createDefaultIdentity(); QString getCurIdentity(); void updateWidgets(); void updateIdentity(QString); @@ -89,9 +89,9 @@ class IdentitiesEditDlg : public QDialog { Q_OBJECT public: - IdentitiesEditDlg(QWidget *parent, VarMap identities, QMap mapping, VarMap templ, QString selected = QString()); + IdentitiesEditDlg(QWidget *parent, QVariantMap identities, QMap mapping, QVariantMap templ, QString selected = QString()); - VarMap getIdentities() { return identities; } + QVariantMap getIdentities() { return identities; } QMap getMapping() { return mapping; } QString getSelectedIdentity() { return ui.identList->currentItem()->text(); } @@ -108,8 +108,8 @@ class IdentitiesEditDlg : public QDialog { private: Ui::IdentitiesEditDlg ui; - VarMap identities; - VarMap identTemplate; + QVariantMap identities; + QVariantMap identTemplate; QMap mapping; void sortList(); diff --git a/src/qtgui/mainwin.cpp b/src/qtgui/mainwin.cpp index 74d62679..ef96c2a0 100644 --- a/src/qtgui/mainwin.cpp +++ b/src/qtgui/mainwin.cpp @@ -23,11 +23,12 @@ #include "bufferview.h" #include "chatline.h" #include "client.h" -#include "clientproxy.h" +//#include "clientproxy.h" #include "coreconnectdlg.h" #include "serverlist.h" #include "settingsdlg.h" //#include "settingspage.h" +#include "signalproxy.h" MainWin::MainWin(QtGui *_gui, QWidget *parent) : QMainWindow(parent), gui(_gui) { ui.setupUi(this); @@ -41,12 +42,13 @@ MainWin::MainWin(QtGui *_gui, QWidget *parent) : QMainWindow(parent), gui(_gui) } void MainWin::init() { - connect(this, SIGNAL(requestBacklog(BufferId, QVariant, QVariant)), ClientProxy::instance(), SLOT(gsRequestBacklog(BufferId, QVariant, QVariant))); + //connect(this, SIGNAL(requestBacklog(BufferId, QVariant, QVariant)), ClientProxy::instance(), SLOT(gsRequestBacklog(BufferId, QVariant, QVariant))); + Client::signalProxy()->attachSignal(this, SIGNAL(requestBacklog(BufferId, QVariant, QVariant))); ui.bufferWidget->init(); show(); - //VarMap connInfo; + //QVariantMap connInfo; //connInfo["User"] = "Default"; //connInfo["Password"] = "password"; //connectToCore(connInfo); @@ -108,7 +110,8 @@ void MainWin::setupMenus() { connect(ui.actionAboutQt, SIGNAL(triggered()), QApplication::instance(), SLOT(aboutQt())); // for debugging connect(ui.actionImportBacklog, SIGNAL(triggered()), this, SLOT(importBacklog())); - connect(this, SIGNAL(importOldBacklog()), ClientProxy::instance(), SLOT(gsImportBacklog())); + //connect(this, SIGNAL(importOldBacklog()), ClientProxy::instance(), SLOT(gsImportBacklog())); + Client::signalProxy()->attachSignal(this, SIGNAL(importOldBacklog())); } void MainWin::setupViews() { diff --git a/src/qtgui/mainwin.h b/src/qtgui/mainwin.h index 60ffc184..f5224492 100644 --- a/src/qtgui/mainwin.h +++ b/src/qtgui/mainwin.h @@ -66,7 +66,7 @@ class MainWin : public QMainWindow { void importBacklog(); signals: - void connectToCore(const VarMap &connInfo); + void connectToCore(const QVariantMap &connInfo); void disconnectFromCore(); void requestBacklog(BufferId, QVariant, QVariant); void importOldBacklog(); diff --git a/src/qtgui/qtgui.cpp b/src/qtgui/qtgui.cpp index 8b242175..985a9ad5 100644 --- a/src/qtgui/qtgui.cpp +++ b/src/qtgui/qtgui.cpp @@ -24,7 +24,7 @@ QtGui::QtGui() : AbstractUi() { mainWin = new MainWin(this); - connect(mainWin, SIGNAL(connectToCore(const VarMap &)), this, SIGNAL(connectToCore(const VarMap &))); + connect(mainWin, SIGNAL(connectToCore(const QVariantMap &)), this, SIGNAL(connectToCore(const QVariantMap &))); connect(mainWin, SIGNAL(disconnectFromCore()), this, SIGNAL(disconnectFromCore())); } diff --git a/src/qtgui/serverlist.cpp b/src/qtgui/serverlist.cpp index a374dafd..99265f1c 100644 --- a/src/qtgui/serverlist.cpp +++ b/src/qtgui/serverlist.cpp @@ -21,7 +21,8 @@ #include "serverlist.h" #include "identities.h" #include "client.h" -#include "clientproxy.h" +//#include "clientproxy.h" +#include "signalproxy.h" /* NOTE: This dialog holds not only the server list, but also the identities. * This makes perfect sense given the fact that connections are initiated from @@ -41,12 +42,13 @@ ServerListDlg::ServerListDlg(QWidget *parent) : QDialog(parent) { settings.endGroup(); - connect(this, SIGNAL(requestConnect(QStringList)), ClientProxy::instance(), SLOT(gsRequestConnect(QStringList))); + //connect(this, SIGNAL(requestConnect(QStringList)), ClientProxy::instance(), SLOT(gsRequestConnect(QStringList))); + Client::signalProxy()->attachSignal(this, SIGNAL(requestConnect(QString))); // Autoconnect /* Should not be the client's task... :-P QStringList list; - VarMap networks = Client::retrieveSessionData("Networks").toMap(); + QVariantMap networks = Client::retrieveSessionData("Networks").toMap(); foreach(QString net, networks.keys()) { if(networks[net].toMap()["AutoConnect"].toBool()) { list << net; @@ -61,7 +63,7 @@ ServerListDlg::~ServerListDlg() { } void ServerListDlg::updateNetworkTree() { - VarMap networks = Client::retrieveSessionData("Networks").toMap(); + QVariantMap networks = Client::retrieveSessionData("Networks").toMap(); //QStringList headers; //headers << "Network" << "Autoconnect"; ui.networkTree->clear(); @@ -69,7 +71,7 @@ void ServerListDlg::updateNetworkTree() { ui.networkTree->setHeaderLabel("Networks"); QHash groups; foreach(QString net, networks.keys()) { - VarMap s = networks[net].toMap(); + QVariantMap s = networks[net].toMap(); QString gr = s["Group"].toString(); QTreeWidgetItem *item = 0; if(gr.isEmpty()) { @@ -111,10 +113,10 @@ bool ServerListDlg::showOnStartup() { } void ServerListDlg::on_addButton_clicked() { - NetworkEditDlg dlg(this, VarMap()); + NetworkEditDlg dlg(this, QVariantMap()); if(dlg.exec() == QDialog::Accepted) { - VarMap networks = Client::retrieveSessionData("Networks").toMap(); - VarMap net = dlg.getNetwork(); + QVariantMap networks = Client::retrieveSessionData("Networks").toMap(); + QVariantMap net = dlg.getNetwork(); networks[net["Name"].toString()] = net; Client::storeSessionData("Networks", networks); updateNetworkTree(); @@ -123,10 +125,10 @@ void ServerListDlg::on_addButton_clicked() { void ServerListDlg::on_editButton_clicked() { QString curnet = ui.networkTree->currentItem()->text(0); - VarMap networks = Client::retrieveSessionData("Networks").toMap(); + QVariantMap networks = Client::retrieveSessionData("Networks").toMap(); NetworkEditDlg dlg(this, networks[curnet].toMap()); if(dlg.exec() == QDialog::Accepted) { - VarMap net = dlg.getNetwork(); + QVariantMap net = dlg.getNetwork(); networks.remove(curnet); networks[net["Name"].toString()] = net; Client::storeSessionData("Networks", networks); @@ -137,7 +139,7 @@ void ServerListDlg::on_editButton_clicked() { void ServerListDlg::on_deleteButton_clicked() { if(QMessageBox::warning(this, tr("Remove Network?"), tr("Are you sure you want to delete the selected network(s)?"), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { - VarMap networks = Client::retrieveSessionData("Networks").toMap(); + QVariantMap networks = Client::retrieveSessionData("Networks").toMap(); QList sel = ui.networkTree->selectedItems(); foreach(QTreeWidgetItem *item, sel) { networks.remove(item->text(0)); @@ -173,27 +175,27 @@ void ServerListDlg::accept() { foreach(QTreeWidgetItem *item, list) { nets << item->text(0); } - emit requestConnect(nets); + emit requestConnect(nets[0]); // FIXME QDialog::accept(); } /***************************************************************************/ -NetworkEditDlg::NetworkEditDlg(QWidget *parent, VarMap _network) : QDialog(parent) { +NetworkEditDlg::NetworkEditDlg(QWidget *parent, QVariantMap _network) : QDialog(parent) { ui.setupUi(this); network = _network; oldName = network["Name"].toString(); connect(ui.serverList, SIGNAL(itemSelectionChanged()), this, SLOT(updateServerButtons())); - VarMap identities = Client::retrieveSessionData("Identities").toMap(); + QVariantMap identities = Client::retrieveSessionData("Identities").toMap(); ui.identityList->addItem(tr("Default Identity")); foreach(QString id, identities.keys()) { if(id != "Default") ui.identityList->addItem(id); } QStringList groups; groups << ""; - VarMap nets = Client::retrieveSessionData("Networks").toMap(); + QVariantMap nets = Client::retrieveSessionData("Networks").toMap(); foreach(QString net, nets.keys()) { QString gr = nets[net].toMap()["Group"].toString(); if(!groups.contains(gr) && !gr.isEmpty()) { @@ -215,8 +217,8 @@ NetworkEditDlg::NetworkEditDlg(QWidget *parent, VarMap _network) : QDialog(paren ui.networkName->setFocus(); } -VarMap NetworkEditDlg::createDefaultNetwork() { - VarMap net; +QVariantMap NetworkEditDlg::createDefaultNetwork() { + QVariantMap net; net["Name"] = QString(); net["Group"] = QString(); @@ -228,7 +230,7 @@ VarMap NetworkEditDlg::createDefaultNetwork() { void NetworkEditDlg::updateWidgets() { ui.serverList->clear(); foreach(QVariant s, network["Servers"].toList()) { - VarMap server = s.toMap(); + QVariantMap server = s.toMap(); QString entry = QString("%1:%2").arg(server["Address"].toString()).arg(server["Port"].toInt()); QListWidgetItem *item = new QListWidgetItem(entry); //if(server["Exclude"].toBool()) item->setCheckState(Qt::Checked); @@ -276,7 +278,7 @@ void NetworkEditDlg::accept() { QString NetworkEditDlg::checkValidity() { QString r; - VarMap nets = Client::retrieveSessionData("Networks").toMap(); + QVariantMap nets = Client::retrieveSessionData("Networks").toMap(); if(ui.networkName->text() != oldName && nets.keys().contains(ui.networkName->text())) { r += tr(" Network name already exists."); } @@ -341,7 +343,7 @@ void NetworkEditDlg::on_editIdentities_clicked() { else id = "Default"; IdentitiesDlg dlg(this, id); if(dlg.exec() == QDialog::Accepted) { - VarMap identities = Client::retrieveSessionData("Identities").toMap(); + QVariantMap identities = Client::retrieveSessionData("Identities").toMap(); ui.identityList->clear(); ui.identityList->addItem(tr("Default Identity")); foreach(QString i, identities.keys()) { @@ -358,7 +360,7 @@ void NetworkEditDlg::on_editIdentities_clicked() { /***************************************************************************/ -ServerEditDlg::ServerEditDlg(QWidget *parent, VarMap server) : QDialog(parent) { +ServerEditDlg::ServerEditDlg(QWidget *parent, QVariantMap server) : QDialog(parent) { ui.setupUi(this); if(!server.isEmpty()) { @@ -375,8 +377,8 @@ void ServerEditDlg::on_serverAddress_textChanged() { ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!ui.serverAddress->text().isEmpty()); } -VarMap ServerEditDlg::getServer() { - VarMap s; +QVariantMap ServerEditDlg::getServer() { + QVariantMap s; s["Address"] = ui.serverAddress->text(); s["Port"] = ui.serverPort->text(); return s; diff --git a/src/qtgui/serverlist.h b/src/qtgui/serverlist.h index aa4c825b..f3058b81 100644 --- a/src/qtgui/serverlist.h +++ b/src/qtgui/serverlist.h @@ -46,7 +46,7 @@ class ServerListDlg : public QDialog { virtual void accept(); signals: - void requestConnect(QStringList networks); + void requestConnect(QString network); private slots: void updateButtons(); @@ -59,17 +59,17 @@ class ServerListDlg : public QDialog { private: Ui::ServerListDlg ui; - //VarMap networks; - //VarMap identities; <-- this is now stored in global + //QVariantMap networks; + //QVariantMap identities; <-- this is now stored in global }; class NetworkEditDlg : public QDialog { Q_OBJECT public: - NetworkEditDlg(QWidget *parent, VarMap network); + NetworkEditDlg(QWidget *parent, QVariantMap network); - VarMap getNetwork() { return network; } + QVariantMap getNetwork() { return network; } public slots: virtual void accept(); @@ -87,11 +87,11 @@ class NetworkEditDlg : public QDialog { private: Ui::NetworkEditDlg ui; - VarMap network; - //VarMap identities; + QVariantMap network; + //QVariantMap identities; QString oldName; - VarMap createDefaultNetwork(); + QVariantMap createDefaultNetwork(); QString checkValidity(); }; @@ -99,9 +99,9 @@ class ServerEditDlg : public QDialog { Q_OBJECT public: - ServerEditDlg(QWidget *parent, VarMap server = VarMap()); + ServerEditDlg(QWidget *parent, QVariantMap server = QVariantMap()); - VarMap getServer(); + QVariantMap getServer(); private slots: void on_serverAddress_textChanged(); -- 2.20.1