diff options
Diffstat (limited to 'Swift/Controllers')
-rw-r--r-- | Swift/Controllers/Chat/ChatController.cpp | 5 | ||||
-rw-r--r-- | Swift/Controllers/Chat/ChatController.h | 4 | ||||
-rw-r--r-- | Swift/Controllers/Chat/ChatControllerBase.cpp | 4 | ||||
-rw-r--r-- | Swift/Controllers/Chat/ChatControllerBase.h | 2 | ||||
-rw-r--r-- | Swift/Controllers/Chat/ChatsManager.cpp | 56 | ||||
-rw-r--r-- | Swift/Controllers/Chat/ChatsManager.h | 4 | ||||
-rw-r--r-- | Swift/Controllers/UIInterfaces/ChatListWindow.h | 7 | ||||
-rw-r--r-- | Swift/Controllers/UIInterfaces/ChatWindow.h | 1 | ||||
-rw-r--r-- | Swift/Controllers/UnitTest/MockChatWindow.h | 1 |
9 files changed, 65 insertions, 19 deletions
diff --git a/Swift/Controllers/Chat/ChatController.cpp b/Swift/Controllers/Chat/ChatController.cpp index 9df7708..9b65c9f 100644 --- a/Swift/Controllers/Chat/ChatController.cpp +++ b/Swift/Controllers/Chat/ChatController.cpp @@ -96,4 +96,5 @@ ChatController::ChatController(const JID& self, StanzaChannel* stanzaChannel, IQ chatWindow_->onUnblockUserRequest.connect(boost::bind(&ChatController::handleUnblockUserRequest, this)); chatWindow_->onInviteToChat.connect(boost::bind(&ChatController::handleInviteToChat, this, _1)); + chatWindow_->onClosed.connect(boost::bind(&ChatController::handleWindowClosed, this)); handleBareJIDCapsChanged(toJID_); @@ -307,4 +308,8 @@ void ChatController::handleInviteToChat(const std::vector<JID>& droppedJIDs) { } +void ChatController::handleWindowClosed() { + onWindowClosed(); +} + void ChatController::handleUIEvent(boost::shared_ptr<UIEvent> event) { boost::shared_ptr<InviteToMUCUIEvent> inviteEvent = boost::dynamic_pointer_cast<InviteToMUCUIEvent>(event); diff --git a/Swift/Controllers/Chat/ChatController.h b/Swift/Controllers/Chat/ChatController.h index 8b1bb9a..2e92be7 100644 --- a/Swift/Controllers/Chat/ChatController.h +++ b/Swift/Controllers/Chat/ChatController.h @@ -80,6 +80,6 @@ namespace Swift { void handleInviteToChat(const std::vector<JID>& droppedJIDs); - void handleInviteToMUCWindowDismissed(); - void handleInviteToMUCWindowCompleted(); + + void handleWindowClosed(); void handleUIEvent(boost::shared_ptr<UIEvent> event); diff --git a/Swift/Controllers/Chat/ChatControllerBase.cpp b/Swift/Controllers/Chat/ChatControllerBase.cpp index 5363e0c..24341e6 100644 --- a/Swift/Controllers/Chat/ChatControllerBase.cpp +++ b/Swift/Controllers/Chat/ChatControllerBase.cpp @@ -198,4 +198,8 @@ void ChatControllerBase::activateChatWindow() { } +bool ChatControllerBase::hasOpenWindow() const { + return chatWindow_ && chatWindow_->isVisible(); +} + std::string ChatControllerBase::addMessage(const std::string& message, const std::string& senderName, bool senderIsSelf, const boost::shared_ptr<SecurityLabel> label, const boost::filesystem::path& avatarPath, const boost::posix_time::ptime& time, const HighlightAction& highlight) { if (boost::starts_with(message, "/me ")) { diff --git a/Swift/Controllers/Chat/ChatControllerBase.h b/Swift/Controllers/Chat/ChatControllerBase.h index cf0a4d2..a0b848b 100644 --- a/Swift/Controllers/Chat/ChatControllerBase.h +++ b/Swift/Controllers/Chat/ChatControllerBase.h @@ -53,4 +53,5 @@ namespace Swift { void showChatWindow(); void activateChatWindow(); + bool hasOpenWindow() const; virtual void setAvailableServerFeatures(boost::shared_ptr<DiscoInfo> info); void handleIncomingMessage(boost::shared_ptr<MessageEvent> message); @@ -63,4 +64,5 @@ namespace Swift { boost::signal<void (const std::string& /*activity*/)> onActivity; boost::signal<void ()> onUnreadCountChanged; + boost::signal<void ()> onWindowClosed; int getUnreadCount(); const JID& getToJID() {return toJID_;} diff --git a/Swift/Controllers/Chat/ChatsManager.cpp b/Swift/Controllers/Chat/ChatsManager.cpp index 8a077d1..3db1327 100644 --- a/Swift/Controllers/Chat/ChatsManager.cpp +++ b/Swift/Controllers/Chat/ChatsManager.cpp @@ -225,4 +225,13 @@ void ChatsManager::saveRecents() { } + class RemoveRecent { + public: + static bool ifPrivateMessage(const ChatListWindow::Chat& chat) { + return chat.isPrivateMessage; + } + }; + + recentsLimited.erase(std::remove_if(recentsLimited.begin(), recentsLimited.end(), RemoveRecent::ifPrivateMessage), recentsLimited.end()); + oa << recentsLimited; std::string serializedStr = Base64::encode(createByteArray(serializeStream.str())); @@ -311,5 +320,5 @@ void ChatsManager::loadRecents() { boost::filesystem::path path; - ChatListWindow::Chat chat(jid, nickResolver_->jidToNick(jid), activity, 0, type, path, isMUC, nick); + ChatListWindow::Chat chat(jid, nickResolver_->jidToNick(jid), activity, 0, type, path, isMUC, false, nick); chat = updateChatStatusAndAvatarHelper(chat); prependRecent(chat); @@ -369,5 +378,5 @@ void ChatsManager::handleMUCBookmarkRemoved(const MUCBookmark& bookmark) { } -ChatListWindow::Chat ChatsManager::createChatListChatItem(const JID& jid, const std::string& activity) { +ChatListWindow::Chat ChatsManager::createChatListChatItem(const JID& jid, const std::string& activity, bool privateMessage) { int unreadCount = 0; if (mucRegistry_->isMUC(jid)) { @@ -388,5 +397,5 @@ ChatListWindow::Chat ChatsManager::createChatListChatItem(const JID& jid, const if (controller->isImpromptu()) { - ChatListWindow::Chat chat = ChatListWindow::Chat(jid, jid.toString(), activity, unreadCount, type, boost::filesystem::path(), true, nick, password); + ChatListWindow::Chat chat = ChatListWindow::Chat(jid, jid.toString(), activity, unreadCount, type, boost::filesystem::path(), true, privateMessage, nick, password); typedef std::pair<std::string, JID> StringJIDPair; std::map<std::string, JID> participants = controller->getParticipantJIDs(); @@ -395,5 +404,5 @@ ChatListWindow::Chat ChatsManager::createChatListChatItem(const JID& jid, const } } - return ChatListWindow::Chat(jid, jid.toString(), activity, unreadCount, type, boost::filesystem::path(), true, nick, password); + return ChatListWindow::Chat(jid, jid.toString(), activity, unreadCount, type, boost::filesystem::path(), true, privateMessage, nick, password); } else { ChatController* controller = getChatControllerIfExists(jid, false); @@ -405,14 +414,11 @@ ChatListWindow::Chat ChatsManager::createChatListChatItem(const JID& jid, const StatusShow::Type type = presence ? presence->getShow() : StatusShow::None; boost::filesystem::path avatarPath = avatarManager_ ? avatarManager_->getAvatarPath(bareishJID) : boost::filesystem::path(); - return ChatListWindow::Chat(bareishJID, nickResolver_->jidToNick(bareishJID), activity, unreadCount, type, avatarPath, false); + return ChatListWindow::Chat(bareishJID, nickResolver_->jidToNick(bareishJID), activity, unreadCount, type, avatarPath, false, privateMessage); } } void ChatsManager::handleChatActivity(const JID& jid, const std::string& activity, bool isMUC) { - if (mucRegistry_->isMUC(jid.toBare()) && !isMUC) { - /* Don't include PMs in MUC rooms.*/ - return; - } - ChatListWindow::Chat chat = createChatListChatItem(jid, activity); + const bool privateMessage = mucRegistry_->isMUC(jid.toBare()) && !isMUC; + ChatListWindow::Chat chat = createChatListChatItem(jid, activity, privateMessage); /* FIXME: handle nick changes */ appendRecent(chat); @@ -421,4 +427,9 @@ void ChatsManager::handleChatActivity(const JID& jid, const std::string& activit } +void ChatsManager::handleChatClosed(const JID& /*jid*/) { + cleanupPrivateMessageRecents(); + chatListWindow_->setRecents(recentChats_); +} + void ChatsManager::handleUnreadCountChanged(ChatControllerBase* controller) { int unreadTotal = 0; @@ -455,4 +466,22 @@ boost::optional<ChatListWindow::Chat> ChatsManager::removeExistingChat(const Cha } +void ChatsManager::cleanupPrivateMessageRecents() { + /* if we leave a MUC and close a PM, remove it's recent chat entry */ + const std::list<ChatListWindow::Chat> chats = recentChats_; + foreach (const ChatListWindow::Chat& chat, chats) { + if (chat.isPrivateMessage) { + typedef std::map<JID, MUCController*> ControllerMap; + ControllerMap::iterator muc = mucControllers_.find(chat.jid.toBare()); + if (muc == mucControllers_.end() || !muc->second->isJoined()) { + ChatController* chatController = getChatControllerIfExists(chat.jid); + if (!chatController || !chatController->hasOpenWindow()) { + removeExistingChat(chat); + break; + } + } + } + } +} + void ChatsManager::appendRecent(const ChatListWindow::Chat& chat) { boost::optional<ChatListWindow::Chat> oldChat = removeExistingChat(chat); @@ -480,13 +509,13 @@ void ChatsManager::handleUserLeftMUC(MUCController* mucController) { if (chat.isMUC && chat.jid == (*it).first) { chat.statusType = StatusShow::None; - chatListWindow_->setRecents(recentChats_); - break; } } mucControllers_.erase(it); delete mucController; - return; + break; } } + cleanupPrivateMessageRecents(); + chatListWindow_->setRecents(recentChats_); } @@ -702,4 +731,5 @@ ChatController* ChatsManager::createNewChatController(const JID& contact) { controller->setAvailableServerFeatures(serverDiscoInfo_); controller->onActivity.connect(boost::bind(&ChatsManager::handleChatActivity, this, contact, _1, false)); + controller->onWindowClosed.connect(boost::bind(&ChatsManager::handleChatClosed, this, contact)); controller->onUnreadCountChanged.connect(boost::bind(&ChatsManager::handleUnreadCountChanged, this, controller)); controller->onConvertToMUC.connect(boost::bind(&ChatsManager::handleTransformChatToMUC, this, controller, _1, _2, _3)); diff --git a/Swift/Controllers/Chat/ChatsManager.h b/Swift/Controllers/Chat/ChatsManager.h index 41435d9..179f536 100644 --- a/Swift/Controllers/Chat/ChatsManager.h +++ b/Swift/Controllers/Chat/ChatsManager.h @@ -90,5 +90,5 @@ namespace Swift { private: - ChatListWindow::Chat createChatListChatItem(const JID& jid, const std::string& activity); + ChatListWindow::Chat createChatListChatItem(const JID& jid, const std::string& activity, bool privateMessage); void handleChatRequest(const std::string& contact); void finalizeImpromptuJoin(MUC::ref muc, const std::vector<JID>& jidsToInvite, const std::string& reason, const boost::optional<JID>& reuseChatJID = boost::optional<JID>()); @@ -104,8 +104,10 @@ namespace Swift { void handleBookmarksReady(); void handleChatActivity(const JID& jid, const std::string& activity, bool isMUC); + void handleChatClosed(const JID& jid); void handleNewFileTransferController(FileTransferController*); void handleWhiteboardSessionRequest(const JID& contact, bool senderIsSelf); void handleWhiteboardStateChange(const JID& contact, const ChatWindow::WhiteboardSessionState state); boost::optional<ChatListWindow::Chat> removeExistingChat(const ChatListWindow::Chat& chat); + void cleanupPrivateMessageRecents(); void appendRecent(const ChatListWindow::Chat& chat); void prependRecent(const ChatListWindow::Chat& chat); diff --git a/Swift/Controllers/UIInterfaces/ChatListWindow.h b/Swift/Controllers/UIInterfaces/ChatListWindow.h index 38d8c3e..f7eb151 100644 --- a/Swift/Controllers/UIInterfaces/ChatListWindow.h +++ b/Swift/Controllers/UIInterfaces/ChatListWindow.h @@ -22,7 +22,7 @@ namespace Swift { class Chat { public: - Chat() : statusType(StatusShow::None), isMUC(false), unreadCount(0) {} - Chat(const JID& jid, const std::string& chatName, const std::string& activity, int unreadCount, StatusShow::Type statusType, const boost::filesystem::path& avatarPath, bool isMUC, const std::string& nick = "", const boost::optional<std::string> password = boost::optional<std::string>()) - : jid(jid), chatName(chatName), activity(activity), statusType(statusType), isMUC(isMUC), nick(nick), password(password), unreadCount(unreadCount), avatarPath(avatarPath) {} + Chat() : statusType(StatusShow::None), isMUC(false), unreadCount(0), isPrivateMessage(false) {} + Chat(const JID& jid, const std::string& chatName, const std::string& activity, int unreadCount, StatusShow::Type statusType, const boost::filesystem::path& avatarPath, bool isMUC, bool isPrivateMessage = false, const std::string& nick = "", const boost::optional<std::string> password = boost::optional<std::string>()) + : jid(jid), chatName(chatName), activity(activity), statusType(statusType), isMUC(isMUC), nick(nick), password(password), unreadCount(unreadCount), avatarPath(avatarPath), isPrivateMessage(isPrivateMessage) {} /** Assume that nicks and other transient features aren't important for equality */ bool operator==(const Chat& other) const { @@ -78,4 +78,5 @@ namespace Swift { boost::filesystem::path avatarPath; std::map<std::string, JID> impromptuJIDs; + bool isPrivateMessage; }; virtual ~ChatListWindow(); diff --git a/Swift/Controllers/UIInterfaces/ChatWindow.h b/Swift/Controllers/UIInterfaces/ChatWindow.h index bf4744b..81d26c8 100644 --- a/Swift/Controllers/UIInterfaces/ChatWindow.h +++ b/Swift/Controllers/UIInterfaces/ChatWindow.h @@ -131,4 +131,5 @@ namespace Swift { virtual void setName(const std::string& name) = 0; virtual void show() = 0; + virtual bool isVisible() const = 0; virtual void activate() = 0; virtual void setAvailableSecurityLabels(const std::vector<SecurityLabelsCatalog::Item>& labels) = 0; diff --git a/Swift/Controllers/UnitTest/MockChatWindow.h b/Swift/Controllers/UnitTest/MockChatWindow.h index 823ea3a..5e6606b 100644 --- a/Swift/Controllers/UnitTest/MockChatWindow.h +++ b/Swift/Controllers/UnitTest/MockChatWindow.h @@ -42,4 +42,5 @@ namespace Swift { virtual void setName(const std::string& name) {name_ = name;} virtual void show() {} + virtual bool isVisible() const { return true; } virtual void activate() {} virtual void setAvailableSecurityLabels(const std::vector<SecurityLabelsCatalog::Item>& labels) {labels_ = labels;} |