YES! We finally have dynamic signals between Core and Client, meaning that arbitrary
authorManuel Nickschas <sputnick@quassel-irc.org>
Wed, 29 Aug 2007 20:44:47 +0000 (20:44 +0000)
committerManuel Nickschas <sputnick@quassel-irc.org>
Wed, 29 Aug 2007 20:44:47 +0000 (20:44 +0000)
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 <http://www.libqxt.org>.

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.

45 files changed:
Quassel.kdevelop.filelist
src/client/buffer.cpp
src/client/buffer.h
src/client/buffertreemodel.cpp
src/client/client.cpp
src/client/client.h
src/client/clientproxy.h
src/common/global.h
src/common/main.cpp
src/common/quasselui.h
src/common/signalproxy.cpp
src/common/signalproxy.h
src/contrib/qxt/CMakeLists.txt
src/contrib/qxt/qxtboundcfunction.h [new file with mode: 0644]
src/contrib/qxt/qxtboundfunction.h [new file with mode: 0644]
src/contrib/qxt/qxtboundfunctionbase.h [new file with mode: 0644]
src/contrib/qxt/qxtglobal.h
src/contrib/qxt/qxtmetaobject.cpp [new file with mode: 0644]
src/contrib/qxt/qxtmetaobject.h [new file with mode: 0644]
src/contrib/qxt/qxtnull.cpp [new file with mode: 0644]
src/contrib/qxt/qxtnull.h [new file with mode: 0644]
src/contrib/qxt/qxtnullable.h [new file with mode: 0644]
src/contrib/qxt/qxtpimpl.h
src/contrib/qxt/qxtrpcpeer.cpp
src/contrib/qxt/qxtrpcpeer.h
src/core/core.cpp
src/core/core.h
src/core/coreproxy.h
src/core/coresession.cpp
src/core/coresession.h
src/core/server.cpp
src/core/server.h
src/core/serverinfo.h
src/core/sqlitestorage.cpp
src/qtgui/bufferwidget.cpp
src/qtgui/bufferwidget.h
src/qtgui/coreconnectdlg.cpp
src/qtgui/coreconnectdlg.h
src/qtgui/identities.cpp
src/qtgui/identities.h
src/qtgui/mainwin.cpp
src/qtgui/mainwin.h
src/qtgui/qtgui.cpp
src/qtgui/serverlist.cpp
src/qtgui/serverlist.h

index 5125950..584525a 100644 (file)
@@ -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
index 7f4d885..917d71a 100644 (file)
@@ -85,7 +85,7 @@ QList<AbstractUiMsg *> 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);
 }
index 8e9bf6c..76b1440 100644 (file)
@@ -55,14 +55,14 @@ class Buffer : public QObject {
     QString displayName() const;
     BufferId bufferId() const;
     QList<AbstractUiMsg *> 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;
index 54ef7a8..c6fb996 100644 (file)
 
 #include <QColor>  // 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)));
 }
 
 QList<QVariant >BufferTreeModel::defaultHeader() {
index 85096c7..3cb067b 100644 (file)
 
 #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<BufferId, Buffer *> Client::buffers;
 QHash<uint, BufferId> Client::bufferIds;
-QHash<QString, QHash<QString, VarMap> > Client::nicks;
+QHash<QString, QHash<QString, QVariantMap> > Client::nicks;
 QHash<QString, bool> Client::netConnected;
 QStringList Client::netsAwaitingInit;
 QHash<QString, QString> 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<QVariant> &, bool)), this, SLOT(recvBacklogData(BufferId, QList<QVariant>, 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<QVariant> &, bool)), this, SLOT(recvBacklogData(BufferId, QList<QVariant>, 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<QAbstractSocket*>(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<QVariant> 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<QVariant> sigdata = item.toList();
-    Q_ASSERT(sigdata.size() == 4);
-    ClientProxy::instance()->recv((CoreSignal)sigdata[0].toInt(), sigdata[1], sigdata[2], sigdata[3]);
+    //QList<QVariant> 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<QVariant> &msgs, bool /*done*/) {
+void Client::recvBacklogData(BufferId id, QVariantList msgs, bool /*done*/) {
   Buffer *b = buffer(id);
   foreach(QVariant v, msgs) {
     Message msg = v.value<Message>();
@@ -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);
   }
index a55a92b..9d7df3e 100644 (file)
@@ -24,6 +24,7 @@
 #include <QAbstractSocket>
 #include <QTcpSocket>
 #include <QList>
+#include <QPointer>
 
 #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<QVariant> &, 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<QIODevice> socket;
     quint32 blockSize;
 
     static bool connectedToCore;
-    static VarMap coreConnectionInfo;
+    static QVariantMap coreConnectionInfo;
     static QHash<BufferId, Buffer *> buffers;
     static QHash<uint, BufferId> bufferIds;
-    static QHash<QString, QHash<QString, VarMap> > nicks;
+    static QHash<QString, QHash<QString, QVariantMap> > nicks;
     static QHash<QString, bool> netConnected;
     static QStringList netsAwaitingInit;
     static QHash<QString, QString> ownNick;
@@ -149,7 +154,7 @@ class Client : public QObject {
     QTimer *layoutTimer;
     QList<Buffer *> layoutQueue;
 
-    VarMap sessionData;
+    QVariantMap sessionData;
 };
 
 #endif
index 4845faf..e579e12 100644 (file)
@@ -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<QVariant>, bool);
index c672c40..4ec49eb 100644 (file)
@@ -35,7 +35,6 @@
 #include <QVariant>
 
 /* Some global stuff */
-typedef QMap<QString, QVariant> VarMap;
 
 typedef uint UserId;
 typedef uint MsgId;
index 86d874b..4b99a39 100644 (file)
 #include <QCoreApplication>
 #include <QDir>
 #include "core.h"
+#include "message.h"
 
 #elif defined BUILD_QTGUI
 #include <QApplication>
 #include "client.h"
-#include "clientproxy.h"
+//#include "clientproxy.h"
 #include "qtgui.h"
 #include "style.h"
 
 #elif defined BUILD_MONO
 #include <QApplication>
 #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>("QVariant");
   qRegisterMetaType<Message>("Message");
   qRegisterMetaType<BufferId>("BufferId");
+  qRegisterMetaTypeStreamOperators<QVariant>("QVariant");
   qRegisterMetaTypeStreamOperators<Message>("Message");
   qRegisterMetaTypeStreamOperators<BufferId>("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
index 5cfc5f0..414d599 100644 (file)
@@ -49,7 +49,7 @@ class AbstractUi : public QObject {
     virtual void disconnectedFromCore() {}
 
   signals:
-    void connectToCore(const VarMap &connInfo);
+    void connectToCore(const QVariantMap &connInfo);
     void disconnectFromCore();
 
 };
index bd12b15..d6c105b 100644 (file)
@@ -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<QAbstractSocket*>(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);
+  }
+}
+
index 90dadde..ed8b46b 100644 (file)
@@ -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 {
index 9f3c2f2..cd8448f 100644 (file)
@@ -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 (file)
index 0000000..02ba596
--- /dev/null
@@ -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.
+**
+** <http://libqxt.sourceforge.net>  <foundation@libqxt.org>
+**
+****************************************************************************/
+
+#ifndef QXTBOUNDCFUNCTION_H
+#define QXTBOUNDCFUNCTION_H
+
+#include <QObject>
+#include <QMetaObject>
+#include <QGenericArgument>
+#include <qxtmetaobject.h>
+#include <qxtboundfunctionbase.h>
+#include <qxtnull.h>
+#include <QThread>
+/*
+template <typename FUNCTION, int argc, typename RETURN = void>
+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<FUNCTION, argc, RETURN>(funcPtr, returnValue, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);
+    }
+};
+
+template <typename FUNCTION, int argc>
+class QxtBoundCFunction<FUNCTION, argc, void> : 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<FUNCTION, argc>(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<FP, 1>(0, fn, qbcfP, types); }
+QxtBoundCFunction<void(*)(int), 1> 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 (file)
index 0000000..80d0294
--- /dev/null
@@ -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.
+**
+** <http://libqxt.sourceforge.net>  <foundation@libqxt.org>
+**
+****************************************************************************/
+
+#ifndef QXTBOUNDFUNCTION_H
+#define QXTBOUNDFUNCTION_H
+
+#include <QObject>
+#include <QMetaObject>
+#include <QGenericArgument>
+#include <qxtmetaobject.h>
+#include <qxtnull.h>
+#include <QThread>
+
+class QxtBoundFunction : public QObject
+{
+    Q_OBJECT
+public:
+    template <class T>
+    inline QxtNullable<T> invoke(QXT_PROTO_10ARGS(QVariant))
+    {
+        if (QThread::currentThread() == parent()->thread())
+            return invoke<T>(Qt::DirectConnection, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); 
+#if QT_VERSION >= 0x040300
+        return invoke<T>(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 <class T>
+    QxtNullable<T> 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<T>(*reinterpret_cast<T*>(0)).typeName(), reinterpret_cast<void*>(&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 (file)
index 0000000..1be80f0
--- /dev/null
@@ -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.
+**
+** <http://libqxt.sourceforge.net>  <foundation@libqxt.org>
+**
+****************************************************************************/
+
+// 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 <QObject>
+#include <QMetaObject>
+#include <QGenericArgument>
+#include <qxtmetaobject.h>
+#include <qxtboundfunction.h>
+
+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
index 4a2e6b7..2fff049 100644 (file)
 ** 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.
-** 
+**
 ** <http://libqxt.sourceforge.net>  <foundation@libqxt.org>
 **
 ****************************************************************************/
@@ -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 (file)
index 0000000..e6aa03c
--- /dev/null
@@ -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.
+**
+** <http://libqxt.sourceforge.net>  <foundation@libqxt.org>
+**
+****************************************************************************/
+/**
+\class QxtMetaObject QxtMetaObject
+
+\ingroup core
+
+\brief provides extensions to QMetaObject
+
+including QxtMetaObject::bind \n
+
+*/
+#include "qxtmetaobject.h"
+#include "qxtboundfunction.h"
+#include "qxtboundcfunction.h"
+
+#include <QByteArray>
+#include <QMetaObject>
+#include <QMetaMethod>
+#include <QtDebug>
+
+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<QxtBoundFunctionBase*>(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<QByteArray> paramTypes = method.parameterTypes();
+
+    for (int i=0; i<argCount; i++)
+    {
+        if (paramTypes[i] == "QxtBoundArgument") continue;
+        int type = QMetaType::type(paramTypes[i].constData());
+        if (!args[i]->canConvert((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 (file)
index 0000000..02adaae
--- /dev/null
@@ -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.
+**
+** <http://libqxt.sourceforge.net>  <foundation@libqxt.org>
+**
+****************************************************************************/
+#ifndef QXTMETAOBJECT_H
+#define QXTMETAOBJECT_H
+
+#include <QMetaObject>
+#include <QVariant>
+#include <QGenericArgument>
+#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 <typename FP>
+QxtBoundFunction* bindFunction(FP funcPointer, QXT_PROTO_10ARGS(QGenericArgument));
+template <class T, typename FP>
+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<void*>(i))
+
+#endif // QXTMETAOBJECT_H
diff --git a/src/contrib/qxt/qxtnull.cpp b/src/contrib/qxt/qxtnull.cpp
new file mode 100644 (file)
index 0000000..967c16f
--- /dev/null
@@ -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 (file)
index 0000000..c520b66
--- /dev/null
@@ -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.
+**
+** <http://libqxt.sourceforge.net>  <foundation@libqxt.org>
+**
+****************************************************************************/
+
+#ifndef QXTNULL_DEFINED
+#define QXTNULL_DEFINED
+#include <qxtglobal.h>
+
+/**
+\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 (file)
index 0000000..f9aa5e3
--- /dev/null
@@ -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.
+**
+** <http://libqxt.sourceforge.net>  <foundation@libqxt.org>
+**
+****************************************************************************/
+
+/**
+\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 <qxtglobal.h>
+
+/*! \relates QxtNullable
+ * defines a skipable argument with type \a t and variable name \a n
+ */
+#define qxtNull(t,n)     QxtNullable<t> n = QxtNullable<t>()
+
+#include <qxtnull.h>
+
+template<typename T>
+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<typename T>
+QxtNullable<T>::QxtNullable(QxtNull)
+{
+    val = 0;
+}
+
+template<typename T>
+QxtNullable<T>::QxtNullable(const T& p)
+{
+    val = const_cast<T*>(&p);
+}
+
+template<typename T>
+QxtNullable<T>::QxtNullable()
+{
+    val = 0;
+}
+
+template<typename T>
+QxtNullable<T>::operator T() const
+{
+    return *val;
+}
+
+template<typename T>
+T& QxtNullable<T>::value() const
+{
+    return *val;
+}
+
+template<typename T>
+bool QxtNullable<T>::isNull() const
+{
+    return (val==0);
+}
+
+template<typename T>
+void QxtNullable<T>::nullify()
+{
+    val=0;
+}
+
+template<typename T>
+void QxtNullable<T>::operator=(const T& p)
+{
+    val = const_cast<T*>(&p);
+}
+
+#endif
index e1aeaa4..1f7093a 100644 (file)
 ** 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.
-** 
+**
 ** <http://libqxt.sourceforge.net>  <foundation@libqxt.org>
 **
 ****************************************************************************/
@@ -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 <typename PUB>
-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 <typename PUB, typename PVT>
-class QxtPrivateInterface {
-friend class QxtPrivate<PUB>;
+class QxtPrivateInterface
+{
+    friend class QxtPrivate<PUB>;
 public:
-    QxtPrivateInterface() { pvt = new PVT; }
-    ~QxtPrivateInterface() { delete pvt; }
-
-    inline void setPublic(PUB* pub) { pvt->QXT_setPublic(pub); }
-    inline PVT& operator()() { return *static_cast<PVT*>(pvt); }
-    inline const PVT& operator()() const { return *static_cast<PVT*>(pvt); }
+    QxtPrivateInterface()
+    {
+        pvt = new PVT;
+    }
+    ~QxtPrivateInterface()
+    {
+        delete pvt;
+    }
+
+    inline void setPublic(PUB* pub)
+    {
+        pvt->QXT_setPublic(pub);
+    }
+    inline PVT& operator()()
+    {
+        return *static_cast<PVT*>(pvt);
+    }
+    inline const PVT& operator()() const
+    {
+        return *static_cast<PVT*>(pvt);
+    }
 private:
     QxtPrivate<PUB>* pvt;
 };
index f976605..e986050 100644 (file)
@@ -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.
-** 
-** <http://libqxt.sourceforge.net>  <foundation@libqxt.org>
-**
-****************************************************************************/
+ **
+ ** 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.
+ **
+ ** <http://libqxt.sourceforge.net>  <foundation@libqxt.org>
+ **
+ ****************************************************************************/
 
 #include "qxtrpcpeer.h"
 #include <QObject>
 #include <QDebug>
 #include <QMetaMethod>
 #include <cassert>
-
-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 <QStack>
+
+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<int> argTypes;
 };
 
-struct QxtRPCConnection {
+struct QxtRPCConnection
+{
     QTcpSocket* socket;
     QByteArray buffer;
     QString lastMethod;
 };
 
-class QxtRPCPeerPrivate : public QxtPrivate<QxtRPCPeer> {
+class QxtRPCPeerPrivate : public QxtPrivate<QxtRPCPeer>, 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<QObject*, QxtRPCConnection*> ConnHash;
     ConnHash m_clients;
-    QTcpServer* m_server;
-    QIODevice* m_peer;  ///aep: doom
+    QIODevice* m_peer;
 
     QByteArray m_buffer;
     int m_rpctype;
+
+
+    QStack<QTcpSocket*> 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<QTcpSocket *>(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<QAbstractSocket *>(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<QAbstractSocket*>(qxt_d().m_peer);
+    if (!sock)
+    {
+        qWarning("QxtRPCPeer: cannot connect a custom QIODevice");
         return;
     }
-    QTcpSocket * sock  = qobject_cast<QTcpSocket*>(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<QAbstractSocket*>( 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<QPair<QObject*, int> >::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<QPair<QObject*, int> >::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<QAbstractSocket*>(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<quint64> ids, QString fn, QVariant p1, QVariant p2, QVariant p3, QVariant p4, QVariant p5, QVariant p6, QVariant p7, QVariant p8) {
+
+void QxtRPCPeer::callClientList(QList<quint64> 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<quint64>() << 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<quint64> cs = clients();
     cs.removeAll(id);
     callClientList(cs, fn, p1, p2, p3, p4, p5, p6, p7, p8);
 }
 
+#include <QStringList>
 #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<QTcpSocket*>(sender())) {
+    if (!conn)
+    {
+        if (qxt_d().m_peer!= qobject_cast<QAbstractSocket*>(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<QString, QList<QVariant> > 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<quint64> QxtRPCPeer::clients() const {
+
+QList<quint64> QxtRPCPeer::clients() const
+{
     QList<quint64> rv;
     QList<QObject*> 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<QByteArray> p = source->metaObject()->method(idx).parameterTypes();
     int ct = p.count();
-    for(int i=0; i<ct; i++) argTypes.append(QMetaType::type(p.value(i).constData()));
+    for (int i=0; i<ct; i++) argTypes.append(QMetaType::type(p.value(i).constData()));
 }
 
-int QxtIntrospector::qt_metacall(QMetaObject::Call _c, int _id, void **_a) {
+
+int QxtIntrospector::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) {
+    if (_c == QMetaObject::InvokeMetaMethod)
+    {
+        if (_id==0)
+        {
             QVariant v[9];
             int n = argTypes.size();
-            for(int i=0; i<n; i++) v[i] = QVariant(argTypes[i], _a[i+1]);
+            for (int i=0; i<n; i++) v[i] = QVariant(argTypes[i], _a[i+1]);
             peer->call(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<QString, QList<QVariant> > QxtRPCPeer::deserialize(QByteArray& data) {
+
+QPair<QString, QList<QVariant> > 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<QVariant>());
+    if (cmd.length()==0) return qMakePair(QString(), QList<QVariant>());
     cmd.replace(QByteArray("\\n"), QByteArray("\n"));
     cmd.replace(QByteArray("\\\\"), QByteArray("\\"));
     QDataStream str(cmd);
@@ -495,23 +638,69 @@ QPair<QString, QList<QVariant> > 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<argCount; i++) {
+    for (int i=0; i<argCount; i++)
+    {
         str >> 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<quint64> QxtRPCPeer::clients()
+    {
+    QList<quint64> list;
+    foreach(QObject * o,qxt_d().m_clients.keys ())
+        {
+        list.append((quint64)o);
+        }
+    return list;
+    }
+
+
+
index 3ff8784..377e802 100644 (file)
@@ -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.
-** 
-** <http://libqxt.sourceforge.net>  <foundation@libqxt.org>
-**
-*****************************************************************************
-**
-** 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.
+ **
+ ** <http://libqxt.sourceforge.net>  <foundation@libqxt.org>
+ **
+ ****************************************************************************/
 
 #ifndef QXTRPCPEER
 #define QXTRPCPEER
@@ -38,7 +33,7 @@
 #include <QHostAddress>
 #include <qxtpimpl.h>
 #include <qxtglobal.h>
-
+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<quint64> 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<quint64> 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<quint64> 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();
 };
index 98aa497..dfaa1b7 100644 (file)
@@ -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<QVariant> sigdata = item.toList();
-      sessions[validClients[socket]]->processSignal((ClientSignal)sigdata[0].toInt(), sigdata[1], sigdata[2], sigdata[3]);
+      Q_ASSERT(false);
+      //QList<QVariant> 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<QVariant> 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<QVariant> 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<CoreSession*>(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));
   }
 }
+*/
index af5fd92..eef6a2f 100644 (file)
@@ -26,7 +26,7 @@
 #include <QTcpServer>
 #include <QTcpSocket>
 
-#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();
index 9a48fe0..e8c8e63 100644 (file)
@@ -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<QVariant> msg, bool done) { send(CS_BACKLOG_DATA, QVariant::fromValue(id), msg, done); }
index ccfa2a1..da8e3c5 100644 (file)
 
 #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<QVariant>, bool)), coreProxy, SLOT(csBacklogData(BufferId, QList<QVariant>, 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<QVariant>, bool)), coreProxy, SLOT(csBacklogData(BufferId, QList<QVariant>, 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<BufferId> CoreSession::buffers() const {
 
 
 QVariant CoreSession::sessionState() {
-  VarMap v;
+  QVariantMap v;
   QList<QVariant> bufs;
   foreach(BufferId id, storage->requestBuffers(user)) { bufs.append(QVariant::fromValue(id)); }
   v["Buffers"] = bufs;
index 54af24e..73204f6 100644 (file)
 #include <QString>
 #include <QVariant>
 
-#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<BufferId> 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<QVariant>, 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<QString, Server *> servers;
 
-    VarMap sessionData;
+    QVariantMap sessionData;
     QMutex mutex;
 
 };
index 6bccd56..60accee 100644 (file)
@@ -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 <nick>!<user>@<host>"
   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;
index dd8aac9..360bed8 100644 (file)
@@ -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<QString, VarMap> nicks;  // stores all known nicks for the server
+    QVariantMap networkSettings;
+    QVariantMap identity;
+    QHash<QString, QVariantMap> nicks;  // stores all known nicks for the server
     QHash<QString, QString> 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);
index 22421ec..958c90a 100644 (file)
@@ -71,8 +71,8 @@ private:
   QString currentServer_;
   QString ownNick_;
   
-  //VarMap networkSettings;
-  //VarMap identity;
+  //QVariantMap networkSettings;
+  //QVariantMap identity;
   
   QHash<QString, IrcUser *> ircUsers_;  // stores all known nicks for the server
   QHash<QString, QString> topics_; // stores topics for each buffer
index dda91b4..86bf988 100644 (file)
@@ -109,6 +109,7 @@ SqliteStorage::SqliteStorage() {
 }
 
 SqliteStorage::~SqliteStorage() {
+  //logDb.close();
   delete logMessageQuery;
   delete addSenderQuery;
   delete getLastMessageIdQuery;
index f1a8946..2deb46b 100644 (file)
@@ -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<Buffer*>(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;
index 2024588..251643f 100644 (file)
@@ -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);
index d845f00..9992496 100644 (file)
@@ -20,7 +20,7 @@
 
 #include <QtGui>
 #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("<b>Could not connect to Quassel Core!</b><br>\n") + err, QMessageBox::Retry);
-  disconnect(ClientProxy::instance(), 0, this, 0);
+  //disconnect(ClientProxy::instance(), 0, this, 0); FIXME?
   //ui.autoConnect->setChecked(false);
   setStartState();
 }
index 384e257..9f988a3 100644 (file)
@@ -61,7 +61,7 @@ class CoreConnectDlg: public QDialog {
 
     void cancelConnect();
     void setStartState();
-    VarMap accountData;
+    QVariantMap accountData;
     QString curacc;
 };
 
index f1cc27c..a168b2f 100644 (file)
@@ -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<QString, QString> _mapping, VarMap templ, QString selected)
+IdentitiesEditDlg::IdentitiesEditDlg(QWidget *parent, QVariantMap _identities, QMap<QString, QString> _mapping, QVariantMap templ, QString selected)
   : QDialog(parent) {
   ui.setupUi(this);
   identities = _identities;
@@ -331,7 +331,7 @@ IdentitiesEditDlg::IdentitiesEditDlg(QWidget *parent, VarMap _identities, QMap<Q
   void IdentitiesEditDlg::addIdentity() {
     RenameIdentityDlg dlg(this, identities.keys());
     if(dlg.exec() == QDialog::Accepted) {
-      VarMap id = identTemplate;
+      QVariantMap id = identTemplate;
       identities[dlg.getName()] = id;
       Q_ASSERT(!mapping.contains(dlg.getName()));
       mapping[dlg.getName()] = dlg.getName();
index d528d9d..91cf06e 100644 (file)
@@ -35,7 +35,7 @@ class IdentitiesDlg : public QDialog {
   public:
     IdentitiesDlg(QWidget *parent, QString selectedId = QString());
 
-    VarMap getIdentities() { return identities; }
+    QVariantMap getIdentities() { return identities; }
     QMap<QString, QString> getNameMapping() { return nameMapping; }
 
   public slots:
@@ -58,12 +58,12 @@ class IdentitiesDlg : public QDialog {
 
   private:
     Ui::IdentitiesDlg ui;
-    VarMap identities;
+    QVariantMap identities;
     QMap<QString, QString> 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<QString, QString> mapping, VarMap templ, QString selected = QString());
+    IdentitiesEditDlg(QWidget *parent, QVariantMap identities, QMap<QString, QString> mapping, QVariantMap templ, QString selected = QString());
 
-    VarMap getIdentities() { return identities; }
+    QVariantMap getIdentities() { return identities; }
     QMap<QString, QString> 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<QString, QString> mapping;
 
     void sortList();
index 74d6267..ef96c2a 100644 (file)
 #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() {
index 60ffc18..f522449 100644 (file)
@@ -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();
index 8b24217..985a9ad 100644 (file)
@@ -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()));
 
 }
index a374daf..99265f1 100644 (file)
@@ -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<QString, QTreeWidgetItem *> 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<QTreeWidgetItem *> 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;
index aa4c825..f3058b8 100644 (file)
@@ -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();