***************************************************************************/
#include "network.h"
-#include "signalproxy.h"
-#include "ircuser.h"
-#include "ircchannel.h"
-
#include <QDebug>
#include <QTextCodec>
QTextCodec *Network::_defaultCodecForServer = 0;
QTextCodec *Network::_defaultCodecForEncoding = 0;
QTextCodec *Network::_defaultCodecForDecoding = 0;
-
// ====================
// Public:
// ====================
-Network::Network(const NetworkId &networkid, QObject *parent) : SyncableObject(parent),
+Network::Network(const NetworkId &networkid, QObject *parent)
+ : SyncableObject(parent),
+ _proxy(0),
_networkId(networkid),
_identity(0),
_myNick(QString()),
_connectionState(Disconnected),
_prefixes(QString()),
_prefixModes(QString()),
- _proxy(0),
_useRandomServer(false),
_useAutoIdentify(false),
_useAutoReconnect(false),
setObjectName(QString::number(networkid.toInt()));
}
-// I think this is unnecessary since IrcUsers have us as their daddy :)
-
Network::~Network() {
emit aboutToBeDestroyed();
-// QHashIterator<QString, IrcUser *> ircuser(_ircUsers);
-// while (ircuser.hasNext()) {
-// ircuser.next();
-// delete ircuser.value();
-// }
-// qDebug() << "Destroying net" << networkName() << networkId();
-}
-
-
-NetworkId Network::networkId() const {
- return _networkId;
-}
-
-SignalProxy *Network::proxy() const {
- return _proxy;
-}
-
-void Network::setProxy(SignalProxy *proxy) {
- _proxy = proxy;
- //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::isMe(IrcUser *ircuser) const {
- return (ircuser->nick().toLower() == myNick().toLower());
}
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.codecForServer = codecForServer();
info.codecForEncoding = codecForEncoding();
info.codecForDecoding = codecForDecoding();
info.serverList = serverList();
info.useAutoReconnect = useAutoReconnect();
info.autoReconnectInterval = autoReconnectInterval();
info.autoReconnectRetries = autoReconnectRetries();
+ info.unlimitedReconnectRetries = unlimitedReconnectRetries();
info.rejoinChannels = rejoinChannels();
return info;
}
return QString();
}
-QString Network::prefixToMode(const QCharRef &prefix) {
- return prefixToMode(QString(prefix));
-}
-
QString Network::modeToPrefix(const QString &mode) {
if(prefixModes().contains(mode))
return QString(prefixes()[prefixModes().indexOf(mode)]);
return QString();
}
-QString Network::modeToPrefix(const QCharRef &mode) {
- return modeToPrefix(QString(mode));
-}
-
-QString Network::networkName() const {
- return _networkName;
-}
-
-QString Network::currentServer() const {
- return _currentServer;
-}
-
-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
return nicks;
}
-QStringList Network::channels() const {
- return _ircChannels.keys();
-}
-
-QVariantList Network::serverList() const {
- return _serverList;
-}
-
-bool Network::useRandomServer() const {
- return _useRandomServer;
-}
-
-QStringList Network::perform() const {
- return _perform;
-}
-
-bool Network::useAutoIdentify() const {
- return _useAutoIdentify;
-}
-
-QString Network::autoIdentifyService() const {
- return _autoIdentifyService;
-}
-
-QString Network::autoIdentifyPassword() const {
- return _autoIdentifyPassword;
-}
-
-bool Network::useAutoReconnect() const {
- return _useAutoReconnect;
-}
-
-quint32 Network::autoReconnectInterval() const {
- return _autoReconnectInterval;
-}
-
-quint16 Network::autoReconnectRetries() const {
- return _autoReconnectRetries;
-}
-
-bool Network::unlimitedReconnectRetries() const {
- return _unlimitedReconnectRetries;
-}
-
-bool Network::rejoinChannels() const {
- return _rejoinChannels;
-}
-
QString Network::prefixes() {
if(_prefixes.isNull())
determinePrefixes();
return _prefixModes;
}
-bool Network::supports(const QString ¶m) const {
- return _supports.contains(param);
+// example Unreal IRCD: CHANMODES=beI,kfL,lj,psmntirRcOAQKVCuzNSMTG
+Network::ChannelModeType Network::channelModeType(const QString &mode) {
+ if(mode.isEmpty())
+ return NOT_A_CHANMODE;
+
+ QString chanmodes = support("CHANMODES");
+ if(chanmodes.isEmpty())
+ return NOT_A_CHANMODE;
+
+ ChannelModeType modeType = A_CHANMODE;
+ for(int i = 0; i < chanmodes.count(); i++) {
+ if(chanmodes[i] == mode[0])
+ break;
+ else if(chanmodes[i] == ',')
+ modeType = (ChannelModeType)(modeType << 1);
+ }
+ if(modeType > D_CHANMODE) {
+ qWarning() << "Network" << networkId() << "supplied invalid CHANMODES:" << chanmodes;
+ modeType = NOT_A_CHANMODE;
+ }
+ return modeType;
}
QString Network::support(const QString ¶m) const {
QString nick(nickFromMask(hostmask).toLower());
if(!_ircUsers.contains(nick)) {
IrcUser *ircuser = new IrcUser(hostmask, this);
- // mark IrcUser as already initialized to keep the SignalProxy from requesting initData
- //if(isInitialized())
- // ircuser->setInitialized();
+
if(proxy())
proxy()->synchronize(ircuser);
else
connect(ircuser, SIGNAL(nickSet(QString)), this, SLOT(ircUserNickChanged(QString)));
connect(ircuser, SIGNAL(initDone()), this, SLOT(ircUserInitDone()));
+ connect(ircuser, SIGNAL(destroyed()), this, SLOT(ircUserDestroyed()));
_ircUsers[nick] = ircuser;
emit ircUserAdded(hostmask);
emit ircUserAdded(ircuser);
return _ircUsers[nick];
}
-IrcUser *Network::newIrcUser(const QByteArray &hostmask) {
- return newIrcUser(decodeString(hostmask));
+void Network::ircUserDestroyed() {
+ IrcUser *ircUser = static_cast<IrcUser *>(sender());
+ if(!ircUser)
+ return;
+
+ QHash<QString, IrcUser *>::iterator ircUserIter = _ircUsers.begin();
+ while(ircUserIter != _ircUsers.end()) {
+ if(ircUser == *ircUserIter) {
+ ircUserIter = _ircUsers.erase(ircUserIter);
+ break;
+ }
+ ircUserIter++;
+ }
}
void Network::removeIrcUser(IrcUser *ircuser) {
ircuser->deleteLater();
}
+void Network::removeIrcUser(const QString &nick) {
+ IrcUser *ircuser;
+ if((ircuser = ircUser(nick)) != 0)
+ removeIrcUser(ircuser);
+}
+
void Network::removeChansAndUsers() {
QList<IrcUser *> users = ircUsers();
foreach(IrcUser *user, users) {
}
}
-void Network::removeIrcUser(const QString &nick) {
- IrcUser *ircuser;
- if((ircuser = ircUser(nick)) != 0)
- removeIrcUser(ircuser);
-}
-
IrcUser *Network::ircUser(QString nickname) const {
nickname = nickname.toLower();
if(_ircUsers.contains(nickname))
return 0;
}
-IrcUser *Network::ircUser(const QByteArray &nickname) const {
- return ircUser(decodeString(nickname));
-}
-
-QList<IrcUser *> 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(isInitialized())
- // channel->setInitialized();
if(proxy())
proxy()->synchronize(channel);
return _ircChannels[channelname.toLower()];
}
-IrcChannel *Network::newIrcChannel(const QByteArray &channelname) {
- return newIrcChannel(decodeString(channelname));
-}
-
IrcChannel *Network::ircChannel(QString channelname) const {
channelname = channelname.toLower();
if(_ircChannels.contains(channelname))
return 0;
}
-IrcChannel *Network::ircChannel(const QByteArray &channelname) const {
- return ircChannel(decodeString(channelname));
-}
-
-
-QList<IrcChannel *> Network::ircChannels() const {
- return _ircChannels.values();
-}
-
-quint32 Network::ircChannelCount() const {
- return _ircChannels.count();
-}
-
QByteArray Network::defaultCodecForServer() {
- if(_defaultCodecForServer) return _defaultCodecForServer->name();
+ if(_defaultCodecForServer)
+ return _defaultCodecForServer->name();
return QByteArray();
}
}
QByteArray Network::defaultCodecForEncoding() {
- if(_defaultCodecForEncoding) return _defaultCodecForEncoding->name();
+ if(_defaultCodecForEncoding)
+ return _defaultCodecForEncoding->name();
return QByteArray();
}
}
QByteArray Network::defaultCodecForDecoding() {
- if(_defaultCodecForDecoding) return _defaultCodecForDecoding->name();
+ if(_defaultCodecForDecoding)
+ return _defaultCodecForDecoding->name();
return QByteArray();
}
}
QByteArray Network::codecForServer() const {
- if(_codecForServer) return _codecForServer->name();
+ if(_codecForServer)
+ return _codecForServer->name();
return QByteArray();
}
}
QByteArray Network::codecForEncoding() const {
- if(_codecForEncoding) return _codecForEncoding->name();
+ if(_codecForEncoding)
+ return _codecForEncoding->name();
return QByteArray();
}
}
QByteArray Network::codecForDecoding() const {
- if(_codecForDecoding) return _codecForDecoding->name();
+ if(_codecForDecoding)
+ return _codecForDecoding->name();
else return QByteArray();
}
// FIXME use server encoding if appropriate
QString Network::decodeString(const QByteArray &text) const {
- if(_codecForDecoding) return ::decodeString(text, _codecForDecoding);
+ if(_codecForDecoding)
+ return ::decodeString(text, _codecForDecoding);
else return ::decodeString(text, _defaultCodecForDecoding);
}
-QByteArray Network::encodeString(const QString string) const {
+QByteArray Network::encodeString(const QString &string) const {
if(_codecForEncoding) {
return _codecForEncoding->fromUnicode(string);
}
return string.toAscii();
}
+QString Network::decodeServerString(const QByteArray &text) const {
+ if(_codecForServer)
+ return ::decodeString(text, _codecForServer);
+ else
+ return ::decodeString(text, _defaultCodecForServer);
+}
+
+QByteArray Network::encodeServerString(const QString &string) const {
+ if(_codecForServer) {
+ return _codecForServer->fromUnicode(string);
+ }
+ if(_defaultCodecForServer) {
+ return _defaultCodecForServer->fromUnicode(string);
+ }
+ return string.toAscii();
+}
+
// ====================
// Public Slots:
// ====================
}
void Network::setConnected(bool connected) {
+ if(_connected == connected)
+ return;
+
_connected = connected;
if(!connected) {
- removeChansAndUsers();
+ setMyNick(QString());
setCurrentServer(QString());
+ removeChansAndUsers();
}
emit connectedSet(connected);
}
void Network::setMyNick(const QString &nickname) {
_myNick = nickname;
+ if(!_myNick.isEmpty() && !ircUser(myNick())) {
+ newIrcUser(myNick());
+ }
emit myNickSet(nickname);
}
return supports;
}
-QVariantList Network::initServerList() const {
- return serverList();
-}
-
QStringList Network::initIrcUsers() const {
QStringList hostmasks;
foreach(IrcUser *ircuser, ircUsers()) {
}
QStringList Network::initIrcChannels() const {
- return _ircChannels.keys();
+ QStringList channels;
+ QHash<QString, IrcChannel *>::const_iterator iter = _ircChannels.constBegin();
+ while(iter != _ircChannels.constEnd()) {
+ channels << iter.value()->name();
+ iter++;
+ }
+ return channels;
}
void Network::initSetSupports(const QVariantMap &supports) {
}
}
-void Network::initSetServerList(const QVariantList & serverList) {
- setServerList(serverList);
-}
-
void Network::initSetIrcUsers(const QStringList &hostmasks) {
if(!_ircUsers.empty())
return;
}
}
-void Network::initSetChannels(const QStringList &channels) {
+void Network::initSetIrcChannels(const QStringList &channels) {
if(!_ircChannels.empty())
return;
foreach(QString channel, channels)
emit ircChannelRemoved(channel);
}
-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);
}
return in;
}
-
-
-
-
-
-
-
-
-
+QDebug operator<<(QDebug dbg, const NetworkInfo &i) {
+ dbg.nospace() << "(id = " << i.networkId << " name = " << i.networkName << " identity = " << i.identity
+ << " codecForServer = " << i.codecForServer << " codecForEncoding = " << i.codecForEncoding << " codecForDecoding = " << i.codecForDecoding
+ << " serverList = " << i.serverList << " useRandomServer = " << i.useRandomServer << " perform = " << i.perform
+ << " useAutoIdentify = " << i.useAutoIdentify << " autoIdentifyService = " << i.autoIdentifyService << " autoIdentifyPassword = " << i.autoIdentifyPassword
+ << " useAutoReconnect = " << i.useAutoReconnect << " autoReconnectInterval = " << i.autoReconnectInterval
+ << " autoReconnectRetries = " << i.autoReconnectRetries << " unlimitedReconnectRetries = " << i.unlimitedReconnectRetries
+ << " rejoinChannels = " << i.rejoinChannels << ")";
+ return dbg.space();
+}