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 /Swift | |
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 'Swift')
-rw-r--r-- | Swift/Controllers/Chat/ChatControllerBase.h | 2 | ||||
-rw-r--r-- | Swift/Controllers/Chat/ChatsManager.cpp | 10 | ||||
-rw-r--r-- | Swift/Controllers/Chat/MUCController.cpp | 48 | ||||
-rw-r--r-- | Swift/Controllers/Chat/MUCController.h | 2 | ||||
-rw-r--r-- | Swift/QtUI/Roster/RosterModel.cpp | 2 |
5 files changed, 49 insertions, 15 deletions
diff --git a/Swift/Controllers/Chat/ChatControllerBase.h b/Swift/Controllers/Chat/ChatControllerBase.h index f0d4b7a..61d0ab7 100644 --- a/Swift/Controllers/Chat/ChatControllerBase.h +++ b/Swift/Controllers/Chat/ChatControllerBase.h @@ -41,7 +41,7 @@ namespace Swift { void setAvailableServerFeatures(boost::shared_ptr<DiscoInfo> info); void handleIncomingMessage(boost::shared_ptr<MessageEvent> message); void addMessage(const String& message, const String& senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const String& avatarPath, const boost::posix_time::ptime& time); - void setEnabled(bool enabled); + virtual void setEnabled(bool enabled); virtual void setToJID(const JID& jid) {toJID_ = jid;}; protected: ChatControllerBase(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &toJID, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool useDelayForLatency, UIEventStream* eventStream, EventController* eventController); diff --git a/Swift/Controllers/Chat/ChatsManager.cpp b/Swift/Controllers/Chat/ChatsManager.cpp index 2ed7051..921cc6f 100644 --- a/Swift/Controllers/Chat/ChatsManager.cpp +++ b/Swift/Controllers/Chat/ChatsManager.cpp @@ -139,12 +139,18 @@ void ChatsManager::setServerDiscoInfo(boost::shared_ptr<DiscoInfo> info) { } } +/** + * This is to be called on connect/disconnect. + */ void ChatsManager::setEnabled(bool enabled) { foreach (JIDChatControllerPair controllerPair, chatControllers_) { controllerPair.second->setEnabled(enabled); } foreach (JIDMUCControllerPair controllerPair, mucControllers_) { controllerPair.second->setEnabled(enabled); + if (enabled) { + controllerPair.second->rejoin(); + } } } @@ -201,9 +207,9 @@ void ChatsManager::rebindControllerJID(const JID& from, const JID& to) { void ChatsManager::handleJoinMUCRequest(const JID &muc, const boost::optional<String>& nickMaybe) { std::map<JID, MUCController*>::iterator it = mucControllers_.find(muc); if (it != mucControllers_.end()) { - //FIXME: What's correct behaviour here? + it->second->rejoin(); } else { - String nick = nickMaybe ? nickMaybe.get() : "Swift user"; + String nick = nickMaybe ? nickMaybe.get() : jid_.getNode(); MUCController* controller = new MUCController(jid_, muc, nick, stanzaChannel_, presenceSender_, iqRouter_, chatWindowFactory_, presenceOracle_, avatarManager_, uiEventStream_, false, timerFactory_, eventController_); mucControllers_[muc] = controller; controller->setAvailableServerFeatures(serverDiscoInfo_); diff --git a/Swift/Controllers/Chat/MUCController.cpp b/Swift/Controllers/Chat/MUCController.cpp index 1e790b7..650a915 100644 --- a/Swift/Controllers/Chat/MUCController.cpp +++ b/Swift/Controllers/Chat/MUCController.cpp @@ -46,10 +46,9 @@ MUCController::MUCController ( bool useDelayForLatency, TimerFactory* timerFactory, EventController* eventController) : - ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, muc, presenceOracle, avatarManager, useDelayForLatency, uiEventStream, eventController), - muc_(new MUC(stanzaChannel, presenceSender, muc)), - nick_(nick) { - parting_ = false; + ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, muc, presenceOracle, avatarManager, useDelayForLatency, uiEventStream, eventController), muc_(new MUC(stanzaChannel, presenceSender, muc)), nick_(nick) { + parting_ = true; + joined_ = false; events_ = uiEventStream; roster_ = new Roster(true); @@ -69,11 +68,9 @@ MUCController::MUCController ( loginCheckTimer_->onTick.connect(boost::bind(&MUCController::handleJoinTimeoutTick, this)); loginCheckTimer_->start(); } - - muc_->joinAs(nick); chatWindow_->convertToMUC(); chatWindow_->addSystemMessage("Trying to join room " + toJID_.toString()); - joined_ = false; + rejoin(); if (avatarManager_ != NULL) { avatarChangedConnection_ = (avatarManager_->onAvatarChanged.connect(boost::bind(&MUCController::handleAvatarChanged, this, _1, _2))); } @@ -90,6 +87,17 @@ MUCController::~MUCController() { delete completer_; } +/** + * Join the MUC if not already in it. + */ +void MUCController::rejoin() { + if (parting_) { + joined_ = false; + parting_ = false; + muc_->joinAs(nick_); + } +} + void MUCController::handleJoinTimeoutTick() { receivedActivity(); chatWindow_->addSystemMessage("Room " + toJID_.toString() + " is not responding. This operation may never complete"); @@ -122,7 +130,7 @@ void MUCController::handleJoinFailed(boost::shared_ptr<ErrorPayload> error) { chatWindow_->addErrorMessage(errorMessage); if (!rejoinNick.isEmpty()) { nick_ = rejoinNick; - muc_->joinAs(rejoinNick); + rejoin(); } } @@ -132,6 +140,7 @@ void MUCController::handleJoinComplete(const String& nick) { String joinMessage = "You have joined room " + toJID_.toString() + " as " + nick; nick_ = nick; chatWindow_->addSystemMessage(joinMessage); + setEnabled(true); } void MUCController::handleAvatarChanged(const JID& jid, const String&) { @@ -194,7 +203,7 @@ bool MUCController::messageTargetsMe(boost::shared_ptr<Message> message) { void MUCController::preHandleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent) { boost::shared_ptr<Message> message = messageEvent->getStanza(); - if (messageTargetsMe(message)) { + if (joined_ && messageTargetsMe(message)) { eventController_->handleIncomingEvent(messageEvent); } String nick = message->getFrom().getResource(); @@ -235,15 +244,32 @@ String MUCController::roleToGroupName(MUCOccupant::Role role) { return result; } +void MUCController::setEnabled(bool enabled) { + ChatControllerBase::setEnabled(enabled); + if (!enabled) { + roster_->removeAll(); + /* handleUserLeft won't throw a part back up unless this is called + when it doesn't yet know we've left - which only happens on + disconnect, so call with disconnect here so if the signal does + bubble back up, it'll be with the right type.*/ + muc_->handleUserLeft(MUC::Disconnect); + } +} + void MUCController::handleOccupantLeft(const MUCOccupant& occupant, MUC::LeavingType, const String& reason) { completer_->removeWord(occupant.getNick()); - String partMessage = occupant.getNick() + " has left the room"; + String partMessage = (occupant.getNick() != nick_) ? occupant.getNick() + " has left the room" : "You have left the room"; if (!reason.isEmpty()) { partMessage += " (" + reason + ")"; } partMessage += "."; chatWindow_->addSystemMessage(partMessage); - roster_->removeContact(JID(toJID_.getNode(), toJID_.getDomain(), occupant.getNick())); + if (occupant.getNick() != nick_) { + roster_->removeContact(JID(toJID_.getNode(), toJID_.getDomain(), occupant.getNick())); + } else { + parting_ = true; + setEnabled(false); + } } void MUCController::handleOccupantPresenceChange(boost::shared_ptr<Presence> presence) { diff --git a/Swift/Controllers/Chat/MUCController.h b/Swift/Controllers/Chat/MUCController.h index 65ef84c..7d40ec2 100644 --- a/Swift/Controllers/Chat/MUCController.h +++ b/Swift/Controllers/Chat/MUCController.h @@ -35,6 +35,8 @@ namespace Swift { MUCController(const JID& self, const JID &muc, const String &nick, StanzaChannel* stanzaChannel, PresenceSender* presenceSender, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, PresenceOracle* presenceOracle, AvatarManager* avatarManager, UIEventStream* events, bool useDelayForLatency, TimerFactory* timerFactory, EventController* eventController); ~MUCController(); boost::signal<void ()> onUserLeft; + virtual void setEnabled(bool enabled); + void rejoin(); protected: void preSendMessageRequest(boost::shared_ptr<Message> message); diff --git a/Swift/QtUI/Roster/RosterModel.cpp b/Swift/QtUI/Roster/RosterModel.cpp index d705d34..c2d4147 100644 --- a/Swift/QtUI/Roster/RosterModel.cpp +++ b/Swift/QtUI/Roster/RosterModel.cpp @@ -177,7 +177,7 @@ QModelIndex RosterModel::index(RosterItem* item) const { /* Recursive check that it's ok to create such an item Assuming there are more contacts in a group than groups in a group, this could save a decent chunk of search time at startup.*/ - if (parent != roster_->getRoot() && !index(parent).isValid()) { + if (parent == NULL || (parent != roster_->getRoot() && !index(parent).isValid())) { return QModelIndex(); } for (size_t i = 0; i < parent->getDisplayedChildren().size(); i++) { |