Besides the new settings page, the underlying structures have muchly improved.
To connect to a network, please use the new settings page (F7) for now; I'll add
a more convenient way soon. Ah, and connection failures are now reported and handled
sanely (auto reconnect is not yet implemented though) :)
Your old settings will be mostly migrated. Good luck.
p->attachSignal(this, SIGNAL(requestRemoveIdentity(IdentityId)), SIGNAL(removeIdentity(IdentityId)));
p->attachSlot(SIGNAL(identityCreated(const Identity &)), this, SLOT(coreIdentityCreated(const Identity &)));
p->attachSlot(SIGNAL(identityRemoved(IdentityId)), this, SLOT(coreIdentityRemoved(IdentityId)));
-/*
+
p->attachSignal(this, SIGNAL(requestCreateNetwork(const NetworkInfo &)), SIGNAL(createNetwork(const NetworkInfo &)));
p->attachSignal(this, SIGNAL(requestUpdateNetwork(const NetworkInfo &)), SIGNAL(updateNetwork(const NetworkInfo &)));
p->attachSignal(this, SIGNAL(requestRemoveNetwork(NetworkId)), SIGNAL(removeNetwork(NetworkId)));
- p->attachSlot(SIGNAL(networkCreated(const NetworkInfo &)), this, SLOT(coreNetworkCreated(const NetworkInfo &)));
+ p->attachSlot(SIGNAL(networkCreated(NetworkId)), this, SLOT(coreNetworkCreated(NetworkId)));
p->attachSlot(SIGNAL(networkRemoved(NetworkId)), this, SLOT(coreNetworkRemoved(NetworkId)));
-*/
+
connect(p, SIGNAL(disconnected()), this, SLOT(disconnectFromCore()));
//connect(mainUi, SIGNAL(connectToCore(const QVariantMap &)), this, SLOT(connectToCore(const QVariantMap &)));
else return 0;
}
+/*
+void Client::networkConnected(uint netid) {
+ // TODO: create statusBuffer / switch to networkids
+ //BufferInfo id = statusBufferInfo(net);
+ //Buffer *b = buffer(id);
+ //b->setActive(true);
+
+ Network *netinfo = new Network(netid, this);
+ netinfo->setProxy(signalProxy());
+ networkModel()->attachNetwork(netinfo);
+ connect(netinfo, SIGNAL(destroyed()), this, SLOT(networkDestroyed()));
+ _networks[netid] = netinfo;
+}
+
+void Client::networkDisconnected(NetworkId networkid) {
+ if(!_networks.contains(networkid)) {
+ qWarning() << "Client::networkDisconnected(uint): unknown Network" << networkid;
+ return;
+}
+
+ Network *net = _networks.take(networkid);
+ if(!net->isInitialized()) {
+ qDebug() << "Network" << networkid << "disconnected while not yet initialized!";
+ updateCoreConnectionProgress();
+}
+ net->deleteLater();
+}
+*/
+
+void Client::createNetwork(const NetworkInfo &info) {
+ emit instance()->requestCreateNetwork(info);
+}
+
+void Client::updateNetwork(const NetworkInfo &info) {
+ emit instance()->requestUpdateNetwork(info);
+}
+
+void Client::removeNetwork(NetworkId id) {
+ emit instance()->requestRemoveNetwork(id);
+}
+
+void Client::addNetwork(Network *net) {
+ net->setProxy(signalProxy());
+ signalProxy()->synchronize(net);
+ networkModel()->attachNetwork(net);
+ connect(net, SIGNAL(destroyed()), instance(), SLOT(networkDestroyed()));
+ instance()->_networks[net->networkId()] = net;
+ emit instance()->networkCreated(net->networkId());
+}
+
+void Client::coreNetworkCreated(NetworkId id) {
+ if(_networks.contains(id)) {
+ qWarning() << "Creation of already existing network requested!";
+ return;
+ }
+ Network *net = new Network(id, this);
+ addNetwork(net);
+}
+
+void Client::coreNetworkRemoved(NetworkId id) {
+ if(!_networks.contains(id)) return;
+ Network *net = _networks.take(id);
+ emit networkRemoved(net->networkId());
+ net->deleteLater();
+}
+
/*** Identity handling ***/
QList<IdentityId> Client::identityIds() {
/*** ***/
-// FIXME
-void Client::disconnectFromNetwork(NetworkId id) {
- if(!instance()->_networks.contains(id)) return;
- Network *net = instance()->_networks[id];
- net->requestDisconnect();
-}
-
-/*
-void Client::networkConnected(uint netid) {
- // TODO: create statusBuffer / switch to networkids
- //BufferInfo id = statusBufferInfo(net);
- //Buffer *b = buffer(id);
- //b->setActive(true);
-
- Network *netinfo = new Network(netid, this);
- netinfo->setProxy(signalProxy());
- networkModel()->attachNetwork(netinfo);
- connect(netinfo, SIGNAL(destroyed()), this, SLOT(networkDestroyed()));
- _networks[netid] = netinfo;
-}
-
-void Client::networkDisconnected(NetworkId networkid) {
- if(!_networks.contains(networkid)) {
- qWarning() << "Client::networkDisconnected(uint): unknown Network" << networkid;
- return;
- }
-
- Network *net = _networks.take(networkid);
- if(!net->isInitialized()) {
- qDebug() << "Network" << networkid << "disconnected while not yet initialized!";
- updateCoreConnectionProgress();
- }
- net->deleteLater();
-}
-*/
-
-void Client::addNetwork(Network *net) {
- net->setProxy(signalProxy());
- signalProxy()->synchronize(net);
- networkModel()->attachNetwork(net);
- connect(net, SIGNAL(destroyed()), instance(), SLOT(networkDestroyed()));
- instance()->_networks[net->networkId()] = net;
- emit instance()->networkCreated(net->networkId());
-}
-
-void Client::createNetwork(const NetworkInfo &info) {
-
-
-}
/*** ***/
static QVariant retrieveSessionData(const QString &key, const QVariant &def = QVariant());
static QStringList sessionDataKeys();
- static void disconnectFromNetwork(NetworkId);
-
enum ClientMode { LocalCore, RemoteCore };
signals:
void requestCreateNetwork(const NetworkInfo &info);
void requestUpdateNetwork(const NetworkInfo &info);
- void requestRemoveNetwork(const NetworkInfo &info);
+ void requestRemoveNetwork(NetworkId);
public slots:
//void selectBuffer(Buffer *);
void networkDestroyed();
void coreIdentityCreated(const Identity &);
void coreIdentityRemoved(IdentityId);
+ void coreNetworkCreated(NetworkId);
+ void coreNetworkRemoved(NetworkId);
private:
Client(QObject *parent = 0);
}
void ModelPropertyMapper::targetDestroyed() {
- QObject *obj = static_cast<QObject *>(sender());
- removeMapping(0, 0, obj, QByteArray());
+ removeMapping(0, 0, sender(), QByteArray());
}
#include "logger.h"
#include "message.h"
#include "identity.h"
+#include "network.h"
#include "bufferinfo.h"
#include "types.h"
#include "syncableobject.h"
qRegisterMetaType<QVariant>("QVariant");
qRegisterMetaType<Message>("Message");
qRegisterMetaType<BufferInfo>("BufferInfo");
+ qRegisterMetaType<NetworkInfo>("NetworkInfo");
qRegisterMetaType<Identity>("Identity");
+ qRegisterMetaType<Network::ConnectionState>("Network::ConnectionState");
qRegisterMetaTypeStreamOperators<QVariant>("QVariant");
qRegisterMetaTypeStreamOperators<Message>("Message");
qRegisterMetaTypeStreamOperators<BufferInfo>("BufferInfo");
+ qRegisterMetaTypeStreamOperators<NetworkInfo>("NetworkInfo");
qRegisterMetaTypeStreamOperators<Identity>("Identity");
+ qRegisterMetaTypeStreamOperators<int>("Network::ConnectionState");
- // Basic types (typedefs)
- // These use the standard stream operators
qRegisterMetaType<IdentityId>("IdentityId");
qRegisterMetaType<BufferId>("BufferId");
qRegisterMetaType<NetworkId>("NetworkId");
_networkName(QString("<not initialized>")),
_currentServer(QString()),
_connected(false),
+ _connectionState(Disconnected),
_prefixes(QString()),
_prefixModes(QString()),
_proxy(0),
}
// I think this is unnecessary since IrcUsers have us as their daddy :)
-/*
+
Network::~Network() {
- QHashIterator<QString, IrcUser *> ircuser(_ircUsers);
- while (ircuser.hasNext()) {
- ircuser.next();
- delete ircuser.value();
- }
+// QHashIterator<QString, IrcUser *> ircuser(_ircUsers);
+// while (ircuser.hasNext()) {
+// ircuser.next();
+// delete ircuser.value();
+// }
+// qDebug() << "Destroying net" << networkName() << networkId();
}
-*/
+
NetworkId Network::networkId() const {
return _networkId;
return _connected;
}
+Network::ConnectionState Network::connectionState() const {
+ return _connectionState;
+}
+
NetworkInfo Network::networkInfo() const {
NetworkInfo info;
info.networkName = networkName();
void Network::setNetworkInfo(const NetworkInfo &info) {
// we don't set our ID!
- if(!info.networkName.isEmpty()) setNetworkName(info.networkName);
- if(info.identity > 0) setIdentity(info.identity);
- if(!info.codecForEncoding.isEmpty()) setCodecForEncoding(QTextCodec::codecForName(info.codecForEncoding));
- if(!info.codecForDecoding.isEmpty()) setCodecForDecoding(QTextCodec::codecForName(info.codecForDecoding));
- if(info.serverList.count()) setServerList(info.serverList);
+ if(!info.networkName.isEmpty() && info.networkName != networkName()) setNetworkName(info.networkName);
+ if(info.identity > 0 && info.identity != identity()) setIdentity(info.identity);
+ if(!info.codecForEncoding.isEmpty() && info.codecForEncoding != codecForEncoding())
+ setCodecForEncoding(QTextCodec::codecForName(info.codecForEncoding));
+ if(!info.codecForDecoding.isEmpty() && info.codecForDecoding != codecForDecoding())
+ setCodecForDecoding(QTextCodec::codecForName(info.codecForDecoding));
+ if(info.serverList.count()) setServerList(info.serverList); // FIXME compare components
}
QString Network::prefixToMode(const QString &prefix) {
return _ircChannels.keys();
}
-QList<QVariantMap> Network::serverList() const {
+QVariantList Network::serverList() const {
return _serverList;
}
emit connectedSet(connected);
}
+void Network::setConnectionState(ConnectionState state) {
+ _connectionState = (ConnectionState)state;
+ emit connectionStateSet(_connectionState);
+}
+
void Network::setMyNick(const QString &nickname) {
_myNick = nickname;
emit myNickSet(nickname);
emit identitySet(id);
}
-void Network::setServerList(const QList<QVariantMap> &serverList) {
+void Network::setServerList(const QVariantList &serverList) {
_serverList = serverList;
emit serverListSet(serverList);
}
}
QVariantList Network::initServerList() const {
- QList<QVariant> list;
- foreach(QVariantMap serverdata, serverList()) list << QVariant(serverdata);
- return list;
+ return serverList();
}
QStringList Network::initIrcUsers() const {
}
void Network::initSetServerList(const QVariantList & serverList) {
- QList<QVariantMap> slist;
- foreach(QVariant v, serverList) slist << v.toMap();
- setServerList(slist);
+ setServerList(serverList);
}
void Network::initSetIrcUsers(const QStringList &hostmasks) {
_ircChannels.remove(_ircChannels.key(channel));
}
-void Network::requestConnect() {
+void Network::requestConnect() const {
if(!proxy()) return;
if(proxy()->proxyMode() == SignalProxy::Client) emit connectRequested(); // on the client this triggers calling this slot on the core
- else emit connectRequested(networkId()); // and this is for CoreSession :)
+ else {
+ if(connectionState() != Disconnected) {
+ qWarning() << "Requesting connect while not being disconnected!";
+ return;
+ }
+ emit connectRequested(networkId()); // and this is for CoreSession :)
+ }
}
-void Network::requestDisconnect() {
+void Network::requestDisconnect() const {
if(!proxy()) return;
if(proxy()->proxyMode() == SignalProxy::Client) emit disconnectRequested(); // on the client this triggers calling this slot on the core
- else emit disconnectRequested(networkId()); // and this is for CoreSession :)
+ else {
+ if(connectionState() == Disconnected) {
+ qWarning() << "Requesting disconnect while not being connected!";
+ return;
+ }
+ emit disconnectRequested(networkId()); // and this is for CoreSession :)
+ }
+}
+
+void Network::emitConnectionError(const QString &errorMsg) {
+ emit connectionError(errorMsg);
}
// ====================
bool NetworkInfo::operator!=(const NetworkInfo &other) const {
return !(*this == other);
}
+
+QDataStream &operator<<(QDataStream &out, const NetworkInfo &info) {
+ QVariantMap i;
+ i["NetworkId"] = QVariant::fromValue<NetworkId>(info.networkId);
+ i["NetworkName"] = info.networkName;
+ i["Identity"] = QVariant::fromValue<IdentityId>(info.identity);
+ i["CodecForEncoding"] = info.codecForEncoding;
+ i["CodecForDecoding"] = info.codecForDecoding;
+ i["ServerList"] = info.serverList;
+ out << i;
+ return out;
+}
+
+QDataStream &operator>>(QDataStream &in, NetworkInfo &info) {
+ QVariantMap i;
+ in >> i;
+ info.networkId = i["NetworkId"].value<NetworkId>();
+ info.networkName = i["NetworkName"].toString();
+ info.identity = i["Identity"].value<IdentityId>();
+ info.codecForEncoding = i["CodecForEncoding"].toByteArray();
+ info.codecForDecoding = i["CodecForDecoding"].toByteArray();
+ info.serverList = i["ServerList"].toList();
+ return in;
+}
class Network : public SyncableObject {
Q_OBJECT
+ Q_ENUMS(ConnectionState Network::ConnectionState)
Q_PROPERTY(QString networkName READ networkName WRITE setNetworkName STORED false)
Q_PROPERTY(QString currentServer READ currentServer WRITE setCurrentServer 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 WRITE setConnected STORED false)
+ Q_PROPERTY(Network::ConnectionState connectionState READ connectionState WRITE setConnectionState STORED false)
public:
+ enum ConnectionState { Disconnected, Connecting, Initializing, Initialized, Disconnecting };
+
Network(const NetworkId &networkid, QObject *parent = 0);
- // ~Network();
+ ~Network();
NetworkId networkId() const;
bool isChannelName(const QString &channelname) const;
bool isConnected() const;
+ Network::ConnectionState connectionState() const;
QString prefixToMode(const QString &prefix);
QString prefixToMode(const QCharRef &prefix);
IdentityId identity() const;
QStringList nicks() const;
QStringList channels() const;
- QList<QVariantMap> serverList() const;
+ QVariantList serverList() const;
NetworkInfo networkInfo() const;
void setNetworkInfo(const NetworkInfo &);
void setNetworkName(const QString &networkName);
void setCurrentServer(const QString ¤tServer);
void setConnected(bool isConnected);
+ void setConnectionState(Network::ConnectionState state);
void setMyNick(const QString &mynick);
void setIdentity(IdentityId);
- void setServerList(const QList<QVariantMap> &serverList);
+ void setServerList(const QVariantList &serverList);
void setCodecForEncoding(const QByteArray &codecName);
void setCodecForDecoding(const QByteArray &codecName);
// channel lists up to date
void ircUserNickChanged(QString newnick);
- void requestConnect();
- void requestDisconnect();
+ void requestConnect() const;
+ void requestDisconnect() const;
+
+ void emitConnectionError(const QString &);
private slots:
void ircUserDestroyed();
void networkNameSet(const QString &networkName);
void currentServerSet(const QString ¤tServer);
void connectedSet(bool isConnected);
+ void connectionStateSet(Network::ConnectionState);
+ void connectionError(const QString &errorMsg);
void myNickSet(const QString &mynick);
void identitySet(IdentityId);
- void serverListSet(const QList<QVariantMap> &serverList);
+ void serverListSet(QVariantList serverList);
void codecForEncodingSet(const QString &codecName);
void codecForDecodingSet(const QString &codecName);
void ircUserInitDone(IrcUser *);
void ircChannelInitDone(IrcChannel *);
- void connectRequested(NetworkId = 0);
- void disconnectRequested(NetworkId = 0);
+ void connectRequested(NetworkId id = 0) const;
+ void disconnectRequested(NetworkId id = 0) const;
private:
NetworkId _networkId;
QString _networkName;
QString _currentServer;
bool _connected;
+ ConnectionState _connectionState;
QString _prefixes;
QString _prefixModes;
QHash<QString, IrcChannel *> _ircChannels; // stores all known channels
QHash<QString, QString> _supports; // stores results from RPL_ISUPPORT
- QList<QVariantMap> _serverList;
+ QVariantList _serverList;
QStringList _perform;
//QVariantMap networkSettings;
//! Stores all editable information about a network (as opposed to runtime state).
struct NetworkInfo {
NetworkId networkId;
- IdentityId identity;
QString networkName;
+ IdentityId identity;
QByteArray codecForEncoding;
QByteArray codecForDecoding;
- QList<QVariantMap> serverList;
+ QVariantList serverList;
bool operator==(const NetworkInfo &other) const;
bool operator!=(const NetworkInfo &other) const;
};
+QDataStream &operator<<(QDataStream &out, const NetworkInfo &info);
+QDataStream &operator>>(QDataStream &in, NetworkInfo &info);
+
+Q_DECLARE_METATYPE(NetworkInfo);
#endif
CoreUserSettings s(user());
sessionData = s.sessionData();
- foreach(IdentityId id, s.identityIds()) {
- Identity *i = new Identity(s.identity(id), this);
- if(!i->isValid()) {
- qWarning() << QString("Invalid identity! Removing...");
- s.removeIdentity(id);
- delete i;
- continue;
- }
- if(_identities.contains(i->id())) {
- qWarning() << "Duplicate identity, ignoring!";
- delete i;
- continue;
- }
- _identities[i->id()] = i;
- }
- if(!_identities.count()) {
- Identity i(1);
- i.setToDefaults();
- i.setIdentityName(tr("Default Identity"));
- createIdentity(i);
- }
-
- //p->attachSlot(SIGNAL(requestNetworkStates()), this, SLOT(networkStateRequested()));
p->attachSlot(SIGNAL(requestConnect(QString)), this, SLOT(connectToNetwork(QString)));
p->attachSlot(SIGNAL(disconnectFromNetwork(NetworkId)), this, SLOT(disconnectFromNetwork(NetworkId))); // FIXME
p->attachSlot(SIGNAL(sendInput(BufferInfo, QString)), this, SLOT(msgFromClient(BufferInfo, QString)));
p->attachSlot(SIGNAL(updateIdentity(const Identity &)), this, SLOT(updateIdentity(const Identity &)));
p->attachSlot(SIGNAL(removeIdentity(IdentityId)), this, SLOT(removeIdentity(IdentityId)));
- initScriptEngine();
-
- foreach(Identity *id, _identities.values()) {
- p->synchronize(id);
- }
+ p->attachSignal(this, SIGNAL(networkCreated(NetworkId)));
+ p->attachSignal(this, SIGNAL(networkRemoved(NetworkId)));
+ p->attachSlot(SIGNAL(createNetwork(const NetworkInfo &)), this, SLOT(createNetwork(const NetworkInfo &)));
+ p->attachSlot(SIGNAL(updateNetwork(const NetworkInfo &)), this, SLOT(updateNetwork(const NetworkInfo &)));
+ p->attachSlot(SIGNAL(removeNetwork(NetworkId)), this, SLOT(removeNetwork(NetworkId)));
- // Load and init networks.
- // FIXME For now we use the old info from sessionData...
-
- QVariantMap networks = retrieveSessionData("Networks").toMap();
- foreach(QString netname, networks.keys()) {
- QVariantMap network = networks[netname].toMap();
- NetworkId netid = Core::networkId(user(), netname);
- Network *net = new Network(netid, this);
- connect(net, SIGNAL(connectRequested(NetworkId)), this, SLOT(connectToNetwork(NetworkId)));
- net->setNetworkName(netname);
- net->setIdentity(1); // FIXME default identity for now
- net->setCodecForEncoding("ISO-8859-15"); // FIXME
- net->setCodecForDecoding("ISO-8859-15"); // FIXME
- QList<QVariantMap> slist;
- foreach(QVariant v, network["Servers"].toList()) {
- QVariantMap server;
- server["Host"] = v.toMap()["Address"];
- server["Address"] = v.toMap()["Address"];
- server["Port"] = v.toMap()["Port"];
- slist << server;
- }
- net->setServerList(slist);
- net->setProxy(p);
- _networks[netid] = net;
- p->synchronize(net);
- }
+ loadSettings();
+ initScriptEngine();
// Restore session state
if(restoreState) restoreSessionState();
CoreSession::~CoreSession() {
saveSessionState();
+ foreach(NetworkConnection *conn, _connections.values()) {
+ conn->deleteLater();
+ }
+ foreach(Network *net, _networks.values()) {
+ net->deleteLater();
+ }
}
UserId CoreSession::user() const {
return 0;
}
+void CoreSession::loadSettings() {
+ CoreUserSettings s(user());
+
+ foreach(IdentityId id, s.identityIds()) {
+ Identity *i = new Identity(s.identity(id), this);
+ if(!i->isValid()) {
+ qWarning() << QString("Invalid identity! Removing...");
+ s.removeIdentity(id);
+ delete i;
+ continue;
+ }
+ if(_identities.contains(i->id())) {
+ qWarning() << "Duplicate identity, ignoring!";
+ delete i;
+ continue;
+ }
+ _identities[i->id()] = i;
+ signalProxy()->synchronize(i);
+ }
+ if(!_identities.count()) {
+ Identity i(1);
+ i.setToDefaults();
+ i.setIdentityName(tr("Default Identity"));
+ createIdentity(i);
+ }
+
+ foreach(NetworkId id, s.networkIds()) {
+ NetworkInfo info = s.networkInfo(id);
+ createNetwork(info, true);
+ }
+
+ // FIXME Migrate old settings if available...
+ if(!_networks.count()) {
+ QVariantMap networks = retrieveSessionData("Networks").toMap();
+ if(networks.keys().count()) {
+ qWarning() << "Migrating your old network settings to the new format!";
+ foreach(QString netname, networks.keys()) {
+ QVariantMap network = networks[netname].toMap();
+ NetworkId netid = Core::networkId(user(), netname);
+ NetworkInfo info;
+ info.networkId = netid;
+ info.networkName = netname;
+ info.identity = 1;
+ info.codecForEncoding = "ISO-8859-15";
+ info.codecForDecoding = "ISO-8859-15";
+ QVariantList slist;
+ foreach(QVariant v, network["Servers"].toList()) {
+ QVariantMap server;
+ server["Host"] = v.toMap()["Address"];
+ server["Port"] = v.toMap()["Port"];
+ slist << server;
+ }
+ info.serverList = slist;
+ createNetwork(info, true);
+ }
+ }
+ }
+}
+
void CoreSession::saveSessionState() const {
QVariantMap res;
QVariantList conn;
conn = new NetworkConnection(net, this, previousState);
_connections[id] = conn;
attachNetworkConnection(conn);
- conn->connectToIrc();
}
+ conn->connectToIrc();
}
void CoreSession::attachNetworkConnection(NetworkConnection *conn) {
- //connect(this, SIGNAL(connectToIrc(QString)), network, SLOT(connectToIrc(QString)));
- //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)));
- signalProxy()->attachSignal(conn, SIGNAL(connected(NetworkId)), SIGNAL(networkConnected(NetworkId)));
- signalProxy()->attachSignal(conn, SIGNAL(disconnected(NetworkId)), SIGNAL(networkDisconnected(NetworkId)));
+
+ // I guess we don't need these anymore, client-side can just connect the network's signals directly
+ //signalProxy()->attachSignal(conn, SIGNAL(connected(NetworkId)), SIGNAL(networkConnected(NetworkId)));
+ //signalProxy()->attachSignal(conn, SIGNAL(disconnected(NetworkId)), SIGNAL(networkDisconnected(NetworkId)));
connect(conn, SIGNAL(displayMsg(Message::Type, QString, QString, QString, quint8)), this, SLOT(recvMessageFromServer(Message::Type, QString, QString, QString, quint8)));
connect(conn, SIGNAL(displayStatusMsg(QString)), this, SLOT(recvStatusMsgFromServer(QString)));
- // TODO add error handling
}
void CoreSession::disconnectFromNetwork(NetworkId id) {
+ if(!_connections.contains(id)) return;
_connections[id]->disconnectFromIrc();
}
return _signalProxy;
}
+// FIXME we need a sane way for creating buffers!
void CoreSession::networkConnected(NetworkId networkid) {
- network(networkid)->setConnected(true);
Core::bufferInfo(user(), networkConnection(networkid)->networkName()); // create status buffer
}
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));
}
// FIXME switch to BufferId
void CoreSession::scriptRequest(QString script) {
emit scriptResult(scriptEngine->evaluate(script).toString());
}
-#include <QDebug>
+
+/*** Identity Handling ***/
+
void CoreSession::createIdentity(const Identity &id) {
// find free ID
int i;
}
}
+/*** Network Handling ***/
+
+void CoreSession::createNetwork(const NetworkInfo &_info, bool useId) {
+ NetworkInfo info = _info;
+ int id;
+ if(useId && info.networkId > 0) id = info.networkId.toInt();
+ else {
+ for(id = 1; id <= _networks.count(); id++) {
+ if(!_networks.keys().contains(id)) break;
+ }
+ //qDebug() << "found free id" << i;
+ info.networkId = id;
+ }
+ Network *net = new Network(id, this);
+ connect(net, SIGNAL(connectRequested(NetworkId)), this, SLOT(connectToNetwork(NetworkId)));
+ connect(net, SIGNAL(disconnectRequested(NetworkId)), this, SLOT(disconnectFromNetwork(NetworkId)));
+ net->setNetworkInfo(info);
+ net->setProxy(signalProxy());
+ _networks[id] = net;
+ signalProxy()->synchronize(net);
+ CoreUserSettings s(user());
+ s.storeNetworkInfo(info);
+ emit networkCreated(id);
+}
+
+void CoreSession::updateNetwork(const NetworkInfo &info) {
+ if(!_networks.contains(info.networkId)) {
+ qWarning() << "Update request for unknown network received!";
+ return;
+ }
+ _networks[info.networkId]->setNetworkInfo(info);
+ CoreUserSettings s(user());
+ s.storeNetworkInfo(info);
+}
+
+void CoreSession::removeNetwork(NetworkId id) {
+ Network *net = _networks.take(id);
+ if(net) {
+ emit networkRemoved(id);
+ CoreUserSettings s(user());
+ s.removeNetworkInfo(id);
+ net->deleteLater();
+ }
+}
class Identity;
class NetworkConnection; // FIXME get rid of
class Network;
+struct NetworkInfo;
class SignalProxy;
class QScriptEngine;
*/
void removeIdentity(IdentityId identity);
+ //! Create a network and propagate the changes to the clients.
+ /** \param info The network's settings.
+ */
+ void createNetwork(const NetworkInfo &info, bool useId = false);
+
+ //! Update a network and propagate the changes to the clients.
+ /** \param info The updated network settings.
+ */
+ void updateNetwork(const NetworkInfo &info);
+
+ //! Remove identity and propagate that fact to the clients.
+ /** \param identity The identity to be removed.
+ */
+ void removeNetwork(NetworkId network);
+
signals:
void initialized();
*/
void identityRemoved(IdentityId identity);
+ void networkCreated(NetworkId);
+ void networkRemoved(NetworkId);
+
private slots:
void recvStatusMsgFromServer(QString msg);
void recvMessageFromServer(Message::Type, QString target, QString text, QString sender = "", quint8 flags = Message::None);
void scriptRequest(QString script);
private:
+ void loadSettings();
void initScriptEngine();
UserId _user;
}
-void CoreUserSettings::storeIdentity(const Identity &identity) {
- setLocalValue(QString("Identities/%1").arg(identity.id().toInt()), qVariantFromValue(identity));
-}
-
-void CoreUserSettings::removeIdentity(const Identity &identity) {
- removeLocalKey(QString("Identities/%1").arg(identity.id().toInt()));
-}
-
Identity CoreUserSettings::identity(IdentityId id) {
QVariant v = localValue(QString("Identities/%1").arg(id.toInt()));
if(qVariantCanConvert<Identity>(v)) {
return res;
}
+void CoreUserSettings::storeIdentity(const Identity &identity) {
+ setLocalValue(QString("Identities/%1").arg(identity.id().toInt()), qVariantFromValue(identity));
+}
+
+void CoreUserSettings::removeIdentity(IdentityId id) {
+ removeLocalKey(QString("Identities/%1").arg(id.toInt()));
+}
+
+
+NetworkInfo CoreUserSettings::networkInfo(NetworkId id) {
+ QVariant v = localValue(QString("Networks/%1").arg(id.toInt()));
+ if(v.canConvert<NetworkInfo>()) {
+ return v.value<NetworkInfo>();
+ }
+ return NetworkInfo();
+}
+
+QList<NetworkId> CoreUserSettings::networkIds() {
+ QList<NetworkId> res;
+ foreach(QString id, localChildKeys("Networks")) {
+ res << id.toInt();
+ }
+ return res;
+}
+
+void CoreUserSettings::storeNetworkInfo(const NetworkInfo &info) {
+ setLocalValue(QString("Networks/%1").arg(info.networkId.toInt()), QVariant::fromValue<NetworkInfo>(info));
+}
+
+void CoreUserSettings::removeNetworkInfo(NetworkId id) {
+ removeLocalKey(QString("Networks/%1").arg(id.toInt()));
+}
+
+
void CoreUserSettings::setSessionState(const QVariant &data) {
setLocalValue("SessionState", data);
}
#include "coresettings.h"
#include "identity.h"
+#include "network.h"
#include "types.h"
#include <QVariantMap>
public:
CoreUserSettings(UserId user);
- void storeIdentity(const Identity &identity);
- void removeIdentity(const Identity &identity);
-
Identity identity(IdentityId id);
QList<IdentityId> identityIds();
+ void storeIdentity(const Identity &identity);
+ void removeIdentity(IdentityId id);
+
+ NetworkInfo networkInfo(NetworkId id);
+ QList<NetworkId> networkIds();
+ void storeNetworkInfo(const NetworkInfo &info);
+ void removeNetworkInfo(NetworkId id);
void setSessionState(const QVariant &data);
QVariant sessionState(const QVariant &def = QVariant());
#include "ctcphandler.h"
NetworkConnection::NetworkConnection(Network *network, CoreSession *session, const QVariant &state) : QObject(network),
+ _connectionState(Network::Disconnected),
_network(network),
_coreSession(session),
_ircServerHandler(new IrcServerHandler(this)),
_ctcpHandler(new CtcpHandler(this)),
_previousState(state)
{
- connect(network, SIGNAL(currentServerSet(const QString &)), this, SLOT(sendPerform()));
+ connect(network, SIGNAL(currentServerSet(const QString &)), this, SLOT(networkInitialized()));
connect(&socket, SIGNAL(connected()), this, SLOT(socketConnected()));
connect(&socket, SIGNAL(disconnected()), this, SLOT(socketDisconnected()));
}
NetworkConnection::~NetworkConnection() {
+ disconnectFromIrc();
delete _ircServerHandler;
delete _userInputHandler;
delete _ctcpHandler;
}
bool NetworkConnection::isConnected() const {
- return socket.state() == QAbstractSocket::ConnectedState;
+ // return socket.state() == QAbstractSocket::ConnectedState;
+ return connectionState() == Network::Initialized;
+}
+
+Network::ConnectionState NetworkConnection::connectionState() const {
+ return _connectionState;
+}
+
+void NetworkConnection::setConnectionState(Network::ConnectionState state) {
+ _connectionState = state;
+ network()->setConnectionState(state);
+ emit connectionStateChanged(state);
}
NetworkId NetworkConnection::networkId() const {
void NetworkConnection::connectToIrc() {
- QList<QVariantMap> serverList = network()->serverList();
+ QVariantList serverList = network()->serverList();
Identity *identity = coreSession()->identity(network()->identity());
if(!serverList.count()) {
qWarning() << "Server list empty, ignoring connect request!";
qWarning() << "Invalid identity configures, ignoring connect request!";
return;
}
-
// TODO implement cycling / random servers
- QString host = serverList[0]["Host"].toString();
- quint16 port = serverList[0]["Port"].toUInt();
+ QString host = serverList[0].toMap()["Host"].toString();
+ quint16 port = serverList[0].toMap()["Port"].toUInt();
displayStatusMsg(QString("Connecting to %1:%2...").arg(host).arg(port));
socket.connectToHost(host, port);
}
+void NetworkConnection::networkInitialized() {
+ sendPerform();
+
+ // rejoin channels we've been in
+ QStringList chans = _previousState.toStringList();
+ if(chans.count() > 0) {
+ qDebug() << "autojoining" << chans;
+ QString list = chans.join(",");
+ putCmd("join", QStringList(list)); // FIXME check for 512 byte limit!
+ }
+ // delete _previousState, we won't need it again
+ _previousState = QVariant();
+ // now we are initialized
+ setConnectionState(Network::Initialized);
+ network()->setConnected(true);
+ emit connected(networkId());
+}
+
void NetworkConnection::sendPerform() {
// TODO: reimplement perform List!
//// send performlist
// }
//}
- // rejoin channels we've been in
- QStringList chans = _previousState.toStringList();
- if(chans.count() > 0) {
- qDebug() << "autojoining" << chans;
- QString list = chans.join(",");
- putCmd("join", QStringList(list));
- }
- // delete _previousState, we won't need it again
- _previousState = QVariant();
}
QVariant NetworkConnection::state() const {
}
}
-void NetworkConnection::socketError( QAbstractSocket::SocketError err ) {
- Q_UNUSED(err);
- qDebug() << "Socket Error!";
+void NetworkConnection::socketError(QAbstractSocket::SocketError) {
+ qDebug() << qPrintable(tr("Could not connect to %1 (%2)").arg(network()->networkName(), socket.errorString()));
+ emit connectionError(socket.errorString());
+ emit displayMsg(Message::Error, "", tr("Connection failure: %1").arg(socket.errorString()));
+ network()->emitConnectionError(socket.errorString());
}
void NetworkConnection::socketConnected() {
- emit connected(networkId());
+ //emit connected(networkId()); initialize first!
Identity *identity = coreSession()->identity(network()->identity());
if(!identity) {
qWarning() << "Identity invalid!";
putRawLine(QString("USER %1 8 * :%2").arg(identity->ident(), identity->realName()));
}
-void NetworkConnection::socketStateChanged(QAbstractSocket::SocketState state) {
- Q_UNUSED(state);
- //qDebug() << "Socket state changed: " << state;
+void NetworkConnection::socketStateChanged(QAbstractSocket::SocketState socketState) {
+ Network::ConnectionState state;
+ switch(socketState) {
+ case QAbstractSocket::UnconnectedState:
+ state = Network::Disconnected;
+ break;
+ case QAbstractSocket::HostLookupState:
+ case QAbstractSocket::ConnectingState:
+ state = Network::Connecting;
+ break;
+ case QAbstractSocket::ConnectedState:
+ state = Network::Initializing;
+ break;
+ case QAbstractSocket::ClosingState:
+ state = Network::Disconnecting;
+ break;
+ default:
+ state = Network::Disconnected;
+ }
+ setConnectionState(state);
}
void NetworkConnection::socketDisconnected() {
+ network()->setConnected(false);
emit disconnected(networkId());
}
#include <QTimer>
#include "message.h"
+#include "network.h"
#include "signalproxy.h"
class CoreSession;
CoreSession *coreSession() const;
bool isConnected() const;
+ Network::ConnectionState connectionState() const;
IrcServerHandler *ircServerHandler() const;
UserInputHandler *userInputHandler() const;
void displayStatusMsg(QString);
//void displayMsg(Message msg);
void displayMsg(Message::Type, QString target, QString text, QString sender = "", quint8 flags = Message::None);
- void connected(NetworkId networkId);
+ void connected(NetworkId networkId); ///< Emitted after receipt of 001 to indicate that we can now send data to the IRC server
void disconnected(NetworkId networkId);
-
+ void connectionStateChanged(Network::ConnectionState);
void connectionInitialized(); ///< Emitted after receipt of 001 to indicate that we can now send data to the IRC server
+ void connectionError(const QString &errorMsg);
//void queryRequested(QString network, QString nick);
void socketConnected();
void socketDisconnected();
void socketStateChanged(QAbstractSocket::SocketState);
+ void setConnectionState(Network::ConnectionState);
+ void networkInitialized();
private:
QTcpSocket socket;
+ Network::ConnectionState _connectionState;
Network *_network;
CoreSession *_coreSession;
}
void UserInputHandler::handleWhois(QString bufname, QString msg) {
- qDebug() << "WHOIS" << QStringList(msg);
emit putCmd("WHOIS", msg.split(' '));
}
<file>oxygen/16x16/actions/games-highscores.png</file>
<file>oxygen/16x16/actions/games-hint.png</file>
<file>oxygen/16x16/actions/games-solve.png</file>
- <file>oxygen/16x16/actions/gear.png</file>
+ <file alias="gear">oxygen/16x16/actions/gear.png</file>
<file>oxygen/16x16/actions/get-hot-new-stuff.png</file>
<file>oxygen/16x16/actions/go-bottom.png</file>
<file>oxygen/16x16/actions/go-down-search.png</file>
<file>oxygen/22x22/actions/games-highscores.png</file>
<file>oxygen/22x22/actions/games-hint.png</file>
<file>oxygen/22x22/actions/games-solve.png</file>
- <file>oxygen/22x22/actions/gear.png</file>
+ <file alias="gear">oxygen/22x22/actions/gear.png</file>
<file>oxygen/22x22/actions/get-hot-new-stuff.png</file>
<file>oxygen/22x22/actions/go-bottom.png</file>
<file>oxygen/22x22/actions/go-down-search.png</file>
settingsDlg->registerSettingsPage(new FontsSettingsPage(settingsDlg));
settingsDlg->registerSettingsPage(new IdentitiesSettingsPage(settingsDlg));
-#ifdef SPUTDEV
settingsDlg->registerSettingsPage(new NetworksSettingsPage(settingsDlg));
+
+#ifdef SPUTDEV
connect(settingsDlg, SIGNAL(finished(int)), QApplication::instance(), SLOT(quit())); // FIXME
#endif
}
ui.menuCore->setEnabled(true);
ui.actionConnectCore->setEnabled(false);
ui.actionDisconnectCore->setEnabled(true);
- ui.actionNetworkList->setEnabled(true);
+ //ui.actionNetworkList->setEnabled(true);
ui.bufferWidget->show();
statusBar()->showMessage(tr("Connected to core."));
}
ui.menuViews->setEnabled(false);
ui.menuCore->setEnabled(false);
ui.actionDisconnectCore->setEnabled(false);
- ui.actionNetworkList->setEnabled(false);
+ //ui.actionNetworkList->setEnabled(false);
ui.bufferWidget->hide();
ui.actionConnectCore->setEnabled(true);
nickListWidget->reset();
void IdentitiesSettingsPage::on_deleteNick_clicked() {
// no confirmation, since a nickname is really nothing hard to recreate
if(ui.nicknameList->selectedItems().count()) {
- delete ui.nicknameList->selectedItems()[0];
+ delete ui.nicknameList->takeItem(ui.nicknameList->row(ui.nicknameList->selectedItems()[0]));
ui.nicknameList->setCurrentRow(qMin(ui.nicknameList->currentRow()+1, ui.nicknameList->count()-1));
setWidgetStates();
widgetHasChanged();
/*********************************************************************************************/
-SaveIdentitiesDlg::SaveIdentitiesDlg(QList<Identity *> tocreate, QList<Identity *> toupdate, QList<IdentityId> toremove, QWidget *parent)
- : QDialog(parent), toCreate(tocreate), toUpdate(toupdate), toRemove(toremove) {
+SaveIdentitiesDlg::SaveIdentitiesDlg(const QList<Identity *> &toCreate, const QList<Identity *> &toUpdate, const QList<IdentityId> &toRemove, QWidget *parent)
+ : QDialog(parent) { //, toCreate(tocreate), toUpdate(toupdate), toRemove(toremove) {
ui.setupUi(this);
numevents = toCreate.count() + toUpdate.count() + toRemove.count();
rcvevents = 0;
numevents--;
continue;
}
+ // FIXME this only checks for one changed item rather than all!
connect(cid, SIGNAL(updatedRemotely()), this, SLOT(clientEvent()));
Client::updateIdentity(*id);
}
Q_OBJECT
public:
- SaveIdentitiesDlg(QList<Identity *> toCreate, QList<Identity *> toUpdate, QList<IdentityId> toRemove, QWidget *parent = 0);
+ SaveIdentitiesDlg(const QList<Identity *> &toCreate, const QList<Identity *> &toUpdate, const QList<IdentityId> &toRemove, QWidget *parent = 0);
private slots:
void clientEvent();
private:
Ui::SaveIdentitiesDlg ui;
- QList<Identity *> toCreate, toUpdate;
- QList<IdentityId> toRemove;
+ //QList<Identity *> toCreate, toUpdate;
+ //QList<IdentityId> toRemove;
int numevents, rcvevents;
ui.setupUi(this);
connectedIcon = QIcon(":/22x22/actions/network-connect");
+ connectingIcon = QIcon(":/22x22/actions/gear");
disconnectedIcon = QIcon(":/22x22/actions/network-disconnect");
currentId = 0;
}
void NetworksSettingsPage::save() {
+ setEnabled(false);
if(currentId != 0) saveToNetworkInfo(networkInfos[currentId]);
- // First, remove the temporarily created networks
QList<NetworkInfo> toCreate, toUpdate;
QList<NetworkId> toRemove;
QHash<NetworkId, NetworkInfo>::iterator i = networkInfos.begin();
while(i != networkInfos.end()) {
- if((*i).networkId < 0) {
+ NetworkId id = (*i).networkId;
+ if(id < 0) {
toCreate.append(*i);
- i = networkInfos.erase(i);
+ //if(id == currentId) currentId = 0;
+ //QList<QListWidgetItem *> items = ui.networkList->findItems((*i).networkName, Qt::MatchExactly);
+ //if(items.count()) {
+ // Q_ASSERT(items[0]->data(Qt::UserRole).value<NetworkId>() == id);
+ // delete items[0];
+ //}
+ //i = networkInfos.erase(i);
+ ++i;
} else {
if((*i) != Client::network((*i).networkId)->networkInfo()) {
toUpdate.append(*i);
// canceled -> reload everything to be safe
load();
}
+ setChangedState(false);
+ setEnabled(true);
}
void NetworksSettingsPage::load() {
ui.networkList->clear();
networkInfos.clear();
- /*
- foreach(Identity *identity, identities.values()) {
- identity->deleteLater();
- }
- identities.clear();
- deletedIdentities.clear();
- changedIdentities.clear();
- ui.identityList->clear();
- */
}
bool NetworksSettingsPage::aboutToSave() {
-
- return true; // FIXME
+ if(currentId != 0) saveToNetworkInfo(networkInfos[currentId]);
+ QList<int> errors;
+ foreach(NetworkInfo info, networkInfos.values()) {
+ if(!info.serverList.count()) errors.append(1);
+ }
+ if(!errors.count()) return true;
+ QString error(tr("<b>The following problems need to be corrected before your changes can be applied:</b><ul>"));
+ if(errors.contains(1)) error += tr("<li>All networks need at least one server defined</li>");
+ error += tr("</ul>");
+ QMessageBox::warning(this, tr("Invalid Network Settings"), error);
+ return false;
}
void NetworksSettingsPage::widgetHasChanged() {
ui.detailsBox->setEnabled(true);
ui.renameNetwork->setEnabled(true);
ui.deleteNetwork->setEnabled(true);
- ui.connectNow->setEnabled(true);
+ ui.connectNow->setEnabled(id > 0
+ && (Client::network(id)->connectionState() == Network::Initialized
+ || Client::network(id)->connectionState() == Network::Disconnected));
if(Client::network(id) && Client::network(id)->isConnected()) {
ui.connectNow->setIcon(disconnectedIcon);
ui.connectNow->setText(tr("Disconnect"));
}
}
+void NetworksSettingsPage::setItemState(NetworkId id, QListWidgetItem *item) {
+ if(!item) item = networkItem(id);
+ const Network *net = Client::network(id);
+ if(!net || net->isInitialized()) item->setFlags(item->flags() | Qt::ItemIsEnabled);
+ else item->setFlags(item->flags() & ~Qt::ItemIsEnabled);
+ if(net && net->connectionState() == Network::Initialized) {
+ item->setIcon(connectedIcon);
+ } else if(net && net->connectionState() != Network::Disconnected) {
+ item->setIcon(connectingIcon);
+ } else {
+ item->setIcon(disconnectedIcon);
+ }
+ if(net) {
+ // check if we already have another net of this name in the list, and replace it
+ QList<QListWidgetItem *> items = ui.networkList->findItems(net->networkName(), Qt::MatchExactly);
+ if(items.count()) {
+ foreach(QListWidgetItem *i, items) {
+ NetworkId oldid = i->data(Qt::UserRole).value<NetworkId>();
+ if(oldid > 0) continue; // only locally created nets should be replaced
+ if(oldid == currentId) item->setSelected(true);
+ delete ui.networkList->takeItem(ui.networkList->row(i));
+ networkInfos.remove(oldid);
+ break;
+ }
+ }
+ item->setText(net->networkName());
+ }
+}
+
void NetworksSettingsPage::coreConnectionStateChanged(bool state) {
this->setEnabled(state);
if(state) {
}
}
-QListWidgetItem *NetworksSettingsPage::networkItem(NetworkId id) const {
- for(int i = 0; i < ui.networkList->count(); i++) {
- QListWidgetItem *item = ui.networkList->item(i);
- if(item->data(Qt::UserRole).value<NetworkId>() == id) return item;
- }
- return 0;
-}
-
void NetworksSettingsPage::clientIdentityAdded(IdentityId id) {
const Identity * identity = Client::identity(id);
connect(identity, SIGNAL(updatedRemotely()), this, SLOT(clientIdentityUpdated()));
}
void NetworksSettingsPage::clientIdentityRemoved(IdentityId id) {
- ui.identityList->removeItem(ui.identityList->findData(id.toInt()));
+ if(currentId != 0) saveToNetworkInfo(networkInfos[currentId]);
+ //ui.identityList->removeItem(ui.identityList->findData(id.toInt()));
foreach(NetworkInfo info, networkInfos.values()) {
- if(info.identity == id) info.identity = 1; // set to default
+ qDebug() << info.networkName << info.networkId << info.identity;
+ if(info.identity == id) {
+ if(info.networkId == currentId) ui.identityList->setCurrentIndex(0);
+ info.identity = 1; // set to default
+ networkInfos[info.networkId] = info;
+ if(info.networkId > 0) Client::updateNetwork(info);
+ }
}
+ ui.identityList->removeItem(ui.identityList->findData(id.toInt()));
widgetHasChanged();
}
+QListWidgetItem *NetworksSettingsPage::networkItem(NetworkId id) const {
+ for(int i = 0; i < ui.networkList->count(); i++) {
+ QListWidgetItem *item = ui.networkList->item(i);
+ if(item->data(Qt::UserRole).value<NetworkId>() == id) return item;
+ }
+ return 0;
+}
void NetworksSettingsPage::clientNetworkAdded(NetworkId id) {
insertNetwork(id);
connect(Client::network(id), SIGNAL(updatedRemotely()), this, SLOT(clientNetworkUpdated()));
+ connect(Client::network(id), SIGNAL(connectionStateSet(Network::ConnectionState)), this, SLOT(networkConnectionStateChanged(Network::ConnectionState)));
+ connect(Client::network(id), SIGNAL(connectionError(const QString &)), this, SLOT(networkConnectionError(const QString &)));
}
void NetworksSettingsPage::clientNetworkUpdated() {
qWarning() << "Update request for unknown network received!";
return;
}
- QListWidgetItem *item = networkItem(net->networkId());
- if(!item) return;
- item->setText(net->networkName());
- if(net->isInitialized()) item->setFlags(item->flags() | Qt::ItemIsEnabled);
- else item->setFlags(item->flags() & ~Qt::ItemIsEnabled);
- if(net->isConnected()) {
- item->setIcon(connectedIcon);
- } else {
- item->setIcon(disconnectedIcon);
+ networkInfos[net->networkId()] = net->networkInfo();
+ setItemState(net->networkId());
+ if(net->networkId() == currentId) displayNetwork(net->networkId());
+ setWidgetStates();
+ widgetHasChanged();
+}
+
+void NetworksSettingsPage::clientNetworkRemoved(NetworkId id) {
+ if(!networkInfos.contains(id)) return;
+ if(id == currentId) displayNetwork(0);
+ NetworkInfo info = networkInfos.take(id);
+ QList<QListWidgetItem *> items = ui.networkList->findItems(info.networkName, Qt::MatchExactly);
+ if(items.count()) {
+ Q_ASSERT(items[0]->data(Qt::UserRole).value<NetworkId>() == id);
+ delete ui.networkList->takeItem(ui.networkList->row(items[0]));
+ }
+ setWidgetStates();
+ widgetHasChanged();
+}
+
+void NetworksSettingsPage::networkConnectionStateChanged(Network::ConnectionState state) {
+ const Network *net = qobject_cast<const Network *>(sender());
+ if(!net) return;
+ if(net->networkId() == currentId) {
+ ui.connectNow->setEnabled(state == Network::Initialized || state == Network::Disconnected);
}
+ setItemState(net->networkId());
}
-void NetworksSettingsPage::clientNetworkRemoved(NetworkId) {
+void NetworksSettingsPage::networkConnectionError(const QString &) {
}
}
QListWidgetItem *NetworksSettingsPage::insertNetwork(const NetworkInfo &info) {
- QListWidgetItem *item = new QListWidgetItem(disconnectedIcon, info.networkName);
- item->setData(Qt::UserRole, QVariant::fromValue<NetworkId>(info.networkId));
- ui.networkList->addItem(item);
- const Network *net = Client::network(info.networkId);
- if(net->isInitialized()) item->setFlags(item->flags() | Qt::ItemIsEnabled);
- else item->setFlags(item->flags() & ~Qt::ItemIsEnabled);
- if(net && net->isConnected()) {
- item->setIcon(connectedIcon);
- } else {
- item->setIcon(disconnectedIcon);
+ QListWidgetItem *item = 0;
+ QList<QListWidgetItem *> items = ui.networkList->findItems(info.networkName, Qt::MatchExactly);
+ if(!items.count()) item = new QListWidgetItem(disconnectedIcon, info.networkName, ui.networkList);
+ else {
+ // we overwrite an existing net if it a) has the same name and b) has a negative ID meaning we created it locally before
+ // -> then we can be sure that this is the core-side replacement for the net we created
+ foreach(QListWidgetItem *i, items) {
+ NetworkId id = i->data(Qt::UserRole).value<NetworkId>();
+ if(id < 0) { item = i; break; }
+ }
+ if(!item) item = new QListWidgetItem(disconnectedIcon, info.networkName, ui.networkList);
}
+ item->setData(Qt::UserRole, QVariant::fromValue<NetworkId>(info.networkId));
+ setItemState(info.networkId, item);
widgetHasChanged();
return item;
}
-void NetworksSettingsPage::displayNetwork(NetworkId id, bool dontsave) {
- Q_UNUSED(dontsave);
- NetworkInfo info = networkInfos[id];
- ui.identityList->setCurrentIndex(ui.identityList->findData(info.identity.toInt()));
- ui.serverList->clear();
- foreach(QVariantMap v, info.serverList) {
- ui.serverList->addItem(QString("%1:%2").arg(v["Host"].toString()).arg(v["Port"].toUInt()));
+void NetworksSettingsPage::displayNetwork(NetworkId id) {
+ if(id != 0) {
+ NetworkInfo info = networkInfos[id];
+ ui.identityList->setCurrentIndex(ui.identityList->findData(info.identity.toInt()));
+ ui.serverList->clear();
+ foreach(QVariant v, info.serverList) {
+ ui.serverList->addItem(QString("%1:%2").arg(v.toMap()["Host"].toString()).arg(v.toMap()["Port"].toUInt()));
+ }
+ setItemState(id);
+ } else {
+ // just clear widgets
+ ui.identityList->setCurrentIndex(-1);
+ ui.serverList->clear();
+ ui.performEdit->clear();
+ setWidgetStates();
}
+ currentId = id;
}
void NetworksSettingsPage::saveToNetworkInfo(NetworkInfo &info) {
QMessageBox::Yes|QMessageBox::No, QMessageBox::No);
if(ret == QMessageBox::Yes) {
currentId = 0;
- networkInfos.remove(netid); qDebug() << netid << networkInfos.count();
- delete ui.networkList->selectedItems()[0];
+ networkInfos.remove(netid);
+ delete ui.networkList->takeItem(ui.networkList->row(ui.networkList->selectedItems()[0]));
ui.networkList->setCurrentRow(qMin(ui.networkList->currentRow()+1, ui.networkList->count()-1));
setWidgetStates();
widgetHasChanged();
}
}
+void NetworksSettingsPage::on_connectNow_clicked() {
+ if(!ui.networkList->selectedItems().count()) return;
+ NetworkId id = ui.networkList->selectedItems()[0]->data(Qt::UserRole).value<NetworkId>();
+ const Network *net = Client::network(id);
+ if(!net) return;
+ if(!net->isConnected()) net->requestConnect();
+ else net->requestDisconnect();
+}
+
/*** Server list ***/
void NetworksSettingsPage::on_serverList_itemSelectionChanged() {
void NetworksSettingsPage::on_upServer_clicked() {
int cur = ui.serverList->currentRow();
- QVariantMap foo = networkInfos[currentId].serverList.takeAt(cur);
+ QVariant foo = networkInfos[currentId].serverList.takeAt(cur);
networkInfos[currentId].serverList.insert(cur-1, foo);
displayNetwork(currentId);
ui.serverList->setCurrentRow(cur-1);
void NetworksSettingsPage::on_downServer_clicked() {
int cur = ui.serverList->currentRow();
- QVariantMap foo = networkInfos[currentId].serverList.takeAt(cur);
+ QVariant foo = networkInfos[currentId].serverList.takeAt(cur);
networkInfos[currentId].serverList.insert(cur+1, foo);
displayNetwork(currentId);
ui.serverList->setCurrentRow(cur+1);
* ServerEditDlg
*************************************************************************/
-ServerEditDlgNew::ServerEditDlgNew(const QVariantMap &serverData, QWidget *parent) : QDialog(parent) {
+ServerEditDlgNew::ServerEditDlgNew(const QVariant &_serverData, QWidget *parent) : QDialog(parent) {
ui.setupUi(this);
+ QVariantMap serverData = _serverData.toMap();
if(serverData.count()) {
ui.host->setText(serverData["Host"].toString());
ui.port->setValue(serverData["Port"].toUInt());
on_host_textChanged();
}
-QVariantMap ServerEditDlgNew::serverData() const {
+QVariant ServerEditDlgNew::serverData() const {
QVariantMap _serverData;
_serverData["Host"] = ui.host->text();
_serverData["Port"] = ui.port->value();
{
ui.setupUi(this);
+ numevents = toCreate.count() + toUpdate.count() + toRemove.count();
+ rcvevents = 0;
+ if(numevents) {
+ ui.progressBar->setMaximum(numevents);
+ ui.progressBar->setValue(0);
+
+ connect(Client::instance(), SIGNAL(networkCreated(NetworkId)), this, SLOT(clientEvent()));
+ connect(Client::instance(), SIGNAL(networkRemoved(NetworkId)), this, SLOT(clientEvent()));
+
+ foreach(NetworkInfo info, toCreate) {
+ Client::createNetwork(info);
+ }
+ foreach(NetworkInfo info, toUpdate) {
+ const Network *net = Client::network(info.networkId);
+ if(!net) {
+ qWarning() << "Invalid client network!";
+ numevents--;
+ continue;
+ }
+ // FIXME this only checks for one changed item rather than all!
+ connect(net, SIGNAL(updatedRemotely()), this, SLOT(clientEvent()));
+ Client::updateNetwork(info);
+ }
+ foreach(NetworkId id, toRemove) {
+ Client::removeNetwork(id);
+ }
+ } else {
+ qWarning() << "Sync dialog called without stuff to change!";
+ accept();
+ }
}
+void SaveNetworksDlg::clientEvent() {
+ ui.progressBar->setValue(++rcvevents);
+ if(rcvevents >= numevents) accept();
+}
void widgetHasChanged();
void setWidgetStates();
void coreConnectionStateChanged(bool);
+ void networkConnectionStateChanged(Network::ConnectionState state);
+ void networkConnectionError(const QString &msg);
- void displayNetwork(NetworkId, bool dontsave = false);
+ void displayNetwork(NetworkId);
+ void setItemState(NetworkId, QListWidgetItem *item = 0);
void clientNetworkAdded(NetworkId);
void clientNetworkRemoved(NetworkId);
void on_deleteNetwork_clicked();
void on_renameNetwork_clicked();
+ void on_connectNow_clicked();
+
void on_serverList_itemSelectionChanged();
void on_addServer_clicked();
void on_deleteServer_clicked();
NetworkId currentId;
QHash<NetworkId, NetworkInfo> networkInfos;
- QIcon connectedIcon, disconnectedIcon;
+ QIcon connectedIcon, connectingIcon, disconnectedIcon;
void reset();
bool testHasChanged();
Q_OBJECT
public:
- ServerEditDlgNew(const QVariantMap &serverData = QVariantMap(), QWidget *parent = 0);
+ ServerEditDlgNew(const QVariant &serverData = QVariant(), QWidget *parent = 0);
- QVariantMap serverData() const;
+ QVariant serverData() const;
private slots:
void on_host_textChanged();
public:
SaveNetworksDlg(const QList<NetworkInfo> &toCreate, const QList<NetworkInfo> &toUpdate, const QList<NetworkId> &toRemove, QWidget *parent = 0);
+ private slots:
+ void clientEvent();
+
private:
Ui::SaveIdentitiesDlg ui;
+
+ int numevents, rcvevents;
};
#endif
<rect>
<x>0</x>
<y>0</y>
- <width>246</width>
- <height>104</height>
+ <width>316</width>
+ <height>110</height>
</rect>
</property>
<property name="windowTitle" >
</property>
<layout class="QVBoxLayout" >
<item>
- <widget class="QLabel" name="label" >
- <property name="text" >
- <string>Syncing data with core, please wait...</string>
- </property>
- <property name="alignment" >
- <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
- </property>
- <property name="wordWrap" >
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QProgressBar" name="progressBar" >
- <property name="maximum" >
- <number>0</number>
- </property>
- <property name="value" >
- <number>0</number>
- </property>
- <property name="invertedAppearance" >
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item>
- <spacer>
- <property name="orientation" >
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" >
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <layout class="QHBoxLayout" >
+ <layout class="QVBoxLayout" >
+ <item>
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Syncing data with core, please wait...</string>
+ </property>
+ <property name="alignment" >
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+ </property>
+ <property name="wordWrap" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
<item>
<spacer>
<property name="orientation" >
- <enum>Qt::Horizontal</enum>
+ <enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" >
<size>
- <width>40</width>
- <height>20</height>
+ <width>20</width>
+ <height>40</height>
</size>
</property>
</spacer>
</item>
<item>
- <widget class="QPushButton" name="abort" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
+ <widget class="QProgressBar" name="progressBar" >
+ <property name="maximum" >
+ <number>0</number>
</property>
- <property name="text" >
- <string>Abort</string>
+ <property name="value" >
+ <number>0</number>
</property>
- <property name="icon" >
- <iconset resource="../../icons/icons.qrc" >:/22x22/actions/oxygen/22x22/actions/dialog-cancel.png</iconset>
+ <property name="invertedAppearance" >
+ <bool>false</bool>
</property>
</widget>
</item>
<item>
- <spacer>
- <property name="orientation" >
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" >
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
+ <layout class="QHBoxLayout" >
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="abort" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Abort</string>
+ </property>
+ <property name="icon" >
+ <iconset resource="../../icons/icons.qrc" >:/22x22/actions/oxygen/22x22/actions/dialog-cancel.png</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
</item>
</layout>
</item>
</widget>
<widget class="QStatusBar" name="statusbar" />
<action name="actionNetworkList" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
<property name="text" >
<string>&Network List...</string>
</property>
</property>
</action>
<action name="actionAboutQuassel" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
<property name="icon" >
<iconset resource="../../icons/icons.qrc" >:/icons/quassel-icon.png</iconset>
</property>
<rect>
<x>0</x>
<y>0</y>
- <width>780</width>
- <height>580</height>
+ <width>881</width>
+ <height>663</height>
</rect>
</property>
<property name="windowTitle" >