Lots of new internal stuff (breaking protocol):
authorMarcus Eggenberger <egs@quassel-irc.org>
Sun, 16 Mar 2008 21:49:02 +0000 (21:49 +0000)
committerMarcus Eggenberger <egs@quassel-irc.org>
Sun, 16 Mar 2008 21:49:02 +0000 (21:49 +0000)
- improvements to the SignalProxy: return value of remotely called slots are return to the sending peer
- syncable objects can reside in libclient or libcore
- backlog is now handled by the BacklogManager

23 files changed:
src/client/client.cpp
src/client/client.h
src/client/client.pri
src/client/clientbacklogmanager.cpp [new file with mode: 0644]
src/client/clientbacklogmanager.h [new file with mode: 0644]
src/common/backlogmanager.cpp [new file with mode: 0644]
src/common/backlogmanager.h [new file with mode: 0644]
src/common/common.pri
src/common/signalproxy.cpp
src/common/signalproxy.h
src/common/syncableobject.h
src/core/core.cpp
src/core/core.h
src/core/core.pri
src/core/corebacklogmanager.cpp [new file with mode: 0644]
src/core/corebacklogmanager.h [new file with mode: 0644]
src/core/coresession.cpp
src/core/coresession.h
src/core/sqlitestorage.cpp
src/core/sqlitestorage.h
src/core/storage.h
src/qtui/mainwin.cpp
version.inc

index c90bcf6..e276cd8 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "bufferinfo.h"
 #include "buffersyncer.h"
+#include "clientbacklogmanager.h"
 #include "global.h"
 #include "identity.h"
 #include "ircchannel.h"
@@ -64,10 +65,13 @@ Client::Client(QObject *parent)
     _networkModel(0),
     _bufferModel(0),
     _bufferSyncer(0),
+    _backlogManager(new ClientBacklogManager(this)),
     _connectedToCore(false),
     _syncedToCore(false)
 {
   _monitorBuffer = new Buffer(BufferInfo(), this);
+  connect(_backlogManager, SIGNAL(backlog(BufferId, const QVariantList &)),
+         this, SLOT(receiveBacklog(BufferId, const QVariantList &)));
 }
 
 Client::~Client() {
@@ -89,7 +93,6 @@ void Client::init() {
   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(backlogData(BufferInfo, const QVariantList &, bool)), this, SLOT(recvBacklogData(BufferInfo, const QVariantList &, bool)));
   p->attachSlot(SIGNAL(bufferInfoUpdated(BufferInfo)), this, SLOT(updateBufferInfo(BufferInfo)));
   p->attachSignal(this, SIGNAL(sendInput(BufferInfo, QString)));
   p->attachSignal(this, SIGNAL(requestNetworkStates()));
@@ -302,6 +305,9 @@ void Client::setSyncedToCore() {
   connect(bufferSyncer(), SIGNAL(bufferRenamed(BufferId, QString)), this, SLOT(bufferRenamed(BufferId, QString)));
   signalProxy()->synchronize(bufferSyncer());
 
+  // attach backlog manager
+  signalProxy()->synchronize(backlogManager());
+  
   _syncedToCore = true;
   emit connected();
   emit coreConnectionStateChanged(true);
@@ -475,31 +481,46 @@ void Client::recvStatusMsg(QString /*net*/, QString /*msg*/) {
   //recvMessage(net, Message::server("", QString("[STATUS] %1").arg(msg)));
 }
 
-void Client::recvBacklogData(BufferInfo id, QVariantList msgs, bool /*done*/) {
-  Buffer *b = buffer(id);
-  if(!b) {
-    qWarning() << "Client::recvBacklogData(): received Backlog for unknown Buffer:" << id;
+void Client::receiveBacklog(BufferId bufferId, const QVariantList &msgs) {
+  Buffer *buffer_ = buffer(bufferId);
+  if(!buffer_) {
+    qWarning() << "Client::recvBacklogData(): received Backlog for unknown Buffer:" << bufferId;
     return;
   }
-    
-  foreach(QVariant v, msgs) {
-    Message msg = v.value<Message>();
-    checkForHighlight(msg);
-    b->prependMsg(msg);
-    //networkModel()->updateBufferActivity(msg);
-    if(!layoutQueue.contains(b)) layoutQueue.append(b);
+
+  if(msgs.isEmpty())
+    return; // no work to be done...
+  
+  QVariantList::const_iterator msgIter = msgs.constBegin();
+  QVariantList::const_iterator msgIterEnd = msgs.constEnd();
+  Message msg;
+  while(msgIter != msgIterEnd) {
+    msg = (*msgIter).value<Message>();
+    buffer_->prependMsg(msg);
+    msgIter++;
+  }
+
+  if(!layoutQueue.contains(buffer_))
+    layoutQueue.append(buffer_);
+
+  if(!layoutTimer->isActive()) {
+    layoutTimer->start();
   }
-  if(layoutQueue.count() && !layoutTimer->isActive()) layoutTimer->start();
 }
 
 void Client::layoutMsg() {
-  if(layoutQueue.count()) {
-    Buffer *b = layoutQueue.takeFirst();  // TODO make this the current buffer
-    if(b->layoutMsg())
-      layoutQueue.append(b);  // Buffer has more messages in its queue --> Round Robin
+  if(layoutQueue.isEmpty()) {
+    layoutTimer->stop();
+    return;
   }
   
-  if(!layoutQueue.count())
+  Buffer *buffer = layoutQueue.takeFirst();
+  if(buffer->layoutMsg()) {
+    layoutQueue.append(buffer);  // Buffer has more messages in its queue --> Round Robin
+    return;
+  } 
+
+  if(layoutQueue.isEmpty())
     layoutTimer->stop();
 }
 
index b51cc50..f7e0dc0 100644 (file)
@@ -40,6 +40,7 @@ class AbstractUiMsg;
 class NetworkModel;
 class BufferModel;
 class BufferSyncer;
+class ClientBacklogManager;
 class IrcUser;
 class IrcChannel;
 class SignalProxy;
@@ -94,6 +95,8 @@ public:
   static inline BufferModel *bufferModel() { return instance()->_bufferModel; }
   static inline SignalProxy *signalProxy() { return instance()->_signalProxy; }
 
+  static inline ClientBacklogManager *backlogManager() { return instance()->_backlogManager; }
+
   static AccountId currentCoreAccount();
 
   static AbstractUiMsg *layoutMsg(const Message &);
@@ -168,7 +171,7 @@ private slots:
 
   void recvMessage(const Message &message);
   void recvStatusMsg(QString network, QString message);
-  void recvBacklogData(BufferInfo, QVariantList, bool);
+  void receiveBacklog(BufferId bufferId, const QVariantList &msgs);
   void updateBufferInfo(BufferInfo);
   void updateLastSeenMsg(BufferId id, const MsgId &msgId);
 
@@ -204,6 +207,7 @@ private:
   NetworkModel * _networkModel;
   BufferModel * _bufferModel;
   BufferSyncer * _bufferSyncer;
+  ClientBacklogManager *_backlogManager;
 
   ClientMode clientMode;
 
index 46ddc54..726690c 100644 (file)
@@ -1,6 +1,6 @@
 DEPMOD = common
 QT_MOD = core network gui
-SRCS += buffer.cpp buffersettings.cpp treemodel.cpp networkmodel.cpp buffermodel.cpp client.cpp clientsettings.cpp clientsyncer.cpp \
+SRCS += buffer.cpp buffersettings.cpp clientbacklogmanager.cpp treemodel.cpp networkmodel.cpp buffermodel.cpp client.cpp clientsettings.cpp clientsyncer.cpp \
         mappedselectionmodel.cpp selectionmodelsynchronizer.cpp
-HDRS += buffer.h buffersettings.h treemodel.h networkmodel.h buffermodel.h client.h clientsettings.h clientsyncer.h quasselui.h \
+HDRS += buffer.h buffersettings.h clientbacklogmanager.h treemodel.h networkmodel.h buffermodel.h client.h clientsettings.h clientsyncer.h quasselui.h \
         mappedselectionmodel.h selectionmodelsynchronizer.h
diff --git a/src/client/clientbacklogmanager.cpp b/src/client/clientbacklogmanager.cpp
new file mode 100644 (file)
index 0000000..86b1b1c
--- /dev/null
@@ -0,0 +1,35 @@
+/***************************************************************************
+ *   Copyright (C) 2005-08 by the Quassel IRC Team                         *
+ *   devel@quassel-irc.org                                                 *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) version 3.                                           *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#include "clientbacklogmanager.h"
+#include "client.h"
+
+#include <QDebug>
+
+ClientBacklogManager::ClientBacklogManager(QObject *parent)
+  : BacklogManager(parent)
+{
+}
+
+void ClientBacklogManager::receiveBacklog(BufferId bufferId, int lastMsgs, int offset, QVariantList msgs) {
+  Q_UNUSED(lastMsgs)
+  Q_UNUSED(offset)
+  emit backlog(bufferId, msgs);
+}
diff --git a/src/client/clientbacklogmanager.h b/src/client/clientbacklogmanager.h
new file mode 100644 (file)
index 0000000..5ead663
--- /dev/null
@@ -0,0 +1,41 @@
+/***************************************************************************
+ *   Copyright (C) 2005-08 by the Quassel IRC Team                         *
+ *   devel@quassel-irc.org                                                 *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) version 3.                                           *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#ifndef CLIENTBACKLOGMANAGER_H
+#define CLIENTBACKLOGMANAGER_H
+
+#include "backlogmanager.h"
+
+class ClientBacklogManager : public BacklogManager {
+  Q_OBJECT
+
+public:
+  ClientBacklogManager(QObject *parent = 0);
+
+  virtual const QMetaObject *syncMetaObject() const { return &BacklogManager::staticMetaObject; }
+
+public slots:
+  virtual void receiveBacklog(BufferId bufferId, int lastMsgs, int offset, QVariantList msgs);
+
+signals:
+  void backlog(BufferId bufferId, const QVariantList &msgs);
+};
+
+#endif // CLIENTBACKLOGMANAGER_H
diff --git a/src/common/backlogmanager.cpp b/src/common/backlogmanager.cpp
new file mode 100644 (file)
index 0000000..399db0c
--- /dev/null
@@ -0,0 +1,33 @@
+/***************************************************************************
+ *   Copyright (C) 2005-08 by the Quassel IRC Team                         *
+ *   devel@quassel-irc.org                                                 *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) version 3.                                           *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#include "backlogmanager.h"
+
+#include <QDebug>
+
+BacklogManager::BacklogManager(QObject *parent)
+  : SyncableObject(parent)
+{
+}
+
+QVariantList BacklogManager::requestBacklog(BufferId bufferId, int lastMsgs, int offset) {
+  emit backlogRequested(bufferId, lastMsgs, offset);
+  return QVariantList();
+}
diff --git a/src/common/backlogmanager.h b/src/common/backlogmanager.h
new file mode 100644 (file)
index 0000000..6ff6b9c
--- /dev/null
@@ -0,0 +1,42 @@
+/***************************************************************************
+ *   Copyright (C) 2005-08 by the Quassel IRC Team                         *
+ *   devel@quassel-irc.org                                                 *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) version 3.                                           *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#ifndef BACKLOGMANAGER_H
+#define BACKLOGMANAGER_H
+
+#include "syncableobject.h"
+#include "types.h"
+
+class BacklogManager : public SyncableObject {
+  Q_OBJECT
+
+public:
+  BacklogManager(QObject *parent = 0);
+
+public slots:
+  virtual QVariantList requestBacklog(BufferId bufferId, int lastMsgs = -1, int offset = -1);
+  virtual void receiveBacklog(BufferId, int, int, QVariantList) {};
+
+signals:
+  void backlogRequested(BufferId, int, int);
+
+};
+
+#endif // BACKLOGMANAGER_H
index 98e9a3e..3a9dcce 100644 (file)
@@ -1,6 +1,6 @@
 DEPMOD =
 QT_MOD = network
-SRCS += bufferinfo.cpp buffersyncer.cpp global.cpp identity.cpp logger.cpp message.cpp settings.cpp signalproxy.cpp syncableobject.cpp \
+SRCS += backlogmanager.cpp bufferinfo.cpp buffersyncer.cpp global.cpp identity.cpp logger.cpp message.cpp settings.cpp signalproxy.cpp syncableobject.cpp \
         util.cpp network.cpp ircuser.cpp ircchannel.cpp
-HDRS += bufferinfo.h buffersyncer.h global.h identity.h logger.h message.h settings.h signalproxy.h syncableobject.h \
+HDRS += backlogmanager.h bufferinfo.h buffersyncer.h global.h identity.h logger.h message.h settings.h signalproxy.h syncableobject.h \
         util.h network.h ircuser.h ircchannel.h types.h
index e7c4644..411c8da 100644 (file)
@@ -96,7 +96,8 @@ int SignalRelay::qt_metacall(QMetaObject::Call _c, int _id, void **_a) {
       
       // dispatch Sync Signal if necessary
       QByteArray signature(caller->metaObject()->method(_id).signature());
-      if(synchronize() && proxy->syncMap(qobject_cast<SyncableObject *>(caller)).contains(signature)) {
+      SyncableObject *syncObject = qobject_cast<SyncableObject *>(caller);
+      if(synchronize() && proxy->syncMap(syncObject).contains(signature)) {
         //qDebug() << "__SYNC__ >>>"
         //      << caller->metaObject()->className()
         //      << caller->objectName()
@@ -104,8 +105,8 @@ int SignalRelay::qt_metacall(QMetaObject::Call _c, int _id, void **_a) {
         //      << params;
        // params.prepend(QVariant(_id));
        params.prepend(signature);
-       params.prepend(caller->objectName());
-       params.prepend(caller->metaObject()->className());
+       params.prepend(syncObject->objectName());
+       params.prepend(syncObject->syncMetaObject()->className());
        proxy->dispatchSignal(SignalProxy::Sync, params);
       }
     }
@@ -115,7 +116,11 @@ int SignalRelay::qt_metacall(QMetaObject::Call _c, int _id, void **_a) {
 }
 
 void SignalRelay::setSynchronize(bool sync) {
-  const QMetaObject *meta = caller->metaObject();
+  SyncableObject *syncObject = qobject_cast<SyncableObject *>(caller);
+  if(!syncObject)
+    return;
+
+  const QMetaObject *meta = syncObject->syncMetaObject();
   if(!_sync && sync) {
     // enable Sync
     for(int i = 0; i < meta->methodCount(); i++ ) {
@@ -133,8 +138,12 @@ void SignalRelay::setSynchronize(bool sync) {
 }
 
 bool SignalRelay::isSyncMethod(int i) {
-  QByteArray signature = caller->metaObject()->method(i).signature();
-  if(!proxy->syncMap(qobject_cast<SyncableObject *>(caller)).contains(signature))
+  SyncableObject *syncObject = qobject_cast<SyncableObject *>(caller);
+  if(!syncObject)
+    return false;
+
+  QByteArray signature = syncObject->syncMetaObject()->method(i).signature();
+  if(!proxy->syncMap(syncObject).contains(signature))
     return false;
   
   if(proxy->proxyMode() == SignalProxy::Server && !signature.contains("Requested"))
@@ -309,7 +318,8 @@ void SignalProxy::removePeerBySender() {
 }
 
 void SignalProxy::objectRenamed(const QString &newname, const QString &oldname) {
-  const QMetaObject *meta = sender()->metaObject();
+  SyncableObject *syncObject = qobject_cast<SyncableObject *>(sender());
+  const QMetaObject *meta = syncObject->metaObject();
   const QByteArray className(meta->className());
   objectRenamed(className, newname, oldname);
 
@@ -329,7 +339,7 @@ void SignalProxy::objectRenamed(const QByteArray &classname, const QString &newn
 }
 
 void SignalProxy::setArgTypes(QObject* obj, int methodId) {
-  const QMetaObject *meta = obj->metaObject();
+  const QMetaObject *meta = metaObject(obj);
   QList<QByteArray> p = meta->method(methodId).parameterTypes();
   QList<int> argTypes;
   int ct = p.count();
@@ -341,14 +351,31 @@ void SignalProxy::setArgTypes(QObject* obj, int methodId) {
 }
 
 const QList<int> &SignalProxy::argTypes(QObject *obj, int methodId) {
-  Q_ASSERT(_classInfo.contains(obj->metaObject()));
-  if(!_classInfo[obj->metaObject()]->argTypes.contains(methodId))
+  const QMetaObject *meta = metaObject(obj);
+  Q_ASSERT(_classInfo.contains(meta));
+  if(!_classInfo[meta]->argTypes.contains(methodId))
     setArgTypes(obj, methodId);
-  return _classInfo[obj->metaObject()]->argTypes[methodId];
+  return _classInfo[meta]->argTypes[methodId];
+}
+
+void SignalProxy::setReturnType(QObject *obj, int methodId) {
+  const QMetaObject *meta = metaObject(obj);
+  int returnType = QMetaType::type(meta->method(methodId).typeName());
+
+  Q_ASSERT(!_classInfo[meta]->returnType.contains(methodId));
+  _classInfo[meta]->returnType[methodId] = returnType;
+}
+
+const int &SignalProxy::returnType(QObject *obj, int methodId) {
+  const QMetaObject *meta = metaObject(obj);
+  Q_ASSERT(_classInfo.contains(meta));
+  if(!_classInfo[meta]->returnType.contains(methodId))
+    setReturnType(obj, methodId);
+  return _classInfo[meta]->returnType[methodId];
 }
 
 void SignalProxy::setMinArgCount(QObject *obj, int methodId) {
-  const QMetaObject *meta = obj->metaObject();
+  const QMetaObject *meta = metaObject(obj);
   QString signature(meta->method(methodId).signature());
   int minCount = meta->method(methodId).parameterTypes().count() - signature.count("=");
   Q_ASSERT(!_classInfo[meta]->minArgCount.contains(methodId));
@@ -356,29 +383,31 @@ void SignalProxy::setMinArgCount(QObject *obj, int methodId) {
 }
 
 const int &SignalProxy::minArgCount(QObject *obj, int methodId) {
-  Q_ASSERT(_classInfo.contains(obj->metaObject()));
-  if(!_classInfo[obj->metaObject()]->minArgCount.contains(methodId))
+  const QMetaObject *meta = metaObject(obj);
+  Q_ASSERT(_classInfo.contains(meta));
+  if(!_classInfo[meta]->minArgCount.contains(methodId))
     setMinArgCount(obj, methodId);
-  return _classInfo[obj->metaObject()]->minArgCount[methodId];
+  return _classInfo[meta]->minArgCount[methodId];
 }
 
 void SignalProxy::setMethodName(QObject *obj, int methodId) {
-  const QMetaObject *meta = obj->metaObject();
+  const QMetaObject *meta = metaObject(obj);
   QByteArray method(::methodName(meta->method(methodId)));
   Q_ASSERT(!_classInfo[meta]->methodNames.contains(methodId));
   _classInfo[meta]->methodNames[methodId] = method;
 }
 
 const QByteArray &SignalProxy::methodName(QObject *obj, int methodId) {
-  Q_ASSERT(_classInfo.contains(obj->metaObject()));
-  if(!_classInfo[obj->metaObject()]->methodNames.contains(methodId))
+  const QMetaObject *meta = metaObject(obj);
+  Q_ASSERT(_classInfo.contains(meta));
+  if(!_classInfo[meta]->methodNames.contains(methodId))
     setMethodName(obj, methodId);
-  return _classInfo[obj->metaObject()]->methodNames[methodId];
+  return _classInfo[meta]->methodNames[methodId];
 }
 
 
 void SignalProxy::setSyncMap(SyncableObject *obj) {
-  const QMetaObject *meta = obj->metaObject();
+  const QMetaObject *meta = obj->syncMetaObject();
   QHash<QByteArray, int> syncMap;
   
   QList<int> slotIndexes;
@@ -387,6 +416,15 @@ void SignalProxy::setSyncMap(SyncableObject *obj) {
       slotIndexes << i;
   }
 
+  // we're faking sync pairs for sync replies
+  QByteArray slotSignature;
+  foreach(int slotIdx, slotIndexes) {
+    slotSignature = QByteArray(meta->method(slotIdx).signature());
+    if(!slotSignature.startsWith("receive"))
+      continue;
+    syncMap[slotSignature] = slotIdx;
+  }
+
   QMetaMethod signal, slot;
   int matchIdx;
   for(int signalIdx = 0; signalIdx < meta->methodCount(); signalIdx++) {
@@ -413,34 +451,101 @@ void SignalProxy::setSyncMap(SyncableObject *obj) {
 }
 
 const QHash<QByteArray,int> &SignalProxy::syncMap(SyncableObject *obj) {
-  Q_ASSERT(_classInfo.contains(obj->metaObject()));
-  if(_classInfo[obj->metaObject()]->syncMap.isEmpty())
+  const QMetaObject *meta = obj->syncMetaObject();
+  Q_ASSERT(_classInfo.contains(meta));
+  if(_classInfo[meta]->syncMap.isEmpty())
     setSyncMap(obj);
-  return _classInfo[obj->metaObject()]->syncMap;
+  return _classInfo[meta]->syncMap;
+}
+
+void SignalProxy::setReceiveMap(SyncableObject *obj) {
+  const QMetaObject *meta = obj->syncMetaObject();
+  Q_ASSERT(_classInfo.contains(meta));
+
+  QHash<int, int> receiveMap;
+
+  QMetaMethod requestSlot;
+  QByteArray returnTypeName;
+  QByteArray signature;
+  QByteArray methodName;
+  QByteArray params;
+  int paramsPos;
+  int receiverId;
+  const int methodCount = meta->methodCount();
+  for(int i = 0; i < methodCount; i++) {
+    requestSlot = meta->method(i);
+    if(requestSlot.methodType() != QMetaMethod::Slot)
+      continue;
+
+    returnTypeName = requestSlot.typeName();
+    if(QMetaType::Void == (QMetaType::Type)returnType(obj, i))
+      continue;
+
+    signature = QByteArray(requestSlot.signature());
+    if(!signature.startsWith("request"))
+      continue;
+    
+    paramsPos = signature.indexOf('(');
+    if(paramsPos == -1)
+      continue;
+
+    methodName = signature.left(paramsPos);
+    params = signature.mid(paramsPos);
+
+    methodName = methodName.replace("request", "receive");
+    params = params.left(params.count() - 1) + ", " + returnTypeName + ")";
+
+    signature = QMetaObject::normalizedSignature(methodName + params);
+    receiverId = meta->indexOfSlot(signature);
+
+    if(receiverId == -1) {
+      signature = QMetaObject::normalizedSignature(methodName + "(" + returnTypeName + ")");
+      receiverId = meta->indexOfSlot(signature);
+    }
+
+    if(receiverId != -1)
+      receiveMap[i] = receiverId;
+  }
+  _classInfo[meta]->receiveMap = receiveMap;  
+}
+
+const QHash<int, int> &SignalProxy::receiveMap(SyncableObject *obj) {
+  const QMetaObject *meta = obj->syncMetaObject();
+  Q_ASSERT(_classInfo.contains(meta));
+  if(_classInfo[meta]->receiveMap.isEmpty())
+    setReceiveMap(obj);
+  return _classInfo[meta]->receiveMap;
 }
 
-void SignalProxy::setUpdatedRemotelyId(QObject *obj) {
-  const QMetaObject *meta = obj->metaObject();
+void SignalProxy::setUpdatedRemotelyId(SyncableObject *obj) {
+  const QMetaObject *meta = obj->syncMetaObject();
   Q_ASSERT(_classInfo.contains(meta));
   _classInfo[meta]->updatedRemotelyId = meta->indexOfSignal("updatedRemotely()");
 }
 
 int SignalProxy::updatedRemotelyId(SyncableObject *obj) {
-  Q_ASSERT(_classInfo.contains(obj->metaObject()));
-  return _classInfo[obj->metaObject()]->updatedRemotelyId;
+  Q_ASSERT(_classInfo.contains(obj->syncMetaObject()));
+  return _classInfo[obj->syncMetaObject()]->updatedRemotelyId;
+}
+
+const QMetaObject *SignalProxy::metaObject(QObject *obj) {
+  if(SyncableObject *syncObject = qobject_cast<SyncableObject *>(obj))
+    return syncObject->syncMetaObject();
+  else
+    return obj->metaObject();
 }
 
 void SignalProxy::createClassInfo(QObject *obj) {
-  if(_classInfo.contains(obj->metaObject()))
+  const QMetaObject *meta = metaObject(obj);
+  if(_classInfo.contains(meta))
     return;
 
   ClassInfo *classInfo = new ClassInfo();
-  _classInfo[obj->metaObject()] = classInfo;
-  setUpdatedRemotelyId(obj);
+  _classInfo[meta] = classInfo;
 }
 
 bool SignalProxy::attachSignal(QObject* sender, const char* signal, const QByteArray& sigName) {
-  const QMetaObject* meta = sender->metaObject();
+  const QMetaObject* meta = metaObject(sender);
   QByteArray sig(meta->normalizedSignature(signal).mid(1));
   int methodId = meta->indexOfMethod(sig.constData());
   if(methodId == -1 || meta->method(methodId).methodType() != QMetaMethod::Signal) {
@@ -482,7 +587,8 @@ bool SignalProxy::attachSlot(const QByteArray& sigName, QObject* recv, const cha
 
 void SignalProxy::synchronize(SyncableObject *obj) {
   createClassInfo(obj);
-
+  setUpdatedRemotelyId(obj);
+  
   // attaching all the Signals
   SignalRelay* relay;
   if(_relayHash.contains(obj))
@@ -493,7 +599,7 @@ void SignalProxy::synchronize(SyncableObject *obj) {
   relay->setSynchronize(true);
 
   // attaching as slave to receive sync Calls
-  QByteArray className(obj->metaObject()->className());
+  QByteArray className(obj->syncMetaObject()->className());
   _syncSlave[className][obj->objectName()] = obj;
 
   if(proxyMode() == Server) {
@@ -518,7 +624,7 @@ void SignalProxy::requestInit(SyncableObject *obj) {
     return;
 
   QVariantList params;
-  params << obj->metaObject()->className()
+  params << obj->syncMetaObject()->className()
         << obj->objectName();
   dispatchSignal(InitRequest, params);
 }
@@ -600,7 +706,7 @@ void SignalProxy::receivePeerSignal(QIODevice *sender, const QVariant &packedFun
       return handleSignal(params.takeFirst().toByteArray(), params);
     }
   case Sync:
-    return handleSync(params);
+    return handleSync(sender, params);
   case InitRequest:
     return handleInitRequest(sender, params);
   case InitData:
@@ -613,7 +719,7 @@ void SignalProxy::receivePeerSignal(QIODevice *sender, const QVariant &packedFun
   }
 }
 
-void SignalProxy::handleSync(QVariantList params) {
+void SignalProxy::handleSync(QIODevice *sender, QVariantList params) {
   if(params.count() < 3) {
     qWarning() << "received invalid Sync call" << params;
     return;
@@ -637,10 +743,26 @@ void SignalProxy::handleSync(QVariantList params) {
   }
 
   int slotId = syncMap(receiver)[signal];
-  if(!invokeSlot(receiver, slotId, params)) {
+
+  QVariant returnValue((QVariant::Type)returnType(receiver, slotId));
+  if(!invokeSlot(receiver, slotId, params, returnValue)) {
     qWarning("SignalProxy::handleSync(): invokeMethod for \"%s\" failed ", methodName(receiver, slotId).constData());
     return;
   }
+
+  if(returnValue.type() != QVariant::Invalid && receiveMap(receiver).contains(slotId)) {
+    int receiverId = receiveMap(receiver)[slotId];
+    QVariantList returnParams;
+    returnParams << className
+                << objectName
+                << QByteArray(receiver->metaObject()->method(receiverId).signature());
+    if(argTypes(receiver, receiverId).count() > 1)
+      returnParams << params;
+    returnParams << returnValue;
+    dispatchSignal(sender, Sync, returnParams);
+  }
+  
+  // send emit update signal
   invokeSlot(receiver, updatedRemotelyId(receiver));
 }
 
@@ -669,8 +791,8 @@ void SignalProxy::handleInitRequest(QIODevice *sender, const QVariantList &param
   SyncableObject *obj = _syncSlave[className][objectName];
 
   QVariantList params_;
-  params_ << obj->metaObject()->className()
-         << obj->objectName()
+  params_ << className
+         << objectName
          << initData(obj);
 
   dispatchSignal(sender, InitData, params_);
@@ -717,7 +839,7 @@ void SignalProxy::handleSignal(const QByteArray &funcName, const QVariantList &p
   }
 }
 
-bool SignalProxy::invokeSlot(QObject *receiver, int methodId, const QVariantList &params) {
+bool SignalProxy::invokeSlot(QObject *receiver, int methodId, const QVariantList &params, QVariant &returnValue) {
   const QList<int> args = argTypes(receiver, methodId);
   const int numArgs = params.count() < args.count()
     ? params.count()
@@ -728,9 +850,10 @@ bool SignalProxy::invokeSlot(QObject *receiver, int methodId, const QVariantList
       return false;
   }
 
-  void *_a[] = {0, // return type
+  void *_a[] = {0,              // return type... 
                0, 0, 0, 0 , 0, // and 10 args - that's the max size qt can handle with signals and slots
                0, 0, 0, 0 , 0};
+
   // check for argument compatibility and build params array
   for(int i = 0; i < numArgs; i++) {
     if(!params[i].isValid()) {
@@ -745,6 +868,8 @@ bool SignalProxy::invokeSlot(QObject *receiver, int methodId, const QVariantList
     _a[i+1] = const_cast<void *>(params[i].constData());
   }
 
+  if(returnValue.type() != QVariant::Invalid)
+    _a[0] = const_cast<void *>(returnValue.constData());
     
   Qt::ConnectionType type = QThread::currentThread() == receiver->thread()
     ? Qt::DirectConnection
@@ -754,12 +879,17 @@ bool SignalProxy::invokeSlot(QObject *receiver, int methodId, const QVariantList
     return receiver->qt_metacall(QMetaObject::InvokeMetaMethod, methodId, _a) < 0;
   } else {
     qWarning() << "Queued Connections are not implemented yet";
-    // not to self: qmetaobject.cpp:990 ff
+    // note to self: qmetaobject.cpp:990 ff
     return false;
   }
   
 }
 
+bool SignalProxy::invokeSlot(QObject *receiver, int methodId, const QVariantList &params) {
+  QVariant ret;
+  return invokeSlot(receiver, methodId, params, ret);
+}
+
 void SignalProxy::dataAvailable() {
   // yet again. it's a private slot. no need for checks.
   QIODevice* ioDev = qobject_cast<QIODevice* >(sender());
index f4d6166..cca2ccb 100644 (file)
@@ -92,19 +92,23 @@ public:
   static QString methodBaseName(const QMetaMethod &method);
 
   const QList<int> &argTypes(QObject *obj, int methodId);
+  const int &returnType(QObject *obj, int methodId);
   const int &minArgCount(QObject *obj, int methodId);
   const QByteArray &methodName(QObject *obj, int methodId);
   const QHash<QByteArray, int> &syncMap(SyncableObject *obj);
+  const QHash<int, int> &receiveMap(SyncableObject *obj);
   int updatedRemotelyId(SyncableObject *obj);
 
   typedef QHash<int, QList<int> > ArgHash;
   typedef QHash<int, QByteArray> MethodNameHash;
   struct ClassInfo {
     ArgHash argTypes;
+    QHash<int, int> returnType;
     QHash<int, int> minArgCount;
     MethodNameHash methodNames;
     int updatedRemotelyId; // id of the updatedRemotely() signal - makes things faster
     QHash<QByteArray, int> syncMap;
+    QHash<int, int> receiveMap;
   };
 
   void dumpProxyStats();
@@ -127,12 +131,15 @@ private:
   void initServer();
   void initClient();
   
+  const QMetaObject *metaObject(QObject *obj);
   void createClassInfo(QObject *obj);
   void setArgTypes(QObject *obj, int methodId);
+  void setReturnType(QObject *obj, int methodId);
   void setMinArgCount(QObject *obj, int methodId);
   void setMethodName(QObject *obj, int methodId);
   void setSyncMap(SyncableObject *obj);
-  void setUpdatedRemotelyId(QObject *obj);
+  void setReceiveMap(SyncableObject *obj);
+  void setUpdatedRemotelyId(SyncableObject *obj);
 
   bool methodsMatch(const QMetaMethod &signal, const QMetaMethod &slot) const;
 
@@ -140,11 +147,12 @@ private:
   void dispatchSignal(const RequestType &requestType, const QVariantList &params);
   
   void receivePeerSignal(QIODevice *sender, const QVariant &packedFunc);
-  void handleSync(QVariantList params);
+  void handleSync(QIODevice *sender, QVariantList params);
   void handleInitRequest(QIODevice *sender, const QVariantList &params);
   void handleInitData(QIODevice *sender, const QVariantList &params);
   void handleSignal(const QByteArray &funcName, const QVariantList &params);
 
+  bool invokeSlot(QObject *receiver, int methodId, const QVariantList &params, QVariant &returnValue);
   bool invokeSlot(QObject *receiver, int methodId, const QVariantList &params = QVariantList());
 
   QVariantMap initData(SyncableObject *obj) const;
index 1eb8ed4..388ed90 100644 (file)
@@ -53,6 +53,8 @@ public:
 
   virtual bool isInitialized() const;
 
+  virtual const QMetaObject *syncMetaObject() const { return metaObject(); };
+
 public slots:
   virtual void setInitialized();
 
index b7714e3..20dc449 100644 (file)
@@ -275,19 +275,19 @@ MsgId Core::storeMessage(const Message &message) {
   return instance()->storage->logMessage(message);
 }
 
-QList<Message> Core::requestMsgs(BufferInfo buffer, int lastmsgs, int offset) {
+QList<Message> Core::requestMsgs(UserId user, BufferId buffer, int lastmsgs, int offset) {
   QMutexLocker locker(&mutex);
-  return instance()->storage->requestMsgs(buffer, lastmsgs, offset);
+  return instance()->storage->requestMsgs(user, buffer, lastmsgs, offset);
 }
 
-QList<Message> Core::requestMsgs(BufferInfo buffer, QDateTime since, int offset) {
+QList<Message> Core::requestMsgs(UserId user, BufferId buffer, QDateTime since, int offset) {
   QMutexLocker locker(&mutex);
-  return instance()->storage->requestMsgs(buffer, since, offset);
+  return instance()->storage->requestMsgs(user, buffer, since, offset);
 }
 
-QList<Message> Core::requestMsgRange(BufferInfo buffer, int first, int last) {
+QList<Message> Core::requestMsgRange(UserId user, BufferId buffer, int first, int last) {
   QMutexLocker locker(&mutex);
-  return instance()->storage->requestMsgRange(buffer, first, last);
+  return instance()->storage->requestMsgRange(user, buffer, first, last);
 }
 
 QList<BufferInfo> Core::requestBuffers(UserId user, QDateTime since) {
index 31d01be..19d6541 100644 (file)
@@ -179,7 +179,7 @@ class Core : public QObject {
      *  \param offset   Do not return (but DO count) messages with MsgId >= offset, if offset >= 0
      *  \return The requested list of messages
      */
-    static QList<Message> requestMsgs(BufferInfo buffer, int lastmsgs = -1, int offset = -1);
+    static QList<Message> requestMsgs(UserId user, BufferId buffer, int lastmsgs = -1, int offset = -1);
 
     //! Request messages stored in a given buffer since a certain point in time.
     /** \note This method is threadsafe.
@@ -189,7 +189,7 @@ class Core : public QObject {
      *  \param offset   Do not return messages with MsgId >= offset, if offset >= 0
      *  \return The requested list of messages
      */
-    static QList<Message> requestMsgs(BufferInfo buffer, QDateTime since, int offset = -1);
+    static QList<Message> requestMsgs(UserId user, BufferId buffer, QDateTime since, int offset = -1);
 
     //! Request a range of messages stored in a given buffer.
     /** \note This method is threadsafe.
@@ -199,7 +199,7 @@ class Core : public QObject {
      *  \param last     Return messages with first <= MsgId <= last
      *  \return The requested list of messages
      */
-    static QList<Message> requestMsgRange(BufferInfo buffer, int first, int last);
+    static QList<Message> requestMsgRange(UserId user, BufferId buffer, int first, int last);
 
     //! Request a list of all buffers known to a user since a certain point in time.
     /** This method is used to get a list of all buffers we have stored a backlog from.
index 8d71feb..9782316 100644 (file)
@@ -1,6 +1,6 @@
 DEPMOD = common
 QT_MOD = core network sql script
-SRCS = core.cpp coresession.cpp coresettings.cpp networkconnection.cpp sqlitestorage.cpp abstractsqlstorage.cpp storage.cpp basichandler.cpp \
+SRCS = core.cpp corebacklogmanager.cpp coresession.cpp coresettings.cpp networkconnection.cpp sqlitestorage.cpp abstractsqlstorage.cpp storage.cpp basichandler.cpp \
        ircserverhandler.cpp userinputhandler.cpp ctcphandler.cpp coreusersettings.cpp sessionthread.cpp
-HDRS = core.h coresession.h coresettings.h networkconnection.h sqlitestorage.h abstractsqlstorage.h storage.h basichandler.h \
+HDRS = core.h corebacklogmanager.h coresession.h coresettings.h networkconnection.h sqlitestorage.h abstractsqlstorage.h storage.h basichandler.h \
        ircserverhandler.h userinputhandler.h ctcphandler.h coreusersettings.h sessionthread.h
diff --git a/src/core/corebacklogmanager.cpp b/src/core/corebacklogmanager.cpp
new file mode 100644 (file)
index 0000000..7c79cb7
--- /dev/null
@@ -0,0 +1,45 @@
+/***************************************************************************
+ *   Copyright (C) 2005-08 by the Quassel IRC Team                         *
+ *   devel@quassel-irc.org                                                 *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) version 3.                                           *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#include "corebacklogmanager.h"
+#include "core.h"
+#include "coresession.h"
+
+#include <QDebug>
+
+CoreBacklogManager::CoreBacklogManager(CoreSession *coreSession)
+  : BacklogManager(coreSession),
+    _coreSession(coreSession)
+{
+}
+
+QVariantList CoreBacklogManager::requestBacklog(BufferId bufferId, int lastMsgs, int offset) {
+  QVariantList backlog;
+  QList<Message> msgList;
+  msgList = Core::requestMsgs(coreSession()->user(), bufferId, lastMsgs, offset);
+
+  QList<Message>::const_iterator msgIter = msgList.constBegin();
+  QList<Message>::const_iterator msgListEnd = msgList.constEnd();
+  while(msgIter != msgListEnd) {
+    backlog << qVariantFromValue(*msgIter);
+    msgIter++;
+  }
+  return backlog;
+}
diff --git a/src/core/corebacklogmanager.h b/src/core/corebacklogmanager.h
new file mode 100644 (file)
index 0000000..0272bbb
--- /dev/null
@@ -0,0 +1,45 @@
+/***************************************************************************
+ *   Copyright (C) 2005-08 by the Quassel IRC Team                         *
+ *   devel@quassel-irc.org                                                 *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) version 3.                                           *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
+ ***************************************************************************/
+
+#ifndef COREBACKLOGMANAGER_H
+#define COREBACKLOGMANAGER_H
+
+#include "backlogmanager.h"
+
+class CoreSession;
+
+class CoreBacklogManager : public BacklogManager {
+  Q_OBJECT
+
+public:
+  CoreBacklogManager(CoreSession *coreSession = 0);
+
+  virtual const QMetaObject *syncMetaObject() const { return &BacklogManager::staticMetaObject; }
+
+  CoreSession *coreSession() { return _coreSession; }
+
+public slots:
+  virtual QVariantList requestBacklog(BufferId bufferId, int lastMsgs = -1, int offset = -1);
+
+private:
+  CoreSession *_coreSession;
+};
+
+#endif // COREBACKLOGMANAGER_H
index bc4289b..c93324b 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "signalproxy.h"
 #include "buffersyncer.h"
+#include "corebacklogmanager.h"
 #include "storage.h"
 
 #include "network.h"
 #include "util.h"
 #include "coreusersettings.h"
 
-CoreSession::CoreSession(UserId uid, bool restoreState, QObject *parent) : QObject(parent),
+CoreSession::CoreSession(UserId uid, bool restoreState, QObject *parent)
+  : QObject(parent),
     _user(uid),
     _signalProxy(new SignalProxy(SignalProxy::Server, 0, this)),
     _bufferSyncer(new BufferSyncer(this)),
+    _backlogManager(new CoreBacklogManager(this)),
     scriptEngine(new QScriptEngine(this))
 {
 
@@ -47,10 +50,8 @@ CoreSession::CoreSession(UserId uid, bool restoreState, QObject *parent) : QObje
 
   //p->attachSlot(SIGNAL(disconnectFromNetwork(NetworkId)), this, SLOT(disconnectFromNetwork(NetworkId))); // FIXME
   p->attachSlot(SIGNAL(sendInput(BufferInfo, QString)), this, SLOT(msgFromClient(BufferInfo, QString)));
-  p->attachSlot(SIGNAL(requestBacklog(BufferInfo, QVariant, QVariant)), this, SLOT(sendBacklog(BufferInfo, QVariant, QVariant)));
   p->attachSignal(this, SIGNAL(displayMsg(Message)));
   p->attachSignal(this, SIGNAL(displayStatusMsg(QString, QString)));
-  p->attachSignal(this, SIGNAL(backlogData(BufferInfo, QVariantList, bool)));
   p->attachSignal(this, SIGNAL(bufferInfoUpdated(BufferInfo)));
 
   p->attachSignal(this, SIGNAL(identityCreated(const Identity &)));
@@ -79,6 +80,10 @@ CoreSession::CoreSession(UserId uid, bool restoreState, QObject *parent) : QObje
   connect(this, SIGNAL(bufferRenamed(BufferId, QString)), _bufferSyncer, SLOT(renameBuffer(BufferId, QString)));
   p->synchronize(_bufferSyncer);
 
+
+  // init BacklogManager;
+  p->synchronize(_backlogManager);
+    
   // Restore session state
   if(restoreState) restoreSessionState();
 
@@ -312,28 +317,6 @@ void CoreSession::storeBufferLastSeenMsg(BufferId buffer, const MsgId &msgId) {
   Core::setBufferLastSeenMsg(user(), buffer, msgId);
 }
 
-void CoreSession::sendBacklog(BufferInfo id, QVariant v1, QVariant v2) {
-  QList<QVariant> log;
-  QList<Message> msglist;
-  if(v1.type() == QVariant::DateTime) {
-
-
-  } else {
-    msglist = Core::requestMsgs(id, v1.toInt(), v2.toInt());
-  }
-
-  // Send messages out in smaller packages - we don't want to make the signal data too large!
-  for(int i = 0; i < msglist.count(); i++) {
-    log.append(qVariantFromValue(msglist[i]));
-    if(log.count() >= 5) {
-      emit backlogData(id, log, i >= msglist.count() - 1);
-      log.clear();
-    }
-  }
-  if(log.count() > 0) emit backlogData(id, log, true);
-}
-
-
 void CoreSession::initScriptEngine() {
   signalProxy()->attachSlot(SIGNAL(scriptRequest(QString)), this, SLOT(scriptRequest(QString)));
   signalProxy()->attachSignal(this, SIGNAL(scriptResult(QString)));
index 6d01d17..9965f0d 100644 (file)
@@ -27,6 +27,7 @@
 #include "message.h"
 
 class BufferSyncer;
+class CoreBacklogManager;
 class Identity;
 class NetworkConnection;
 class Network;
@@ -66,7 +67,6 @@ public slots:
   void connectToNetwork(NetworkId);
   void disconnectFromNetwork(NetworkId id);
 
-  void sendBacklog(BufferInfo, QVariant, QVariant);
   void msgFromClient(BufferInfo, QString message);
 
   //! Create an identity and propagate the changes to the clients.
@@ -127,8 +127,6 @@ signals:
   //void connectToIrc(QString net);
   //void disconnectFromIrc(QString net);
 
-  void backlogData(BufferInfo, QVariantList, bool done);
-
   void bufferInfoUpdated(BufferInfo);
 
   void scriptResult(QString result);
@@ -182,6 +180,7 @@ private:
   QHash<IdentityId, Identity *> _identities;
 
   BufferSyncer *_bufferSyncer;
+  CoreBacklogManager *_backlogManager;
 
   QScriptEngine *scriptEngine;
 
index d4b7d0c..3176ec4 100644 (file)
@@ -612,11 +612,16 @@ MsgId SqliteStorage::logMessage(Message msg) {
   return msgId;
 }
 
-QList<Message> SqliteStorage::requestMsgs(BufferInfo buffer, int lastmsgs, int offset) {
+QList<Message> SqliteStorage::requestMsgs(UserId user, BufferId bufferId, int lastmsgs, int offset) {
   QList<Message> messagelist;
+
+  BufferInfo bufferInfo = getBufferInfo(user, bufferId);
+  if(!bufferInfo.isValid())
+    return messagelist;
+
   // we have to determine the real offset first
   QSqlQuery *offsetQuery = cachedQuery("select_messagesOffset");
-  offsetQuery->bindValue(":bufferid", buffer.bufferId().toInt());
+  offsetQuery->bindValue(":bufferid", bufferId.toInt());
   offsetQuery->bindValue(":messageid", offset);
   offsetQuery->exec();
   offsetQuery->first();
@@ -624,7 +629,7 @@ QList<Message> SqliteStorage::requestMsgs(BufferInfo buffer, int lastmsgs, int o
 
   // now let's select the messages
   QSqlQuery *msgQuery = cachedQuery("select_messages");
-  msgQuery->bindValue(":bufferid", buffer.bufferId().toInt());
+  msgQuery->bindValue(":bufferid", bufferId.toInt());
   msgQuery->bindValue(":limit", lastmsgs);
   msgQuery->bindValue(":offset", offset);
   msgQuery->exec();
@@ -633,7 +638,7 @@ QList<Message> SqliteStorage::requestMsgs(BufferInfo buffer, int lastmsgs, int o
   
   while(msgQuery->next()) {
     Message msg(QDateTime::fromTime_t(msgQuery->value(1).toInt()),
-                buffer,
+                bufferInfo,
                 (Message::Type)msgQuery->value(2).toUInt(),
                 msgQuery->value(5).toString(),
                 msgQuery->value(4).toString(),
@@ -645,11 +650,16 @@ QList<Message> SqliteStorage::requestMsgs(BufferInfo buffer, int lastmsgs, int o
 }
 
 
-QList<Message> SqliteStorage::requestMsgs(BufferInfo buffer, QDateTime since, int offset) {
+QList<Message> SqliteStorage::requestMsgs(UserId user, BufferId bufferId, QDateTime since, int offset) {
   QList<Message> messagelist;
+
+  BufferInfo bufferInfo = getBufferInfo(user, bufferId);
+  if(!bufferInfo.isValid())
+    return messagelist;
+
   // we have to determine the real offset first
   QSqlQuery *offsetQuery = cachedQuery("select_messagesSinceOffset");
-  offsetQuery->bindValue(":bufferid", buffer.bufferId().toInt());
+  offsetQuery->bindValue(":bufferid", bufferId.toInt());
   offsetQuery->bindValue(":since", since.toTime_t());
   offsetQuery->exec();
   offsetQuery->first();
@@ -657,7 +667,7 @@ QList<Message> SqliteStorage::requestMsgs(BufferInfo buffer, QDateTime since, in
 
   // now let's select the messages
   QSqlQuery *msgQuery = cachedQuery("select_messagesSince");
-  msgQuery->bindValue(":bufferid", buffer.bufferId().toInt());
+  msgQuery->bindValue(":bufferid", bufferId.toInt());
   msgQuery->bindValue(":since", since.toTime_t());
   msgQuery->bindValue(":offset", offset);
   msgQuery->exec();
@@ -666,7 +676,7 @@ QList<Message> SqliteStorage::requestMsgs(BufferInfo buffer, QDateTime since, in
   
   while(msgQuery->next()) {
     Message msg(QDateTime::fromTime_t(msgQuery->value(1).toInt()),
-                buffer,
+                bufferInfo,
                 (Message::Type)msgQuery->value(2).toUInt(),
                 msgQuery->value(5).toString(),
                 msgQuery->value(4).toString(),
@@ -679,10 +689,15 @@ QList<Message> SqliteStorage::requestMsgs(BufferInfo buffer, QDateTime since, in
 }
 
 
-QList<Message> SqliteStorage::requestMsgRange(BufferInfo buffer, int first, int last) {
+QList<Message> SqliteStorage::requestMsgRange(UserId user, BufferId bufferId, int first, int last) {
   QList<Message> messagelist;
+
+  BufferInfo bufferInfo = getBufferInfo(user, bufferId);
+  if(!bufferInfo.isValid())
+    return messagelist;
+
   QSqlQuery *rangeQuery = cachedQuery("select_messageRange");
-  rangeQuery->bindValue(":bufferid", buffer.bufferId().toInt());
+  rangeQuery->bindValue(":bufferid", bufferId.toInt());
   rangeQuery->bindValue(":firstmsg", first);
   rangeQuery->bindValue(":lastmsg", last);
   rangeQuery->exec();
@@ -691,7 +706,7 @@ QList<Message> SqliteStorage::requestMsgRange(BufferInfo buffer, int first, int
   
   while(rangeQuery->next()) {
     Message msg(QDateTime::fromTime_t(rangeQuery->value(1).toInt()),
-                buffer,
+                bufferInfo,
                 (Message::Type)rangeQuery->value(2).toUInt(),
                 rangeQuery->value(5).toString(),
                 rangeQuery->value(4).toString(),
index 9968ec7..1242315 100644 (file)
@@ -76,9 +76,9 @@ public slots:
   /* Message handling */
   
   virtual MsgId logMessage(Message msg);
-  virtual QList<Message> requestMsgs(BufferInfo buffer, int lastmsgs = -1, int offset = -1);
-  virtual QList<Message> requestMsgs(BufferInfo buffer, QDateTime since, int offset = -1);
-  virtual QList<Message> requestMsgRange(BufferInfo buffer, int first, int last);
+  virtual QList<Message> requestMsgs(UserId user, BufferId bufferId, int lastmsgs = -1, int offset = -1);
+  virtual QList<Message> requestMsgs(UserId user, BufferId bufferId, QDateTime since, int offset = -1);
+  virtual QList<Message> requestMsgRange(UserId user, BufferId bufferId, int first, int last);
 
 protected:
   inline virtual QString driverName() { return "QSQLITE"; }
index d4c4b8b..6786359 100644 (file)
@@ -268,7 +268,7 @@ class Storage : public QObject {
      *  \param offset   Do not return (but DO count) messages with MsgId >= offset, if offset >= 0
      *  \return The requested list of messages
      */
-    virtual QList<Message> requestMsgs(BufferInfo buffer, int lastmsgs = -1, int offset = -1) = 0;
+    virtual QList<Message> requestMsgs(UserId user, BufferId buffer, int lastmsgs = -1, int offset = -1) = 0;
 
     //! Request messages stored in a given buffer since a certain point in time.
     /** \param buffer   The buffer we request messages from
@@ -276,7 +276,7 @@ class Storage : public QObject {
      *  \param offset   Do not return messages with MsgId >= offset, if offset >= 0
      *  \return The requested list of messages
      */
-    virtual QList<Message> requestMsgs(BufferInfo buffer, QDateTime since, int offset = -1) = 0;
+    virtual QList<Message> requestMsgs(UserId user, BufferId buffer, QDateTime since, int offset = -1) = 0;
 
     //! Request a range of messages stored in a given buffer.
     /** \param buffer   The buffer we request messages from
@@ -284,7 +284,7 @@ class Storage : public QObject {
      *  \param last     Return messages with first <= MsgId <= last
      *  \return The requested list of messages
      */
-    virtual QList<Message> requestMsgRange(BufferInfo buffer, int first, int last) = 0;
+    virtual QList<Message> requestMsgRange(UserId user, BufferId buffer, int first, int last) = 0;
 
   signals:
     //! Sent when a new BufferInfo is created, or an existing one changed somehow.
index 4c89e8e..d916771 100644 (file)
@@ -25,6 +25,7 @@
 #include "chatline.h"
 #include "chatline-old.h"
 #include "client.h"
+#include "clientbacklogmanager.h"
 #include "coreconnectdlg.h"
 #include "networkmodel.h"
 #include "buffermodel.h"
@@ -318,7 +319,8 @@ void MainWin::changeTopic(const QString &topic) {
 
 void MainWin::connectedToCore() {
   foreach(BufferInfo id, Client::allBufferInfos()) {
-    emit requestBacklog(id, 1000, -1);
+    // emit requestBacklog(id, 1000, -1);
+    Client::backlogManager()->requestBacklog(id.bufferId(), 1000, -1);
   }
 
   ui.menuViews->setEnabled(true);
index ccfe25c..9130de4 100644 (file)
@@ -3,16 +3,16 @@
 
 { using namespace Global;
 
-  quasselVersion = "0.2.0-alpha3";
+  quasselVersion = "0.2.0-alpha4-pre";
   quasselDate = "2008-03-16";
-  quasselBuild = 640;
+  quasselBuild = 641;
 
   //! Minimum client build number the core needs
-  clientBuildNeeded = 628;
+  clientBuildNeeded = 641;
   clientVersionNeeded = quasselVersion;
 
   //! Minimum core build number the client needs
-  coreBuildNeeded = 628;
+  coreBuildNeeded = 641;
   coreVersionNeeded = quasselVersion;
 
 }