From c6fc5ae878a4f92b658c3da2861bcc7da9c2594f Mon Sep 17 00:00:00 2001 From: Marcus Eggenberger Date: Tue, 2 Dec 2008 01:06:40 +0100 Subject: [PATCH] Fixing BR #315: Nicks missing from nick lists - also fixes BR #310: Nicklist freaks out when cycling - breaks protocol --- src/client/clientsyncer.cpp | 2 - src/client/networkmodel.cpp | 18 ++---- src/client/networkmodel.h | 6 +- src/common/ircchannel.cpp | 21 +++++-- src/common/ircchannel.h | 7 ++- src/common/ircuser.cpp | 19 ++++-- src/common/ircuser.h | 6 +- src/common/network.cpp | 105 ++++++++-------------------------- src/common/network.h | 19 +----- src/core/ircserverhandler.cpp | 2 +- version.inc | 6 +- 11 files changed, 80 insertions(+), 131 deletions(-) diff --git a/src/client/clientsyncer.cpp b/src/client/clientsyncer.cpp index 139f44b3..a8e08ef2 100644 --- a/src/client/clientsyncer.cpp +++ b/src/client/clientsyncer.cpp @@ -26,8 +26,6 @@ #include "client.h" #include "identity.h" -#include "ircuser.h" -#include "ircchannel.h" #include "network.h" #include "networkmodel.h" #include "quassel.h" diff --git a/src/client/networkmodel.cpp b/src/client/networkmodel.cpp index f58dc971..c75dd576 100644 --- a/src/client/networkmodel.cpp +++ b/src/client/networkmodel.cpp @@ -363,12 +363,12 @@ QString QueryBufferItem::toolTip(int column) const { void QueryBufferItem::attachIrcUser(IrcUser *ircUser) { _ircUser = ircUser; - connect(_ircUser, SIGNAL(destroyed()), this, SLOT(ircUserDestroyed())); + connect(_ircUser, SIGNAL(quited()), this, SLOT(ircUserQuited())); connect(_ircUser, SIGNAL(awaySet(bool)), this, SIGNAL(dataChanged())); emit dataChanged(); } -void QueryBufferItem::ircUserDestroyed() { +void QueryBufferItem::ircUserQuited() { _ircUser = 0; emit dataChanged(); } @@ -442,8 +442,8 @@ void ChannelBufferItem::attachIrcChannel(IrcChannel *ircChannel) { this, SLOT(join(QList))); connect(ircChannel, SIGNAL(ircUserParted(IrcUser *)), this, SLOT(part(IrcUser *))); - connect(ircChannel, SIGNAL(destroyed()), - this, SLOT(ircChannelDestroyed())); + connect(ircChannel, SIGNAL(parted()), + this, SLOT(ircChannelParted())); connect(ircChannel, SIGNAL(ircUserModesSet(IrcUser *, QString)), this, SLOT(userModeChanged(IrcUser *))); connect(ircChannel, SIGNAL(ircUserModeAdded(IrcUser *, QString)), @@ -457,7 +457,7 @@ void ChannelBufferItem::attachIrcChannel(IrcChannel *ircChannel) { emit dataChanged(); } -void ChannelBufferItem::ircChannelDestroyed() { +void ChannelBufferItem::ircChannelParted() { Q_CHECK_PTR(_ircChannel); disconnect(_ircChannel, 0, this, 0); _ircChannel = 0; @@ -672,7 +672,7 @@ IrcUserItem::IrcUserItem(IrcUser *ircUser, AbstractTreeItem *parent) _ircUser(ircUser) { setObjectName(ircUser->nick()); - connect(ircUser, SIGNAL(destroyed()), this, SLOT(ircUserDestroyed())); + connect(ircUser, SIGNAL(quited()), this, SLOT(ircUserQuited())); connect(ircUser, SIGNAL(nickSet(QString)), this, SIGNAL(dataChanged())); connect(ircUser, SIGNAL(awaySet(bool)), this, SIGNAL(dataChanged())); } @@ -729,12 +729,6 @@ QString IrcUserItem::toolTip(int column) const { return QString("

%1

").arg(toolTip.join("
")); } -// void IrcUserItem::ircUserDestroyed() { -// parent()->removeChild(this); -// if(parent()->childCount() == 0) -// parent()->parent()->removeChild(parent()); -// } - /***************************************** * NetworkModel *****************************************/ diff --git a/src/client/networkmodel.h b/src/client/networkmodel.h index 018d6e7f..807403e5 100644 --- a/src/client/networkmodel.h +++ b/src/client/networkmodel.h @@ -158,7 +158,7 @@ public: public slots: void attachIrcUser(IrcUser *ircUser); - void ircUserDestroyed(); + void ircUserQuited(); private: IrcUser *_ircUser; @@ -195,7 +195,7 @@ public slots: void userModeChanged(IrcUser *ircUser); private slots: - void ircChannelDestroyed(); + void ircChannelParted(); private: IrcChannel *_ircChannel; @@ -246,7 +246,7 @@ public: virtual QString toolTip(int column) const; private slots: - inline void ircUserDestroyed() { parent()->removeChild(this); } + inline void ircUserQuited() { parent()->removeChild(this); } private: QPointer _ircUser; diff --git a/src/common/ircchannel.cpp b/src/common/ircchannel.cpp index fd983608..04ff1435 100644 --- a/src/common/ircchannel.cpp +++ b/src/common/ircchannel.cpp @@ -43,6 +43,9 @@ IrcChannel::IrcChannel(const QString &channelname, Network *network) setObjectName(QString::number(network->networkId().toInt()) + "/" + channelname); } +IrcChannel::~IrcChannel() { +} + // ==================== // PUBLIC: // ==================== @@ -144,9 +147,8 @@ void IrcChannel::joinIrcUsers(const QList &users, const QStringList & _userModes[ircuser] = modes[i]; ircuser->joinChannel(this); - //qDebug() << "JOIN" << name() << ircuser->nick() << ircUsers().count(); connect(ircuser, SIGNAL(nickSet(QString)), this, SLOT(ircUserNickSet(QString))); - connect(ircuser, SIGNAL(destroyed()), this, SLOT(ircUserDestroyed())); + // connect(ircuser, SIGNAL(destroyed()), this, SLOT(ircUserDestroyed())); // if you wonder why there is no counterpart to ircUserJoined: // the joines are propagted by the ircuser. the signal ircUserJoined is only for convenience @@ -185,13 +187,22 @@ void IrcChannel::part(IrcUser *ircuser) { if(isKnownUser(ircuser)) { _userModes.remove(ircuser); ircuser->partChannel(this); - //qDebug() << "PART" << name() << ircuser->nick() << ircUsers().count(); // if you wonder why there is no counterpart to ircUserParted: // the joines are propagted by the ircuser. the signal ircUserParted is only for convenience disconnect(ircuser, 0, this, 0); emit ircUserParted(ircuser); - if(network->isMe(ircuser)) - deleteLater(); + + if(network->isMe(ircuser)) { + // we left -> clean up the channel and destroy it + QList users = _userModes.keys(); + _userModes.clear(); + foreach(IrcUser *user, users) { + disconnect(user, 0, this, 0); + user->partChannel(this); + } + emit parted(); + network->removeIrcChannel(this); + } } } diff --git a/src/common/ircchannel.h b/src/common/ircchannel.h index 24347a8e..5bcaa79e 100644 --- a/src/common/ircchannel.h +++ b/src/common/ircchannel.h @@ -18,8 +18,8 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ -#ifndef _IRCCHANNEL_H_ -#define _IRCCHANNEL_H_ +#ifndef IRCCHANNEL_H +#define IRCCHANNEL_H #include #include @@ -41,6 +41,7 @@ class IrcChannel : public SyncableObject { public: IrcChannel(const QString &channelname, Network *network); + ~IrcChannel(); bool isKnownUser(IrcUser *ircuser) const; bool isValidChannelUserMode(const QString &mode) const; @@ -118,6 +119,8 @@ signals: void ircUserModeRemoved(IrcUser *ircuser, QString mode); void ircUserModesSet(IrcUser *ircuser, QString modes); + void parted(); // convenience signal emitted before channels destruction + private slots: void ircUserDestroyed(); void ircUserNickSet(QString nick); diff --git a/src/common/ircuser.cpp b/src/common/ircuser.cpp index 22df0c94..ab773d9e 100644 --- a/src/common/ircuser.cpp +++ b/src/common/ircuser.cpp @@ -218,7 +218,7 @@ void IrcUser::joinChannel(IrcChannel *channel) { if(!_channels.contains(channel)) { _channels.insert(channel); channel->joinIrcUsers(this); - connect(channel, SIGNAL(destroyed()), this, SLOT(channelDestroyed())); + // connect(channel, SIGNAL(destroyed()), this, SLOT(channelDestroyed())); } } @@ -233,7 +233,7 @@ void IrcUser::partChannel(IrcChannel *channel) { channel->part(this); emit channelParted(channel->name()); if(_channels.isEmpty() && !network()->isMe(this)) - deleteLater(); + quit(); } } @@ -246,13 +246,24 @@ void IrcUser::partChannel(const QString &channelname) { } } +void IrcUser::quit() { + QList channels = _channels.toList(); + _channels.clear(); + foreach(IrcChannel *channel, channels) { + disconnect(channel, 0, this, 0); + channel->part(this); + } + network()->removeIrcUser(this); + emit quited(); +} + void IrcUser::channelDestroyed() { // private slot! IrcChannel *channel = static_cast(sender()); if(_channels.contains(channel)) { _channels.remove(channel); - if(_channels.isEmpty()) - deleteLater(); + if(_channels.isEmpty() && !network()->isMe(this)) + quit(); } } diff --git a/src/common/ircuser.h b/src/common/ircuser.h index 00df169c..4a9a5be5 100644 --- a/src/common/ircuser.h +++ b/src/common/ircuser.h @@ -18,8 +18,8 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ -#ifndef _IRCUSER_H_ -#define _IRCUSER_H_ +#ifndef IRCUSER_H +#define IRCUSER_H #include #include @@ -110,6 +110,7 @@ public slots: void joinChannel(const QString &channelname); void partChannel(IrcChannel *channel); void partChannel(const QString &channelname); + void quit(); void addUserModes(const QString &modes); void removeUserModes(const QString &modes); @@ -134,6 +135,7 @@ signals: // void channelJoined(QString channel); void channelParted(QString channel); + void quited(); void userModesAdded(QString modes); void userModesRemoved(QString modes); diff --git a/src/common/network.cpp b/src/common/network.cpp index 23ce589f..9c0f915b 100644 --- a/src/common/network.cpp +++ b/src/common/network.cpp @@ -197,34 +197,22 @@ IrcUser *Network::newIrcUser(const QString &hostmask, const QVariantMap &initDat 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(destroyed()), this, SLOT(ircUserDestroyed())); - if(!ircuser->isInitialized()) - connect(ircuser, SIGNAL(initDone()), this, SLOT(ircUserInitDone())); _ircUsers[nick] = ircuser; emit ircUserAdded(hostmask); emit ircUserAdded(ircuser); - if(ircuser->isInitialized()) - emit ircUserInitDone(ircuser); } return _ircUsers[nick]; } -void Network::ircUserDestroyed() { - IrcUser *ircUser = static_cast(sender()); - if(!ircUser) - return; - - QHash::iterator ircUserIter = _ircUsers.begin(); - while(ircUserIter != _ircUsers.end()) { - if(ircUser == *ircUserIter) { - ircUserIter = _ircUsers.erase(ircUserIter); - break; - } - ircUserIter++; - } +IrcUser *Network::ircUser(QString nickname) const { + nickname = nickname.toLower(); + if(_ircUsers.contains(nickname)) + return _ircUsers[nickname]; + else + return 0; } void Network::removeIrcUser(IrcUser *ircuser) { @@ -234,34 +222,34 @@ void Network::removeIrcUser(IrcUser *ircuser) { _ircUsers.remove(nick); disconnect(ircuser, 0, this, 0); - emit ircUserRemoved(nick); - emit ircUserRemoved(ircuser); ircuser->deleteLater(); } -void Network::removeIrcUser(const QString &nick) { - IrcUser *ircuser; - if((ircuser = ircUser(nick)) != 0) - removeIrcUser(ircuser); +void Network::removeIrcChannel(IrcChannel *channel) { + QString chanName = _ircChannels.key(channel); + if(chanName.isNull()) + return; + + _ircChannels.remove(chanName); + disconnect(channel, 0, this, 0); + channel->deleteLater(); } void Network::removeChansAndUsers() { QList users = ircUsers(); - foreach(IrcUser *user, users) { - removeIrcUser(user); - } + _ircUsers.clear(); QList channels = ircChannels(); + _ircChannels.clear(); + foreach(IrcChannel *channel, channels) { - removeIrcChannel(channel); + disconnect(channel, 0, this, 0); } -} - -IrcUser *Network::ircUser(QString nickname) const { - nickname = nickname.toLower(); - if(_ircUsers.contains(nickname)) - return _ircUsers[nickname]; - else - return 0; + foreach(IrcUser *user, users) { + disconnect(user, 0, this, 0); + user->quit(); + } + qDeleteAll(users); + qDeleteAll(channels); } IrcChannel *Network::newIrcChannel(const QString &channelname, const QVariantMap &initData) { @@ -277,16 +265,10 @@ IrcChannel *Network::newIrcChannel(const QString &channelname, const QVariantMap else qWarning() << "unable to synchronize new IrcChannel" << channelname << "forgot to call Network::setProxy(SignalProxy *)?"; - connect(channel, SIGNAL(destroyed()), this, SLOT(channelDestroyed())); - if(!channel->isInitialized()) - connect(channel, SIGNAL(initDone()), this, SLOT(ircChannelInitDone())); - _ircChannels[channelname.toLower()] = channel; emit ircChannelAdded(channelname); emit ircChannelAdded(channel); - if(channel->isInitialized()) - emit ircChannelInitDone(channel); } return _ircChannels[channelname.toLower()]; } @@ -623,45 +605,6 @@ void Network::ircUserNickChanged(QString newnick) { setMyNick(newnick); } -void Network::ircUserInitDone() { - IrcUser *ircuser = static_cast(sender()); - Q_ASSERT(ircuser); - connect(ircuser, SIGNAL(initDone()), this, SLOT(ircUserInitDone())); - emit ircUserInitDone(ircuser); -} - -void Network::ircChannelInitDone() { - IrcChannel *ircChannel = static_cast(sender()); - Q_ASSERT(ircChannel); - disconnect(ircChannel, SIGNAL(initDone()), this, SLOT(ircChannelInitDone())); - 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::emitConnectionError(const QString &errorMsg) { emit connectionError(errorMsg); } diff --git a/src/common/network.h b/src/common/network.h index 17853722..4a432d84 100644 --- a/src/common/network.h +++ b/src/common/network.h @@ -210,8 +210,6 @@ public slots: inline void addIrcUser(const QString &hostmask) { newIrcUser(hostmask); } inline void addIrcChannel(const QString &channel) { newIrcChannel(channel); } - void removeIrcUser(const QString &nick); - void removeIrcChannel(const QString &channel); //init geters QVariantMap initSupports() const; @@ -240,13 +238,9 @@ public slots: void emitConnectionError(const QString &); private slots: - void ircUserDestroyed(); - void channelDestroyed(); void removeIrcUser(IrcUser *ircuser); void removeIrcChannel(IrcChannel *ircChannel); void removeChansAndUsers(); - void ircUserInitDone(); - void ircChannelInitDone(); signals: void aboutToBeDestroyed(); @@ -284,16 +278,6 @@ signals: void ircChannelAdded(const QString &channelname); void ircChannelAdded(IrcChannel *); - void ircUserRemoved(const QString &nick); - void ircChannelRemoved(const QString &channel); - - // needed for client sync progress - void ircUserRemoved(QObject *); - void ircChannelRemoved(QObject *); - - void ircUserInitDone(IrcUser *); - void ircChannelInitDone(IrcChannel *); - void connectRequested(NetworkId id = 0) const; void disconnectRequested(NetworkId id = 0) const; void setNetworkInfoRequested(const NetworkInfo &) const; @@ -346,6 +330,9 @@ private: static QTextCodec *_defaultCodecForDecoding; bool _autoAwayActive; // when this is active handle305 and handle306 don't trigger any output + + friend class IrcUser; + friend class IrcChannel; }; //! Stores all editable information about a network (as opposed to runtime state). diff --git a/src/core/ircserverhandler.cpp b/src/core/ircserverhandler.cpp index 4d32f1dd..4f5206ad 100644 --- a/src/core/ircserverhandler.cpp +++ b/src/core/ircserverhandler.cpp @@ -438,7 +438,7 @@ void IrcServerHandler::handleQuit(const QString &prefix, const QList foreach(QString channel, ircuser->channels()) emit displayMsg(Message::Quit, BufferInfo::ChannelBuffer, channel, msg, prefix); - network()->removeIrcUser(nickFromMask(prefix)); + ircuser->quit(); } void IrcServerHandler::handleTopic(const QString &prefix, const QList ¶ms) { diff --git a/version.inc b/version.inc index d6419314..fb1f18d7 100644 --- a/version.inc +++ b/version.inc @@ -1,9 +1,9 @@ //! This is the fallback version number in case we can't autogenerate one baseVersion = "0.3.1"; -protocolVersion = 6; //< Version of the client/core protocol -coreNeedsProtocol = 6; //< Minimum protocol version the core needs -clientNeedsProtocol = 6; //< Minimum protocol version the client needs +protocolVersion = 7; //< Version of the client/core protocol +coreNeedsProtocol = 7; //< Minimum protocol version the core needs +clientNeedsProtocol = 7; //< Minimum protocol version the client needs distCommittish = $Format:%H$ distCommitDate = $Format:%at$ -- 2.20.1