summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Markmann <tm@ayena.de>2017-01-31 14:57:22 (GMT)
committerEdwin Mons <edwin.mons@isode.com>2017-02-27 14:07:13 (GMT)
commitfc8f5b31c22ed7af4f0e2473f269601a87a0438c (patch)
tree0c59a9debf72247c7409947a3a4cccb6c616dd06 /Swift/Controllers/Chat/ChatsManager.cpp
parentabd81d4a3cf08ffaa1e5265d204cdd80c8c0583b (diff)
downloadswift-fc8f5b31c22ed7af4f0e2473f269601a87a0438c.zip
swift-fc8f5b31c22ed7af4f0e2473f269601a87a0438c.tar.bz2
Redesign highlight logic and processing
The new highlight logic follows a simpler model. It supports: * highlighting of whole words in a message * highlighting messages by sender name * highlighting if the user’s name is mentioned Possible actions for these highlights are text colouring, sound playback of WAV files, and system notifications. In addition the user can decide to receive sound and system notification on general incoming direct and group messages. Redesigned the highlight configuration UI dialog for this new model. ChatMessageParser class now deals with all parsing and marking up the chat message with the matching HighlightActions. Highlighter class has been extended to deal with all sound and system notification highlights that should be emitted by a specified chat message. Moved some tests over to gtest in the process. Test-Information: Tested UI on macOS 10.12.3 with Qt 5.7.1. Manually tested that correct system notification are emitted on mentions, keyword highlights and general messages. Added new unit tests to cover new highlighting behaviour. Change-Id: I1c89e29d81022174187fb44af0d384036ec51594
Diffstat (limited to 'Swift/Controllers/Chat/ChatsManager.cpp')
-rw-r--r--Swift/Controllers/Chat/ChatsManager.cpp8
1 files changed, 4 insertions, 4 deletions
diff --git a/Swift/Controllers/Chat/ChatsManager.cpp b/Swift/Controllers/Chat/ChatsManager.cpp
index f55df1e..fc96701 100644
--- a/Swift/Controllers/Chat/ChatsManager.cpp
+++ b/Swift/Controllers/Chat/ChatsManager.cpp
@@ -1,32 +1,32 @@
/*
- * Copyright (c) 2010-2016 Isode Limited.
+ * Copyright (c) 2010-2017 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/Controllers/Chat/ChatsManager.h>
#include <memory>
#include <boost/algorithm/string.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/bind.hpp>
#include <boost/serialization/map.hpp>
#include <boost/serialization/optional.hpp>
#include <boost/serialization/split_free.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/vector.hpp>
#include <Swiften/Avatars/AvatarManager.h>
#include <Swiften/Base/Log.h>
#include <Swiften/Client/ClientBlockListManager.h>
#include <Swiften/Client/NickResolver.h>
#include <Swiften/Client/StanzaChannel.h>
#include <Swiften/Disco/DiscoServiceWalker.h>
#include <Swiften/Disco/FeatureOracle.h>
#include <Swiften/Elements/CarbonsReceived.h>
#include <Swiften/Elements/CarbonsSent.h>
#include <Swiften/Elements/ChatState.h>
#include <Swiften/Elements/DeliveryReceipt.h>
#include <Swiften/Elements/DeliveryReceiptRequest.h>
@@ -719,61 +719,61 @@ void ChatsManager::setOnline(bool enabled) {
localMUCServiceFinderWalker_->onWalkAborted.connect(boost::bind(&ChatsManager::handleLocalServiceWalkFinished, this));
localMUCServiceFinderWalker_->onWalkComplete.connect(boost::bind(&ChatsManager::handleLocalServiceWalkFinished, this));
localMUCServiceFinderWalker_->beginWalk();
}
if (chatListWindow_) {
chatListWindow_->setBookmarksEnabled(enabled);
}
}
void ChatsManager::handleChatRequest(const std::string &contact) {
ChatController* controller = getChatControllerOrFindAnother(JID(contact));
controller->activateChatWindow();
}
ChatController* ChatsManager::getChatControllerOrFindAnother(const JID &contact) {
ChatController* controller = getChatControllerIfExists(contact);
if (!controller && !mucRegistry_->isMUC(contact.toBare())) {
for (JIDChatControllerPair pair : chatControllers_) {
if (pair.first.toBare() == contact.toBare()) {
controller = pair.second;
break;
}
}
}
return controller ? controller : createNewChatController(contact);
}
ChatController* ChatsManager::createNewChatController(const JID& contact) {
assert(chatControllers_.find(contact) == chatControllers_.end());
- std::shared_ptr<ChatMessageParser> chatMessageParser = std::make_shared<ChatMessageParser>(emoticons_, highlightManager_->getRules(), false); /* a message parser that knows this is a chat (not a room/MUC) */
+ std::shared_ptr<ChatMessageParser> chatMessageParser = std::make_shared<ChatMessageParser>(emoticons_, highlightManager_->getConfiguration(), ChatMessageParser::Mode::Chat); /* a message parser that knows this is a chat (not a room/MUC) */
ChatController* controller = new ChatController(jid_, stanzaChannel_, iqRouter_, chatWindowFactory_, contact, nickResolver_, presenceOracle_, avatarManager_, mucRegistry_->isMUC(contact.toBare()), useDelayForLatency_, uiEventStream_, eventController_, timerFactory_, entityCapsProvider_, userWantsReceipts_, settings_, historyController_, mucRegistry_, highlightManager_, clientBlockListManager_, chatMessageParser, autoAcceptMUCInviteDecider_);
chatControllers_[contact] = controller;
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));
updatePresenceReceivingStateOnChatController(contact);
controller->setCanStartImpromptuChats(!localMUCServiceJID_.toString().empty());
return controller;
}
ChatController* ChatsManager::getChatControllerOrCreate(const JID &contact) {
ChatController* controller = getChatControllerIfExists(contact);
return controller ? controller : createNewChatController(contact);
}
ChatController* ChatsManager::getChatControllerIfExists(const JID &contact, bool rebindIfNeeded) {
if (chatControllers_.find(contact) == chatControllers_.end()) {
if (mucRegistry_->isMUC(contact.toBare())) {
return nullptr;
}
//Need to look for an unbound window to bind first
JID bare(contact.toBare());
if (chatControllers_.find(bare) != chatControllers_.end()) {
if (rebindIfNeeded) {
rebindControllerJID(bare, contact);
}
else {
return chatControllers_[bare];
@@ -808,62 +808,62 @@ MUC::ref ChatsManager::handleJoinMUCRequest(const JID &mucJID, const boost::opti
bookmark.setAutojoin(true);
if (nickMaybe) {
bookmark.setNick(*nickMaybe);
}
if (password) {
bookmark.setPassword(*password);
}
mucBookmarkManager_->addBookmark(bookmark);
}
std::map<JID, MUCController*>::iterator it = mucControllers_.find(mucJID);
if (it != mucControllers_.end()) {
if (stanzaChannel_->isAvailable()) {
it->second->rejoin();
}
} else {
std::string nick = (nickMaybe && !(*nickMaybe).empty()) ? nickMaybe.get() : nickResolver_->jidToNick(jid_);
muc = mucManager->createMUC(mucJID);
if (createAsReservedIfNew) {
muc->setCreateAsReservedIfNew();
}
if (isImpromptu) {
muc->setCreateAsReservedIfNew();
}
MUCController* controller = nullptr;
SingleChatWindowFactoryAdapter* chatWindowFactoryAdapter = nullptr;
if (reuseChatwindow) {
chatWindowFactoryAdapter = new SingleChatWindowFactoryAdapter(reuseChatwindow);
}
- std::shared_ptr<ChatMessageParser> chatMessageParser = std::make_shared<ChatMessageParser>(emoticons_, highlightManager_->getRules(), true); /* a message parser that knows this is a room/MUC (not a chat) */
- controller = new MUCController(jid_, muc, password, nick, stanzaChannel_, iqRouter_, reuseChatwindow ? chatWindowFactoryAdapter : chatWindowFactory_, presenceOracle_, avatarManager_, uiEventStream_, false, timerFactory_, eventController_, entityCapsProvider_, roster_, historyController_, mucRegistry_, highlightManager_, clientBlockListManager_, chatMessageParser, isImpromptu, autoAcceptMUCInviteDecider_, vcardManager_, mucBookmarkManager_);
+ std::shared_ptr<ChatMessageParser> chatMessageParser = std::make_shared<ChatMessageParser>(emoticons_, highlightManager_->getConfiguration(), ChatMessageParser::Mode::GroupChat); /* a message parser that knows this is a room/MUC (not a chat) */
+ controller = new MUCController(jid_, muc, password, nick, stanzaChannel_, iqRouter_, reuseChatwindow ? chatWindowFactoryAdapter : chatWindowFactory_, nickResolver_, presenceOracle_, avatarManager_, uiEventStream_, false, timerFactory_, eventController_, entityCapsProvider_, roster_, historyController_, mucRegistry_, highlightManager_, clientBlockListManager_, chatMessageParser, isImpromptu, autoAcceptMUCInviteDecider_, vcardManager_, mucBookmarkManager_);
if (chatWindowFactoryAdapter) {
/* The adapters are only passed to chat windows, which are deleted in their
* controllers' dtor, which are deleted in ChatManager's dtor. The adapters
* are also deleted there.*/
chatWindowFactoryAdapters_[controller] = chatWindowFactoryAdapter;
}
mucControllers_[mucJID] = controller;
controller->setAvailableServerFeatures(serverDiscoInfo_);
controller->onUserLeft.connect(boost::bind(&ChatsManager::handleUserLeftMUC, this, controller));
controller->onUserJoined.connect(boost::bind(&ChatsManager::handleChatActivity, this, mucJID.toBare(), "", true));
controller->onUserNicknameChanged.connect(boost::bind(&ChatsManager::handleUserNicknameChanged, this, controller, _1, _2));
controller->onActivity.connect(boost::bind(&ChatsManager::handleChatActivity, this, mucJID.toBare(), _1, true));
controller->onUnreadCountChanged.connect(boost::bind(&ChatsManager::handleUnreadCountChanged, this, controller));
if (!stanzaChannel_->isAvailable()) {
/* When online, the MUC is added to the registry in MUCImpl::internalJoin. This method is not
* called when Swift is offline, so we add it here as only MUCs in the registry are rejoined
* when going back online.
*/
mucRegistry_->addMUC(mucJID.toBare());
}
handleChatActivity(mucJID.toBare(), "", true);
}
mucControllers_[mucJID]->showChatWindow();
return muc;
}
void ChatsManager::handleSearchMUCRequest() {
mucSearchController_->openSearchWindow();