_myNick(QString()),
_networkName(QString("<not initialized>")),
_currentServer(QString()),
+ _connected(false),
_prefixes(QString()),
_prefixModes(QString()),
_proxy(0),
return QString("#&!+").contains(channelname[0]);
}
+bool Network::isConnected() const {
+ return _connected;
+}
+
QString Network::prefixToMode(const QString &prefix) {
if(prefixes().contains(prefix))
return QString(prefixModes()[prefixes().indexOf(prefix)]);
emit currentServerSet(currentServer);
}
+void Network::setConnected(bool connected) {
+ _connected = connected;
+ emit connectedSet(connected);
+}
+
void Network::setMyNick(const QString &nickname) {
_myNick = nickname;
emit myNickSet(nickname);
Q_PROPERTY(QByteArray codecForEncoding READ codecForEncoding WRITE setCodecForEncoding STORED false)
Q_PROPERTY(QByteArray codecForDecoding READ codecForDecoding WRITE setCodecForDecoding STORED false)
Q_PROPERTY(IdentityId identityId READ identity WRITE setIdentity STORED false)
- // Q_PROPERTY(bool isConnected READ isConnected STORED false)
+ Q_PROPERTY(bool isConnected READ isConnected WRITE setConnected STORED false)
public:
Network(const NetworkId &networkid, QObject *parent = 0);
bool isChannelName(const QString &channelname) const;
+ bool isConnected() const;
+
QString prefixToMode(const QString &prefix);
QString prefixToMode(const QCharRef &prefix);
QString modeToPrefix(const QString &mode);
public slots:
void setNetworkName(const QString &networkName);
void setCurrentServer(const QString ¤tServer);
+ void setConnected(bool isConnected);
void setMyNick(const QString &mynick);
void setIdentity(IdentityId);
signals:
void networkNameSet(const QString &networkName);
void currentServerSet(const QString ¤tServer);
+ void connectedSet(bool isConnected);
void myNickSet(const QString &mynick);
void identitySet(IdentityId);
QString _myNick;
QString _networkName;
QString _currentServer;
+ bool _connected;
QString _prefixes;
QString _prefixModes;
}
void Core::restoreState() {
- return;
- /*
- Q_ASSERT(!instance()->sessions.count());
+ if(instance()->sessions.count()) {
+ qWarning() << qPrintable(tr("Calling restoreState() even though active sessions exist!"));
+ return;
+ }
CoreSettings s;
- QList<QVariant> users = s.coreState().toList();
- if(users.count() > 0) {
+ uint build = s.coreState().toMap()["CoreBuild"].toUInt();
+ if(build < 362) {
+ qWarning() << qPrintable(tr("Core state too old, ignoring..."));
+ return;
+ }
+ QVariantList activeSessions = s.coreState().toMap()["ActiveSessions"].toList();
+ if(activeSessions.count() > 0) {
qDebug() << "Restoring previous core state...";
- foreach(QVariant v, users) {
- QVariantMap m = v.toMap();
- if(m.contains("UserId")) {
- CoreSession *sess = createSession(m["UserId"].toUInt());
- sess->restoreState(m["State"]); // FIXME multithreading
- }
+ foreach(QVariant v, activeSessions) {
+ UserId user = v.value<UserId>();
+ instance()->createSession(user, true);
}
qDebug() << "...done.";
}
- */
}
void Core::saveState() {
- /*
CoreSettings s;
- QList<QVariant> users;
- foreach(CoreSession *sess, instance()->sessions.values()) {
- QVariantMap m;
- m["UserId"] = sess->user(); // FIXME multithreading
- m["State"] = sess->state();
- users << m;
- }
- s.setCoreState(users);
- */
+ QVariantMap state;
+ QVariantList activeSessions;
+ foreach(UserId user, instance()->sessions.keys()) activeSessions << QVariant::fromValue<UserId>(user);
+ state["CoreBuild"] = Global::quasselBuild;
+ state["ActiveSessions"] = activeSessions;
+ s.setCoreState(state);
}
/*** Storage Access ***/
// Suggestion: kill sessions if they are not connected to any network and client.
}
-
- //disconnect(socket, 0, this, 0);
- /*
- sessions[uid]->addClient(socket); // FIXME multithreading
- qDebug() << "Client initialized successfully.";
- SignalProxy::writeDataToDevice(socket, reply);
- */
-
-
void Core::processCoreSetup(QTcpSocket *socket, QVariantMap &msg) {
if(msg["HasSettings"].toBool()) {
QVariantMap auth;
sess->addClient(socket);
}
-SessionThread *Core::createSession(UserId uid) {
+SessionThread *Core::createSession(UserId uid, bool restore) {
if(sessions.contains(uid)) {
qWarning() << "Calling createSession() when a session for the user already exists!";
return 0;
}
- SessionThread *sess = new SessionThread(uid, this);
+ SessionThread *sess = new SessionThread(uid, restore, this);
sessions[uid] = sess;
sess->start();
return sess;
void init();
static Core *instanceptr;
- SessionThread *createSession(UserId userId);
+ SessionThread *createSession(UserId userId, bool restoreState = false);
void setupClientSession(QTcpSocket *socket, UserId uid);
void processCoreSetup(QTcpSocket *socket, QVariantMap &msg);
#include <QtScript>
-CoreSession::CoreSession(UserId uid, QObject *parent) : QObject(parent),
+CoreSession::CoreSession(UserId uid, bool restoreState, QObject *parent) : QObject(parent),
_user(uid),
_signalProxy(new SignalProxy(SignalProxy::Server, 0, this)),
scriptEngine(new QScriptEngine(this))
p->synchronize(net);
}
+ // Restore session state
+ if(restoreState) restoreSessionState();
+
emit initialized();
}
CoreSession::~CoreSession() {
+ saveSessionState();
}
UserId CoreSession::user() const {
return 0;
}
-QVariant CoreSession::state() const { // FIXME
+void CoreSession::saveSessionState() const {
QVariantMap res;
- /*
- QList<QVariant> conn;
- foreach(NetworkConnection *net, connections.values()) {
- if(net->isConnected()) {
- QVariantMap m;
- m["Network"] = net->networkName();
- m["State"] = net->state();
- conn << m;
- }
+ QVariantList conn;
+ foreach(NetworkConnection *net, _connections.values()) {
+ QVariantMap m;
+ m["NetworkId"] = QVariant::fromValue<NetworkId>(net->networkId());
+ m["State"] = net->state();
+ conn << m;
}
- res["ConnectedServers"] = conn;
- */
- return res;
+ res["CoreBuild"] = Global::quasselBuild;
+ res["ConnectedNetworks"] = conn;
+ CoreUserSettings s(user());
+ s.setSessionState(res);
}
-void CoreSession::restoreState(const QVariant &previousState) { // FIXME
- // Session restore
- /*
- QVariantMap state = previousState.toMap();
- if(state.contains("ConnectedServers")) {
- foreach(QVariant v, state["ConnectedServers"].toList()) {
- QVariantMap m = v.toMap();
- QString net = m["Network"].toString();
- if(!net.isEmpty()) connectToNetwork(net, m["State"]);
- }
+void CoreSession::restoreSessionState() {
+ CoreUserSettings s(user());
+ uint build = s.sessionState().toMap()["CoreBuild"].toUInt();
+ if(build < 362) {
+ qWarning() << qPrintable(tr("Session state does not exist or is too old!"));
+ return;
+ }
+ QVariantList conn = s.sessionState().toMap()["ConnectedNetworks"].toList();
+ foreach(QVariant v, conn) {
+ NetworkId id = v.toMap()["NetworkId"].value<NetworkId>();
+ if(_networks.keys().contains(id)) connectToNetwork(id, v.toMap()["State"]);
}
- */
}
//connect(this, SIGNAL(disconnectFromIrc(QString)), network, SLOT(disconnectFromIrc(QString)));
//connect(this, SIGNAL(msgFromGui(uint, QString, QString)), network, SLOT(userInput(uint, QString, QString)));
- //connect(conn, SIGNAL(connected(NetworkId)), this, SLOT(networkConnected(NetworkId)));
- //connect(conn, SIGNAL(disconnected(NetworkId)), this, SLOT(networkDisconnected(NetworkId)));
+ connect(conn, SIGNAL(connected(NetworkId)), this, SLOT(networkConnected(NetworkId)));
+ connect(conn, SIGNAL(disconnected(NetworkId)), this, SLOT(networkDisconnected(NetworkId)));
signalProxy()->attachSignal(conn, SIGNAL(connected(NetworkId)), SIGNAL(networkConnected(NetworkId)));
signalProxy()->attachSignal(conn, SIGNAL(disconnected(NetworkId)), SIGNAL(networkDisconnected(NetworkId)));
return _signalProxy;
}
-void CoreSession::networkConnected(uint networkid) {
+void CoreSession::networkConnected(NetworkId networkid) {
+ network(networkid)->setConnected(true);
Core::bufferInfo(user(), networkConnection(networkid)->networkName()); // create status buffer
}
-void CoreSession::networkDisconnected(uint networkid) {
+void CoreSession::networkDisconnected(NetworkId networkid) {
// FIXME
// connection should only go away on explicit /part, and handle reconnections etcpp internally otherwise
+ network(networkid)->setConnected(false);
+
Q_ASSERT(_connections.contains(networkid));
_connections.take(networkid)->deleteLater();
Q_ASSERT(!_connections.contains(networkid));
Q_OBJECT
public:
- CoreSession(UserId, QObject *parent = 0);
+ CoreSession(UserId, bool restoreState, QObject *parent = 0);
~CoreSession();
QList<BufferInfo> buffers() const;
void attachNetworkConnection(NetworkConnection *conn);
//! Return necessary data for restoring the session after restarting the core
- QVariant state() const;
- void restoreState(const QVariant &previousState);
+ void saveSessionState() const;
+ void restoreSessionState();
public slots:
//! Store a piece session-wide data and distribute it to connected clients.
private slots:
void recvStatusMsgFromServer(QString msg);
void recvMessageFromServer(Message::Type, QString target, QString text, QString sender = "", quint8 flags = Message::None);
- void networkConnected(uint networkid);
- void networkDisconnected(uint networkid);
+ void networkConnected(NetworkId networkid);
+ void networkDisconnected(NetworkId networkid);
//! Called when storage updated a BufferInfo.
/** This emits bufferInfoUpdated() via SignalProxy, iff it's one of our buffers.
return res;
}
+void CoreUserSettings::setSessionState(const QVariant &data) {
+ setLocalValue("SessionState", data);
+}
+
+QVariant CoreUserSettings::sessionState(const QVariant &def) {
+ return localValue("SessionState", def);
+}
+
QVariantMap CoreUserSettings::sessionData() {
QVariantMap res;
foreach(QString key, localChildKeys(QString("SessionData"))) {
Identity identity(IdentityId id);
QList<IdentityId> identityIds();
+ void setSessionState(const QVariant &data);
+ QVariant sessionState(const QVariant &def = QVariant());
+
private:
// this stuff should only be accessed by CoreSession!
QVariantMap sessionData();
}
void NetworkConnection::socketError( QAbstractSocket::SocketError err ) {
+ Q_UNUSED(err);
qDebug() << "Socket Error!";
}
}
void NetworkConnection::socketStateChanged(QAbstractSocket::SocketState state) {
+ Q_UNUSED(state);
//qDebug() << "Socket state changed: " << state;
}
#include "coresession.h"
-SessionThread::SessionThread(UserId uid, QObject *parent) : QThread(parent) {
+SessionThread::SessionThread(UserId uid, bool restoreState, QObject *parent) : QThread(parent) {
_user = uid;
_session = 0;
_sessionInitialized = false;
+ _restoreState = restoreState,
connect(this, SIGNAL(initialized()), this, SLOT(setSessionInitialized()));
}
SessionThread::~SessionThread() {
- // FIXME
+ // shut down thread gracefully
quit();
wait();
- if(session()) _session->deleteLater();
}
CoreSession *SessionThread::session() {
}
void SessionThread::run() {
- _session = new CoreSession(user());
+ _session = new CoreSession(user(), _restoreState);
emit initialized();
exec();
+ delete _session;
}
Q_OBJECT
public:
- SessionThread(UserId user, QObject *parent = 0);
+ SessionThread(UserId user, bool restoreState, QObject *parent = 0);
~SessionThread();
void run();
signals:
void initialized();
+ void shutdown();
private:
CoreSession *_session;
UserId _user;
QList<QIODevice *> clientQueue;
bool _sessionInitialized;
+ bool _restoreState;
bool isSessionInitialized();
void addClientToSession(QIODevice *socket);
{ using namespace Global;
quasselVersion = "0.2.0-pre";
- quasselDate = "2008-01-19";
- quasselBuild = 360;
+ quasselDate = "2008-01-20";
+ quasselBuild = 362;
//! Minimum client build number the core needs
clientBuildNeeded = 358;