diff options
author | Kevin Smith <git@kismith.co.uk> | 2010-07-23 14:47:48 (GMT) |
---|---|---|
committer | Kevin Smith <git@kismith.co.uk> | 2010-07-23 15:01:33 (GMT) |
commit | 4cc96003c6702168da2faa955e3c771272211e32 (patch) | |
tree | b15355b09676583b2fb468f616f3dd284c52eac9 /Swiften | |
parent | e00480d2f4326decd23ff7665fcb1af5e752c8ec (diff) | |
download | swift-4cc96003c6702168da2faa955e3c771272211e32.zip swift-4cc96003c6702168da2faa955e3c771272211e32.tar.bz2 |
Recognise when leaving a MUC (disconnect or kick).
Also cleans up some outstanding MUC issues.
Resolves: #288
Resolves: #392
Resolves: #279
Resolves: #114
Diffstat (limited to 'Swiften')
-rw-r--r-- | Swiften/MUC/MUC.cpp | 30 | ||||
-rw-r--r-- | Swiften/MUC/MUC.h | 4 | ||||
-rw-r--r-- | Swiften/Roster/GroupRosterItem.cpp | 21 | ||||
-rw-r--r-- | Swiften/Roster/GroupRosterItem.h | 1 | ||||
-rw-r--r-- | Swiften/Roster/Roster.cpp | 7 | ||||
-rw-r--r-- | Swiften/Roster/Roster.h | 1 |
6 files changed, 56 insertions, 8 deletions
diff --git a/Swiften/MUC/MUC.cpp b/Swiften/MUC/MUC.cpp index b4265b5..91ba043 100644 --- a/Swiften/MUC/MUC.cpp +++ b/Swiften/MUC/MUC.cpp @@ -44,6 +44,18 @@ void MUC::part() { presenceSender->removeDirectedPresenceReceiver(ownMUCJID); } +void MUC::handleUserLeft(LeavingType type) { + std::map<String,MUCOccupant>::iterator i = occupants.find(ownMUCJID.getResource()); + if (i != occupants.end()) { + MUCOccupant me = i->second; + occupants.erase(i); + onOccupantLeft(me, type, ""); + } + occupants.clear(); + joinComplete_ = false; + presenceSender->removeDirectedPresenceReceiver(ownMUCJID); +} + void MUC::handleIncomingPresence(boost::shared_ptr<Presence> presence) { if (!isFromMUC(presence->getFrom())) { return; @@ -79,14 +91,18 @@ void MUC::handleIncomingPresence(boost::shared_ptr<Presence> presence) { //170 is room logging to http //TODO: Nick changes if (presence->getType() == Presence::Unavailable) { - std::map<String,MUCOccupant>::iterator i = occupants.find(nick); - if (i != occupants.end()) { - //TODO: part type - onOccupantLeft(i->second, Part, ""); - occupants.erase(i); + if (presence->getFrom() == ownMUCJID) { + handleUserLeft(Part); + return; + } else { + std::map<String,MUCOccupant>::iterator i = occupants.find(nick); + if (i != occupants.end()) { + //TODO: part type + onOccupantLeft(i->second, Part, ""); + occupants.erase(i); + } } - } - else if (presence->getType() == Presence::Available) { + } else if (presence->getType() == Presence::Available) { std::map<String, MUCOccupant>::iterator it = occupants.find(nick); MUCOccupant occupant(nick, role, affiliation); if (it != occupants.end()) { diff --git a/Swiften/MUC/MUC.h b/Swiften/MUC/MUC.h index 40fc2f6..bccc26c 100644 --- a/Swiften/MUC/MUC.h +++ b/Swiften/MUC/MUC.h @@ -25,7 +25,7 @@ namespace Swift { class MUC { public: enum JoinResult { JoinSucceeded, JoinFailed }; - enum LeavingType { Part }; + enum LeavingType { Part, Disconnect }; public: MUC(StanzaChannel* stanzaChannel, PresenceSender* presenceSender, const JID &muc); @@ -36,6 +36,8 @@ namespace Swift { String getCurrentNick(); void part(); void handleIncomingMessage(boost::shared_ptr<Message> message); + /** Expose public so it can be called when e.g. user goes offline */ + void handleUserLeft(LeavingType); public: boost::signal<void (const String& /*nick*/)> onJoinComplete; diff --git a/Swiften/Roster/GroupRosterItem.cpp b/Swiften/Roster/GroupRosterItem.cpp index e5490e2..8e4be35 100644 --- a/Swiften/Roster/GroupRosterItem.cpp +++ b/Swiften/Roster/GroupRosterItem.cpp @@ -55,6 +55,27 @@ void GroupRosterItem::addChild(RosterItem* item) { } /** + * Does not emit a changed signal. + */ +void GroupRosterItem::removeAll() { + std::vector<RosterItem*>::iterator it = children_.begin(); + displayedChildren_.clear(); + while (it != children_.end()) { + ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(*it); + if (contact) { + delete contact; + } + GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(*it); + if (group) { + group->removeAll(); + delete group; + } + it++; + } + children_.clear(); +} + +/** * Returns the removed item - but only if it's the only one, otherwise * the return result is undefined. */ diff --git a/Swiften/Roster/GroupRosterItem.h b/Swiften/Roster/GroupRosterItem.h index aca2b05..096d053 100644 --- a/Swiften/Roster/GroupRosterItem.h +++ b/Swiften/Roster/GroupRosterItem.h @@ -22,6 +22,7 @@ class GroupRosterItem : public RosterItem { const std::vector<RosterItem*>& getDisplayedChildren() const; void addChild(RosterItem* item); ContactRosterItem* removeChild(const JID& jid); + void removeAll(); void setDisplayed(RosterItem* item, bool displayed); boost::signal<void ()> onChildrenChanged; static bool itemLessThan(const RosterItem* left, const RosterItem* right); diff --git a/Swiften/Roster/Roster.cpp b/Swiften/Roster/Roster.cpp index b7ed6c4..e91b843 100644 --- a/Swiften/Roster/Roster.cpp +++ b/Swiften/Roster/Roster.cpp @@ -82,6 +82,13 @@ struct JIDEqualsTo { JID jid; }; +void Roster::removeAll() { + root_->removeAll(); + itemMap_.clear(); + onChildrenChanged(root_); + onDataChanged(root_); +} + void Roster::removeContact(const JID& jid) { std::vector<ContactRosterItem*>* items = &itemMap_[fullJIDMapping_ ? jid : jid.toBare()]; items->erase(std::remove_if(items->begin(), items->end(), JIDEqualsTo(jid)), items->end()); diff --git a/Swiften/Roster/Roster.h b/Swiften/Roster/Roster.h index 346157e..d54a12e 100644 --- a/Swiften/Roster/Roster.h +++ b/Swiften/Roster/Roster.h @@ -31,6 +31,7 @@ class Roster { void addContact(const JID& jid, const JID& displayJID, const String& name, const String& group); void removeContact(const JID& jid); void removeContactFromGroup(const JID& jid, const String& group); + void removeAll(); void applyOnItems(const RosterItemOperation& operation); void applyOnAllItems(const RosterItemOperation& operation); void applyOnItem(const RosterItemOperation& operation, const JID& jid); |