Fixes #410 - away log (you'll find it in the views menu)
[quassel.git] / src / core / sessionthread.cpp
index d507095..c29d1ff 100644 (file)
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2005-08 by the Quassel IRC Team                         *
+ *   Copyright (C) 2005-09 by the Quassel Project                          *
  *   devel@quassel-irc.org                                                 *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
 #include <QMutexLocker>
 
 #include "sessionthread.h"
-
+#include "signalproxy.h"
 #include "coresession.h"
+#include "core.h"
 
-SessionThread::SessionThread(UserId uid, QObject *parent) : QThread(parent) {
-    _user = uid;
-    _session = 0;
-    _sessionInitialized = false;
-    connect(this, SIGNAL(initialized()), this, SLOT(setSessionInitialized()));
+SessionThread::SessionThread(UserId uid, bool restoreState, QObject *parent)
+  : QThread(parent),
+    _session(0),
+    _user(uid),
+    _sessionInitialized(false),
+    _restoreState(restoreState)
+{
+  connect(this, SIGNAL(initialized()), this, SLOT(setSessionInitialized()));
 }
 
 SessionThread::~SessionThread() {
-  // FIXME
-  quit();
-  wait();
-  if(session()) _session->deleteLater();
+  if(_session) {
+    _session->setParent(0);
+    _session->moveToThread(thread());
+    _session->deleteLater();
+    _session = 0;
+  }
 }
 
 CoreSession *SessionThread::session() {
@@ -52,32 +58,61 @@ bool SessionThread::isSessionInitialized() {
 
 void SessionThread::setSessionInitialized() {
   _sessionInitialized = true;
-  foreach(QIODevice *socket, clientQueue) {
-    addClientToSession(socket);
+  foreach(QObject *peer, clientQueue) {
+    addClientToSession(peer);
   }
   clientQueue.clear();
 }
 
-void SessionThread::addClient(QIODevice *socket) {
+void SessionThread::addClient(QObject *peer) {
   if(isSessionInitialized()) {
-    addClientToSession(socket);
+    addClientToSession(peer);
   } else {
-    clientQueue.append(socket);
+    clientQueue.append(peer);
+  }
+}
+
+void SessionThread::addClientToSession(QObject *peer) {
+  QIODevice *socket = qobject_cast<QIODevice *>(peer);
+  if(socket) {
+    addRemoteClientToSession(socket);
+    return;
+  }
+
+  SignalProxy *proxy = qobject_cast<SignalProxy *>(peer);
+  if(proxy) {
+    addInternalClientToSession(proxy);
+    return;
   }
+
+  qWarning() << "SessionThread::addClient() received neither QIODevice nor SignalProxy as peer!" << peer;
 }
 
-void SessionThread::addClientToSession(QIODevice *socket) {
+void SessionThread::addRemoteClientToSession(QIODevice *socket) {
   socket->setParent(0);
   socket->moveToThread(session()->thread());
-  if(!QMetaObject::invokeMethod(session(), "addClient", Q_ARG(QObject *, socket))) {
-    qWarning() << qPrintable(tr("Could not initialize session!"));
-    socket->close();
-  }
+  emit addRemoteClient(socket);
+}
+
+void SessionThread::addInternalClientToSession(SignalProxy *proxy) {
+  emit addInternalClient(proxy);
 }
 
 void SessionThread::run() {
-  _session = new CoreSession(user());
+  _session = new CoreSession(user(), _restoreState);
+  connect(this, SIGNAL(addRemoteClient(QIODevice *)), _session, SLOT(addClient(QIODevice *)));
+  connect(this, SIGNAL(addInternalClient(SignalProxy *)), _session, SLOT(addClient(SignalProxy *)));
+  connect(_session, SIGNAL(sessionState(const QVariant &)), Core::instance(), SIGNAL(sessionState(const QVariant &)));
   emit initialized();
   exec();
+  delete _session;
+  _session = 0;
 }
 
+void SessionThread::stopSession() {
+  if(_session) {
+    connect(_session, SIGNAL(destroyed()), this, SLOT(quit()));
+    _session->deleteLater();
+    _session = 0;
+  }
+}