return _ircChannels.keys();
}
-QStringList Network::initPersistentChannels() const {
- QStringList list;
- foreach(QString chan, _persistentChannels.keys()) {
- list << QString("%1/%2").arg(chan).arg(_persistentChannels.value(chan));
- }
- return list;
-}
-
void Network::initSetSupports(const QVariantMap &supports) {
QMapIterator<QString, QVariant> iter(supports);
while(iter.hasNext()) {
newIrcChannel(channel);
}
-void Network::initSetPersistentChannels(const QStringList &channels) {
- foreach(QString chan, channels) {
- QStringList l = chan.split("/");
- _persistentChannels[l[0]] = l[1];
- }
-}
-
-void Network::addPersistentChannel(const QString &channel, const QString &key) {
- _persistentChannels[channel.toLower()] = key;
- emit persistentChannelAdded(channel, key);
-}
-
-void Network::removePersistentChannel(const QString &channel) {
- _persistentChannels.remove(channel.toLower());
- emit persistentChannelRemoved(channel);
-}
-
-void Network::setPersistentChannelKey(const QString &channel, const QString &key) {
- _persistentChannels[channel.toLower()] = key;
- emit persistentChannelKeySet(channel, key);
-}
-
IrcUser *Network::updateNickFromMask(const QString &mask) {
QString nick(nickFromMask(mask).toLower());
IrcUser *ircuser;
QList<IrcChannel *> ircChannels() const;
quint32 ircChannelCount() const;
- inline QHash<QString, QString> persistentChannels() const { return _persistentChannels; }
-
QByteArray codecForServer() const;
QByteArray codecForEncoding() const;
QByteArray codecForDecoding() const;
void removeIrcUser(const QString &nick);
void removeIrcChannel(const QString &channel);
- void addPersistentChannel(const QString &channel, const QString &key = QString());
- void removePersistentChannel(const QString &channel);
- void setPersistentChannelKey(const QString &channel, const QString &key);
-
//init geters
QVariantMap initSupports() const;
QVariantList initServerList() const;
QStringList initIrcUsers() const;
QStringList initIrcChannels() const;
- QStringList initPersistentChannels() const;
//init seters
void initSetSupports(const QVariantMap &supports);
void initSetServerList(const QVariantList &serverList);
void initSetIrcUsers(const QStringList &hostmasks);
void initSetIrcChannels(const QStringList &channels);
- void initSetPersistentChannels(const QStringList &channels);
IrcUser *updateNickFromMask(const QString &mask);
void ircUserRemoved(const QString &nick);
void ircChannelRemoved(const QString &channel);
- void persistentChannelAdded(const QString &channel, const QString &key);
- void persistentChannelRemoved(const QString &channel);
- void persistentChannelKeySet(const QString &channel, const QString &key);
-
// needed for client sync progress
void ircUserRemoved(QObject *);
void ircChannelRemoved(QObject *);
QHash<QString, IrcUser *> _ircUsers; // stores all known nicks for the server
QHash<QString, IrcChannel *> _ircChannels; // stores all known channels
QHash<QString, QString> _supports; // stores results from RPL_ISUPPORT
- QHash<QString, QString> _persistentChannels; // stores persistent channels and their passwords, if any
QVariantList _serverList;
bool _useRandomServer;
createIdentity(i);
}
-
- // migration to pure DB storage
- QList<NetworkId> netIds = s.networkIds();
- if(!netIds.isEmpty()) {
- qDebug() << "Migrating Networksettings to DB Storage for User:" << user();
- foreach(NetworkId id, netIds) {
- NetworkInfo info = s.networkInfo(id);
-
- // default new options
- info.useRandomServer = false;
- info.useAutoReconnect = true;
- info.autoReconnectInterval = 60;
- info.autoReconnectRetries = 20;
- info.unlimitedReconnectRetries = false;
- info.useAutoIdentify = false;
- info.autoIdentifyService = "NickServ";
- info.rejoinChannels = true;
-
- Core::updateNetwork(user(), info);
- s.removeNetworkInfo(id);
- }
- }
-
foreach(NetworkInfo info, Core::networks(user())) {
createNetwork(info);
}
}
void CoreSession::saveSessionState() const {
- QVariantMap res;
- QVariantList conn;
- foreach(NetworkConnection *nc, _connections.values()) {
- QHash<QString, QString> persistentChans = nc->network()->persistentChannels();
- QStringList list;
- foreach(QString chan, persistentChans.keys()) list << QString("%1/%2").arg(chan).arg(persistentChans.value(chan));
- QVariantMap m;
- m["NetworkId"] = QVariant::fromValue<NetworkId>(nc->networkId());
- m["PersistentChannels"] = list;
- conn << m;
- }
- res["CoreBuild"] = Global::quasselBuild;
- res["ConnectedNetworks"] = conn;
- CoreUserSettings s(user());
- s.setSessionState(res);
+
}
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>();
- // TODO remove migration code some time
- QStringList list = v.toMap()["PersistentChannels"].toStringList();
- if(!list.count()) {
- // migrate older state
- QStringList old = v.toMap()["State"].toStringList();
- foreach(QString chan, old) list << QString("%1/").arg(chan);
- }
- foreach(QString chan, list) {
- QStringList l = chan.split("/");
- network(id)->addPersistentChannel(l[0], l[1]);
- }
- //qDebug() << "User" << user() << "connecting to" << network(id)->networkName();
+ // FIXME db support
+ //QList<NetworkId> nets = Core::connectedNetworks(user());
+ QList<NetworkId> nets;
+ foreach(NetworkId id, nets) {
connectToNetwork(id);
}
}
if(uid == user()) emit bufferInfoUpdated(bufinfo);
}
-// FIXME remove
-/*
-void CoreSession::connectToNetwork(QString netname, const QVariant &previousState) {
- Network *net = 0;
- foreach(Network *n, _networks.values()) {
- if(n->networkName() == netname) {
- net = n; break;
- }
- }
- if(!net) {
- qWarning() << "Connect to unknown network requested, ignoring!";
- return;
- }
- connectToNetwork(net->networkId(), previousState);
-}
-*/
-
void CoreSession::connectToNetwork(NetworkId id) {
Network *net = network(id);
if(!net) {
connect(conn, SIGNAL(nickChanged(const NetworkId &, const QString &, const QString &)),
this, SLOT(renameBuffer(const NetworkId &, const QString &, const QString &)));
+ connect(conn, SIGNAL(channelJoined(NetworkId, const QString &, const QString &)),
+ this, SLOT(channelJoined(NetworkId, const QString &, const QString &)));
+ connect(conn, SIGNAL(channelParted(NetworkId, const QString &)),
+ this, SLOT(channelParted(NetworkId, const QString &)));
}
void CoreSession::disconnectFromNetwork(NetworkId id) {
// FIXME we need a sane way for creating buffers!
void CoreSession::networkConnected(NetworkId networkid) {
Core::bufferInfo(user(), networkid, BufferInfo::StatusBuffer); // create status buffer
+ //Core::setNetworkConnected(user(), networkid, true);
}
// called now only on /quit and requested disconnects, not on normal disconnects!
void CoreSession::networkDisconnected(NetworkId networkid) {
+ //Core::setNetworkConnected(user(), networkid, false);
if(_connections.contains(networkid)) _connections.take(networkid)->deleteLater();
}
+void CoreSession::channelJoined(NetworkId id, const QString &channel, const QString &key) {
+ //Core::setChannelPersistent(user(), id, channel, true);
+ //Core::setPersistentChannelKey(user(), id, channel, key);
+}
+
+void CoreSession::channelParted(NetworkId id, const QString &channel) {
+ //Core::setChannelPersistent(user(), id, channel, false);
+}
+
+QHash<QString, QString> CoreSession::persistentChannels(NetworkId id) const {
+ //return Core::persistentChannels(user(), id);
+ return QHash<QString, QString>();
+}
+
// FIXME switch to BufferId
void CoreSession::msgFromClient(BufferInfo bufinfo, QString msg) {
NetworkConnection *conn = networkConnection(bufinfo.networkId());
void addClient(QObject *socket);
-// void connectToNetwork(QString, const QVariant &previousState = QVariant());
void connectToNetwork(NetworkId);
void disconnectFromNetwork(NetworkId id);
- //void processSignal(ClientSignal, QVariant, QVariant, QVariant);
void sendBacklog(BufferInfo, QVariant, QVariant);
void msgFromClient(BufferInfo, QString message);
* emits bufferRenamed(bufferId, newName) on success.
*/
void renameBuffer(const NetworkId &networkId, const QString &newName, const QString &oldName);
-
+
+ void channelJoined(NetworkId id, const QString &channel, const QString &key = QString());
+ void channelParted(NetworkId, const QString &channel);
+ QHash<QString, QString> persistentChannels(NetworkId) const;
+
signals:
void initialized();
// IRC SERVER HANDLER
//******************************/
void IrcServerHandler::handleJoin(const QString &prefix, const QList<QByteArray> ¶ms) {
- Q_ASSERT(params.count() == 1);
+ if(params.count() < 1) return;
QString channel = serverDecode(params[0]);
IrcUser *ircuser = network()->updateNickFromMask(prefix);
emit displayMsg(Message::Join, BufferInfo::ChannelBuffer, channel, channel, prefix);
//qDebug() << "IrcServerHandler::handleJoin()" << prefix << params;
ircuser->joinChannel(channel);
- if(network()->isMe(ircuser)) network()->addPersistentChannel(channel, networkConnection()->channelKey(channel));
+ if(network()->isMe(ircuser)) networkConnection()->setChannelJoined(channel);
}
void IrcServerHandler::handleKick(const QString &prefix, const QList<QByteArray> ¶ms) {
network()->updateNickFromMask(prefix);
IrcUser *victim = network()->ircUser(params[1]);
+ if(!victim) return;
QString channel = serverDecode(params[0]);
- Q_ASSERT(victim);
victim->partChannel(channel);
msg = userDecode(ircuser->nick(), params[1]);
emit displayMsg(Message::Part, BufferInfo::ChannelBuffer, channel, msg, prefix);
- if(network()->isMe(ircuser)) network()->removePersistentChannel(channel);
+ if(network()->isMe(ircuser)) networkConnection()->setChannelParted(channel);
}
void IrcServerHandler::handlePing(const QString &prefix, const QList<QByteArray> ¶ms) {
_whoTimer.setInterval(60 * 1000);
_whoTimer.setSingleShot(false);
+ QHash<QString, QString> channels = coreSession()->persistentChannels(networkId());
+ foreach(QString chan, channels.keys()) {
+ _channelKeys[chan.toLower()] = channels[chan];
+ }
+
connect(&_autoReconnectTimer, SIGNAL(timeout()), this, SLOT(doAutoReconnect()));
connect(&_whoTimer, SIGNAL(timeout()), this, SLOT(sendWho()));
NetworkConnection::~NetworkConnection() {
if(connectionState() != Network::Disconnected && connectionState() != Network::Reconnecting)
- disconnectFromIrc();
+ disconnectFromIrc(false); // clean up, but this does not count as requested disconnect!
delete _ircServerHandler;
delete _userInputHandler;
delete _ctcpHandler;
// rejoin channels we've been in
QStringList channels, keys;
- foreach(QString chan, network()->persistentChannels().keys()) {
- QString key = network()->persistentChannels()[chan];
+ foreach(QString chan, persistentChannels()) {
+ QString key = channelKey(chan);
if(!key.isEmpty()) {
channels.prepend(chan); keys.prepend(key);
} else {
if(!joinString.isEmpty()) userInputHandler()->handleJoin(statusBuf, joinString);
}
-void NetworkConnection::disconnectFromIrc() {
- _autoReconnectTimer.stop();
- _autoReconnectCount = 0;
+void NetworkConnection::disconnectFromIrc(bool requested) {
+ if(requested) {
+ _autoReconnectTimer.stop();
+ _autoReconnectCount = 0;
+ }
displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("Disconnecting."));
if(socket.state() < QAbstractSocket::ConnectedState) {
setConnectionState(Network::Disconnected);
}
}
+void NetworkConnection::setChannelJoined(const QString &channel) {
+ emit channelJoined(networkId(), channel, _channelKeys[channel.toLower()]);
+}
+
+void NetworkConnection::setChannelParted(const QString &channel) {
+ removeChannelKey(channel);
+ emit channelParted(networkId(), channel);
+}
+
void NetworkConnection::addChannelKey(const QString &channel, const QString &key) {
- if(key.isEmpty()) removeChannelKey(channel);
- else _channelKeys[channel] = key;
+ if(key.isEmpty()) {
+ removeChannelKey(channel);
+ } else {
+ _channelKeys[channel.toLower()] = key;
+ }
}
void NetworkConnection::removeChannelKey(const QString &channel) {
- _channelKeys.remove(channel);
+ _channelKeys.remove(channel.toLower());
}
void NetworkConnection::nickChanged(const QString &newNick, const QString &oldNick) {
- emit nickChanged(_network->networkId(), newNick, oldNick);
+ emit nickChanged(networkId(), newNick, oldNick);
}
/* Exception classes for message handling */
//! Encode a string using the user-specific encoding, if set, and use the standard encoding else.
QByteArray userEncode(const QString &userNick, const QString &string) const;
- inline QString channelKey(const QString &channel) const { return _channelKeys.value(channel, QString()); }
+ inline QString channelKey(const QString &channel) const { return _channelKeys.value(channel.toLower(), QString()); }
+ inline QStringList persistentChannels() const { return _channelKeys.keys(); }
public slots:
// void setServerOptions();
void connectToIrc(bool reconnecting = false);
- void disconnectFromIrc();
+ void disconnectFromIrc(bool requested = true);
void userInput(BufferInfo bufferInfo, QString msg);
void putRawLine(QByteArray input);
void putCmd(const QString &cmd, const QVariantList ¶ms, const QByteArray &prefix = QByteArray());
+ void setChannelJoined(const QString &channel);
+ void setChannelParted(const QString &channel);
void addChannelKey(const QString &channel, const QString &key);
void removeChannelKey(const QString &channel);
//void queryRequested(QString network, QString nick);
void nickChanged(const NetworkId &networkId, const QString &newNick, const QString &oldNick); // this signal is inteded to rename query buffers in the storage backend
+ void channelJoined(NetworkId, const QString &channel, const QString &key = QString());
+ void channelParted(NetworkId, const QString &channel);
private slots:
void socketHasData();
UserInputHandler *_userInputHandler;
CtcpHandler *_ctcpHandler;
- QHash<QString, QString> _channelKeys;
+ QHash<QString, QString> _channelKeys; // stores persistent channels and their passwords, if any
+
QTimer _autoReconnectTimer;
int _autoReconnectCount;
<bool>false</bool>
</property>
<property name="text" >
- <string> in query buffer (if exists)</string>
+ <string>in query buffer (if exists)</string>
</property>
</widget>
</item>
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
- <property name="sizeHint" >
+ <property name="sizeHint" stdset="0" >
<size>
<width>457</width>
<height>51</height>
</item>
<item>
<widget class="QCheckBox" name="rejoinOnReconnect" >
+ <property name="enabled" >
+ <bool>false</bool>
+ </property>
<property name="text" >
<string>Rejoin all channels on reconnect</string>
</property>