X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fcommon%2Fnetwork.cpp;h=0d367af292ef99884cc35583b58ff07439957c66;hp=780a5d8644bff930bb7f4581e0ee14fac0e33f5d;hb=5b083e1f67c77ceb7d1d134e976cd6081b70bf12;hpb=fd7c2c4a41b5bb9cffcfe7a8f86a28ab7f38ac27 diff --git a/src/common/network.cpp b/src/common/network.cpp index 780a5d86..0d367af2 100644 --- a/src/common/network.cpp +++ b/src/common/network.cpp @@ -31,37 +31,38 @@ // ==================== // Public: // ==================== -Network::Network(const uint &networkid, QObject *parent) - : SyncableObject(parent), +Network::Network(const NetworkId &networkid, QObject *parent) : SyncableObject(parent), _networkId(networkid), - _initialized(false), + _identity(0), _myNick(QString()), - _networkName(QString()), + _networkName(QString("")), _currentServer(QString()), + _connected(false), + _connectionState(Disconnected), _prefixes(QString()), _prefixModes(QString()), _proxy(0), _codecForEncoding(0), _codecForDecoding(0) { - setObjectName(QString::number(networkid)); + setObjectName(QString::number(networkid.toInt())); } // I think this is unnecessary since IrcUsers have us as their daddy :) -//Network::~Network() { -// QHashIterator ircuser(_ircUsers); -// while (ircuser.hasNext()) { -// ircuser.next(); -// delete ircuser.value(); -// } -//} - -uint Network::networkId() const { - return _networkId; + +Network::~Network() { + emit aboutToBeDestroyed(); +// QHashIterator ircuser(_ircUsers); +// while (ircuser.hasNext()) { +// ircuser.next(); +// delete ircuser.value(); +// } +// qDebug() << "Destroying net" << networkName() << networkId(); } -bool Network::initialized() const { - return _initialized; + +NetworkId Network::networkId() const { + return _networkId; } SignalProxy *Network::proxy() const { @@ -70,14 +71,14 @@ SignalProxy *Network::proxy() const { void Network::setProxy(SignalProxy *proxy) { _proxy = proxy; - proxy->synchronize(this); + //proxy->synchronize(this); // we should to this explicitly from the outside! } bool Network::isMyNick(const QString &nick) const { return (myNick().toLower() == nick.toLower()); } -bool Network::isMyNick(IrcUser *ircuser) const { +bool Network::isMe(IrcUser *ircuser) const { return (ircuser->nick().toLower() == myNick().toLower()); } @@ -91,6 +92,37 @@ bool Network::isChannelName(const QString &channelname) const { return QString("#&!+").contains(channelname[0]); } +bool Network::isConnected() const { + return _connected; +} + +//Network::ConnectionState Network::connectionState() const { +int Network::connectionState() const { + return _connectionState; +} + +NetworkInfo Network::networkInfo() const { + NetworkInfo info; + info.networkName = networkName(); + info.networkId = networkId(); + info.identity = identity(); + info.codecForEncoding = codecForEncoding(); + info.codecForDecoding = codecForDecoding(); + info.serverList = serverList(); + return info; +} + +void Network::setNetworkInfo(const NetworkInfo &info) { + // we don't set our ID! + 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) { if(prefixes().contains(prefix)) return QString(prefixModes()[prefixes().indexOf(prefix)]); @@ -125,6 +157,10 @@ QString Network::myNick() const { return _myNick; } +IdentityId Network::identity() const { + return _identity; +} + QStringList Network::nicks() const { // we don't use _ircUsers.keys() since the keys may be // not up to date after a nick change @@ -139,6 +175,10 @@ QStringList Network::channels() const { return _ircChannels.keys(); } +QVariantList Network::serverList() const { + return _serverList; +} + QString Network::prefixes() { if(_prefixes.isNull()) determinePrefixes(); @@ -170,18 +210,18 @@ IrcUser *Network::newIrcUser(const QString &hostmask) { if(!_ircUsers.contains(nick)) { IrcUser *ircuser = new IrcUser(hostmask, this); // mark IrcUser as already initialized to keep the SignalProxy from requesting initData - if(initialized()) - ircuser->setInitialized(); + //if(isInitialized()) + // ircuser->setInitialized(); if(proxy()) proxy()->synchronize(ircuser); else qWarning() << "unable to synchronize new IrcUser" << hostmask << "forgot to call Network::setProxy(SignalProxy *)?"; connect(ircuser, SIGNAL(nickSet(QString)), this, SLOT(ircUserNickChanged(QString))); - connect(ircuser, SIGNAL(initDone()), this, SIGNAL(ircUserInitDone())); - connect(ircuser, SIGNAL(destroyed()), this, SLOT(ircUserDestroyed())); + connect(ircuser, SIGNAL(initDone()), this, SLOT(ircUserInitDone())); _ircUsers[nick] = ircuser; emit ircUserAdded(hostmask); + emit ircUserAdded(ircuser); } return _ircUsers[nick]; } @@ -196,11 +236,24 @@ void Network::removeIrcUser(IrcUser *ircuser) { return; _ircUsers.remove(nick); - ircuser->deleteLater(); + disconnect(ircuser, 0, this, 0); emit ircUserRemoved(nick); + emit ircUserRemoved(ircuser); + ircuser->deleteLater(); +} + +void Network::removeChansAndUsers() { + QList users = ircUsers(); + foreach(IrcUser *user, users) { + removeIrcUser(user); + } + QList channels = ircChannels(); + foreach(IrcChannel *channel, channels) { + removeIrcChannel(channel); + } } -void Network::removeIrcUser(QString nick) { +void Network::removeIrcUser(const QString &nick) { IrcUser *ircuser; if((ircuser = ircUser(nick)) != 0) removeIrcUser(ircuser); @@ -222,22 +275,27 @@ QList Network::ircUsers() const { return _ircUsers.values(); } +quint32 Network::ircUserCount() const { + return _ircUsers.count(); +} + IrcChannel *Network::newIrcChannel(const QString &channelname) { if(!_ircChannels.contains(channelname.toLower())) { IrcChannel *channel = new IrcChannel(channelname, this); // mark IrcUser as already initialized to keep the SignalProxy from requesting initData - if(initialized()) - channel->setInitialized(); + //if(isInitialized()) + // channel->setInitialized(); if(proxy()) proxy()->synchronize(channel); else qWarning() << "unable to synchronize new IrcChannel" << channelname << "forgot to call Network::setProxy(SignalProxy *)?"; - connect(channel, SIGNAL(initDone()), this, SIGNAL(ircChannelInitDone())); + connect(channel, SIGNAL(initDone()), this, SLOT(ircChannelInitDone())); connect(channel, SIGNAL(destroyed()), this, SLOT(channelDestroyed())); _ircChannels[channelname.toLower()] = channel; emit ircChannelAdded(channelname); + emit ircChannelAdded(channel); } return _ircChannels[channelname.toLower()]; } @@ -246,7 +304,7 @@ IrcChannel *Network::newIrcChannel(const QByteArray &channelname) { return newIrcChannel(decodeString(channelname)); } -IrcChannel *Network::ircChannel(QString channelname) { +IrcChannel *Network::ircChannel(QString channelname) const { channelname = channelname.toLower(); if(_ircChannels.contains(channelname)) return _ircChannels[channelname]; @@ -254,7 +312,7 @@ IrcChannel *Network::ircChannel(QString channelname) { return 0; } -IrcChannel *Network::ircChannel(const QByteArray &channelname) { +IrcChannel *Network::ircChannel(const QByteArray &channelname) const { return ircChannel(decodeString(channelname)); } @@ -263,28 +321,36 @@ QList Network::ircChannels() const { return _ircChannels.values(); } -QTextCodec *Network::codecForEncoding() const { - return _codecForEncoding; +quint32 Network::ircChannelCount() const { + return _ircChannels.count(); +} + +QByteArray Network::codecForEncoding() const { + if(_codecForEncoding) return _codecForEncoding->name(); + return QByteArray(); } -void Network::setCodecForEncoding(const QString &name) { - setCodecForEncoding(QTextCodec::codecForName(name.toAscii())); +void Network::setCodecForEncoding(const QByteArray &name) { + setCodecForEncoding(QTextCodec::codecForName(name)); } void Network::setCodecForEncoding(QTextCodec *codec) { _codecForEncoding = codec; + emit codecForEncodingSet(codecForEncoding()); } -QTextCodec *Network::codecForDecoding() const { - return _codecForDecoding; +QByteArray Network::codecForDecoding() const { + if(_codecForDecoding) return _codecForDecoding->name(); + else return QByteArray(); } -void Network::setCodecForDecoding(const QString &name) { - setCodecForDecoding(QTextCodec::codecForName(name.toAscii())); +void Network::setCodecForDecoding(const QByteArray &name) { + setCodecForDecoding(QTextCodec::codecForName(name)); } void Network::setCodecForDecoding(QTextCodec *codec) { _codecForDecoding = codec; + emit codecForDecodingSet(codecForDecoding()); } QString Network::decodeString(const QByteArray &text) const { @@ -311,11 +377,36 @@ void Network::setCurrentServer(const QString ¤tServer) { emit currentServerSet(currentServer); } +void Network::setConnected(bool connected) { + _connected = connected; + if(!connected) + removeChansAndUsers(); + emit connectedSet(connected); +} + +//void Network::setConnectionState(ConnectionState state) { +void Network::setConnectionState(int state) { + _connectionState = (ConnectionState)state; + //qDebug() << "netstate" << networkId() << networkName() << state; + emit connectionStateSet(state); + emit connectionStateSet(_connectionState); +} + void Network::setMyNick(const QString &nickname) { _myNick = nickname; emit myNickSet(nickname); } +void Network::setIdentity(IdentityId id) { + _identity = id; + emit identitySet(id); +} + +void Network::setServerList(const QVariantList &serverList) { + _serverList = serverList; + emit serverListSet(serverList); +} + void Network::addSupport(const QString ¶m, const QString &value) { if(!_supports.contains(param)) { _supports[param] = value; @@ -340,6 +431,10 @@ QVariantMap Network::initSupports() const { return supports; } +QVariantList Network::initServerList() const { + return serverList(); +} + QStringList Network::initIrcUsers() const { QStringList hostmasks; foreach(IrcUser *ircuser, ircUsers()) { @@ -360,6 +455,10 @@ void Network::initSetSupports(const QVariantMap &supports) { } } +void Network::initSetServerList(const QVariantList & serverList) { + setServerList(serverList); +} + void Network::initSetIrcUsers(const QStringList &hostmasks) { if(!_ircUsers.empty()) return; @@ -395,26 +494,74 @@ void Network::ircUserNickChanged(QString newnick) { return; if(newnick.toLower() != oldnick) _ircUsers[newnick.toLower()] = _ircUsers.take(oldnick); - + if(myNick().toLower() == oldnick) setMyNick(newnick); } -void Network::ircUserDestroyed() { +void Network::ircUserInitDone() { IrcUser *ircuser = static_cast(sender()); Q_ASSERT(ircuser); - removeIrcUser(ircuser); + emit ircUserInitDone(ircuser); +} + +void Network::ircChannelInitDone() { + IrcChannel *ircchannel = static_cast(sender()); + Q_ASSERT(ircchannel); + emit ircChannelInitDone(ircchannel); +} + +void Network::removeIrcChannel(IrcChannel *channel) { + QString chanName = _ircChannels.key(channel); + if(chanName.isNull()) + return; + + _ircChannels.remove(chanName); + disconnect(channel, 0, this, 0); + emit ircChannelRemoved(chanName); + emit ircChannelRemoved(channel); + channel->deleteLater(); +} + +void Network::removeIrcChannel(const QString &channel) { + IrcChannel *chan; + if((chan = ircChannel(channel)) != 0) + removeIrcChannel(chan); } void Network::channelDestroyed() { IrcChannel *channel = static_cast(sender()); Q_ASSERT(channel); _ircChannels.remove(_ircChannels.key(channel)); + emit ircChannelRemoved(channel); } -void Network::setInitialized() { - _initialized = true; - emit initDone(); +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 { + if(connectionState() != Disconnected) { + qWarning() << "Requesting connect while not being disconnected!"; + return; + } + emit connectRequested(networkId()); // and this is for CoreSession :) + } +} + +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 { + 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); } // ==================== @@ -454,3 +601,44 @@ void Network::determinePrefixes() { } } +/************************************************************************ + * NetworkInfo + ************************************************************************/ + +bool NetworkInfo::operator==(const NetworkInfo &other) const { + if(networkId != other.networkId) return false; + if(networkName != other.networkName) return false; + if(identity != other.identity) return false; + if(codecForEncoding != other.codecForEncoding) return false; + if(codecForDecoding != other.codecForDecoding) return false; + if(serverList != other.serverList) return false; + return true; +} + +bool NetworkInfo::operator!=(const NetworkInfo &other) const { + return !(*this == other); +} + +QDataStream &operator<<(QDataStream &out, const NetworkInfo &info) { + QVariantMap i; + i["NetworkId"] = QVariant::fromValue(info.networkId); + i["NetworkName"] = info.networkName; + i["Identity"] = QVariant::fromValue(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(); + info.networkName = i["NetworkName"].toString(); + info.identity = i["Identity"].value(); + info.codecForEncoding = i["CodecForEncoding"].toByteArray(); + info.codecForDecoding = i["CodecForDecoding"].toByteArray(); + info.serverList = i["ServerList"].toList(); + return in; +}