summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swift/Controllers')
-rw-r--r--Swift/Controllers/Chat/ChatController.cpp15
-rw-r--r--Swift/Controllers/Chat/ChatController.h5
-rw-r--r--Swift/Controllers/Chat/ChatControllerBase.cpp39
-rw-r--r--Swift/Controllers/Chat/ChatControllerBase.h22
-rw-r--r--Swift/Controllers/Chat/ChatsManager.cpp10
-rw-r--r--Swift/Controllers/Chat/ChatsManager.h4
-rw-r--r--Swift/Controllers/Chat/MUCController.cpp41
-rw-r--r--Swift/Controllers/Chat/MUCController.h8
-rw-r--r--Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp7
-rw-r--r--Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp11
-rw-r--r--Swift/Controllers/Chat/UnitTest/MockChatListWindow.h8
-rw-r--r--Swift/Controllers/DummySoundPlayer.h2
-rw-r--r--Swift/Controllers/DummySystemTray.h4
-rw-r--r--Swift/Controllers/FileTransfer/FileTransferController.cpp3
-rw-r--r--Swift/Controllers/FileTransfer/FileTransferProgressInfo.cpp4
-rw-r--r--Swift/Controllers/HighlightAction.cpp28
-rw-r--r--Swift/Controllers/HighlightAction.h45
-rw-r--r--Swift/Controllers/HighlightEditorController.cpp40
-rw-r--r--Swift/Controllers/HighlightEditorController.h38
-rw-r--r--Swift/Controllers/HighlightManager.cpp139
-rw-r--r--Swift/Controllers/HighlightManager.h49
-rw-r--r--Swift/Controllers/HighlightRule.cpp200
-rw-r--r--Swift/Controllers/HighlightRule.h77
-rw-r--r--Swift/Controllers/Highlighter.cpp41
-rw-r--r--Swift/Controllers/Highlighter.h37
-rw-r--r--Swift/Controllers/MainController.cpp29
-rw-r--r--Swift/Controllers/MainController.h6
-rw-r--r--Swift/Controllers/ProfileController.cpp1
-rw-r--r--Swift/Controllers/Roster/ContactRosterItem.cpp12
-rw-r--r--Swift/Controllers/Roster/LeastCommonSubsequence.h25
-rw-r--r--Swift/Controllers/Roster/Roster.cpp4
-rw-r--r--Swift/Controllers/Roster/Roster.h4
-rw-r--r--Swift/Controllers/Roster/RosterController.h2
-rw-r--r--Swift/Controllers/Roster/RosterItemOperation.h8
-rw-r--r--Swift/Controllers/Roster/TableRoster.cpp7
-rw-r--r--Swift/Controllers/Roster/UnitTest/RosterControllerTest.cpp20
-rw-r--r--Swift/Controllers/Roster/UnitTest/TableRosterTest.cpp2
-rw-r--r--Swift/Controllers/SConscript10
-rw-r--r--Swift/Controllers/SettingConstants.cpp1
-rw-r--r--Swift/Controllers/SettingConstants.h1
-rw-r--r--Swift/Controllers/Settings/DummySettingsProvider.h12
-rw-r--r--Swift/Controllers/Settings/UnitTest/SettingsProviderHierachyTest.cpp2
-rw-r--r--Swift/Controllers/ShowProfileController.cpp76
-rw-r--r--Swift/Controllers/ShowProfileController.h36
-rw-r--r--Swift/Controllers/SoundEventController.cpp19
-rw-r--r--Swift/Controllers/SoundEventController.h8
-rw-r--r--Swift/Controllers/SoundPlayer.h6
-rw-r--r--Swift/Controllers/StatusCache.cpp107
-rw-r--r--Swift/Controllers/StatusCache.h40
-rw-r--r--Swift/Controllers/StatusUtil.cpp2
-rw-r--r--Swift/Controllers/Storages/CertificateFileStorage.cpp5
-rw-r--r--Swift/Controllers/SystemTray.h2
-rw-r--r--Swift/Controllers/Translator.cpp2
-rw-r--r--Swift/Controllers/UIEvents/AddContactUIEvent.h6
-rw-r--r--Swift/Controllers/UIEvents/AddMUCBookmarkUIEvent.h2
-rw-r--r--Swift/Controllers/UIEvents/EditMUCBookmarkUIEvent.h6
-rw-r--r--Swift/Controllers/UIEvents/JoinMUCUIEvent.h2
-rw-r--r--Swift/Controllers/UIEvents/RemoveMUCBookmarkUIEvent.h2
-rw-r--r--Swift/Controllers/UIEvents/RemoveRosterItemUIEvent.h6
-rw-r--r--Swift/Controllers/UIEvents/RequestAdHocUIEvent.h2
-rw-r--r--Swift/Controllers/UIEvents/RequestAddUserDialogUIEvent.h8
-rw-r--r--Swift/Controllers/UIEvents/RequestChatUIEvent.h2
-rw-r--r--Swift/Controllers/UIEvents/RequestHighlightEditorUIEvent.h16
-rw-r--r--Swift/Controllers/UIEvents/RequestWhiteboardUIEvent.h2
-rw-r--r--Swift/Controllers/UIEvents/ShowProfileForRosterItemUIEvent.h25
-rw-r--r--Swift/Controllers/UIEvents/ShowWhiteboardUIEvent.h2
-rw-r--r--Swift/Controllers/UIEvents/UIEventStream.h2
-rw-r--r--Swift/Controllers/UIInterfaces/AdHocCommandWindow.h2
-rw-r--r--Swift/Controllers/UIInterfaces/ChatListWindow.h2
-rw-r--r--Swift/Controllers/UIInterfaces/ChatWindow.h13
-rw-r--r--Swift/Controllers/UIInterfaces/ChatWindowFactory.h2
-rw-r--r--Swift/Controllers/UIInterfaces/ContactEditWindowFactory.h2
-rw-r--r--Swift/Controllers/UIInterfaces/EventWindow.h2
-rw-r--r--Swift/Controllers/UIInterfaces/EventWindowFactory.h2
-rw-r--r--Swift/Controllers/UIInterfaces/HighlightEditorWidget.h22
-rw-r--r--Swift/Controllers/UIInterfaces/HighlightEditorWidgetFactory.h20
-rw-r--r--Swift/Controllers/UIInterfaces/HistoryWindow.h2
-rw-r--r--Swift/Controllers/UIInterfaces/HistoryWindowFactory.h2
-rw-r--r--Swift/Controllers/UIInterfaces/InviteToChatWindow.h2
-rw-r--r--Swift/Controllers/UIInterfaces/JoinMUCWindow.h2
-rw-r--r--Swift/Controllers/UIInterfaces/JoinMUCWindowFactory.h2
-rw-r--r--Swift/Controllers/UIInterfaces/LoginWindow.h2
-rw-r--r--Swift/Controllers/UIInterfaces/LoginWindowFactory.h2
-rw-r--r--Swift/Controllers/UIInterfaces/MUCSearchWindow.h2
-rw-r--r--Swift/Controllers/UIInterfaces/MUCSearchWindowFactory.h2
-rw-r--r--Swift/Controllers/UIInterfaces/MainWindow.h2
-rw-r--r--Swift/Controllers/UIInterfaces/MainWindowFactory.h2
-rw-r--r--Swift/Controllers/UIInterfaces/ProfileWindow.h7
-rw-r--r--Swift/Controllers/UIInterfaces/ProfileWindowFactory.h2
-rw-r--r--Swift/Controllers/UIInterfaces/UIFactory.h4
-rw-r--r--Swift/Controllers/UIInterfaces/UserSearchWindowFactory.h2
-rw-r--r--Swift/Controllers/UIInterfaces/WhiteboardWindowFactory.h2
-rw-r--r--Swift/Controllers/UIInterfaces/XMLConsoleWidgetFactory.h2
-rw-r--r--Swift/Controllers/UnitTest/ChatMessageSummarizerTest.cpp2
-rw-r--r--Swift/Controllers/UnitTest/HighlightRuleTest.cpp318
-rw-r--r--Swift/Controllers/UnitTest/MockChatWindow.h64
-rw-r--r--Swift/Controllers/UnitTest/MockMainWindow.h20
-rw-r--r--Swift/Controllers/UnitTest/MockMainWindowFactory.h6
-rw-r--r--Swift/Controllers/XMPPEvents/ErrorEvent.h8
-rw-r--r--Swift/Controllers/XMPPEvents/EventController.cpp5
-rw-r--r--Swift/Controllers/XMPPEvents/MessageEvent.h2
-rw-r--r--Swift/Controllers/XMPPEvents/StanzaEvent.h8
-rw-r--r--Swift/Controllers/XMPPEvents/SubscriptionRequestEvent.h12
103 files changed, 1724 insertions, 238 deletions
diff --git a/Swift/Controllers/Chat/ChatController.cpp b/Swift/Controllers/Chat/ChatController.cpp
index 16b22fe..0ffef0c 100644
--- a/Swift/Controllers/Chat/ChatController.cpp
+++ b/Swift/Controllers/Chat/ChatController.cpp
@@ -32,7 +32,7 @@
#include <Swiften/Elements/DeliveryReceipt.h>
#include <Swiften/Elements/DeliveryReceiptRequest.h>
#include <Swift/Controllers/SettingConstants.h>
-
+#include <Swift/Controllers/Highlighter.h>
#include <Swiften/Base/Log.h>
namespace Swift {
@@ -40,8 +40,8 @@ namespace Swift {
/**
* The controller does not gain ownership of the stanzaChannel, nor the factory.
*/
-ChatController::ChatController(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &contact, NickResolver* nickResolver, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool isInMUC, bool useDelayForLatency, UIEventStream* eventStream, EventController* eventController, TimerFactory* timerFactory, EntityCapsProvider* entityCapsProvider, bool userWantsReceipts, SettingsProvider* settings, HistoryController* historyController, MUCRegistry* mucRegistry)
- : ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, contact, presenceOracle, avatarManager, useDelayForLatency, eventStream, eventController, timerFactory, entityCapsProvider, historyController, mucRegistry), eventStream_(eventStream), userWantsReceipts_(userWantsReceipts), settings_(settings) {
+ChatController::ChatController(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &contact, NickResolver* nickResolver, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool isInMUC, bool useDelayForLatency, UIEventStream* eventStream, EventController* eventController, TimerFactory* timerFactory, EntityCapsProvider* entityCapsProvider, bool userWantsReceipts, SettingsProvider* settings, HistoryController* historyController, MUCRegistry* mucRegistry, HighlightManager* highlightManager)
+ : ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, contact, presenceOracle, avatarManager, useDelayForLatency, eventStream, eventController, timerFactory, entityCapsProvider, historyController, mucRegistry, highlightManager), eventStream_(eventStream), userWantsReceipts_(userWantsReceipts), settings_(settings) {
isInMUC_ = isInMUC;
lastWasPresence_ = false;
chatStateNotifier_ = new ChatStateNotifier(stanzaChannel, contact, entityCapsProvider);
@@ -174,8 +174,11 @@ void ChatController::preHandleIncomingMessage(boost::shared_ptr<MessageEvent> me
}
}
-void ChatController::postHandleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent) {
+void ChatController::postHandleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent, const HighlightAction& highlight) {
eventController_->handleIncomingEvent(messageEvent);
+ if (!messageEvent->getConcluded()) {
+ highlighter_->handleHighlightAction(highlight);
+ }
}
@@ -211,9 +214,9 @@ void ChatController::postSendMessage(const std::string& body, boost::shared_ptr<
boost::shared_ptr<Replace> replace = sentStanza->getPayload<Replace>();
if (replace) {
eraseIf(unackedStanzas_, PairSecondEquals<boost::shared_ptr<Stanza>, std::string>(myLastMessageUIID_));
- replaceMessage(body, myLastMessageUIID_, boost::posix_time::microsec_clock::universal_time());
+ replaceMessage(body, myLastMessageUIID_, boost::posix_time::microsec_clock::universal_time(), HighlightAction());
} else {
- myLastMessageUIID_ = addMessage(body, QT_TRANSLATE_NOOP("", "me"), true, labelsEnabled_ ? chatWindow_->getSelectedSecurityLabel().getLabel() : boost::shared_ptr<SecurityLabel>(), std::string(avatarManager_->getAvatarPath(selfJID_).string()), boost::posix_time::microsec_clock::universal_time());
+ myLastMessageUIID_ = addMessage(body, QT_TRANSLATE_NOOP("", "me"), true, labelsEnabled_ ? chatWindow_->getSelectedSecurityLabel().getLabel() : boost::shared_ptr<SecurityLabel>(), std::string(avatarManager_->getAvatarPath(selfJID_).string()), boost::posix_time::microsec_clock::universal_time(), HighlightAction());
}
if (stanzaChannel_->getStreamManagementEnabled() && !myLastMessageUIID_.empty() ) {
diff --git a/Swift/Controllers/Chat/ChatController.h b/Swift/Controllers/Chat/ChatController.h
index 66ec37d..6021ec1 100644
--- a/Swift/Controllers/Chat/ChatController.h
+++ b/Swift/Controllers/Chat/ChatController.h
@@ -22,10 +22,11 @@ namespace Swift {
class FileTransferController;
class SettingsProvider;
class HistoryController;
+ class HighlightManager;
class ChatController : public ChatControllerBase {
public:
- ChatController(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &contact, NickResolver* nickResolver, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool isInMUC, bool useDelayForLatency, UIEventStream* eventStream, EventController* eventController, TimerFactory* timerFactory, EntityCapsProvider* entityCapsProvider, bool userWantsReceipts, SettingsProvider* settings, HistoryController* historyController, MUCRegistry* mucRegistry);
+ ChatController(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &contact, NickResolver* nickResolver, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool isInMUC, bool useDelayForLatency, UIEventStream* eventStream, EventController* eventController, TimerFactory* timerFactory, EntityCapsProvider* entityCapsProvider, bool userWantsReceipts, SettingsProvider* settings, HistoryController* historyController, MUCRegistry* mucRegistry, HighlightManager* highlightManager);
virtual ~ChatController();
virtual void setToJID(const JID& jid);
virtual void setOnline(bool online);
@@ -45,7 +46,7 @@ namespace Swift {
bool isIncomingMessageFromMe(boost::shared_ptr<Message> message);
void postSendMessage(const std::string &body, boost::shared_ptr<Stanza> sentStanza);
void preHandleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent);
- void postHandleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent);
+ void postHandleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent, const HighlightAction&);
void preSendMessageRequest(boost::shared_ptr<Message>);
std::string senderDisplayNameFromMessage(const JID& from);
virtual boost::optional<boost::posix_time::ptime> getMessageTimestamp(boost::shared_ptr<Message>) const;
diff --git a/Swift/Controllers/Chat/ChatControllerBase.cpp b/Swift/Controllers/Chat/ChatControllerBase.cpp
index 50709f7..ad7f76a 100644
--- a/Swift/Controllers/Chat/ChatControllerBase.cpp
+++ b/Swift/Controllers/Chat/ChatControllerBase.cpp
@@ -13,6 +13,7 @@
#include <boost/shared_ptr.hpp>
#include <boost/smart_ptr/make_shared.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/numeric/conversion/cast.hpp>
#include <boost/algorithm/string.hpp>
#include <Swift/Controllers/Intl.h>
@@ -30,15 +31,18 @@
#include <Swiften/Queries/Requests/GetSecurityLabelsCatalogRequest.h>
#include <Swiften/Avatars/AvatarManager.h>
#include <Swift/Controllers/XMPPEvents/MUCInviteEvent.h>
+#include <Swift/Controllers/HighlightManager.h>
+#include <Swift/Controllers/Highlighter.h>
namespace Swift {
-ChatControllerBase::ChatControllerBase(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &toJID, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool useDelayForLatency, UIEventStream* eventStream, EventController* eventController, TimerFactory* timerFactory, EntityCapsProvider* entityCapsProvider, HistoryController* historyController, MUCRegistry* mucRegistry) : selfJID_(self), stanzaChannel_(stanzaChannel), iqRouter_(iqRouter), chatWindowFactory_(chatWindowFactory), toJID_(toJID), labelsEnabled_(false), presenceOracle_(presenceOracle), avatarManager_(avatarManager), useDelayForLatency_(useDelayForLatency), eventController_(eventController), timerFactory_(timerFactory), entityCapsProvider_(entityCapsProvider), historyController_(historyController), mucRegistry_(mucRegistry) {
+ChatControllerBase::ChatControllerBase(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &toJID, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool useDelayForLatency, UIEventStream* eventStream, EventController* eventController, TimerFactory* timerFactory, EntityCapsProvider* entityCapsProvider, HistoryController* historyController, MUCRegistry* mucRegistry, HighlightManager* highlightManager) : selfJID_(self), stanzaChannel_(stanzaChannel), iqRouter_(iqRouter), chatWindowFactory_(chatWindowFactory), toJID_(toJID), labelsEnabled_(false), presenceOracle_(presenceOracle), avatarManager_(avatarManager), useDelayForLatency_(useDelayForLatency), eventController_(eventController), timerFactory_(timerFactory), entityCapsProvider_(entityCapsProvider), historyController_(historyController), mucRegistry_(mucRegistry) {
chatWindow_ = chatWindowFactory_->createChatWindow(toJID, eventStream);
chatWindow_->onAllMessagesRead.connect(boost::bind(&ChatControllerBase::handleAllMessagesRead, this));
chatWindow_->onSendMessageRequest.connect(boost::bind(&ChatControllerBase::handleSendMessageRequest, this, _1, _2));
chatWindow_->onLogCleared.connect(boost::bind(&ChatControllerBase::handleLogCleared, this));
entityCapsProvider_->onCapsChanged.connect(boost::bind(&ChatControllerBase::handleCapsChanged, this, _1));
+ highlighter_ = highlightManager->createHighlighter();
setOnline(stanzaChannel->isAvailable() && iqRouter->isAvailable());
createDayChangeTimer();
}
@@ -62,7 +66,7 @@ void ChatControllerBase::createDayChangeTimer() {
boost::posix_time::ptime now = boost::posix_time::second_clock::local_time();
boost::posix_time::ptime midnight(now.date() + boost::gregorian::days(1));
long millisecondsUntilMidnight = (midnight - now).total_milliseconds();
- dateChangeTimer_ = boost::shared_ptr<Timer>(timerFactory_->createTimer(millisecondsUntilMidnight));
+ dateChangeTimer_ = boost::shared_ptr<Timer>(timerFactory_->createTimer(boost::numeric_cast<int>(millisecondsUntilMidnight)));
dateChangeTimer_->onTick.connect(boost::bind(&ChatControllerBase::handleDayChangeTick, this));
dateChangeTimer_->start();
}
@@ -112,7 +116,7 @@ void ChatControllerBase::handleAllMessagesRead() {
}
int ChatControllerBase::getUnreadCount() {
- return targetedUnreadMessages_.size();
+ return boost::numeric_cast<int>(targetedUnreadMessages_.size());
}
void ChatControllerBase::handleSendMessageRequest(const std::string &body, bool isCorrectionMessage) {
@@ -175,19 +179,19 @@ void ChatControllerBase::activateChatWindow() {
chatWindow_->activate();
}
-std::string ChatControllerBase::addMessage(const std::string& message, const std::string& senderName, bool senderIsSelf, const boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time) {
+std::string ChatControllerBase::addMessage(const std::string& message, const std::string& senderName, bool senderIsSelf, const boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time, const HighlightAction& highlight) {
if (boost::starts_with(message, "/me ")) {
- return chatWindow_->addAction(String::getSplittedAtFirst(message, ' ').second, senderName, senderIsSelf, label, avatarPath, time);
+ return chatWindow_->addAction(String::getSplittedAtFirst(message, ' ').second, senderName, senderIsSelf, label, avatarPath, time, highlight);
} else {
- return chatWindow_->addMessage(message, senderName, senderIsSelf, label, avatarPath, time);
+ return chatWindow_->addMessage(message, senderName, senderIsSelf, label, avatarPath, time, highlight);
}
}
-void ChatControllerBase::replaceMessage(const std::string& message, const std::string& id, const boost::posix_time::ptime& time) {
+void ChatControllerBase::replaceMessage(const std::string& message, const std::string& id, const boost::posix_time::ptime& time, const HighlightAction& highlight) {
if (boost::starts_with(message, "/me ")) {
- chatWindow_->replaceWithAction(String::getSplittedAtFirst(message, ' ').second, id, time);
+ chatWindow_->replaceWithAction(String::getSplittedAtFirst(message, ' ').second, id, time, highlight);
} else {
- chatWindow_->replaceMessage(message, id, time);
+ chatWindow_->replaceMessage(message, id, time, highlight);
}
}
@@ -205,6 +209,7 @@ void ChatControllerBase::handleIncomingMessage(boost::shared_ptr<MessageEvent> m
}
boost::shared_ptr<Message> message = messageEvent->getStanza();
std::string body = message->getBody();
+ HighlightAction highlight;
if (message->isError()) {
std::string errorMessage = str(format(QT_TRANSLATE_NOOP("", "Couldn't send message: %1%")) % getErrorMessage(message->getPayload<ErrorPayload>()));
chatWindow_->addErrorMessage(errorMessage);
@@ -243,6 +248,11 @@ void ChatControllerBase::handleIncomingMessage(boost::shared_ptr<MessageEvent> m
}
onActivity(body);
+ // Highlight
+ if (!isIncomingMessageFromMe(message)) {
+ highlight = highlighter_->findAction(body, senderDisplayNameFromMessage(from));
+ }
+
boost::shared_ptr<Replace> replace = message->getPayload<Replace>();
if (replace) {
std::string body = message->getBody();
@@ -250,19 +260,19 @@ void ChatControllerBase::handleIncomingMessage(boost::shared_ptr<MessageEvent> m
std::map<JID, std::string>::iterator lastMessage;
lastMessage = lastMessagesUIID_.find(from);
if (lastMessage != lastMessagesUIID_.end()) {
- replaceMessage(body, lastMessagesUIID_[from], timeStamp);
+ replaceMessage(body, lastMessagesUIID_[from], timeStamp, highlight);
}
}
else {
- lastMessagesUIID_[from] = addMessage(body, senderDisplayNameFromMessage(from), isIncomingMessageFromMe(message), label, std::string(avatarManager_->getAvatarPath(from).string()), timeStamp);
+ lastMessagesUIID_[from] = addMessage(body, senderDisplayNameFromMessage(from), isIncomingMessageFromMe(message), label, std::string(avatarManager_->getAvatarPath(from).string()), timeStamp, highlight);
}
logMessage(body, from, selfJID_, timeStamp, true);
}
chatWindow_->show();
- chatWindow_->setUnreadMessageCount(unreadMessages_.size());
+ chatWindow_->setUnreadMessageCount(boost::numeric_cast<int>(unreadMessages_.size()));
onUnreadCountChanged();
- postHandleIncomingMessage(messageEvent);
+ postHandleIncomingMessage(messageEvent, highlight);
}
std::string ChatControllerBase::getErrorMessage(boost::shared_ptr<ErrorPayload> error) {
@@ -296,13 +306,14 @@ std::string ChatControllerBase::getErrorMessage(boost::shared_ptr<ErrorPayload>
case ErrorPayload::UnexpectedRequest: return QT_TRANSLATE_NOOP("", "Unexpected request");
}
}
+ assert(false);
return defaultMessage;
}
void ChatControllerBase::handleGeneralMUCInvitation(MUCInviteEvent::ref event) {
unreadMessages_.push_back(event);
chatWindow_->show();
- chatWindow_->setUnreadMessageCount(unreadMessages_.size());
+ chatWindow_->setUnreadMessageCount(boost::numeric_cast<int>(unreadMessages_.size()));
onUnreadCountChanged();
chatWindow_->addMUCInvitation(senderDisplayNameFromMessage(event->getInviter()), event->getRoomJID(), event->getReason(), event->getPassword(), event->getDirect());
eventController_->handleIncomingEvent(event);
diff --git a/Swift/Controllers/Chat/ChatControllerBase.h b/Swift/Controllers/Chat/ChatControllerBase.h
index b26af02..baef9e6 100644
--- a/Swift/Controllers/Chat/ChatControllerBase.h
+++ b/Swift/Controllers/Chat/ChatControllerBase.h
@@ -29,6 +29,7 @@
#include "Swiften/Base/IDGenerator.h"
#include <Swift/Controllers/HistoryController.h>
#include <Swiften/MUC/MUCRegistry.h>
+#include <Swift/Controllers/HighlightManager.h>
namespace Swift {
class IQRouter;
@@ -39,6 +40,8 @@ namespace Swift {
class UIEventStream;
class EventController;
class EntityCapsProvider;
+ class HighlightManager;
+ class Highlighter;
class ChatControllerBase : public boost::bsignals::trackable {
public:
@@ -47,11 +50,11 @@ namespace Swift {
void activateChatWindow();
void setAvailableServerFeatures(boost::shared_ptr<DiscoInfo> info);
void handleIncomingMessage(boost::shared_ptr<MessageEvent> message);
- std::string addMessage(const std::string& message, const std::string& senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time);
- void replaceMessage(const std::string& message, const std::string& id, const boost::posix_time::ptime& time);
+ std::string addMessage(const std::string& message, const std::string& senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time, const HighlightAction& highlight);
+ void replaceMessage(const std::string& message, const std::string& id, const boost::posix_time::ptime& time, const HighlightAction& highlight);
virtual void setOnline(bool online);
virtual void setEnabled(bool enabled);
- virtual void setToJID(const JID& jid) {toJID_ = jid;};
+ virtual void setToJID(const JID& jid) {toJID_ = jid;}
/** Used for determining when something is recent.*/
boost::signal<void (const std::string& /*activity*/)> onActivity;
boost::signal<void ()> onUnreadCountChanged;
@@ -60,20 +63,20 @@ namespace Swift {
void handleCapsChanged(const JID& 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, TimerFactory* timerFactory, EntityCapsProvider* entityCapsProvider, HistoryController* historyController, MUCRegistry* mucRegistry);
+ ChatControllerBase(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &toJID, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool useDelayForLatency, UIEventStream* eventStream, EventController* eventController, TimerFactory* timerFactory, EntityCapsProvider* entityCapsProvider, HistoryController* historyController, MUCRegistry* mucRegistry, HighlightManager* highlightManager);
/**
* Pass the Message appended, and the stanza used to send it.
*/
- virtual void postSendMessage(const std::string&, boost::shared_ptr<Stanza>) {};
+ virtual void postSendMessage(const std::string&, boost::shared_ptr<Stanza>) {}
virtual std::string senderDisplayNameFromMessage(const JID& from) = 0;
virtual bool isIncomingMessageFromMe(boost::shared_ptr<Message>) = 0;
- virtual void preHandleIncomingMessage(boost::shared_ptr<MessageEvent>) {};
- virtual void postHandleIncomingMessage(boost::shared_ptr<MessageEvent>) {};
- virtual void preSendMessageRequest(boost::shared_ptr<Message>) {};
+ virtual void preHandleIncomingMessage(boost::shared_ptr<MessageEvent>) {}
+ virtual void postHandleIncomingMessage(boost::shared_ptr<MessageEvent>, const HighlightAction&) {}
+ virtual void preSendMessageRequest(boost::shared_ptr<Message>) {}
virtual bool isFromContact(const JID& from);
virtual boost::optional<boost::posix_time::ptime> getMessageTimestamp(boost::shared_ptr<Message>) const = 0;
- virtual void dayTicked() {};
+ virtual void dayTicked() {}
virtual void handleBareJIDCapsChanged(const JID& jid) = 0;
std::string getErrorMessage(boost::shared_ptr<ErrorPayload>);
virtual void setContactIsReceivingPresence(bool /* isReceivingPresence */) {}
@@ -116,5 +119,6 @@ namespace Swift {
SecurityLabelsCatalog::Item lastLabel_;
HistoryController* historyController_;
MUCRegistry* mucRegistry_;
+ Highlighter* highlighter_;
};
}
diff --git a/Swift/Controllers/Chat/ChatsManager.cpp b/Swift/Controllers/Chat/ChatsManager.cpp
index 1e0e9c2..dba8565 100644
--- a/Swift/Controllers/Chat/ChatsManager.cpp
+++ b/Swift/Controllers/Chat/ChatsManager.cpp
@@ -74,7 +74,8 @@ ChatsManager::ChatsManager(
bool eagleMode,
SettingsProvider* settings,
HistoryController* historyController,
- WhiteboardManager* whiteboardManager) :
+ WhiteboardManager* whiteboardManager,
+ HighlightManager* highlightManager) :
jid_(jid),
joinMUCWindowFactory_(joinMUCWindowFactory),
useDelayForLatency_(useDelayForLatency),
@@ -86,7 +87,8 @@ ChatsManager::ChatsManager(
eagleMode_(eagleMode),
settings_(settings),
historyController_(historyController),
- whiteboardManager_(whiteboardManager) {
+ whiteboardManager_(whiteboardManager),
+ highlightManager_(highlightManager) {
timerFactory_ = timerFactory;
eventController_ = eventController;
stanzaChannel_ = stanzaChannel;
@@ -521,7 +523,7 @@ ChatController* ChatsManager::getChatControllerOrFindAnother(const JID &contact)
ChatController* ChatsManager::createNewChatController(const JID& contact) {
assert(chatControllers_.find(contact) == chatControllers_.end());
- 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_);
+ 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_);
chatControllers_[contact] = controller;
controller->setAvailableServerFeatures(serverDiscoInfo_);
controller->onActivity.connect(boost::bind(&ChatsManager::handleChatActivity, this, contact, _1, false));
@@ -594,7 +596,7 @@ void ChatsManager::handleJoinMUCRequest(const JID &mucJID, const boost::optional
if (createAsReservedIfNew) {
muc->setCreateAsReservedIfNew();
}
- MUCController* controller = new MUCController(jid_, muc, password, nick, stanzaChannel_, iqRouter_, chatWindowFactory_, presenceOracle_, avatarManager_, uiEventStream_, false, timerFactory_, eventController_, entityCapsProvider_, roster_, historyController_, mucRegistry_);
+ MUCController* controller = new MUCController(jid_, muc, password, nick, stanzaChannel_, iqRouter_, chatWindowFactory_, presenceOracle_, avatarManager_, uiEventStream_, false, timerFactory_, eventController_, entityCapsProvider_, roster_, historyController_, mucRegistry_, highlightManager_);
mucControllers_[mucJID] = controller;
controller->setAvailableServerFeatures(serverDiscoInfo_);
controller->onUserLeft.connect(boost::bind(&ChatsManager::handleUserLeftMUC, this, controller));
diff --git a/Swift/Controllers/Chat/ChatsManager.h b/Swift/Controllers/Chat/ChatsManager.h
index 5b8b785..55e62b9 100644
--- a/Swift/Controllers/Chat/ChatsManager.h
+++ b/Swift/Controllers/Chat/ChatsManager.h
@@ -50,10 +50,11 @@ namespace Swift {
class SettingsProvider;
class WhiteboardManager;
class HistoryController;
+ class HighlightManager;
class ChatsManager {
public:
- ChatsManager(JID jid, StanzaChannel* stanzaChannel, IQRouter* iqRouter, EventController* eventController, ChatWindowFactory* chatWindowFactory, JoinMUCWindowFactory* joinMUCWindowFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, PresenceSender* presenceSender, UIEventStream* uiEventStream, ChatListWindowFactory* chatListWindowFactory, bool useDelayForLatency, TimerFactory* timerFactory, MUCRegistry* mucRegistry, EntityCapsProvider* entityCapsProvider, MUCManager* mucManager, MUCSearchWindowFactory* mucSearchWindowFactory, ProfileSettingsProvider* profileSettings, FileTransferOverview* ftOverview, XMPPRoster* roster, bool eagleMode, SettingsProvider* settings, HistoryController* historyController_, WhiteboardManager* whiteboardManager);
+ ChatsManager(JID jid, StanzaChannel* stanzaChannel, IQRouter* iqRouter, EventController* eventController, ChatWindowFactory* chatWindowFactory, JoinMUCWindowFactory* joinMUCWindowFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, PresenceSender* presenceSender, UIEventStream* uiEventStream, ChatListWindowFactory* chatListWindowFactory, bool useDelayForLatency, TimerFactory* timerFactory, MUCRegistry* mucRegistry, EntityCapsProvider* entityCapsProvider, MUCManager* mucManager, MUCSearchWindowFactory* mucSearchWindowFactory, ProfileSettingsProvider* profileSettings, FileTransferOverview* ftOverview, XMPPRoster* roster, bool eagleMode, SettingsProvider* settings, HistoryController* historyController_, WhiteboardManager* whiteboardManager, HighlightManager* highlightManager);
virtual ~ChatsManager();
void setAvatarManager(AvatarManager* avatarManager);
void setOnline(bool enabled);
@@ -136,5 +137,6 @@ namespace Swift {
SettingsProvider* settings_;
HistoryController* historyController_;
WhiteboardManager* whiteboardManager_;
+ HighlightManager* highlightManager_;
};
}
diff --git a/Swift/Controllers/Chat/MUCController.cpp b/Swift/Controllers/Chat/MUCController.cpp
index 50eee68..a61b5f0 100644
--- a/Swift/Controllers/Chat/MUCController.cpp
+++ b/Swift/Controllers/Chat/MUCController.cpp
@@ -24,6 +24,7 @@
#include <Swift/Controllers/UIEvents/UIEventStream.h>
#include <Swift/Controllers/UIEvents/RequestChatUIEvent.h>
#include <Swift/Controllers/UIEvents/RequestAddUserDialogUIEvent.h>
+#include <Swift/Controllers/UIEvents/ShowProfileForRosterItemUIEvent.h>
#include <Swift/Controllers/Roster/GroupRosterItem.h>
#include <Swift/Controllers/Roster/ContactRosterItem.h>
#include <Swiften/Avatars/AvatarManager.h>
@@ -35,6 +36,7 @@
#include <Swift/Controllers/Roster/SetPresence.h>
#include <Swiften/Disco/EntityCapsProvider.h>
#include <Swiften/Roster/XMPPRoster.h>
+#include <Swift/Controllers/Highlighter.h>
#define MUC_JOIN_WARNING_TIMEOUT_MILLISECONDS 60000
@@ -61,8 +63,9 @@ MUCController::MUCController (
EntityCapsProvider* entityCapsProvider,
XMPPRoster* roster,
HistoryController* historyController,
- MUCRegistry* mucRegistry) :
- ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, muc->getJID(), presenceOracle, avatarManager, useDelayForLatency, uiEventStream, eventController, timerFactory, entityCapsProvider, historyController, mucRegistry), muc_(muc), nick_(nick), desiredNick_(nick), password_(password) {
+ MUCRegistry* mucRegistry,
+ HighlightManager* highlightManager) :
+ ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, muc->getJID(), presenceOracle, avatarManager, useDelayForLatency, uiEventStream, eventController, timerFactory, entityCapsProvider, historyController, mucRegistry, highlightManager), muc_(muc), nick_(nick), desiredNick_(nick), password_(password) {
parting_ = true;
joined_ = false;
lastWasPresence_ = false;
@@ -98,6 +101,8 @@ MUCController::MUCController (
muc_->onConfigurationFormReceived.connect(boost::bind(&MUCController::handleConfigurationFormReceived, this, _1));
muc_->onRoleChangeFailed.connect(boost::bind(&MUCController::handleOccupantRoleChangeFailed, this, _1, _2, _3));
muc_->onAffiliationListReceived.connect(boost::bind(&MUCController::handleAffiliationListReceived, this, _1, _2));
+ highlighter_->setMode(Highlighter::MUCMode);
+ highlighter_->setNick(nick_);
if (timerFactory) {
loginCheckTimer_ = boost::shared_ptr<Timer>(timerFactory->createTimer(MUC_JOIN_WARNING_TIMEOUT_MILLISECONDS));
loginCheckTimer_->onTick.connect(boost::bind(&MUCController::handleJoinTimeoutTick, this));
@@ -146,6 +151,7 @@ void MUCController::handleWindowOccupantSelectionChanged(ContactRosterItem* item
if (muc_->getOccupant(item->getJID().getResource()).getRealJID()) {
actions.push_back(ChatWindow::AddContact);
}
+ actions.push_back(ChatWindow::ShowProfile);
}
chatWindow_->setAvailableOccupantActions(actions);
}
@@ -164,6 +170,7 @@ void MUCController::handleActionRequestedOnOccupant(ChatWindow::OccupantAction a
case ChatWindow::MakeParticipant: muc_->changeOccupantRole(mucJID, MUCOccupant::Participant);break;
case ChatWindow::MakeVisitor: muc_->changeOccupantRole(mucJID, MUCOccupant::Visitor);break;
case ChatWindow::AddContact: if (occupant.getRealJID()) events_->send(boost::make_shared<RequestAddUserDialogUIEvent>(realJID, occupant.getNick()));break;
+ case ChatWindow::ShowProfile: events_->send(boost::make_shared<ShowProfileForRosterItemUIEvent>(mucJID));break;
}
}
@@ -228,6 +235,9 @@ void MUCController::receivedActivity() {
}
}
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wswitch-enum"
+
void MUCController::handleJoinFailed(boost::shared_ptr<ErrorPayload> error) {
receivedActivity();
std::string errorMessage = QT_TRANSLATE_NOOP("", "Unable to enter this room");
@@ -270,16 +280,18 @@ void MUCController::handleJoinFailed(boost::shared_ptr<ErrorPayload> error) {
chatWindow_->addErrorMessage(errorMessage);
parting_ = true;
if (!rejoinNick.empty()) {
- nick_ = rejoinNick;
+ setNick(rejoinNick);
rejoin();
}
}
+#pragma clang diagnostic pop
+
void MUCController::handleJoinComplete(const std::string& nick) {
receivedActivity();
joined_ = true;
std::string joinMessage = str(format(QT_TRANSLATE_NOOP("", "You have entered room %1% as %2%.")) % toJID_.toString() % nick);
- nick_ = nick;
+ setNick(nick);
chatWindow_->addSystemMessage(joinMessage);
#ifdef SWIFT_EXPERIMENTAL_HISTORY
@@ -386,6 +398,7 @@ std::string MUCController::roleToFriendlyName(MUCOccupant::Role role) {
case MUCOccupant::Visitor: return QT_TRANSLATE_NOOP("", "visitor");
case MUCOccupant::NoRole: return "";
}
+ assert(false);
return "";
}
@@ -396,6 +409,7 @@ std::string MUCController::roleToSortName(MUCOccupant::Role role) {
case MUCOccupant::Visitor: return "3";
case MUCOccupant::NoRole: return "4";
}
+ assert(false);
return "5";
}
@@ -448,10 +462,13 @@ void MUCController::preHandleIncomingMessage(boost::shared_ptr<MessageEvent> mes
}
}
-void MUCController::postHandleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent) {
+void MUCController::postHandleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent, const HighlightAction& highlight) {
boost::shared_ptr<Message> message = messageEvent->getStanza();
if (joined_ && messageEvent->getStanza()->getFrom().getResource() != nick_ && messageTargetsMe(message) && !message->getPayload<Delay>()) {
eventController_->handleIncomingEvent(messageEvent);
+ if (!messageEvent->getConcluded()) {
+ highlighter_->handleHighlightAction(highlight);
+ }
}
}
@@ -487,7 +504,6 @@ std::string MUCController::roleToGroupName(MUCOccupant::Role role) {
case MUCOccupant::Participant: result = QT_TRANSLATE_NOOP("", "Participants"); break;
case MUCOccupant::Visitor: result = QT_TRANSLATE_NOOP("", "Visitors"); break;
case MUCOccupant::NoRole: result = QT_TRANSLATE_NOOP("", "Occupants"); break;
- default: assert(false);
}
return result;
}
@@ -504,7 +520,7 @@ void MUCController::setOnline(bool online) {
if (loginCheckTimer_) {
loginCheckTimer_->start();
}
- nick_ = desiredNick_;
+ setNick(desiredNick_);
rejoin();
}
}
@@ -611,7 +627,8 @@ void MUCController::appendToJoinParts(std::vector<NickJoinPart>& joinParts, cons
switch (newEvent.type) {
case Join: type = (type == Part) ? PartThenJoin : Join; break;
case Part: type = (type == Join) ? JoinThenPart : Part; break;
- default: /*Nothing to see here */;break;
+ case PartThenJoin: break;
+ case JoinThenPart: break;
}
(*it).type = type;
break;
@@ -811,7 +828,7 @@ void MUCController::addRecentLogs() {
bool senderIsSelf = nick_ == message.getFromJID().getResource();
// the chatWindow uses utc timestamps
- addMessage(message.getMessage(), senderDisplayNameFromMessage(message.getFromJID()), senderIsSelf, boost::shared_ptr<SecurityLabel>(new SecurityLabel()), std::string(avatarManager_->getAvatarPath(message.getFromJID()).string()), message.getTime() - boost::posix_time::hours(message.getOffset()));
+ addMessage(message.getMessage(), senderDisplayNameFromMessage(message.getFromJID()), senderIsSelf, boost::shared_ptr<SecurityLabel>(new SecurityLabel()), std::string(avatarManager_->getAvatarPath(message.getFromJID()).string()), message.getTime() - boost::posix_time::hours(message.getOffset()), HighlightAction());
}
}
@@ -840,4 +857,10 @@ void MUCController::checkDuplicates(boost::shared_ptr<Message> newMessage) {
}
}
+void MUCController::setNick(const std::string& nick)
+{
+ nick_ = nick;
+ highlighter_->setNick(nick_);
+}
+
}
diff --git a/Swift/Controllers/Chat/MUCController.h b/Swift/Controllers/Chat/MUCController.h
index 63893d0..11fe0ff 100644
--- a/Swift/Controllers/Chat/MUCController.h
+++ b/Swift/Controllers/Chat/MUCController.h
@@ -33,18 +33,19 @@ namespace Swift {
class TabComplete;
class InviteToChatWindow;
class XMPPRoster;
+ class HighlightManager;
enum JoinPart {Join, Part, JoinThenPart, PartThenJoin};
struct NickJoinPart {
- NickJoinPart(const std::string& nick, JoinPart type) : nick(nick), type(type) {};
+ NickJoinPart(const std::string& nick, JoinPart type) : nick(nick), type(type) {}
std::string nick;
JoinPart type;
};
class MUCController : public ChatControllerBase {
public:
- MUCController(const JID& self, MUC::ref muc, const boost::optional<std::string>& password, const std::string &nick, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, PresenceOracle* presenceOracle, AvatarManager* avatarManager, UIEventStream* events, bool useDelayForLatency, TimerFactory* timerFactory, EventController* eventController, EntityCapsProvider* entityCapsProvider, XMPPRoster* roster, HistoryController* historyController, MUCRegistry* mucRegistry);
+ MUCController(const JID& self, MUC::ref muc, const boost::optional<std::string>& password, const std::string &nick, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, PresenceOracle* presenceOracle, AvatarManager* avatarManager, UIEventStream* events, bool useDelayForLatency, TimerFactory* timerFactory, EventController* eventController, EntityCapsProvider* entityCapsProvider, XMPPRoster* roster, HistoryController* historyController, MUCRegistry* mucRegistry, HighlightManager* highlightManager);
~MUCController();
boost::signal<void ()> onUserLeft;
boost::signal<void ()> onUserJoined;
@@ -62,7 +63,7 @@ namespace Swift {
std::string senderDisplayNameFromMessage(const JID& from);
boost::optional<boost::posix_time::ptime> getMessageTimestamp(boost::shared_ptr<Message> message) const;
void preHandleIncomingMessage(boost::shared_ptr<MessageEvent>);
- void postHandleIncomingMessage(boost::shared_ptr<MessageEvent>);
+ void postHandleIncomingMessage(boost::shared_ptr<MessageEvent>, const HighlightAction&);
void cancelReplaces();
void logMessage(const std::string& message, const JID& fromJID, const JID& toJID, const boost::posix_time::ptime& timeStamp, bool isIncoming);
@@ -108,6 +109,7 @@ namespace Swift {
void handleInviteToMUCWindowCompleted();
void addRecentLogs();
void checkDuplicates(boost::shared_ptr<Message> newMessage);
+ void setNick(const std::string& nick);
private:
MUC::ref muc_;
diff --git a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
index 482b19c..dd90d66 100644
--- a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
+++ b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
@@ -106,14 +106,16 @@ public:
avatarManager_ = new NullAvatarManager();
wbSessionManager_ = new WhiteboardSessionManager(iqRouter_, stanzaChannel_, presenceOracle_, entityCapsManager_);
wbManager_ = new WhiteboardManager(whiteboardWindowFactory_, uiEventStream_, nickResolver_, wbSessionManager_);
+ highlightManager_ = new HighlightManager(settings_);
mocks_->ExpectCall(chatListWindowFactory_, ChatListWindowFactory::createChatListWindow).With(uiEventStream_).Return(chatListWindow_);
- manager_ = new ChatsManager(jid_, stanzaChannel_, iqRouter_, eventController_, chatWindowFactory_, joinMUCWindowFactory_, nickResolver_, presenceOracle_, directedPresenceSender_, uiEventStream_, chatListWindowFactory_, true, NULL, mucRegistry_, entityCapsManager_, mucManager_, mucSearchWindowFactory_, profileSettings_, ftOverview_, xmppRoster_, false, settings_, NULL, wbManager_);
+ manager_ = new ChatsManager(jid_, stanzaChannel_, iqRouter_, eventController_, chatWindowFactory_, joinMUCWindowFactory_, nickResolver_, presenceOracle_, directedPresenceSender_, uiEventStream_, chatListWindowFactory_, true, NULL, mucRegistry_, entityCapsManager_, mucManager_, mucSearchWindowFactory_, profileSettings_, ftOverview_, xmppRoster_, false, settings_, NULL, wbManager_, highlightManager_);
manager_->setAvatarManager(avatarManager_);
- };
+ }
void tearDown() {
+ delete highlightManager_;
//delete chatListWindowFactory
delete profileSettings_;
delete avatarManager_;
@@ -481,6 +483,7 @@ private:
FileTransferManager* ftManager_;
WhiteboardSessionManager* wbSessionManager_;
WhiteboardManager* wbManager_;
+ HighlightManager* highlightManager_;
};
CPPUNIT_TEST_SUITE_REGISTRATION(ChatsManagerTest);
diff --git a/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp b/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp
index 4f37229..f1fcf79 100644
--- a/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp
+++ b/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp
@@ -26,6 +26,7 @@
#include "Swiften/Network/TimerFactory.h"
#include "Swiften/Elements/MUCUserPayload.h"
#include "Swiften/Disco/DummyEntityCapsProvider.h"
+#include <Swift/Controllers/Settings/DummySettingsProvider.h>
using namespace Swift;
@@ -62,12 +63,16 @@ public:
window_ = new MockChatWindow();
mucRegistry_ = new MUCRegistry();
entityCapsProvider_ = new DummyEntityCapsProvider();
+ settings_ = new DummySettingsProvider();
+ highlightManager_ = new HighlightManager(settings_);
muc_ = boost::make_shared<MUC>(stanzaChannel_, iqRouter_, directedPresenceSender_, mucJID_, mucRegistry_);
mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(muc_->getJID(), uiEventStream_).Return(window_);
- controller_ = new MUCController (self_, muc_, boost::optional<std::string>(), nick_, stanzaChannel_, iqRouter_, chatWindowFactory_, presenceOracle_, avatarManager_, uiEventStream_, false, timerFactory, eventController_, entityCapsProvider_, NULL, NULL, mucRegistry_);
- };
+ controller_ = new MUCController (self_, muc_, boost::optional<std::string>(), nick_, stanzaChannel_, iqRouter_, chatWindowFactory_, presenceOracle_, avatarManager_, uiEventStream_, false, timerFactory, eventController_, entityCapsProvider_, NULL, NULL, mucRegistry_, highlightManager_);
+ }
void tearDown() {
+ delete highlightManager_;
+ delete settings_;
delete entityCapsProvider_;
delete controller_;
delete eventController_;
@@ -338,6 +343,8 @@ private:
MockChatWindow* window_;
MUCRegistry* mucRegistry_;
DummyEntityCapsProvider* entityCapsProvider_;
+ DummySettingsProvider* settings_;
+ HighlightManager* highlightManager_;
};
CPPUNIT_TEST_SUITE_REGISTRATION(MUCControllerTest);
diff --git a/Swift/Controllers/Chat/UnitTest/MockChatListWindow.h b/Swift/Controllers/Chat/UnitTest/MockChatListWindow.h
index 5bbd490..5fa264d 100644
--- a/Swift/Controllers/Chat/UnitTest/MockChatListWindow.h
+++ b/Swift/Controllers/Chat/UnitTest/MockChatListWindow.h
@@ -12,12 +12,12 @@ namespace Swift {
class MockChatListWindow : public ChatListWindow {
public:
- MockChatListWindow() {};
- virtual ~MockChatListWindow() {};
+ MockChatListWindow() {}
+ virtual ~MockChatListWindow() {}
void addMUCBookmark(const MUCBookmark& /*bookmark*/) {}
void removeMUCBookmark(const MUCBookmark& /*bookmark*/) {}
- void addWhiteboardSession(const ChatListWindow::Chat& /*chat*/) {};
- void removeWhiteboardSession(const JID& /*jid*/) {};
+ void addWhiteboardSession(const ChatListWindow::Chat& /*chat*/) {}
+ void removeWhiteboardSession(const JID& /*jid*/) {}
void setBookmarksEnabled(bool /*enabled*/) {}
void setRecents(const std::list<ChatListWindow::Chat>& /*recents*/) {}
void setUnreadCount(int /*unread*/) {}
diff --git a/Swift/Controllers/DummySoundPlayer.h b/Swift/Controllers/DummySoundPlayer.h
index 36dcb28..b91192c 100644
--- a/Swift/Controllers/DummySoundPlayer.h
+++ b/Swift/Controllers/DummySoundPlayer.h
@@ -11,6 +11,6 @@
namespace Swift {
class DummySoundPlayer : public SoundPlayer {
public:
- void playSound(SoundEffect sound) {};
+ void playSound(SoundEffect sound) {}
};
}
diff --git a/Swift/Controllers/DummySystemTray.h b/Swift/Controllers/DummySystemTray.h
index 41da4cd..451588e 100644
--- a/Swift/Controllers/DummySystemTray.h
+++ b/Swift/Controllers/DummySystemTray.h
@@ -11,8 +11,8 @@
namespace Swift {
class DummySystemTray : public SystemTray {
public:
- void setUnreadMessages(bool some) {};
- void setStatusType(StatusShow::Type type) {};
+ void setUnreadMessages(bool some) {}
+ void setStatusType(StatusShow::Type type) {}
void setConnecting() {}
};
}
diff --git a/Swift/Controllers/FileTransfer/FileTransferController.cpp b/Swift/Controllers/FileTransfer/FileTransferController.cpp
index 3feaf49..69b5c89 100644
--- a/Swift/Controllers/FileTransfer/FileTransferController.cpp
+++ b/Swift/Controllers/FileTransfer/FileTransferController.cpp
@@ -10,6 +10,7 @@
#include <Swiften/FileTransfer/FileReadBytestream.h>
#include <Swiften/Base/boost_bsignals.h>
#include <boost/bind.hpp>
+#include <boost/filesystem.hpp>
#include "Swift/Controllers/UIInterfaces/ChatWindow.h"
#include <Swiften/Base/Log.h>
#include <Swift/Controllers/Intl.h>
@@ -138,7 +139,7 @@ void FileTransferController::handleFileTransferStateChange(FileTransfer::State s
case FileTransfer::State::WaitingForStart:
return;
}
- std::cerr << "Unhandled FileTransfer::State!" << std::endl;
+ assert(false);
}
void FileTransferController::handleProgressPercentageChange(int percentage) {
diff --git a/Swift/Controllers/FileTransfer/FileTransferProgressInfo.cpp b/Swift/Controllers/FileTransfer/FileTransferProgressInfo.cpp
index 6d19fa1..3081f71 100644
--- a/Swift/Controllers/FileTransfer/FileTransferProgressInfo.cpp
+++ b/Swift/Controllers/FileTransfer/FileTransferProgressInfo.cpp
@@ -6,6 +6,8 @@
#include "FileTransferProgressInfo.h"
+#include <boost/numeric/conversion/cast.hpp>
+
#include <Swiften/Base/Log.h>
namespace Swift {
@@ -16,7 +18,7 @@ FileTransferProgressInfo::FileTransferProgressInfo(boost::uintmax_t completeByte
void FileTransferProgressInfo::setBytesProcessed(int processedBytes) {
int oldPercentage = int(double(completedBytes) / double(completeBytes) * 100.0);
- completedBytes += processedBytes;
+ completedBytes += boost::numeric_cast<boost::uintmax_t>(processedBytes);
int newPercentage = int(double(completedBytes) / double(completeBytes) * 100.0);
if (oldPercentage != newPercentage) {
onProgressPercentage(newPercentage);
diff --git a/Swift/Controllers/HighlightAction.cpp b/Swift/Controllers/HighlightAction.cpp
new file mode 100644
index 0000000..d4d199d
--- /dev/null
+++ b/Swift/Controllers/HighlightAction.cpp
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2012 Maciej Niedzielski
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <Swift/Controllers/HighlightAction.h>
+
+namespace Swift {
+
+void HighlightAction::setHighlightText(bool highlightText)
+{
+ highlightText_ = highlightText;
+ if (!highlightText_) {
+ textColor_.clear();
+ textBackground_.clear();
+ }
+}
+
+void HighlightAction::setPlaySound(bool playSound)
+{
+ playSound_ = playSound;
+ if (!playSound_) {
+ soundFile_.clear();
+ }
+}
+
+}
diff --git a/Swift/Controllers/HighlightAction.h b/Swift/Controllers/HighlightAction.h
new file mode 100644
index 0000000..bfbed74
--- /dev/null
+++ b/Swift/Controllers/HighlightAction.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2012 Maciej Niedzielski
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <string>
+
+namespace Swift {
+
+ class HighlightRule;
+
+ class HighlightAction {
+ public:
+ HighlightAction() : highlightText_(false), playSound_(false) {}
+
+ bool highlightText() const { return highlightText_; }
+ void setHighlightText(bool highlightText);
+
+ const std::string& getTextColor() const { return textColor_; }
+ void setTextColor(const std::string& textColor) { textColor_ = textColor; }
+
+ const std::string& getTextBackground() const { return textBackground_; }
+ void setTextBackground(const std::string& textBackground) { textBackground_ = textBackground; }
+
+ bool playSound() const { return playSound_; }
+ void setPlaySound(bool playSound);
+
+ const std::string& getSoundFile() const { return soundFile_; }
+ void setSoundFile(const std::string& soundFile) { soundFile_ = soundFile; }
+
+ bool isEmpty() const { return !highlightText_ && !playSound_; }
+
+ private:
+ bool highlightText_;
+ std::string textColor_;
+ std::string textBackground_;
+
+ bool playSound_;
+ std::string soundFile_;
+ };
+
+}
diff --git a/Swift/Controllers/HighlightEditorController.cpp b/Swift/Controllers/HighlightEditorController.cpp
new file mode 100644
index 0000000..899e4bb
--- /dev/null
+++ b/Swift/Controllers/HighlightEditorController.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2012 Maciej Niedzielski
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <boost/bind.hpp>
+
+#include <Swift/Controllers/HighlightEditorController.h>
+#include <Swift/Controllers/UIInterfaces/HighlightEditorWidget.h>
+#include <Swift/Controllers/UIInterfaces/HighlightEditorWidgetFactory.h>
+#include <Swift/Controllers/UIEvents/RequestHighlightEditorUIEvent.h>
+#include <Swift/Controllers/UIEvents/UIEventStream.h>
+
+namespace Swift {
+
+HighlightEditorController::HighlightEditorController(UIEventStream* uiEventStream, HighlightEditorWidgetFactory* highlightEditorWidgetFactory, HighlightManager* highlightManager) : highlightEditorWidgetFactory_(highlightEditorWidgetFactory), highlightEditorWidget_(NULL), highlightManager_(highlightManager)
+{
+ uiEventStream->onUIEvent.connect(boost::bind(&HighlightEditorController::handleUIEvent, this, _1));
+}
+
+HighlightEditorController::~HighlightEditorController()
+{
+ delete highlightEditorWidget_;
+ highlightEditorWidget_ = NULL;
+}
+
+void HighlightEditorController::handleUIEvent(boost::shared_ptr<UIEvent> rawEvent)
+{
+ boost::shared_ptr<RequestHighlightEditorUIEvent> event = boost::dynamic_pointer_cast<RequestHighlightEditorUIEvent>(rawEvent);
+ if (event) {
+ if (!highlightEditorWidget_) {
+ highlightEditorWidget_ = highlightEditorWidgetFactory_->createHighlightEditorWidget();
+ highlightEditorWidget_->setHighlightManager(highlightManager_);
+ }
+ highlightEditorWidget_->show();
+ }
+}
+
+}
diff --git a/Swift/Controllers/HighlightEditorController.h b/Swift/Controllers/HighlightEditorController.h
new file mode 100644
index 0000000..3868251
--- /dev/null
+++ b/Swift/Controllers/HighlightEditorController.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012 Maciej Niedzielski
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <boost/shared_ptr.hpp>
+
+#include <Swift/Controllers/UIEvents/UIEvent.h>
+
+namespace Swift {
+
+ class UIEventStream;
+
+ class HighlightEditorWidgetFactory;
+ class HighlightEditorWidget;
+
+ class HighlightManager;
+
+ class HighlightEditorController {
+ public:
+ HighlightEditorController(UIEventStream* uiEventStream, HighlightEditorWidgetFactory* highlightEditorWidgetFactory, HighlightManager* highlightManager);
+ ~HighlightEditorController();
+
+ HighlightManager* getHighlightManager() const { return highlightManager_; }
+
+ private:
+ void handleUIEvent(boost::shared_ptr<UIEvent> event);
+
+ private:
+ HighlightEditorWidgetFactory* highlightEditorWidgetFactory_;
+ HighlightEditorWidget* highlightEditorWidget_;
+ HighlightManager* highlightManager_;
+ };
+
+}
diff --git a/Swift/Controllers/HighlightManager.cpp b/Swift/Controllers/HighlightManager.cpp
new file mode 100644
index 0000000..7ab578e
--- /dev/null
+++ b/Swift/Controllers/HighlightManager.cpp
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2012 Maciej Niedzielski
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <cassert>
+
+#include <boost/algorithm/string.hpp>
+#include <boost/regex.hpp>
+#include <boost/bind.hpp>
+#include <boost/numeric/conversion/cast.hpp>
+
+#include <Swiften/Base/foreach.h>
+#include <Swift/Controllers/HighlightManager.h>
+#include <Swift/Controllers/Highlighter.h>
+#include <Swift/Controllers/Settings/SettingsProvider.h>
+#include <Swift/Controllers/SettingConstants.h>
+
+/* How does highlighting work?
+ *
+ * HighlightManager manages a list of if-then rules used to highlight messages.
+ * Rule is represented by HighlightRule. Action ("then" part) is HighlightAction.
+ *
+ *
+ * HighlightManager is also used as a factory for Highlighter objects.
+ * Each ChatControllerBase has its own Highlighter.
+ * Highligher may be customized by using setNick(), etc.
+ *
+ * ChatControllerBase passes incoming messages to Highlighter and gets HighlightAction in return
+ * (first matching rule is returned).
+ * If needed, HighlightAction is then passed back to Highlighter for further handling.
+ * This results in HighlightManager emiting onHighlight event,
+ * which is handled by SoundController to play sound notification
+ */
+
+namespace Swift {
+
+HighlightManager::HighlightManager(SettingsProvider* settings)
+ : settings_(settings)
+ , storingSettings_(false)
+{
+ loadSettings();
+ settings_->onSettingChanged.connect(boost::bind(&HighlightManager::handleSettingChanged, this, _1));
+}
+
+void HighlightManager::handleSettingChanged(const std::string& settingPath)
+{
+ if (!storingSettings_ && SettingConstants::HIGHLIGHT_RULES.getKey() == settingPath) {
+ loadSettings();
+ }
+}
+
+void HighlightManager::loadSettings()
+{
+ std::string highlightRules = settings_->getSetting(SettingConstants::HIGHLIGHT_RULES);
+ if (highlightRules == "@") {
+ rules_ = getDefaultRules();
+ } else {
+ rules_ = rulesFromString(highlightRules);
+ }
+}
+
+std::string HighlightManager::rulesToString() const
+{
+ std::string s;
+ foreach (HighlightRule r, rules_) {
+ s += r.toString() + '\f';
+ }
+ if (s.size()) {
+ s.erase(s.end() - 1);
+ }
+ return s;
+}
+
+std::vector<HighlightRule> HighlightManager::rulesFromString(const std::string& rulesString)
+{
+ std::vector<HighlightRule> rules;
+ std::string s(rulesString);
+ typedef boost::split_iterator<std::string::iterator> split_iterator;
+ for (split_iterator it = boost::make_split_iterator(s, boost::first_finder("\f")); it != split_iterator(); ++it) {
+ HighlightRule r = HighlightRule::fromString(boost::copy_range<std::string>(*it));
+ if (!r.isEmpty()) {
+ rules.push_back(r);
+ }
+ }
+ return rules;
+}
+
+std::vector<HighlightRule> HighlightManager::getDefaultRules()
+{
+ std::vector<HighlightRule> rules;
+ HighlightRule r;
+ r.setMatchChat(true);
+ r.getAction().setPlaySound(true);
+ rules.push_back(r);
+ return rules;
+}
+
+void HighlightManager::storeSettings()
+{
+ storingSettings_ = true; // don't reload settings while saving
+ settings_->storeSetting(SettingConstants::HIGHLIGHT_RULES, rulesToString());
+ storingSettings_ = false;
+}
+
+HighlightRule HighlightManager::getRule(int index) const
+{
+ assert(index >= 0 && static_cast<size_t>(index) < rules_.size());
+ return rules_[static_cast<size_t>(index)];
+}
+
+void HighlightManager::setRule(int index, const HighlightRule& rule)
+{
+ assert(index >= 0 && static_cast<size_t>(index) < rules_.size());
+ rules_[static_cast<size_t>(index)] = rule;
+ storeSettings();
+}
+
+void HighlightManager::insertRule(int index, const HighlightRule& rule)
+{
+ assert(index >= 0 && boost::numeric_cast<std::vector<std::string>::size_type>(index) <= rules_.size());
+ rules_.insert(rules_.begin() + index, rule);
+ storeSettings();
+}
+
+void HighlightManager::removeRule(int index)
+{
+ assert(index >= 0 && boost::numeric_cast<std::vector<std::string>::size_type>(index) < rules_.size());
+ rules_.erase(rules_.begin() + index);
+ storeSettings();
+}
+
+Highlighter* HighlightManager::createHighlighter()
+{
+ return new Highlighter(this);
+}
+
+}
diff --git a/Swift/Controllers/HighlightManager.h b/Swift/Controllers/HighlightManager.h
new file mode 100644
index 0000000..d195d05
--- /dev/null
+++ b/Swift/Controllers/HighlightManager.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2012 Maciej Niedzielski
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <vector>
+#include <string>
+
+#include <Swiften/Base/boost_bsignals.h>
+#include <Swift/Controllers/HighlightRule.h>
+
+namespace Swift {
+
+ class SettingsProvider;
+ class Highlighter;
+
+ class HighlightManager {
+ public:
+ HighlightManager(SettingsProvider* settings);
+
+ Highlighter* createHighlighter();
+
+ const std::vector<HighlightRule>& getRules() const { return rules_; }
+ HighlightRule getRule(int index) const;
+ void setRule(int index, const HighlightRule& rule);
+ void insertRule(int index, const HighlightRule& rule);
+ void removeRule(int index);
+
+ boost::signal<void (const HighlightAction&)> onHighlight;
+
+ private:
+ void handleSettingChanged(const std::string& settingPath);
+
+ std::string rulesToString() const;
+ static std::vector<HighlightRule> rulesFromString(const std::string&);
+ static std::vector<HighlightRule> getDefaultRules();
+
+ SettingsProvider* settings_;
+ bool storingSettings_;
+ void storeSettings();
+ void loadSettings();
+
+ std::vector<HighlightRule> rules_;
+ };
+
+}
diff --git a/Swift/Controllers/HighlightRule.cpp b/Swift/Controllers/HighlightRule.cpp
new file mode 100644
index 0000000..28f26cf
--- /dev/null
+++ b/Swift/Controllers/HighlightRule.cpp
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2012 Maciej Niedzielski
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <algorithm>
+#include <boost/algorithm/string.hpp>
+#include <boost/lambda/lambda.hpp>
+
+#include <Swiften/Base/foreach.h>
+#include <Swift/Controllers/HighlightRule.h>
+
+namespace Swift {
+
+HighlightRule::HighlightRule()
+ : nickIsKeyword_(false)
+ , matchCase_(false)
+ , matchWholeWords_(false)
+ , matchChat_(false)
+ , matchMUC_(false)
+{
+}
+
+boost::regex HighlightRule::regexFromString(const std::string & s) const
+{
+ // escape regex special characters: ^.$| etc
+ // these need to be escaped: [\^\$\|.........]
+ // and then C++ requires '\' to be escaped, too....
+ static const boost::regex esc("([\\^\\.\\$\\|\\(\\)\\[\\]\\*\\+\\?\\/\\{\\}\\\\])");
+ // matched character should be prepended with '\'
+ // replace matched special character with \\\1
+ // and escape once more for C++ rules...
+ static const std::string rep("\\\\\\1");
+ std::string escaped = boost::regex_replace(s , esc, rep);
+
+ std::string word = matchWholeWords_ ? "\\b" : "";
+ boost::regex::flag_type flags = boost::regex::normal;
+ if (!matchCase_) {
+ flags |= boost::regex::icase;
+ }
+ return boost::regex(word + escaped + word, flags);
+}
+
+void HighlightRule::updateRegex() const
+{
+ keywordRegex_.clear();
+ foreach (const std::string & k, keywords_) {
+ keywordRegex_.push_back(regexFromString(k));
+ }
+ senderRegex_.clear();
+ foreach (const std::string & s, senders_) {
+ senderRegex_.push_back(regexFromString(s));
+ }
+}
+
+std::string HighlightRule::boolToString(bool b)
+{
+ return b ? "1" : "0";
+}
+
+bool HighlightRule::boolFromString(const std::string& s)
+{
+ return s == "1";
+}
+
+std::string HighlightRule::toString() const
+{
+ std::vector<std::string> v;
+ v.push_back(boost::join(senders_, "\t"));
+ v.push_back(boost::join(keywords_, "\t"));
+ v.push_back(boolToString(nickIsKeyword_));
+ v.push_back(boolToString(matchChat_));
+ v.push_back(boolToString(matchMUC_));
+ v.push_back(boolToString(matchCase_));
+ v.push_back(boolToString(matchWholeWords_));
+ v.push_back(boolToString(action_.highlightText()));
+ v.push_back(action_.getTextColor());
+ v.push_back(action_.getTextBackground());
+ v.push_back(boolToString(action_.playSound()));
+ v.push_back(action_.getSoundFile());
+ return boost::join(v, "\n");
+}
+
+HighlightRule HighlightRule::fromString(const std::string& s)
+{
+ std::vector<std::string> v;
+ boost::split(v, s, boost::is_any_of("\n"));
+
+ HighlightRule r;
+ size_t i = 0;
+ try {
+ boost::split(r.senders_, v.at(i++), boost::is_any_of("\t"));
+ r.senders_.erase(std::remove_if(r.senders_.begin(), r.senders_.end(), boost::lambda::_1 == ""), r.senders_.end());
+ boost::split(r.keywords_, v.at(i++), boost::is_any_of("\t"));
+ r.keywords_.erase(std::remove_if(r.keywords_.begin(), r.keywords_.end(), boost::lambda::_1 == ""), r.keywords_.end());
+ r.nickIsKeyword_ = boolFromString(v.at(i++));
+ r.matchChat_ = boolFromString(v.at(i++));
+ r.matchMUC_ = boolFromString(v.at(i++));
+ r.matchCase_ = boolFromString(v.at(i++));
+ r.matchWholeWords_ = boolFromString(v.at(i++));
+ r.action_.setHighlightText(boolFromString(v.at(i++)));
+ r.action_.setTextColor(v.at(i++));
+ r.action_.setTextBackground(v.at(i++));
+ r.action_.setPlaySound(boolFromString(v.at(i++)));
+ r.action_.setSoundFile(v.at(i++));
+ }
+ catch (std::out_of_range) {
+ // this may happen if more properties are added to HighlightRule object, etc...
+ // in such case, default values (set by default constructor) will be used
+ }
+
+ r.updateRegex();
+
+ return r;
+}
+
+bool HighlightRule::isMatch(const std::string& body, const std::string& sender, const std::string& nick, MessageType messageType) const
+{
+ if ((messageType == HighlightRule::ChatMessage && matchChat_) || (messageType == HighlightRule::MUCMessage && matchMUC_)) {
+
+ bool matchesKeyword = keywords_.empty() && (nick.empty() || !nickIsKeyword_);
+ bool matchesSender = senders_.empty();
+
+ foreach (const boost::regex & rx, keywordRegex_) {
+ if (boost::regex_search(body, rx)) {
+ matchesKeyword = true;
+ break;
+ }
+ }
+
+ if (!matchesKeyword && nickIsKeyword_ && !nick.empty()) {
+ if (boost::regex_search(body, regexFromString(nick))) {
+ matchesKeyword = true;
+ }
+ }
+
+ foreach (const boost::regex & rx, senderRegex_) {
+ if (boost::regex_search(sender, rx)) {
+ matchesSender = true;
+ break;
+ }
+ }
+
+ if (matchesKeyword && matchesSender) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void HighlightRule::setSenders(const std::vector<std::string>& senders)
+{
+ senders_ = senders;
+ updateRegex();
+}
+
+void HighlightRule::setKeywords(const std::vector<std::string>& keywords)
+{
+ keywords_ = keywords;
+ updateRegex();
+}
+
+void HighlightRule::setNickIsKeyword(bool nickIsKeyword)
+{
+ nickIsKeyword_ = nickIsKeyword;
+ updateRegex();
+}
+
+void HighlightRule::setMatchCase(bool matchCase)
+{
+ matchCase_ = matchCase;
+ updateRegex();
+}
+
+void HighlightRule::setMatchWholeWords(bool matchWholeWords)
+{
+ matchWholeWords_ = matchWholeWords;
+ updateRegex();
+}
+
+void HighlightRule::setMatchChat(bool matchChat)
+{
+ matchChat_ = matchChat;
+ updateRegex();
+}
+
+void HighlightRule::setMatchMUC(bool matchMUC)
+{
+ matchMUC_ = matchMUC;
+ updateRegex();
+}
+
+bool HighlightRule::isEmpty() const
+{
+ return senders_.empty() && keywords_.empty() && !nickIsKeyword_ && !matchChat_ && !matchMUC_ && action_.isEmpty();
+}
+
+}
diff --git a/Swift/Controllers/HighlightRule.h b/Swift/Controllers/HighlightRule.h
new file mode 100644
index 0000000..1abfa5a
--- /dev/null
+++ b/Swift/Controllers/HighlightRule.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2012 Maciej Niedzielski
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <vector>
+#include <string>
+
+#include <boost/regex.hpp>
+
+#include <Swift/Controllers/HighlightAction.h>
+
+namespace Swift {
+
+ class HighlightRule {
+ public:
+ HighlightRule();
+
+ enum MessageType { ChatMessage, MUCMessage };
+
+ bool isMatch(const std::string& body, const std::string& sender, const std::string& nick, MessageType) const;
+
+ const HighlightAction& getAction() const { return action_; }
+ HighlightAction& getAction() { return action_; }
+
+ static HighlightRule fromString(const std::string&);
+ std::string toString() const;
+
+ const std::vector<std::string>& getSenders() const { return senders_; }
+ void setSenders(const std::vector<std::string>&);
+
+ const std::vector<std::string>& getKeywords() const { return keywords_; }
+ void setKeywords(const std::vector<std::string>&);
+
+ bool getNickIsKeyword() const { return nickIsKeyword_; }
+ void setNickIsKeyword(bool);
+
+ bool getMatchCase() const { return matchCase_; }
+ void setMatchCase(bool);
+
+ bool getMatchWholeWords() const { return matchWholeWords_; }
+ void setMatchWholeWords(bool);
+
+ bool getMatchChat() const { return matchChat_; }
+ void setMatchChat(bool);
+
+ bool getMatchMUC() const { return matchMUC_; }
+ void setMatchMUC(bool);
+
+ bool isEmpty() const;
+
+ private:
+ static std::string boolToString(bool);
+ static bool boolFromString(const std::string&);
+
+ std::vector<std::string> senders_;
+ std::vector<std::string> keywords_;
+ bool nickIsKeyword_;
+
+ mutable std::vector<boost::regex> senderRegex_;
+ mutable std::vector<boost::regex> keywordRegex_;
+ void updateRegex() const;
+ boost::regex regexFromString(const std::string&) const;
+
+ bool matchCase_;
+ bool matchWholeWords_;
+
+ bool matchChat_;
+ bool matchMUC_;
+
+ HighlightAction action_;
+ };
+
+}
diff --git a/Swift/Controllers/Highlighter.cpp b/Swift/Controllers/Highlighter.cpp
new file mode 100644
index 0000000..754641a
--- /dev/null
+++ b/Swift/Controllers/Highlighter.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2012 Maciej Niedzielski
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <Swiften/Base/foreach.h>
+#include <Swift/Controllers/Highlighter.h>
+#include <Swift/Controllers/HighlightManager.h>
+
+namespace Swift {
+
+Highlighter::Highlighter(HighlightManager* manager)
+ : manager_(manager)
+{
+ setMode(ChatMode);
+}
+
+void Highlighter::setMode(Mode mode)
+{
+ mode_ = mode;
+ messageType_ = mode_ == ChatMode ? HighlightRule::ChatMessage : HighlightRule::MUCMessage;
+}
+
+HighlightAction Highlighter::findAction(const std::string& body, const std::string& sender) const
+{
+ foreach (const HighlightRule & r, manager_->getRules()) {
+ if (r.isMatch(body, sender, nick_, messageType_)) {
+ return r.getAction();
+ }
+ }
+
+ return HighlightAction();
+}
+
+void Highlighter::handleHighlightAction(const HighlightAction& action)
+{
+ manager_->onHighlight(action);
+}
+
+}
diff --git a/Swift/Controllers/Highlighter.h b/Swift/Controllers/Highlighter.h
new file mode 100644
index 0000000..d026f29
--- /dev/null
+++ b/Swift/Controllers/Highlighter.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2012 Maciej Niedzielski
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <string>
+
+#include <Swift/Controllers/HighlightRule.h>
+
+namespace Swift {
+
+ class HighlightManager;
+
+ class Highlighter {
+ public:
+ Highlighter(HighlightManager* manager);
+
+ enum Mode { ChatMode, MUCMode };
+ void setMode(Mode mode);
+
+ void setNick(const std::string& nick) { nick_ = nick; }
+
+ HighlightAction findAction(const std::string& body, const std::string& sender) const;
+
+ void handleHighlightAction(const HighlightAction& action);
+
+ private:
+ HighlightManager* manager_;
+ Mode mode_;
+ HighlightRule::MessageType messageType_;
+ std::string nick_;
+ };
+
+}
diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp
index 28d890d..87ec94d 100644
--- a/Swift/Controllers/MainController.cpp
+++ b/Swift/Controllers/MainController.cpp
@@ -4,6 +4,12 @@
* See Documentation/Licenses/GPLv3.txt for more information.
*/
+/*
+ * Copyright (c) 2013 Remko Tronçon
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
#include <Swift/Controllers/MainController.h>
#include <boost/bind.hpp>
@@ -69,6 +75,7 @@
#include "Swift/Controllers/Storages/CertificateStorageTrustChecker.h"
#include "Swiften/Network/NetworkFactories.h"
#include <Swift/Controllers/ProfileController.h>
+#include <Swift/Controllers/ShowProfileController.h>
#include <Swift/Controllers/ContactEditController.h>
#include <Swift/Controllers/XMPPURIController.h>
#include "Swift/Controllers/AdHocManager.h"
@@ -78,6 +85,8 @@
#include <Swiften/Client/ClientXMLTracer.h>
#include <Swift/Controllers/SettingConstants.h>
#include <Swiften/Client/StanzaChannel.h>
+#include <Swift/Controllers/HighlightManager.h>
+#include <Swift/Controllers/HighlightEditorController.h>
namespace Swift {
@@ -121,6 +130,7 @@ MainController::MainController(
historyViewController_ = NULL;
eventWindowController_ = NULL;
profileController_ = NULL;
+ showProfileController_ = NULL;
contactEditController_ = NULL;
userSearchControllerChat_ = NULL;
userSearchControllerAdd_ = NULL;
@@ -142,7 +152,11 @@ MainController::MainController(
systemTrayController_ = new SystemTrayController(eventController_, systemTray);
loginWindow_ = uiFactory_->createLoginWindow(uiEventStream_);
loginWindow_->setShowNotificationToggle(!notifier->isExternallyConfigured());
- soundEventController_ = new SoundEventController(eventController_, soundPlayer, settings);
+
+ highlightManager_ = new HighlightManager(settings_);
+ highlightEditorController_ = new HighlightEditorController(uiEventStream_, uiFactory_, highlightManager_);
+
+ soundEventController_ = new SoundEventController(eventController_, soundPlayer, settings, highlightManager_);
xmppURIController_ = new XMPPURIController(uriHandler_, uiEventStream_);
@@ -202,6 +216,8 @@ MainController::~MainController() {
eventController_->disconnectAll();
resetClient();
+ delete highlightEditorController_;
+ delete highlightManager_;
delete fileTransferListController_;
delete xmlConsoleController_;
delete xmppURIController_;
@@ -225,6 +241,8 @@ void MainController::resetClient() {
contactEditController_ = NULL;
delete profileController_;
profileController_ = NULL;
+ delete showProfileController_;
+ showProfileController_ = NULL;
delete eventWindowController_;
eventWindowController_ = NULL;
delete chatsManager_;
@@ -297,7 +315,8 @@ void MainController::handleConnected() {
myStatusLooksOnline_ = true;
if (freshLogin) {
profileController_ = new ProfileController(client_->getVCardManager(), uiFactory_, uiEventStream_);
- srand(time(NULL));
+ showProfileController_ = new ShowProfileController(client_->getVCardManager(), uiFactory_, uiEventStream_);
+ srand(static_cast<unsigned int>(time(NULL)));
int randomPort = 10000 + rand() % 10000;
client_->getFileTransferManager()->startListeningOnPort(randomPort);
ftOverview_ = new FileTransferOverview(client_->getFileTransferManager());
@@ -318,9 +337,9 @@ void MainController::handleConnected() {
#ifdef SWIFT_EXPERIMENTAL_HISTORY
historyController_ = new HistoryController(storages_->getHistoryStorage());
historyViewController_ = new HistoryViewController(jid_, uiEventStream_, historyController_, client_->getNickResolver(), client_->getAvatarManager(), client_->getPresenceOracle(), uiFactory_);
- chatsManager_ = new ChatsManager(jid_, client_->getStanzaChannel(), client_->getIQRouter(), eventController_, uiFactory_, uiFactory_, client_->getNickResolver(), client_->getPresenceOracle(), client_->getPresenceSender(), uiEventStream_, uiFactory_, useDelayForLatency_, networkFactories_->getTimerFactory(), client_->getMUCRegistry(), client_->getEntityCapsProvider(), client_->getMUCManager(), uiFactory_, profileSettings_, ftOverview_, client_->getRoster(), !settings_->getSetting(SettingConstants::REMEMBER_RECENT_CHATS), settings_, historyController_, whiteboardManager_);
+ chatsManager_ = new ChatsManager(jid_, client_->getStanzaChannel(), client_->getIQRouter(), eventController_, uiFactory_, uiFactory_, client_->getNickResolver(), client_->getPresenceOracle(), client_->getPresenceSender(), uiEventStream_, uiFactory_, useDelayForLatency_, networkFactories_->getTimerFactory(), client_->getMUCRegistry(), client_->getEntityCapsProvider(), client_->getMUCManager(), uiFactory_, profileSettings_, ftOverview_, client_->getRoster(), !settings_->getSetting(SettingConstants::REMEMBER_RECENT_CHATS), settings_, historyController_, whiteboardManager_, highlightManager_);
#else
- chatsManager_ = new ChatsManager(jid_, client_->getStanzaChannel(), client_->getIQRouter(), eventController_, uiFactory_, uiFactory_, client_->getNickResolver(), client_->getPresenceOracle(), client_->getPresenceSender(), uiEventStream_, uiFactory_, useDelayForLatency_, networkFactories_->getTimerFactory(), client_->getMUCRegistry(), client_->getEntityCapsProvider(), client_->getMUCManager(), uiFactory_, profileSettings_, ftOverview_, client_->getRoster(), !settings_->getSetting(SettingConstants::REMEMBER_RECENT_CHATS), settings_, NULL, whiteboardManager_);
+ chatsManager_ = new ChatsManager(jid_, client_->getStanzaChannel(), client_->getIQRouter(), eventController_, uiFactory_, uiFactory_, client_->getNickResolver(), client_->getPresenceOracle(), client_->getPresenceSender(), uiEventStream_, uiFactory_, useDelayForLatency_, networkFactories_->getTimerFactory(), client_->getMUCRegistry(), client_->getEntityCapsProvider(), client_->getMUCManager(), uiFactory_, profileSettings_, ftOverview_, client_->getRoster(), !settings_->getSetting(SettingConstants::REMEMBER_RECENT_CHATS), settings_, NULL, whiteboardManager_, highlightManager_);
#endif
client_->onMessageReceived.connect(boost::bind(&ChatsManager::handleIncomingMessage, chatsManager_, _1));
@@ -369,7 +388,9 @@ void MainController::handleConnected() {
contactEditController_->setAvailable(true);
/* Send presence later to catch all the incoming presences. */
sendPresence(statusTracker_->getNextPresence());
+
/* Enable chats last of all, so rejoining MUCs has the right sent presence */
+ assert(chatsManager_);
chatsManager_->setOnline(true);
}
diff --git a/Swift/Controllers/MainController.h b/Swift/Controllers/MainController.h
index 2e5bd05..4f37e12 100644
--- a/Swift/Controllers/MainController.h
+++ b/Swift/Controllers/MainController.h
@@ -43,6 +43,7 @@ namespace Swift {
class MUCController;
class Notifier;
class ProfileController;
+ class ShowProfileController;
class ContactEditController;
class TogglableNotifier;
class PresenceNotifier;
@@ -71,6 +72,8 @@ namespace Swift {
class AdHocCommandWindowFactory;
class FileTransferOverview;
class WhiteboardManager;
+ class HighlightManager;
+ class HighlightEditorController;
class MainController {
public:
@@ -153,6 +156,7 @@ namespace Swift {
FileTransferListController* fileTransferListController_;
ChatsManager* chatsManager_;
ProfileController* profileController_;
+ ShowProfileController* showProfileController_;
ContactEditController* contactEditController_;
JID jid_;
JID boundJID_;
@@ -176,5 +180,7 @@ namespace Swift {
static const int SecondsToWaitBeforeForceQuitting;
FileTransferOverview* ftOverview_;
WhiteboardManager* whiteboardManager_;
+ HighlightManager* highlightManager_;
+ HighlightEditorController* highlightEditorController_;
};
}
diff --git a/Swift/Controllers/ProfileController.cpp b/Swift/Controllers/ProfileController.cpp
index 101e283..e641988 100644
--- a/Swift/Controllers/ProfileController.cpp
+++ b/Swift/Controllers/ProfileController.cpp
@@ -37,6 +37,7 @@ void ProfileController::handleUIEvent(UIEvent::ref event) {
if (!profileWindow) {
profileWindow = profileWindowFactory->createProfileWindow();
+ profileWindow->setEditable(true);
profileWindow->onVCardChangeRequest.connect(boost::bind(&ProfileController::handleVCardChangeRequest, this, _1));
vcardManager->onOwnVCardChanged.connect(boost::bind(&ProfileController::handleOwnVCardChanged, this, _1));
}
diff --git a/Swift/Controllers/Roster/ContactRosterItem.cpp b/Swift/Controllers/Roster/ContactRosterItem.cpp
index 8c388bf..5b1b6e0 100644
--- a/Swift/Controllers/Roster/ContactRosterItem.cpp
+++ b/Swift/Controllers/Roster/ContactRosterItem.cpp
@@ -24,12 +24,12 @@ StatusShow::Type ContactRosterItem::getStatusShow() const {
StatusShow::Type ContactRosterItem::getSimplifiedStatusShow() const {
switch (shownPresence_ ? shownPresence_->getShow() : StatusShow::None) {
- case StatusShow::Online: return StatusShow::Online; break;
- case StatusShow::Away: return StatusShow::Away; break;
- case StatusShow::XA: return StatusShow::Away; break;
- case StatusShow::FFC: return StatusShow::Online; break;
- case StatusShow::DND: return StatusShow::DND; break;
- case StatusShow::None: return StatusShow::None; break;
+ case StatusShow::Online: return StatusShow::Online;
+ case StatusShow::Away: return StatusShow::Away;
+ case StatusShow::XA: return StatusShow::Away;
+ case StatusShow::FFC: return StatusShow::Online;
+ case StatusShow::DND: return StatusShow::DND;
+ case StatusShow::None: return StatusShow::None;
}
assert(false);
return StatusShow::None;
diff --git a/Swift/Controllers/Roster/LeastCommonSubsequence.h b/Swift/Controllers/Roster/LeastCommonSubsequence.h
index dd3c95a..9d45679 100644
--- a/Swift/Controllers/Roster/LeastCommonSubsequence.h
+++ b/Swift/Controllers/Roster/LeastCommonSubsequence.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011 Remko Tronçon
+ * Copyright (c) 2011-2013 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
@@ -7,6 +7,7 @@
#pragma once
#include <vector>
+#include <boost/numeric/conversion/cast.hpp>
namespace Swift {
using std::equal_to;
@@ -14,8 +15,8 @@ namespace Swift {
namespace Detail {
template<typename XIt, typename YIt, typename Length, typename Predicate>
void computeLeastCommonSubsequenceMatrix(XIt xBegin, XIt xEnd, YIt yBegin, YIt yEnd, std::vector<Length>& result) {
- size_t width = std::distance(xBegin, xEnd) + 1;
- size_t height = std::distance(yBegin, yEnd) + 1;
+ size_t width = static_cast<size_t>(std::distance(xBegin, xEnd) + 1);
+ size_t height = static_cast<size_t>(std::distance(yBegin, yEnd) + 1);
result.resize(width * height);
// Initialize first row & column
@@ -30,7 +31,7 @@ namespace Swift {
Predicate predicate;
for (size_t i = 1; i < width; ++i) {
for (size_t j = 1; j < height; ++j) {
- result[i + j*width] = (predicate(*(xBegin + i-1), *(yBegin + j-1)) ? result[(i-1) + (j-1)*width] + 1 : std::max(result[i + (j-1)*width], result[i-1 + (j*width)]));
+ result[i + j*width] = predicate(*(xBegin + boost::numeric_cast<long long>(i)-1), *(yBegin + boost::numeric_cast<long long >(j)-1)) ? result[(i-1) + (j-1)*width] + 1 : std::max(result[i + (j-1)*width], result[i-1 + (j*width)]);
}
}
}
@@ -46,29 +47,29 @@ namespace Swift {
typename std::vector<X>::const_iterator yBegin = y.begin();
while (xBegin < x.end() && yBegin < y.end() && insertRemovePredicate(*xBegin, *yBegin)) {
if (updatePredicate(*xBegin, *yBegin)) {
- updates.push_back(std::distance(x.begin(), xBegin));
- postUpdates.push_back(std::distance(y.begin(), yBegin));
+ updates.push_back(static_cast<size_t>(std::distance(x.begin(), xBegin)));
+ postUpdates.push_back(static_cast<size_t>(std::distance(y.begin(), yBegin)));
}
++xBegin;
++yBegin;
}
- size_t prefixLength = std::distance(x.begin(), xBegin);
+ size_t prefixLength = static_cast<size_t>(std::distance(x.begin(), xBegin));
// Find & handle common suffix (Optimization to reduce LCS matrix size)
typename std::vector<X>::const_reverse_iterator xEnd = x.rbegin();
typename std::vector<X>::const_reverse_iterator yEnd = y.rbegin();
while (xEnd.base() > xBegin && yEnd.base() > yBegin && insertRemovePredicate(*xEnd, *yEnd)) {
if (updatePredicate(*xEnd, *yEnd)) {
- updates.push_back(std::distance(x.begin(), xEnd.base()) - 1);
- postUpdates.push_back(std::distance(y.begin(), yEnd.base()) - 1);
+ updates.push_back(static_cast<size_t>(std::distance(x.begin(), xEnd.base()) - 1));
+ postUpdates.push_back(static_cast<size_t>(std::distance(y.begin(), yEnd.base()) - 1));
}
++xEnd;
++yEnd;
}
// Compute lengths
- size_t xLength = std::distance(xBegin, xEnd.base());
- size_t yLength = std::distance(yBegin, yEnd.base());
+ size_t xLength = static_cast<size_t>(std::distance(xBegin, xEnd.base()));
+ size_t yLength = static_cast<size_t>(std::distance(yBegin, yEnd.base()));
// Compute LCS matrix
std::vector<unsigned int> lcs;
@@ -77,7 +78,7 @@ namespace Swift {
// Process LCS matrix
size_t i = xLength;
size_t j = yLength;
- const size_t width = xLength + 1;
+ size_t width = xLength + 1;
while (true) {
if (i > 0 && j > 0 && insertRemovePredicate(x[prefixLength + i-1], y[prefixLength + j-1])) {
// x[i-1] same
diff --git a/Swift/Controllers/Roster/Roster.cpp b/Swift/Controllers/Roster/Roster.cpp
index 65cf4d2..b5c5998 100644
--- a/Swift/Controllers/Roster/Roster.cpp
+++ b/Swift/Controllers/Roster/Roster.cpp
@@ -198,13 +198,13 @@ void Roster::removeFilter(RosterFilter *filter) {
}
void Roster::filterContact(ContactRosterItem* contact, GroupRosterItem* group) {
- int oldDisplayedSize = group->getDisplayedChildren().size();
+ size_t oldDisplayedSize = group->getDisplayedChildren().size();
bool hide = true;
foreach (RosterFilter *filter, filters_) {
hide &= (*filter)(contact);
}
group->setDisplayed(contact, filters_.empty() || !hide);
- int newDisplayedSize = group->getDisplayedChildren().size();
+ size_t newDisplayedSize = group->getDisplayedChildren().size();
if (oldDisplayedSize == 0 && newDisplayedSize > 0) {
onGroupAdded(group);
}
diff --git a/Swift/Controllers/Roster/Roster.h b/Swift/Controllers/Roster/Roster.h
index 2fcfba5..74547d6 100644
--- a/Swift/Controllers/Roster/Roster.h
+++ b/Swift/Controllers/Roster/Roster.h
@@ -36,10 +36,10 @@ class Roster {
void applyOnItems(const RosterItemOperation& operation);
void applyOnAllItems(const RosterItemOperation& operation);
void applyOnItem(const RosterItemOperation& operation, const JID& jid);
- void addFilter(RosterFilter *filter) {filters_.push_back(filter);filterAll();};
+ void addFilter(RosterFilter *filter) {filters_.push_back(filter);filterAll();}
void removeFilter(RosterFilter *filter);
GroupRosterItem* getRoot();
- std::vector<RosterFilter*> getFilters() {return filters_;};
+ std::vector<RosterFilter*> getFilters() {return filters_;}
boost::signal<void (GroupRosterItem*)> onChildrenChanged;
boost::signal<void (GroupRosterItem*)> onGroupAdded;
boost::signal<void (RosterItem*)> onDataChanged;
diff --git a/Swift/Controllers/Roster/RosterController.h b/Swift/Controllers/Roster/RosterController.h
index 5e40124..ec07574 100644
--- a/Swift/Controllers/Roster/RosterController.h
+++ b/Swift/Controllers/Roster/RosterController.h
@@ -45,7 +45,7 @@ namespace Swift {
RosterController(const JID& jid, XMPPRoster* xmppRoster, AvatarManager* avatarManager, MainWindowFactory* mainWindowFactory, NickManager* nickManager, NickResolver* nickResolver, PresenceOracle* presenceOracle, SubscriptionManager* subscriptionManager, EventController* eventController, UIEventStream* uiEventStream, IQRouter* iqRouter_, SettingsProvider* settings, EntityCapsProvider* entityCapsProvider, FileTransferOverview* fileTransferOverview);
~RosterController();
void showRosterWindow();
- MainWindow* getWindow() {return mainWindow_;};
+ MainWindow* getWindow() {return mainWindow_;}
boost::signal<void (StatusShow::Type, const std::string&)> onChangeStatusRequest;
boost::signal<void ()> onSignOutRequest;
void handleAvatarChanged(const JID& jid);
diff --git a/Swift/Controllers/Roster/RosterItemOperation.h b/Swift/Controllers/Roster/RosterItemOperation.h
index 691c8ef..f1dff8d 100644
--- a/Swift/Controllers/Roster/RosterItemOperation.h
+++ b/Swift/Controllers/Roster/RosterItemOperation.h
@@ -12,10 +12,10 @@ namespace Swift {
class RosterItemOperation {
public:
- RosterItemOperation(bool requiresLookup = false, const JID& lookupJID = JID()) : requiresLookup_(requiresLookup), lookupJID_(lookupJID) {};
- virtual ~RosterItemOperation() {};
- bool requiresLookup() const {return requiresLookup_;};
- const JID& lookupJID() const {return lookupJID_;};
+ RosterItemOperation(bool requiresLookup = false, const JID& lookupJID = JID()) : requiresLookup_(requiresLookup), lookupJID_(lookupJID) {}
+ virtual ~RosterItemOperation() {}
+ bool requiresLookup() const {return requiresLookup_;}
+ const JID& lookupJID() const {return lookupJID_;}
/**
* This is called when iterating over possible subjects, so must check it's
* applying to the right items - even if requiresLookup() is true an item
diff --git a/Swift/Controllers/Roster/TableRoster.cpp b/Swift/Controllers/Roster/TableRoster.cpp
index c00bf4f..eb036db 100644
--- a/Swift/Controllers/Roster/TableRoster.cpp
+++ b/Swift/Controllers/Roster/TableRoster.cpp
@@ -9,6 +9,7 @@
#include <boost/cast.hpp>
#include <cassert>
#include <algorithm>
+#include <boost/numeric/conversion/cast.hpp>
#include <Swiften/Base/foreach.h>
#include <Swiften/Network/TimerFactory.h>
@@ -132,13 +133,13 @@ void TableRoster::handleUpdateTimerTick() {
computeIndexDiff<Item, ItemEquals, ItemNeedsUpdate >(sections[sectionUpdates[i]].items, newSections[sectionPostUpdates[i]].items, itemUpdates, itemPostUpdates, itemRemoves, itemInserts);
size_t end = update.insertedRows.size();
update.insertedRows.resize(update.insertedRows.size() + itemInserts.size());
- std::transform(itemInserts.begin(), itemInserts.end(), update.insertedRows.begin() + end, CreateIndexForSection(sectionPostUpdates[i]));
+ std::transform(itemInserts.begin(), itemInserts.end(), update.insertedRows.begin() + boost::numeric_cast<long long>(end), CreateIndexForSection(sectionPostUpdates[i]));
end = update.deletedRows.size();
update.deletedRows.resize(update.deletedRows.size() + itemRemoves.size());
- std::transform(itemRemoves.begin(), itemRemoves.end(), update.deletedRows.begin() + end, CreateIndexForSection(sectionUpdates[i]));
+ std::transform(itemRemoves.begin(), itemRemoves.end(), update.deletedRows.begin() + boost::numeric_cast<long long>(end), CreateIndexForSection(sectionUpdates[i]));
end = update.updatedRows.size();
update.updatedRows.resize(update.updatedRows.size() + itemUpdates.size());
- std::transform(itemUpdates.begin(), itemUpdates.end(), update.updatedRows.begin() + end, CreateIndexForSection(sectionPostUpdates[i]));
+ std::transform(itemUpdates.begin(), itemUpdates.end(), update.updatedRows.begin() + boost::numeric_cast<long long>(end), CreateIndexForSection(sectionPostUpdates[i]));
}
// Switch the old model with the new
diff --git a/Swift/Controllers/Roster/UnitTest/RosterControllerTest.cpp b/Swift/Controllers/Roster/UnitTest/RosterControllerTest.cpp
index fbee894..e439c78 100644
--- a/Swift/Controllers/Roster/UnitTest/RosterControllerTest.cpp
+++ b/Swift/Controllers/Roster/UnitTest/RosterControllerTest.cpp
@@ -84,7 +84,7 @@ class RosterControllerTest : public CppUnit::TestFixture {
ftOverview_ = new FileTransferOverview(ftManager_);
rosterController_ = new RosterController(jid_, xmppRoster_, avatarManager_, mainWindowFactory_, nickManager_, nickResolver_, presenceOracle_, subscriptionManager_, eventController_, uiEventStream_, router_, settings_, entityCapsManager_, ftOverview_);
mainWindow_ = mainWindowFactory_->last;
- };
+ }
void tearDown() {
delete rosterController_;
@@ -105,7 +105,7 @@ class RosterControllerTest : public CppUnit::TestFixture {
delete uiEventStream_;
delete settings_;
delete xmppRoster_;
- };
+ }
GroupRosterItem* groupChild(size_t i) {
return dynamic_cast<GroupRosterItem*>(CHILDREN[i]);
@@ -133,7 +133,7 @@ class RosterControllerTest : public CppUnit::TestFixture {
CPPUNIT_ASSERT(item2);
CPPUNIT_ASSERT_EQUAL(presence->getStatus(), item2->getStatusText());
- };
+ }
void testHighestPresence() {
std::vector<std::string> groups;
@@ -153,7 +153,7 @@ class RosterControllerTest : public CppUnit::TestFixture {
ContactRosterItem* item = dynamic_cast<ContactRosterItem*>(dynamic_cast<GroupRosterItem*>(CHILDREN[0])->getChildren()[0]);
CPPUNIT_ASSERT(item);
CPPUNIT_ASSERT_EQUAL(highPresence->getStatus(), item->getStatusText());
- };
+ }
void testNotHighestPresence() {
std::vector<std::string> groups;
@@ -173,7 +173,7 @@ class RosterControllerTest : public CppUnit::TestFixture {
ContactRosterItem* item = dynamic_cast<ContactRosterItem*>(dynamic_cast<GroupRosterItem*>(CHILDREN[0])->getChildren()[0]);
CPPUNIT_ASSERT(item);
CPPUNIT_ASSERT_EQUAL(highPresence->getStatus(), item->getStatusText());
- };
+ }
void testUnavailablePresence() {
std::vector<std::string> groups;
@@ -215,7 +215,7 @@ class RosterControllerTest : public CppUnit::TestFixture {
CPPUNIT_ASSERT_EQUAL(lowPresenceOffline->getStatus(), high->getStatus());
CPPUNIT_ASSERT_EQUAL(StatusShow::None, item->getStatusShow());
CPPUNIT_ASSERT_EQUAL(lowPresenceOffline->getStatus(), item->getStatusText());
- };
+ }
void testAdd() {
std::vector<std::string> groups;
@@ -225,7 +225,7 @@ class RosterControllerTest : public CppUnit::TestFixture {
CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(CHILDREN.size()));
//CPPUNIT_ASSERT_EQUAL(std::string("Bob"), xmppRoster_->getNameForJID(JID("foo@bar.com")));
- };
+ }
void testAddSubscription() {
std::vector<std::string> groups;
@@ -242,7 +242,7 @@ class RosterControllerTest : public CppUnit::TestFixture {
CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(CHILDREN.size()));
CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(groupChild(0)->getChildren().size()));
- };
+ }
void testReceiveRename() {
std::vector<std::string> groups;
@@ -256,7 +256,7 @@ class RosterControllerTest : public CppUnit::TestFixture {
CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(CHILDREN.size()));
CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(groupChild(0)->getChildren().size()));
CPPUNIT_ASSERT_EQUAL(std::string("NewName"), groupChild(0)->getChildren()[0]->getDisplayName());
- };
+ }
void testReceiveRegroup() {
std::vector<std::string> oldGroups;
@@ -282,7 +282,7 @@ class RosterControllerTest : public CppUnit::TestFixture {
CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(groupChild(0)->getChildren().size()));
CPPUNIT_ASSERT_EQUAL(std::string("new name"), groupChild(0)->getChildren()[0]->getDisplayName());
CPPUNIT_ASSERT_EQUAL(std::string("Best Group"), groupChild(0)->getDisplayName());
- };
+ }
void testSendRename() {
JID jid("testling@wonderland.lit");
diff --git a/Swift/Controllers/Roster/UnitTest/TableRosterTest.cpp b/Swift/Controllers/Roster/UnitTest/TableRosterTest.cpp
index e433b50..db8a2fd 100644
--- a/Swift/Controllers/Roster/UnitTest/TableRosterTest.cpp
+++ b/Swift/Controllers/Roster/UnitTest/TableRosterTest.cpp
@@ -6,6 +6,8 @@
#include <Swift/Controllers/Roster/TableRoster.h>
+std::ostream& operator<<(std::ostream& os, const Swift::TableRoster::Index& i);
+
std::ostream& operator<<(std::ostream& os, const Swift::TableRoster::Index& i) {
os << "(" << i.section << ", " << i.row << ")";
return os;
diff --git a/Swift/Controllers/SConscript b/Swift/Controllers/SConscript
index 7cd017b..26b9334 100644
--- a/Swift/Controllers/SConscript
+++ b/Swift/Controllers/SConscript
@@ -30,6 +30,7 @@ if env["SCONS_STAGE"] == "build" :
"Chat/UserSearchController.cpp",
"MainController.cpp",
"ProfileController.cpp",
+ "ShowProfileController.cpp",
"ContactEditController.cpp",
"FileTransfer/FileTransferController.cpp",
"FileTransfer/FileTransferOverview.cpp",
@@ -74,7 +75,13 @@ if env["SCONS_STAGE"] == "build" :
"XMPPURIController.cpp",
"ChatMessageSummarizer.cpp",
"SettingConstants.cpp",
- "WhiteboardManager.cpp"
+ "WhiteboardManager.cpp",
+ "StatusCache.cpp",
+ "HighlightAction.cpp",
+ "HighlightEditorController.cpp",
+ "HighlightManager.cpp",
+ "HighlightRule.cpp",
+ "Highlighter.cpp"
])
env.Append(UNITTEST_SOURCES = [
@@ -89,4 +96,5 @@ if env["SCONS_STAGE"] == "build" :
File("UnitTest/MockChatWindow.cpp"),
File("UnitTest/ChatMessageSummarizerTest.cpp"),
File("Settings/UnitTest/SettingsProviderHierachyTest.cpp"),
+ File("UnitTest/HighlightRuleTest.cpp"),
])
diff --git a/Swift/Controllers/SettingConstants.cpp b/Swift/Controllers/SettingConstants.cpp
index 7ab4ac4..e430c77 100644
--- a/Swift/Controllers/SettingConstants.cpp
+++ b/Swift/Controllers/SettingConstants.cpp
@@ -19,4 +19,5 @@ const SettingsProvider::Setting<bool> SettingConstants::LOGIN_AUTOMATICALLY = Se
const SettingsProvider::Setting<bool> SettingConstants::SHOW_OFFLINE("showOffline", false);
const SettingsProvider::Setting<std::string> SettingConstants::EXPANDED_ROSTER_GROUPS("GroupExpandiness", "");
const SettingsProvider::Setting<bool> SettingConstants::PLAY_SOUNDS("playSounds", true);
+const SettingsProvider::Setting<std::string> SettingConstants::HIGHLIGHT_RULES("highlightRules", "@");
}
diff --git a/Swift/Controllers/SettingConstants.h b/Swift/Controllers/SettingConstants.h
index ff1ed72..cc3af47 100644
--- a/Swift/Controllers/SettingConstants.h
+++ b/Swift/Controllers/SettingConstants.h
@@ -22,5 +22,6 @@ namespace Swift {
static const SettingsProvider::Setting<bool> SHOW_OFFLINE;
static const SettingsProvider::Setting<std::string> EXPANDED_ROSTER_GROUPS;
static const SettingsProvider::Setting<bool> PLAY_SOUNDS;
+ static const SettingsProvider::Setting<std::string> HIGHLIGHT_RULES;
};
}
diff --git a/Swift/Controllers/Settings/DummySettingsProvider.h b/Swift/Controllers/Settings/DummySettingsProvider.h
index 1d6059f..0183dd3 100644
--- a/Swift/Controllers/Settings/DummySettingsProvider.h
+++ b/Swift/Controllers/Settings/DummySettingsProvider.h
@@ -17,25 +17,25 @@ class DummySettingsProvider : public SettingsProvider {
virtual ~DummySettingsProvider() {}
virtual std::string getSetting(const Setting<std::string>& setting) {
return stringValues.find(setting.getKey()) != stringValues.end() ? stringValues[setting.getKey()] : setting.getDefaultValue();
- };
+ }
virtual void storeSetting(const Setting<std::string>& setting, const std::string& value) {
stringValues[setting.getKey()] = value;
onSettingChanged(setting.getKey());
- };
+ }
virtual bool getSetting(const Setting<bool>& setting) {
return boolValues.find(setting.getKey()) != boolValues.end() ? boolValues[setting.getKey()] : setting.getDefaultValue();
- };
+ }
virtual void storeSetting(const Setting<bool>& setting, const bool& value) {
boolValues[setting.getKey()] = value;
onSettingChanged(setting.getKey());
- };
+ }
virtual int getSetting(const Setting<int>& setting) {
return intValues.find(setting.getKey()) != intValues.end() ? intValues[setting.getKey()] : setting.getDefaultValue();
- };
+ }
virtual void storeSetting(const Setting<int>& setting, const int& value) {
intValues[setting.getKey()] = value;
onSettingChanged(setting.getKey());
- };
+ }
virtual std::vector<std::string> getAvailableProfiles() {return std::vector<std::string>();}
virtual void createProfile(const std::string& ) {}
virtual void removeProfile(const std::string& ) {}
diff --git a/Swift/Controllers/Settings/UnitTest/SettingsProviderHierachyTest.cpp b/Swift/Controllers/Settings/UnitTest/SettingsProviderHierachyTest.cpp
index aa4d14f..2b637a0 100644
--- a/Swift/Controllers/Settings/UnitTest/SettingsProviderHierachyTest.cpp
+++ b/Swift/Controllers/Settings/UnitTest/SettingsProviderHierachyTest.cpp
@@ -26,7 +26,7 @@ class SettingsProviderHierachyTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE_END();
public:
- SettingsProviderHierachyTest() : setting1("somekey", 42) {};
+ SettingsProviderHierachyTest() : setting1("somekey", 42) {}
void setUp() {
bottom = new DummySettingsProvider();
diff --git a/Swift/Controllers/ShowProfileController.cpp b/Swift/Controllers/ShowProfileController.cpp
new file mode 100644
index 0000000..ee0854b
--- /dev/null
+++ b/Swift/Controllers/ShowProfileController.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include "ShowProfileController.h"
+
+#include <boost/bind.hpp>
+
+#include <Swiften/Base/foreach.h>
+#include <Swiften/VCards/VCardManager.h>
+
+#include <Swift/Controllers/UIEvents/ShowProfileForRosterItemUIEvent.h>
+#include <Swift/Controllers/UIEvents/UIEventStream.h>
+#include <Swift/Controllers/UIInterfaces/ProfileWindowFactory.h>
+
+namespace Swift {
+
+ShowProfileController::ShowProfileController(VCardManager* vcardManager, ProfileWindowFactory* profileWindowFactory, UIEventStream* uiEventStream) : vcardManager(vcardManager), profileWindowFactory(profileWindowFactory), uiEventStream(uiEventStream) {
+ uiEventStream->onUIEvent.connect(boost::bind(&ShowProfileController::handleUIEvent, this, _1));
+ vcardManager->onVCardChanged.connect(boost::bind(&ShowProfileController::handleVCardChanged, this, _1, _2));
+}
+
+ShowProfileController::~ShowProfileController() {
+ typedef std::pair<JID, ProfileWindow*> JIDProfileWindowPair;
+ foreach(const JIDProfileWindowPair& jidWndPair, openedProfileWindows) {
+ jidWndPair.second->onWindowClosed.disconnect(boost::bind(&ShowProfileController::handleProfileWindowClosed, this, _1));
+ delete jidWndPair.second;
+ }
+
+ vcardManager->onVCardChanged.disconnect(boost::bind(&ShowProfileController::handleVCardChanged, this, _1, _2));
+ uiEventStream->onUIEvent.disconnect(boost::bind(&ShowProfileController::handleUIEvent, this, _1));
+}
+
+void ShowProfileController::handleUIEvent(UIEvent::ref event) {
+ ShowProfileForRosterItemUIEvent::ref showProfileEvent = boost::dynamic_pointer_cast<ShowProfileForRosterItemUIEvent>(event);
+ if (!showProfileEvent) {
+ return;
+ }
+
+ if (openedProfileWindows.find(showProfileEvent->getJID()) == openedProfileWindows.end()) {
+ ProfileWindow* newProfileWindow = profileWindowFactory->createProfileWindow();
+ newProfileWindow->setJID(showProfileEvent->getJID());
+ newProfileWindow->onWindowClosed.connect(boost::bind(&ShowProfileController::handleProfileWindowClosed, this, _1));
+ openedProfileWindows[showProfileEvent->getJID()] = newProfileWindow;
+ VCard::ref vcard = vcardManager->getVCardAndRequestWhenNeeded(showProfileEvent->getJID());
+ if (vcard) {
+ newProfileWindow->setVCard(vcard);
+ } else {
+ newProfileWindow->setProcessing(true);
+ }
+ newProfileWindow->show();
+ } else {
+ openedProfileWindows[showProfileEvent->getJID()]->show();
+ }
+}
+
+void ShowProfileController::handleVCardChanged(const JID& jid, VCard::ref vcard) {
+ if (openedProfileWindows.find(jid) == openedProfileWindows.end()) {
+ return;
+ }
+
+ ProfileWindow* profileWindow = openedProfileWindows[jid];
+ profileWindow->setVCard(vcard);
+ profileWindow->setProcessing(false);
+ profileWindow->show();
+}
+
+void ShowProfileController::handleProfileWindowClosed(const JID& profileJid) {
+ ProfileWindow* profileWindow = openedProfileWindows[profileJid];
+ openedProfileWindows.erase(profileJid);
+ delete profileWindow;
+}
+
+}
diff --git a/Swift/Controllers/ShowProfileController.h b/Swift/Controllers/ShowProfileController.h
new file mode 100644
index 0000000..5646f5e
--- /dev/null
+++ b/Swift/Controllers/ShowProfileController.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/JID/JID.h>
+#include <Swiften/Elements/VCard.h>
+
+#include <Swift/Controllers/UIEvents/UIEvent.h>
+
+namespace Swift {
+ class VCardManager;
+ class ProfileWindow;
+ class ProfileWindowFactory;
+ class UIEventStream;
+
+ class ShowProfileController {
+ public:
+ ShowProfileController(VCardManager* vcardManager, ProfileWindowFactory* profileWindowFactory, UIEventStream* uiEventStream);
+ ~ShowProfileController();
+
+ private:
+ void handleUIEvent(UIEvent::ref event);
+ void handleVCardChanged(const JID&, VCard::ref);
+ void handleProfileWindowClosed(const JID& profileJid);
+
+ private:
+ VCardManager* vcardManager;
+ ProfileWindowFactory* profileWindowFactory;
+ UIEventStream* uiEventStream;
+ std::map<JID, ProfileWindow*> openedProfileWindows;
+ };
+}
diff --git a/Swift/Controllers/SoundEventController.cpp b/Swift/Controllers/SoundEventController.cpp
index d056990..a5171e2 100644
--- a/Swift/Controllers/SoundEventController.cpp
+++ b/Swift/Controllers/SoundEventController.cpp
@@ -12,22 +12,33 @@
#include <Swift/Controllers/SoundPlayer.h>
#include <Swift/Controllers/UIEvents/UIEventStream.h>
#include <Swift/Controllers/SettingConstants.h>
+#include <Swift/Controllers/HighlightManager.h>
namespace Swift {
-SoundEventController::SoundEventController(EventController* eventController, SoundPlayer* soundPlayer, SettingsProvider* settings) {
+SoundEventController::SoundEventController(EventController* eventController, SoundPlayer* soundPlayer, SettingsProvider* settings, HighlightManager* highlightManager) {
settings_ = settings;
eventController_ = eventController;
soundPlayer_ = soundPlayer;
eventController_->onEventQueueEventAdded.connect(boost::bind(&SoundEventController::handleEventQueueEventAdded, this, _1));
+ highlightManager_ = highlightManager;
+ highlightManager_->onHighlight.connect(boost::bind(&SoundEventController::handleHighlight, this, _1));
+
settings_->onSettingChanged.connect(boost::bind(&SoundEventController::handleSettingChanged, this, _1));
playSounds_ = settings->getSetting(SettingConstants::PLAY_SOUNDS);
}
-void SoundEventController::handleEventQueueEventAdded(boost::shared_ptr<StanzaEvent> event) {
- if (playSounds_ && !event->getConcluded()) {
- soundPlayer_->playSound(SoundPlayer::MessageReceived);
+void SoundEventController::handleEventQueueEventAdded(boost::shared_ptr<StanzaEvent> /*event*/) {
+ // message received sound is now played via highlighting
+ //if (playSounds_ && !event->getConcluded()) {
+ // soundPlayer_->playSound(SoundPlayer::MessageReceived);
+ //}
+}
+
+void SoundEventController::handleHighlight(const HighlightAction& action) {
+ if (playSounds_ && action.playSound()) {
+ soundPlayer_->playSound(SoundPlayer::MessageReceived, action.getSoundFile());
}
}
diff --git a/Swift/Controllers/SoundEventController.h b/Swift/Controllers/SoundEventController.h
index c6dec6f..c9dcab4 100644
--- a/Swift/Controllers/SoundEventController.h
+++ b/Swift/Controllers/SoundEventController.h
@@ -10,21 +10,25 @@
#include <Swift/Controllers/XMPPEvents/StanzaEvent.h>
#include <Swift/Controllers/Settings/SettingsProvider.h>
+#include <Swift/Controllers/HighlightAction.h>
namespace Swift {
class EventController;
class SoundPlayer;
+ class HighlightManager;
class SoundEventController {
public:
- SoundEventController(EventController* eventController, SoundPlayer* soundPlayer, SettingsProvider* settings);
+ SoundEventController(EventController* eventController, SoundPlayer* soundPlayer, SettingsProvider* settings, HighlightManager* highlightManager);
void setPlaySounds(bool playSounds);
- bool getSoundEnabled() {return playSounds_;};
+ bool getSoundEnabled() {return playSounds_;}
private:
void handleSettingChanged(const std::string& settingPath);
void handleEventQueueEventAdded(boost::shared_ptr<StanzaEvent> event);
+ void handleHighlight(const HighlightAction& action);
EventController* eventController_;
SoundPlayer* soundPlayer_;
bool playSounds_;
SettingsProvider* settings_;
+ HighlightManager* highlightManager_;
};
}
diff --git a/Swift/Controllers/SoundPlayer.h b/Swift/Controllers/SoundPlayer.h
index b71d759..f18a2c0 100644
--- a/Swift/Controllers/SoundPlayer.h
+++ b/Swift/Controllers/SoundPlayer.h
@@ -6,11 +6,13 @@
#pragma once
+#include <string>
+
namespace Swift {
class SoundPlayer {
public:
- virtual ~SoundPlayer() {};
+ virtual ~SoundPlayer() {}
enum SoundEffect{MessageReceived};
- virtual void playSound(SoundEffect sound) = 0;
+ virtual void playSound(SoundEffect sound, const std::string& soundResource) = 0;
};
}
diff --git a/Swift/Controllers/StatusCache.cpp b/Swift/Controllers/StatusCache.cpp
new file mode 100644
index 0000000..1569e26
--- /dev/null
+++ b/Swift/Controllers/StatusCache.cpp
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2012 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include <Swift/Controllers/StatusCache.h>
+
+#include <boost/algorithm/string.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/filesystem/fstream.hpp>
+#include <boost/lambda/lambda.hpp>
+#include <boost/lambda/bind.hpp>
+
+#include <Swiften/Base/foreach.h>
+#include <Swiften/Base/ByteArray.h>
+#include <SwifTools/Application/ApplicationPathProvider.h>
+
+namespace lambda = boost::lambda;
+
+namespace Swift {
+
+static const size_t MAX_ENTRIES = 200;
+
+StatusCache::StatusCache(ApplicationPathProvider* paths) {
+ paths_ = paths;
+ path_ = paths_->getDataDir() / "StatusCache";
+ loadRecents();
+}
+
+StatusCache::~StatusCache() {
+
+}
+
+std::vector<StatusCache::PreviousStatus> StatusCache::getMatches(const std::string& substring, size_t maxCount) const {
+ std::vector<PreviousStatus> matches;
+ foreach (const PreviousStatus& status, previousStatuses_) {
+ if (substring.empty() || (boost::algorithm::ifind_first(status.first, substring) && substring != status.first)) {
+ matches.push_back(status);
+ if (matches.size() == maxCount) {
+ break;
+ }
+ }
+ }
+ return matches;
+}
+
+void StatusCache::addRecent(const std::string& text, StatusShow::Type type) {
+ if (text.empty()) {
+ return;
+ }
+ previousStatuses_.remove_if(lambda::bind(&PreviousStatus::first, lambda::_1) == text && lambda::bind(&PreviousStatus::second, lambda::_1) == type);
+ previousStatuses_.push_front(PreviousStatus(text, type));
+ for (size_t i = previousStatuses_.size(); i > MAX_ENTRIES; i--) {
+ previousStatuses_.pop_back();
+ }
+ saveRecents();
+}
+
+void StatusCache::loadRecents() {
+ try {
+ if (boost::filesystem::exists(path_)) {
+ ByteArray data;
+ readByteArrayFromFile(data, path_.string());
+ std::string stringData = byteArrayToString(data);
+ std::vector<std::string> lines;
+ boost::split(lines, stringData, boost::is_any_of("\n"));
+ foreach (const std::string& line, lines) {
+ std::vector<std::string> bits;
+ boost::split(bits, line, boost::is_any_of("\t"));
+ if (bits.size() < 2) {
+ continue;
+ }
+ StatusShow::Type type;
+ type = static_cast<StatusShow::Type>(boost::lexical_cast<size_t>(bits[0]));
+ previousStatuses_.push_back(PreviousStatus(boost::trim_copy(bits[1]), type));
+ }
+ }
+ }
+ catch (const boost::filesystem::filesystem_error& e) {
+ std::cerr << "ERROR: " << e.what() << std::endl;
+ }
+}
+
+void StatusCache::saveRecents() {
+ try {
+ if (!boost::filesystem::exists(path_.parent_path())) {
+ boost::filesystem::create_directories(path_.parent_path());
+ }
+ boost::filesystem::ofstream file(path_);
+ foreach (const PreviousStatus& recent, previousStatuses_) {
+ std::string message = recent.first;
+ boost::replace_all(message, "\t", " ");
+ file << recent.second << "\t" << message << std::endl;
+ }
+ file.close();
+ }
+ catch (const boost::filesystem::filesystem_error& e) {
+ std::cerr << "ERROR: " << e.what() << std::endl;
+ }
+}
+
+}
+
+
+
+
diff --git a/Swift/Controllers/StatusCache.h b/Swift/Controllers/StatusCache.h
new file mode 100644
index 0000000..35b3674
--- /dev/null
+++ b/Swift/Controllers/StatusCache.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2012 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <string>
+#include <utility>
+#include <vector>
+#include <list>
+#include <iostream>
+
+#include <boost/filesystem/path.hpp>
+
+#include <Swiften/Elements/StatusShow.h>
+
+namespace Swift {
+ class ApplicationPathProvider;
+ class StatusCache {
+ public:
+ typedef std::pair<std::string, StatusShow::Type> PreviousStatus;
+ public:
+ StatusCache(ApplicationPathProvider* paths);
+ ~StatusCache();
+
+ std::vector<PreviousStatus> getMatches(const std::string& substring, size_t maxCount) const;
+ void addRecent(const std::string& text, StatusShow::Type type);
+ private:
+ void saveRecents();
+ void loadRecents();
+ private:
+ boost::filesystem::path path_;
+ std::list<PreviousStatus> previousStatuses_;
+ ApplicationPathProvider* paths_;
+ };
+}
+
+
diff --git a/Swift/Controllers/StatusUtil.cpp b/Swift/Controllers/StatusUtil.cpp
index fd1fea3..a72f340 100644
--- a/Swift/Controllers/StatusUtil.cpp
+++ b/Swift/Controllers/StatusUtil.cpp
@@ -6,6 +6,7 @@
#include <Swift/Controllers/StatusUtil.h>
+#include <cassert>
#include <Swift/Controllers/Intl.h>
namespace Swift {
@@ -19,6 +20,7 @@ std::string statusShowTypeToFriendlyName(StatusShow::Type type) {
case StatusShow::DND: return QT_TRANSLATE_NOOP("", "Busy");
case StatusShow::None: return QT_TRANSLATE_NOOP("", "Offline");
}
+ assert(false);
return "";
}
diff --git a/Swift/Controllers/Storages/CertificateFileStorage.cpp b/Swift/Controllers/Storages/CertificateFileStorage.cpp
index a4a95c7..55016d5 100644
--- a/Swift/Controllers/Storages/CertificateFileStorage.cpp
+++ b/Swift/Controllers/Storages/CertificateFileStorage.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010-2013 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
@@ -8,6 +8,7 @@
#include <iostream>
#include <boost/filesystem/fstream.hpp>
+#include <boost/numeric/conversion/cast.hpp>
#include <Swiften/StringCodecs/SHA1.h>
#include <Swiften/StringCodecs/Hexify.h>
@@ -50,7 +51,7 @@ void CertificateFileStorage::addCertificate(Certificate::ref certificate) {
}
boost::filesystem::ofstream file(certificatePath, boost::filesystem::ofstream::binary|boost::filesystem::ofstream::out);
ByteArray data = certificate->toDER();
- file.write(reinterpret_cast<const char*>(vecptr(data)), data.size());
+ file.write(reinterpret_cast<const char*>(vecptr(data)), boost::numeric_cast<std::streamsize>(data.size()));
file.close();
}
diff --git a/Swift/Controllers/SystemTray.h b/Swift/Controllers/SystemTray.h
index 736b1fa..b71a783 100644
--- a/Swift/Controllers/SystemTray.h
+++ b/Swift/Controllers/SystemTray.h
@@ -11,7 +11,7 @@
namespace Swift {
class SystemTray {
public:
- virtual ~SystemTray(){};
+ virtual ~SystemTray(){}
virtual void setUnreadMessages(bool some) = 0;
virtual void setStatusType(StatusShow::Type type) = 0;
virtual void setConnecting() = 0;
diff --git a/Swift/Controllers/Translator.cpp b/Swift/Controllers/Translator.cpp
index 82fc46e..b7766ca 100644
--- a/Swift/Controllers/Translator.cpp
+++ b/Swift/Controllers/Translator.cpp
@@ -10,7 +10,7 @@
namespace Swift {
-struct DefaultTranslator : public Translator {
+static struct DefaultTranslator : public Translator {
virtual std::string translate(const std::string& text, const std::string&) {
return text;
}
diff --git a/Swift/Controllers/UIEvents/AddContactUIEvent.h b/Swift/Controllers/UIEvents/AddContactUIEvent.h
index d92d3af..6b70b76 100644
--- a/Swift/Controllers/UIEvents/AddContactUIEvent.h
+++ b/Swift/Controllers/UIEvents/AddContactUIEvent.h
@@ -14,15 +14,15 @@
namespace Swift {
class AddContactUIEvent : public UIEvent {
public:
- AddContactUIEvent(const JID& jid, const std::string& name, const std::set<std::string>& groups) : jid_(jid), name_(name), groups_(groups) {};
+ AddContactUIEvent(const JID& jid, const std::string& name, const std::set<std::string>& groups) : jid_(jid), name_(name), groups_(groups) {}
const std::string& getName() const {
return name_;
- };
+ }
const JID& getJID() const {
return jid_;
- };
+ }
const std::set<std::string>& getGroups() const {
return groups_;
diff --git a/Swift/Controllers/UIEvents/AddMUCBookmarkUIEvent.h b/Swift/Controllers/UIEvents/AddMUCBookmarkUIEvent.h
index 210da3e..df01d6c 100644
--- a/Swift/Controllers/UIEvents/AddMUCBookmarkUIEvent.h
+++ b/Swift/Controllers/UIEvents/AddMUCBookmarkUIEvent.h
@@ -14,7 +14,7 @@
namespace Swift {
class AddMUCBookmarkUIEvent : public UIEvent {
public:
- AddMUCBookmarkUIEvent(const MUCBookmark& bookmark) : bookmark(bookmark) {};
+ AddMUCBookmarkUIEvent(const MUCBookmark& bookmark) : bookmark(bookmark) {}
const MUCBookmark& getBookmark() { return bookmark; }
private:
diff --git a/Swift/Controllers/UIEvents/EditMUCBookmarkUIEvent.h b/Swift/Controllers/UIEvents/EditMUCBookmarkUIEvent.h
index 2b10f09..7723d89 100644
--- a/Swift/Controllers/UIEvents/EditMUCBookmarkUIEvent.h
+++ b/Swift/Controllers/UIEvents/EditMUCBookmarkUIEvent.h
@@ -14,10 +14,10 @@
namespace Swift {
class EditMUCBookmarkUIEvent : public UIEvent {
public:
- EditMUCBookmarkUIEvent(const MUCBookmark& oldBookmark, const MUCBookmark& newBookmark) : oldBookmark(oldBookmark) , newBookmark(newBookmark) {};
+ EditMUCBookmarkUIEvent(const MUCBookmark& oldBookmark, const MUCBookmark& newBookmark) : oldBookmark(oldBookmark) , newBookmark(newBookmark) {}
- const MUCBookmark& getOldBookmark() {return oldBookmark;};
- const MUCBookmark& getNewBookmark() {return newBookmark;};
+ const MUCBookmark& getOldBookmark() {return oldBookmark;}
+ const MUCBookmark& getNewBookmark() {return newBookmark;}
private:
MUCBookmark oldBookmark;
diff --git a/Swift/Controllers/UIEvents/JoinMUCUIEvent.h b/Swift/Controllers/UIEvents/JoinMUCUIEvent.h
index b3ff8c7..c1e6de7 100644
--- a/Swift/Controllers/UIEvents/JoinMUCUIEvent.h
+++ b/Swift/Controllers/UIEvents/JoinMUCUIEvent.h
@@ -18,7 +18,7 @@ namespace Swift {
class JoinMUCUIEvent : public UIEvent {
public:
typedef boost::shared_ptr<JoinMUCUIEvent> ref;
- JoinMUCUIEvent(const JID& jid, const boost::optional<std::string>& password = boost::optional<std::string>(), const boost::optional<std::string>& nick = boost::optional<std::string>(), bool joinAutomaticallyInFuture = false, bool createAsReservedRoomIfNew = false) : jid_(jid), nick_(nick), joinAutomatically_(joinAutomaticallyInFuture), createAsReservedRoomIfNew_(createAsReservedRoomIfNew), password_(password) {};
+ JoinMUCUIEvent(const JID& jid, const boost::optional<std::string>& password = boost::optional<std::string>(), const boost::optional<std::string>& nick = boost::optional<std::string>(), bool joinAutomaticallyInFuture = false, bool createAsReservedRoomIfNew = false) : jid_(jid), nick_(nick), joinAutomatically_(joinAutomaticallyInFuture), createAsReservedRoomIfNew_(createAsReservedRoomIfNew), password_(password) {}
const boost::optional<std::string>& getNick() const {return nick_;}
const JID& getJID() const {return jid_;}
bool getShouldJoinAutomatically() const {return joinAutomatically_;}
diff --git a/Swift/Controllers/UIEvents/RemoveMUCBookmarkUIEvent.h b/Swift/Controllers/UIEvents/RemoveMUCBookmarkUIEvent.h
index ea2e609..0df40f9 100644
--- a/Swift/Controllers/UIEvents/RemoveMUCBookmarkUIEvent.h
+++ b/Swift/Controllers/UIEvents/RemoveMUCBookmarkUIEvent.h
@@ -14,7 +14,7 @@
namespace Swift {
class RemoveMUCBookmarkUIEvent : public UIEvent {
public:
- RemoveMUCBookmarkUIEvent(const MUCBookmark& bookmark) : bookmark(bookmark) {};
+ RemoveMUCBookmarkUIEvent(const MUCBookmark& bookmark) : bookmark(bookmark) {}
const MUCBookmark& getBookmark() { return bookmark; }
private:
diff --git a/Swift/Controllers/UIEvents/RemoveRosterItemUIEvent.h b/Swift/Controllers/UIEvents/RemoveRosterItemUIEvent.h
index 7e5236a..617daf3 100644
--- a/Swift/Controllers/UIEvents/RemoveRosterItemUIEvent.h
+++ b/Swift/Controllers/UIEvents/RemoveRosterItemUIEvent.h
@@ -13,9 +13,9 @@ namespace Swift {
class RemoveRosterItemUIEvent : public UIEvent {
public:
- RemoveRosterItemUIEvent(const JID& jid) : jid_(jid) {};
- virtual ~RemoveRosterItemUIEvent() {};
- JID getJID() {return jid_;};
+ RemoveRosterItemUIEvent(const JID& jid) : jid_(jid) {}
+ virtual ~RemoveRosterItemUIEvent() {}
+ JID getJID() {return jid_;}
private:
JID jid_;
diff --git a/Swift/Controllers/UIEvents/RequestAdHocUIEvent.h b/Swift/Controllers/UIEvents/RequestAdHocUIEvent.h
index c3b4b49..a0b51f2 100644
--- a/Swift/Controllers/UIEvents/RequestAdHocUIEvent.h
+++ b/Swift/Controllers/UIEvents/RequestAdHocUIEvent.h
@@ -13,7 +13,7 @@
namespace Swift {
class RequestAdHocUIEvent : public UIEvent {
public:
- RequestAdHocUIEvent(const DiscoItems::Item& command) : command_(command) {};
+ RequestAdHocUIEvent(const DiscoItems::Item& command) : command_(command) {}
const DiscoItems::Item& getCommand() const {return command_;}
private:
DiscoItems::Item command_;
diff --git a/Swift/Controllers/UIEvents/RequestAddUserDialogUIEvent.h b/Swift/Controllers/UIEvents/RequestAddUserDialogUIEvent.h
index 5a071cf..7fe1926 100644
--- a/Swift/Controllers/UIEvents/RequestAddUserDialogUIEvent.h
+++ b/Swift/Controllers/UIEvents/RequestAddUserDialogUIEvent.h
@@ -15,11 +15,11 @@ namespace Swift {
class RequestAddUserDialogUIEvent : public UIEvent {
public:
- RequestAddUserDialogUIEvent(const JID& predefinedJID, const std::string& predefinedName) : preJID_(predefinedJID), preName_(predefinedName) {};
- RequestAddUserDialogUIEvent() : preJID_(), preName_() {};
+ RequestAddUserDialogUIEvent(const JID& predefinedJID, const std::string& predefinedName) : preJID_(predefinedJID), preName_(predefinedName) {}
+ RequestAddUserDialogUIEvent() : preJID_(), preName_() {}
- const JID& getPredefinedJID() const { return preJID_; };
- const std::string& getPredefinedName() const { return preName_; };
+ const JID& getPredefinedJID() const { return preJID_; }
+ const std::string& getPredefinedName() const { return preName_; }
private:
JID preJID_;
diff --git a/Swift/Controllers/UIEvents/RequestChatUIEvent.h b/Swift/Controllers/UIEvents/RequestChatUIEvent.h
index b1e86ed..4ef954f 100644
--- a/Swift/Controllers/UIEvents/RequestChatUIEvent.h
+++ b/Swift/Controllers/UIEvents/RequestChatUIEvent.h
@@ -13,7 +13,7 @@
namespace Swift {
class RequestChatUIEvent : public UIEvent {
public:
- RequestChatUIEvent(const JID& contact) : contact_(contact) {};
+ RequestChatUIEvent(const JID& contact) : contact_(contact) {}
JID getContact() {return contact_;}
private:
JID contact_;
diff --git a/Swift/Controllers/UIEvents/RequestHighlightEditorUIEvent.h b/Swift/Controllers/UIEvents/RequestHighlightEditorUIEvent.h
new file mode 100644
index 0000000..42e22a2
--- /dev/null
+++ b/Swift/Controllers/UIEvents/RequestHighlightEditorUIEvent.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2012 Maciej Niedzielski
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swift/Controllers/UIEvents/UIEvent.h>
+
+namespace Swift {
+
+ class RequestHighlightEditorUIEvent : public UIEvent {
+ };
+
+}
diff --git a/Swift/Controllers/UIEvents/RequestWhiteboardUIEvent.h b/Swift/Controllers/UIEvents/RequestWhiteboardUIEvent.h
index f5b995b..5c44da7 100644
--- a/Swift/Controllers/UIEvents/RequestWhiteboardUIEvent.h
+++ b/Swift/Controllers/UIEvents/RequestWhiteboardUIEvent.h
@@ -13,7 +13,7 @@
namespace Swift {
class RequestWhiteboardUIEvent : public UIEvent {
public:
- RequestWhiteboardUIEvent(const JID& contact) : contact_(contact) {};
+ RequestWhiteboardUIEvent(const JID& contact) : contact_(contact) {}
const JID& getContact() const {return contact_;}
private:
JID contact_;
diff --git a/Swift/Controllers/UIEvents/ShowProfileForRosterItemUIEvent.h b/Swift/Controllers/UIEvents/ShowProfileForRosterItemUIEvent.h
new file mode 100644
index 0000000..4a603ea
--- /dev/null
+++ b/Swift/Controllers/UIEvents/ShowProfileForRosterItemUIEvent.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2012 Tobias Markmann
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/JID/JID.h>
+#include <Swift/Controllers/UIEvents/UIEvent.h>
+
+namespace Swift {
+
+class ShowProfileForRosterItemUIEvent : public UIEvent {
+ public:
+ typedef boost::shared_ptr<ShowProfileForRosterItemUIEvent> ref;
+ public:
+ ShowProfileForRosterItemUIEvent(const JID& jid) : jid_(jid) {}
+ virtual ~ShowProfileForRosterItemUIEvent() {}
+ JID getJID() const {return jid_;}
+ private:
+ JID jid_;
+};
+
+}
diff --git a/Swift/Controllers/UIEvents/ShowWhiteboardUIEvent.h b/Swift/Controllers/UIEvents/ShowWhiteboardUIEvent.h
index 265bf7d..bb72d9b 100644
--- a/Swift/Controllers/UIEvents/ShowWhiteboardUIEvent.h
+++ b/Swift/Controllers/UIEvents/ShowWhiteboardUIEvent.h
@@ -13,7 +13,7 @@
namespace Swift {
class ShowWhiteboardUIEvent : public UIEvent {
public:
- ShowWhiteboardUIEvent(const JID& contact) : contact_(contact) {};
+ ShowWhiteboardUIEvent(const JID& contact) : contact_(contact) {}
const JID& getContact() const {return contact_;}
private:
JID contact_;
diff --git a/Swift/Controllers/UIEvents/UIEventStream.h b/Swift/Controllers/UIEvents/UIEventStream.h
index e174029..b1337a2 100644
--- a/Swift/Controllers/UIEvents/UIEventStream.h
+++ b/Swift/Controllers/UIEvents/UIEventStream.h
@@ -18,6 +18,6 @@ namespace Swift {
void send(boost::shared_ptr<UIEvent> event) {
onUIEvent(event);
- };
+ }
};
}
diff --git a/Swift/Controllers/UIInterfaces/AdHocCommandWindow.h b/Swift/Controllers/UIInterfaces/AdHocCommandWindow.h
index f7a5d39..835defe 100644
--- a/Swift/Controllers/UIInterfaces/AdHocCommandWindow.h
+++ b/Swift/Controllers/UIInterfaces/AdHocCommandWindow.h
@@ -9,6 +9,6 @@
namespace Swift {
class AdHocCommandWindow {
public:
- virtual ~AdHocCommandWindow() {};
+ virtual ~AdHocCommandWindow() {}
};
}
diff --git a/Swift/Controllers/UIInterfaces/ChatListWindow.h b/Swift/Controllers/UIInterfaces/ChatListWindow.h
index cb55bb3..6eb932f 100644
--- a/Swift/Controllers/UIInterfaces/ChatListWindow.h
+++ b/Swift/Controllers/UIInterfaces/ChatListWindow.h
@@ -25,7 +25,7 @@ namespace Swift {
bool operator==(const Chat& other) const {
return jid.toBare() == other.jid.toBare()
&& isMUC == other.isMUC;
- };
+ }
void setUnreadCount(int unread) {
unreadCount = unread;
}
diff --git a/Swift/Controllers/UIInterfaces/ChatWindow.h b/Swift/Controllers/UIInterfaces/ChatWindow.h
index 5db1a54..d6b3656 100644
--- a/Swift/Controllers/UIInterfaces/ChatWindow.h
+++ b/Swift/Controllers/UIInterfaces/ChatWindow.h
@@ -17,6 +17,7 @@
#include <Swiften/Elements/ChatState.h>
#include <Swiften/Elements/Form.h>
#include <Swiften/Elements/MUCOccupant.h>
+#include <Swift/Controllers/HighlightManager.h>
namespace Swift {
@@ -34,26 +35,26 @@ namespace Swift {
enum AckState {Pending, Received, Failed};
enum ReceiptState {ReceiptRequested, ReceiptReceived};
enum Tristate {Yes, No, Maybe};
- enum OccupantAction {Kick, Ban, MakeModerator, MakeParticipant, MakeVisitor, AddContact};
+ enum OccupantAction {Kick, Ban, MakeModerator, MakeParticipant, MakeVisitor, AddContact, ShowProfile};
enum RoomAction {ChangeSubject, Configure, Affiliations, Destroy, Invite};
enum FileTransferState {WaitingForAccept, Negotiating, Transferring, Canceled, Finished, FTFailed};
enum WhiteboardSessionState {WhiteboardAccepted, WhiteboardTerminated, WhiteboardRejected};
ChatWindow() {}
- virtual ~ChatWindow() {};
+ virtual ~ChatWindow() {}
/** Add message to window.
* @return id of added message (for acks).
*/
- virtual std::string addMessage(const std::string& message, const std::string& senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time) = 0;
+ virtual std::string addMessage(const std::string& message, const std::string& senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time, const HighlightAction& highlight) = 0;
/** Adds action to window.
* @return id of added message (for acks);
*/
- virtual std::string addAction(const std::string& message, const std::string& senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time) = 0;
+ virtual std::string addAction(const std::string& message, const std::string& senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time, const HighlightAction& highlight) = 0;
virtual void addSystemMessage(const std::string& message) = 0;
virtual void addPresenceMessage(const std::string& message) = 0;
virtual void addErrorMessage(const std::string& message) = 0;
- virtual void replaceMessage(const std::string& message, const std::string& id, const boost::posix_time::ptime& time) = 0;
- virtual void replaceWithAction(const std::string& message, const std::string& id, const boost::posix_time::ptime& time) = 0;
+ virtual void replaceMessage(const std::string& message, const std::string& id, const boost::posix_time::ptime& time, const HighlightAction& highlight) = 0;
+ virtual void replaceWithAction(const std::string& message, const std::string& id, const boost::posix_time::ptime& time, const HighlightAction& highlight) = 0;
// File transfer related stuff
virtual std::string addFileTransfer(const std::string& senderName, bool senderIsSelf, const std::string& filename, const boost::uintmax_t sizeInBytes) = 0;
diff --git a/Swift/Controllers/UIInterfaces/ChatWindowFactory.h b/Swift/Controllers/UIInterfaces/ChatWindowFactory.h
index b7b4479..62e6621 100644
--- a/Swift/Controllers/UIInterfaces/ChatWindowFactory.h
+++ b/Swift/Controllers/UIInterfaces/ChatWindowFactory.h
@@ -14,7 +14,7 @@ namespace Swift {
class UIEventStream;
class ChatWindowFactory {
public:
- virtual ~ChatWindowFactory() {};
+ virtual ~ChatWindowFactory() {}
/**
* Transfers ownership of result.
*/
diff --git a/Swift/Controllers/UIInterfaces/ContactEditWindowFactory.h b/Swift/Controllers/UIInterfaces/ContactEditWindowFactory.h
index 8ad56c0..9d47aef 100644
--- a/Swift/Controllers/UIInterfaces/ContactEditWindowFactory.h
+++ b/Swift/Controllers/UIInterfaces/ContactEditWindowFactory.h
@@ -11,7 +11,7 @@
namespace Swift {
class ContactEditWindowFactory {
public:
- virtual ~ContactEditWindowFactory() {};
+ virtual ~ContactEditWindowFactory() {}
virtual ContactEditWindow* createContactEditWindow() = 0;
};
diff --git a/Swift/Controllers/UIInterfaces/EventWindow.h b/Swift/Controllers/UIInterfaces/EventWindow.h
index 3ca2c82..b3af3d3 100644
--- a/Swift/Controllers/UIInterfaces/EventWindow.h
+++ b/Swift/Controllers/UIInterfaces/EventWindow.h
@@ -19,7 +19,7 @@ namespace Swift {
return canDelete_;
}
- virtual ~EventWindow() {};
+ virtual ~EventWindow() {}
virtual void addEvent(boost::shared_ptr<StanzaEvent> event, bool active) = 0;
virtual void removeEvent(boost::shared_ptr<StanzaEvent> event) = 0;
diff --git a/Swift/Controllers/UIInterfaces/EventWindowFactory.h b/Swift/Controllers/UIInterfaces/EventWindowFactory.h
index 1ff3ada..0b9c28e 100644
--- a/Swift/Controllers/UIInterfaces/EventWindowFactory.h
+++ b/Swift/Controllers/UIInterfaces/EventWindowFactory.h
@@ -11,7 +11,7 @@ namespace Swift {
class EventWindowFactory {
public:
- virtual ~EventWindowFactory() {};
+ virtual ~EventWindowFactory() {}
/**
* Transfers ownership of result.
*/
diff --git a/Swift/Controllers/UIInterfaces/HighlightEditorWidget.h b/Swift/Controllers/UIInterfaces/HighlightEditorWidget.h
new file mode 100644
index 0000000..4745035
--- /dev/null
+++ b/Swift/Controllers/UIInterfaces/HighlightEditorWidget.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2012 Maciej Niedzielski
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+namespace Swift {
+
+ class HighlightManager;
+
+ class HighlightEditorWidget {
+ public:
+ virtual ~HighlightEditorWidget() {}
+
+ virtual void show() = 0;
+
+ virtual void setHighlightManager(HighlightManager* highlightManager) = 0;
+ };
+
+}
diff --git a/Swift/Controllers/UIInterfaces/HighlightEditorWidgetFactory.h b/Swift/Controllers/UIInterfaces/HighlightEditorWidgetFactory.h
new file mode 100644
index 0000000..ade575b
--- /dev/null
+++ b/Swift/Controllers/UIInterfaces/HighlightEditorWidgetFactory.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2012 Maciej Niedzielski
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+namespace Swift {
+
+ class HighlightEditorWidget;
+
+ class HighlightEditorWidgetFactory {
+ public:
+ virtual ~HighlightEditorWidgetFactory() {}
+
+ virtual HighlightEditorWidget* createHighlightEditorWidget() = 0;
+ };
+
+}
diff --git a/Swift/Controllers/UIInterfaces/HistoryWindow.h b/Swift/Controllers/UIInterfaces/HistoryWindow.h
index ffb0ad5..6d50f4b 100644
--- a/Swift/Controllers/UIInterfaces/HistoryWindow.h
+++ b/Swift/Controllers/UIInterfaces/HistoryWindow.h
@@ -11,7 +11,7 @@
namespace Swift {
class HistoryWindow {
public:
- virtual ~HistoryWindow() {};
+ virtual ~HistoryWindow() {}
virtual void activate() = 0;
virtual void setRosterModel(Roster*) = 0;
diff --git a/Swift/Controllers/UIInterfaces/HistoryWindowFactory.h b/Swift/Controllers/UIInterfaces/HistoryWindowFactory.h
index e91bc37..807fec5 100644
--- a/Swift/Controllers/UIInterfaces/HistoryWindowFactory.h
+++ b/Swift/Controllers/UIInterfaces/HistoryWindowFactory.h
@@ -12,7 +12,7 @@ namespace Swift {
class UIEventStream;
class HistoryWindowFactory {
public:
- virtual ~HistoryWindowFactory() {};
+ virtual ~HistoryWindowFactory() {}
virtual HistoryWindow* createHistoryWindow(UIEventStream* eventStream) = 0;
};
}
diff --git a/Swift/Controllers/UIInterfaces/InviteToChatWindow.h b/Swift/Controllers/UIInterfaces/InviteToChatWindow.h
index 4070e01..db128c1 100644
--- a/Swift/Controllers/UIInterfaces/InviteToChatWindow.h
+++ b/Swift/Controllers/UIInterfaces/InviteToChatWindow.h
@@ -15,7 +15,7 @@
namespace Swift {
class InviteToChatWindow {
public:
- virtual ~InviteToChatWindow() {};
+ virtual ~InviteToChatWindow() {}
virtual void setAutoCompletions(std::vector<std::pair<JID, std::string> > completions) = 0;
diff --git a/Swift/Controllers/UIInterfaces/JoinMUCWindow.h b/Swift/Controllers/UIInterfaces/JoinMUCWindow.h
index 4873c9b..56a9587 100644
--- a/Swift/Controllers/UIInterfaces/JoinMUCWindow.h
+++ b/Swift/Controllers/UIInterfaces/JoinMUCWindow.h
@@ -15,7 +15,7 @@
namespace Swift {
class JoinMUCWindow {
public:
- virtual ~JoinMUCWindow() {};
+ virtual ~JoinMUCWindow() {}
virtual void setNick(const std::string& nick) = 0;
virtual void setMUC(const std::string& nick) = 0;
diff --git a/Swift/Controllers/UIInterfaces/JoinMUCWindowFactory.h b/Swift/Controllers/UIInterfaces/JoinMUCWindowFactory.h
index cd8021b..494b418 100644
--- a/Swift/Controllers/UIInterfaces/JoinMUCWindowFactory.h
+++ b/Swift/Controllers/UIInterfaces/JoinMUCWindowFactory.h
@@ -12,7 +12,7 @@ namespace Swift {
class UIEventStream;
class JoinMUCWindowFactory {
public:
- virtual ~JoinMUCWindowFactory() {};
+ virtual ~JoinMUCWindowFactory() {}
virtual JoinMUCWindow* createJoinMUCWindow(UIEventStream* uiEventStream) = 0;
};
diff --git a/Swift/Controllers/UIInterfaces/LoginWindow.h b/Swift/Controllers/UIInterfaces/LoginWindow.h
index dbc77c4..e27c385 100644
--- a/Swift/Controllers/UIInterfaces/LoginWindow.h
+++ b/Swift/Controllers/UIInterfaces/LoginWindow.h
@@ -18,7 +18,7 @@ namespace Swift {
class MainWindow;
class LoginWindow {
public:
- virtual ~LoginWindow() {};
+ virtual ~LoginWindow() {}
virtual void selectUser(const std::string&) = 0;
virtual void morphInto(MainWindow *mainWindow) = 0;
virtual void loggedOut() = 0;
diff --git a/Swift/Controllers/UIInterfaces/LoginWindowFactory.h b/Swift/Controllers/UIInterfaces/LoginWindowFactory.h
index 1cead2a..7b8b7ec 100644
--- a/Swift/Controllers/UIInterfaces/LoginWindowFactory.h
+++ b/Swift/Controllers/UIInterfaces/LoginWindowFactory.h
@@ -16,7 +16,7 @@ namespace Swift {
class LoginWindowFactory {
public:
- virtual ~LoginWindowFactory() {};
+ virtual ~LoginWindowFactory() {}
/**
* Transfers ownership of result.
diff --git a/Swift/Controllers/UIInterfaces/MUCSearchWindow.h b/Swift/Controllers/UIInterfaces/MUCSearchWindow.h
index 5814b06..43a61a1 100644
--- a/Swift/Controllers/UIInterfaces/MUCSearchWindow.h
+++ b/Swift/Controllers/UIInterfaces/MUCSearchWindow.h
@@ -19,7 +19,7 @@ namespace Swift {
class MUCSearchWindow {
public:
- virtual ~MUCSearchWindow() {};
+ virtual ~MUCSearchWindow() {}
virtual void clearList() = 0;
virtual void addService(const MUCService& service) = 0;
diff --git a/Swift/Controllers/UIInterfaces/MUCSearchWindowFactory.h b/Swift/Controllers/UIInterfaces/MUCSearchWindowFactory.h
index d334dff..46488eb 100644
--- a/Swift/Controllers/UIInterfaces/MUCSearchWindowFactory.h
+++ b/Swift/Controllers/UIInterfaces/MUCSearchWindowFactory.h
@@ -12,7 +12,7 @@ namespace Swift {
class UIEventStream;
class MUCSearchWindowFactory {
public:
- virtual ~MUCSearchWindowFactory() {};
+ virtual ~MUCSearchWindowFactory() {}
virtual MUCSearchWindow* createMUCSearchWindow() = 0;
};
diff --git a/Swift/Controllers/UIInterfaces/MainWindow.h b/Swift/Controllers/UIInterfaces/MainWindow.h
index 23328b4..2df2c10 100644
--- a/Swift/Controllers/UIInterfaces/MainWindow.h
+++ b/Swift/Controllers/UIInterfaces/MainWindow.h
@@ -20,7 +20,7 @@ namespace Swift {
class MainWindow {
public:
MainWindow(bool candelete = true) : canDelete_(candelete) {}
- virtual ~MainWindow() {};
+ virtual ~MainWindow() {}
bool canDelete() const {
return canDelete_;
diff --git a/Swift/Controllers/UIInterfaces/MainWindowFactory.h b/Swift/Controllers/UIInterfaces/MainWindowFactory.h
index c5cdfef..6bd34b4 100644
--- a/Swift/Controllers/UIInterfaces/MainWindowFactory.h
+++ b/Swift/Controllers/UIInterfaces/MainWindowFactory.h
@@ -15,7 +15,7 @@ namespace Swift {
class MainWindowFactory {
public:
- virtual ~MainWindowFactory() {};
+ virtual ~MainWindowFactory() {}
/**
* Transfers ownership of result.
*/
diff --git a/Swift/Controllers/UIInterfaces/ProfileWindow.h b/Swift/Controllers/UIInterfaces/ProfileWindow.h
index 5d5c754..0ce2ccf 100644
--- a/Swift/Controllers/UIInterfaces/ProfileWindow.h
+++ b/Swift/Controllers/UIInterfaces/ProfileWindow.h
@@ -12,19 +12,24 @@
#include <Swiften/Elements/VCard.h>
namespace Swift {
+ class JID;
+
class ProfileWindow {
public:
- virtual ~ProfileWindow() {};
+ virtual ~ProfileWindow() {}
+ virtual void setJID(const JID& jid) = 0;
virtual void setVCard(VCard::ref vcard) = 0;
virtual void setEnabled(bool b) = 0;
virtual void setProcessing(bool b) = 0;
virtual void setError(const std::string&) = 0;
+ virtual void setEditable(bool b) = 0;
virtual void show() = 0;
virtual void hide() = 0;
boost::signal<void (VCard::ref)> onVCardChangeRequest;
+ boost::signal<void (const JID&)> onWindowClosed;
};
}
diff --git a/Swift/Controllers/UIInterfaces/ProfileWindowFactory.h b/Swift/Controllers/UIInterfaces/ProfileWindowFactory.h
index 022c3eb..45a340a 100644
--- a/Swift/Controllers/UIInterfaces/ProfileWindowFactory.h
+++ b/Swift/Controllers/UIInterfaces/ProfileWindowFactory.h
@@ -11,7 +11,7 @@
namespace Swift {
class ProfileWindowFactory {
public:
- virtual ~ProfileWindowFactory() {};
+ virtual ~ProfileWindowFactory() {}
virtual ProfileWindow* createProfileWindow() = 0;
};
diff --git a/Swift/Controllers/UIInterfaces/UIFactory.h b/Swift/Controllers/UIInterfaces/UIFactory.h
index 6b4efd8..dcd1779 100644
--- a/Swift/Controllers/UIInterfaces/UIFactory.h
+++ b/Swift/Controllers/UIInterfaces/UIFactory.h
@@ -21,6 +21,7 @@
#include <Swift/Controllers/UIInterfaces/AdHocCommandWindowFactory.h>
#include <Swift/Controllers/UIInterfaces/FileTransferListWidgetFactory.h>
#include <Swift/Controllers/UIInterfaces/WhiteboardWindowFactory.h>
+#include <Swift/Controllers/UIInterfaces/HighlightEditorWidgetFactory.h>
namespace Swift {
class UIFactory :
@@ -38,7 +39,8 @@ namespace Swift {
public ContactEditWindowFactory,
public AdHocCommandWindowFactory,
public FileTransferListWidgetFactory,
- public WhiteboardWindowFactory {
+ public WhiteboardWindowFactory,
+ public HighlightEditorWidgetFactory {
public:
virtual ~UIFactory() {}
};
diff --git a/Swift/Controllers/UIInterfaces/UserSearchWindowFactory.h b/Swift/Controllers/UIInterfaces/UserSearchWindowFactory.h
index 2a15806..331d6dd 100644
--- a/Swift/Controllers/UIInterfaces/UserSearchWindowFactory.h
+++ b/Swift/Controllers/UIInterfaces/UserSearchWindowFactory.h
@@ -14,7 +14,7 @@ namespace Swift {
class UIEventStream;
class UserSearchWindowFactory {
public:
- virtual ~UserSearchWindowFactory() {};
+ virtual ~UserSearchWindowFactory() {}
virtual UserSearchWindow* createUserSearchWindow(UserSearchWindow::Type type, UIEventStream* eventStream, const std::set<std::string>& groups) = 0;
};
diff --git a/Swift/Controllers/UIInterfaces/WhiteboardWindowFactory.h b/Swift/Controllers/UIInterfaces/WhiteboardWindowFactory.h
index c2d2f6c..2be0f9c 100644
--- a/Swift/Controllers/UIInterfaces/WhiteboardWindowFactory.h
+++ b/Swift/Controllers/UIInterfaces/WhiteboardWindowFactory.h
@@ -12,7 +12,7 @@ namespace Swift {
class WhiteboardWindowFactory {
public :
- virtual ~WhiteboardWindowFactory() {};
+ virtual ~WhiteboardWindowFactory() {}
virtual WhiteboardWindow* createWhiteboardWindow(boost::shared_ptr<WhiteboardSession> whiteboardSession) = 0;
};
diff --git a/Swift/Controllers/UIInterfaces/XMLConsoleWidgetFactory.h b/Swift/Controllers/UIInterfaces/XMLConsoleWidgetFactory.h
index e27fe2e..3cba597 100644
--- a/Swift/Controllers/UIInterfaces/XMLConsoleWidgetFactory.h
+++ b/Swift/Controllers/UIInterfaces/XMLConsoleWidgetFactory.h
@@ -12,7 +12,7 @@ namespace Swift {
class UIEventStream;
class XMLConsoleWidgetFactory {
public:
- virtual ~XMLConsoleWidgetFactory() {};
+ virtual ~XMLConsoleWidgetFactory() {}
virtual XMLConsoleWidget* createXMLConsoleWidget() = 0;
};
diff --git a/Swift/Controllers/UnitTest/ChatMessageSummarizerTest.cpp b/Swift/Controllers/UnitTest/ChatMessageSummarizerTest.cpp
index ee0ee9f..985352a 100644
--- a/Swift/Controllers/UnitTest/ChatMessageSummarizerTest.cpp
+++ b/Swift/Controllers/UnitTest/ChatMessageSummarizerTest.cpp
@@ -26,7 +26,7 @@ class ChatMessageSummarizerTest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE_END();
public:
- ChatMessageSummarizerTest() {};
+ ChatMessageSummarizerTest() {}
void setUp() {
diff --git a/Swift/Controllers/UnitTest/HighlightRuleTest.cpp b/Swift/Controllers/UnitTest/HighlightRuleTest.cpp
new file mode 100644
index 0000000..ec81227
--- /dev/null
+++ b/Swift/Controllers/UnitTest/HighlightRuleTest.cpp
@@ -0,0 +1,318 @@
+/*
+ * Copyright (c) 2012 Maciej Niedzielski
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <vector>
+#include <string>
+
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+
+#include <Swift/Controllers/HighlightRule.h>
+
+using namespace Swift;
+
+class HighlightRuleTest : public CppUnit::TestFixture {
+ CPPUNIT_TEST_SUITE(HighlightRuleTest);
+ CPPUNIT_TEST(testEmptyRuleNeverMatches);
+ CPPUNIT_TEST(testKeyword);
+ CPPUNIT_TEST(testNickKeyword);
+ CPPUNIT_TEST(testNickWithoutOtherKeywords);
+ CPPUNIT_TEST(testSender);
+ CPPUNIT_TEST(testSenderAndKeyword);
+ CPPUNIT_TEST(testWholeWords);
+ CPPUNIT_TEST(testCase);
+ CPPUNIT_TEST(testWholeWordsAndCase);
+ CPPUNIT_TEST(testMUC);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ void setUp() {
+ std::vector<std::string> keywords;
+ keywords.push_back("keyword1");
+ keywords.push_back("KEYWORD2");
+
+ std::vector<std::string>senders;
+ senders.push_back("sender1");
+ senders.push_back("SENDER2");
+
+ emptyRule = new HighlightRule();
+
+ keywordRule = new HighlightRule();
+ keywordRule->setKeywords(keywords);
+
+ keywordChatRule = new HighlightRule();
+ keywordChatRule->setKeywords(keywords);
+ keywordChatRule->setMatchChat(true);
+
+ keywordNickChatRule = new HighlightRule();
+ keywordNickChatRule->setKeywords(keywords);
+ keywordNickChatRule->setNickIsKeyword(true);
+ keywordNickChatRule->setMatchChat(true);
+
+ nickChatRule = new HighlightRule();
+ nickChatRule->setNickIsKeyword(true);
+ nickChatRule->setMatchChat(true);
+
+ nickRule = new HighlightRule();
+ nickRule->setNickIsKeyword(true);
+
+ senderRule = new HighlightRule();
+ senderRule->setSenders(senders);
+
+ senderChatRule = new HighlightRule();
+ senderChatRule->setSenders(senders);
+ senderChatRule->setMatchChat(true);
+
+ senderKeywordChatRule = new HighlightRule();
+ senderKeywordChatRule->setSenders(senders);
+ senderKeywordChatRule->setKeywords(keywords);
+ senderKeywordChatRule->setMatchChat(true);
+
+ senderKeywordNickChatRule = new HighlightRule();
+ senderKeywordNickChatRule->setSenders(senders);
+ senderKeywordNickChatRule->setKeywords(keywords);
+ senderKeywordNickChatRule->setNickIsKeyword(true);
+ senderKeywordNickChatRule->setMatchChat(true);
+
+ senderKeywordNickWordChatRule = new HighlightRule();
+ senderKeywordNickWordChatRule->setSenders(senders);
+ senderKeywordNickWordChatRule->setKeywords(keywords);
+ senderKeywordNickWordChatRule->setNickIsKeyword(true);
+ senderKeywordNickWordChatRule->setMatchWholeWords(true);
+ senderKeywordNickWordChatRule->setMatchChat(true);
+
+ senderKeywordNickCaseChatRule = new HighlightRule();
+ senderKeywordNickCaseChatRule->setSenders(senders);
+ senderKeywordNickCaseChatRule->setKeywords(keywords);
+ senderKeywordNickCaseChatRule->setNickIsKeyword(true);
+ senderKeywordNickCaseChatRule->setMatchCase(true);
+ senderKeywordNickCaseChatRule->setMatchChat(true);
+
+ senderKeywordNickCaseWordChatRule = new HighlightRule();
+ senderKeywordNickCaseWordChatRule->setSenders(senders);
+ senderKeywordNickCaseWordChatRule->setKeywords(keywords);
+ senderKeywordNickCaseWordChatRule->setNickIsKeyword(true);
+ senderKeywordNickCaseWordChatRule->setMatchCase(true);
+ senderKeywordNickCaseWordChatRule->setMatchWholeWords(true);
+ senderKeywordNickCaseWordChatRule->setMatchChat(true);
+
+ senderKeywordNickMUCRule = new HighlightRule();
+ senderKeywordNickMUCRule->setSenders(senders);
+ senderKeywordNickMUCRule->setKeywords(keywords);
+ senderKeywordNickMUCRule->setNickIsKeyword(true);
+ senderKeywordNickMUCRule->setMatchMUC(true);
+ }
+
+ void tearDown() {
+ delete emptyRule;
+
+ delete keywordRule;
+ delete keywordChatRule;
+ delete keywordNickChatRule;
+ delete nickChatRule;
+ delete nickRule;
+
+ delete senderRule;
+ delete senderChatRule;
+ delete senderKeywordChatRule;
+ delete senderKeywordNickChatRule;
+
+ delete senderKeywordNickWordChatRule;
+ delete senderKeywordNickCaseChatRule;
+ delete senderKeywordNickCaseWordChatRule;
+
+ delete senderKeywordNickMUCRule;
+ }
+
+ void testEmptyRuleNeverMatches() {
+ CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("body", "from", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("body", "from", "nick", HighlightRule::MUCMessage), false);
+
+ CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("body", "from", "", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("body", "from", "", HighlightRule::MUCMessage), false);
+
+ CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("body", "", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("body", "", "nick", HighlightRule::MUCMessage), false);
+
+ CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("", "from", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("", "from", "nick", HighlightRule::MUCMessage), false);
+
+ CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("body", "", "", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("body", "", "", HighlightRule::MUCMessage), false);
+
+ CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("", "from", "", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("", "from", "", HighlightRule::MUCMessage), false);
+
+ CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("", "", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("", "", "nick", HighlightRule::MUCMessage), false);
+
+ CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("", "", "", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("", "", "", HighlightRule::MUCMessage), false);
+ }
+
+ void testKeyword() {
+ CPPUNIT_ASSERT_EQUAL(keywordChatRule->isMatch("body", "from", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(keywordChatRule->isMatch("body", "from", "nick", HighlightRule::MUCMessage), false);
+
+ CPPUNIT_ASSERT_EQUAL(keywordChatRule->isMatch("keyword1", "from", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(keywordChatRule->isMatch("keyword1", "from", "nick", HighlightRule::MUCMessage), false);
+ CPPUNIT_ASSERT_EQUAL(keywordRule->isMatch("keyword1", "from", "nick", HighlightRule::ChatMessage), false);
+
+ CPPUNIT_ASSERT_EQUAL(keywordChatRule->isMatch("body", "sender contains keyword1", "nick", HighlightRule::ChatMessage), false);
+
+ CPPUNIT_ASSERT_EQUAL(keywordChatRule->isMatch("abc keyword1 xyz", "from", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(keywordChatRule->isMatch("abckeyword1xyz", "from", "nick", HighlightRule::ChatMessage), true);
+
+ CPPUNIT_ASSERT_EQUAL(keywordChatRule->isMatch("KEYword1", "from", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(keywordChatRule->isMatch("abc KEYword1 xyz", "from", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(keywordChatRule->isMatch("abcKEYword1xyz", "from", "nick", HighlightRule::ChatMessage), true);
+
+ CPPUNIT_ASSERT_EQUAL(keywordChatRule->isMatch("keyword2", "from", "nick", HighlightRule::ChatMessage), true);
+ }
+
+ void testNickKeyword() {
+ CPPUNIT_ASSERT_EQUAL(keywordNickChatRule->isMatch("body contains nick", "from", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(keywordNickChatRule->isMatch("body contains nick", "from", "nick", HighlightRule::MUCMessage), false);
+ CPPUNIT_ASSERT_EQUAL(keywordChatRule->isMatch("body contains nick", "from", "nick", HighlightRule::ChatMessage), false);
+
+ CPPUNIT_ASSERT_EQUAL(keywordNickChatRule->isMatch("keyword1", "from", "nick", HighlightRule::ChatMessage), true);
+
+ CPPUNIT_ASSERT_EQUAL(keywordNickChatRule->isMatch("body", "sender contains nick", "nick", HighlightRule::ChatMessage), false);
+
+ CPPUNIT_ASSERT_EQUAL(keywordNickChatRule->isMatch("body contains mixed-case NiCk", "sender", "nick", HighlightRule::ChatMessage), true);
+
+ CPPUNIT_ASSERT_EQUAL(keywordNickChatRule->isMatch("nickname", "from", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(keywordNickChatRule->isMatch("NIckNAME", "from", "nick", HighlightRule::ChatMessage), true);
+
+ CPPUNIT_ASSERT_EQUAL(keywordNickChatRule->isMatch("body", "from", "", HighlightRule::ChatMessage), false);
+ }
+
+ void testNickWithoutOtherKeywords() {
+ CPPUNIT_ASSERT_EQUAL(nickChatRule->isMatch("body contains nick", "from", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(nickChatRule->isMatch("body contains nick", "from", "nick", HighlightRule::MUCMessage), false);
+ CPPUNIT_ASSERT_EQUAL(nickRule->isMatch("body contains nick", "from", "nick", HighlightRule::ChatMessage), false);
+
+ CPPUNIT_ASSERT_EQUAL(nickChatRule->isMatch("keyword1", "from", "nick", HighlightRule::ChatMessage), false);
+
+ CPPUNIT_ASSERT_EQUAL(nickChatRule->isMatch("body", "sender contains nick but it does't matter", "nick", HighlightRule::ChatMessage), false);
+
+ CPPUNIT_ASSERT_EQUAL(nickChatRule->isMatch("body contains mixed-case NiCk", "from", "nick", HighlightRule::ChatMessage), true);
+
+ CPPUNIT_ASSERT_EQUAL(nickChatRule->isMatch("nickname", "from", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(nickChatRule->isMatch("NIckNAME", "from", "nick", HighlightRule::ChatMessage), true);
+
+ // there are no keywords in this rule and empty nick is not treated as a keyword, so we don't check for keywords to get a match
+ CPPUNIT_ASSERT_EQUAL(nickChatRule->isMatch("body", "from", "", HighlightRule::ChatMessage), true);
+ }
+
+ void testSender() {
+ CPPUNIT_ASSERT_EQUAL(senderChatRule->isMatch("body", "from", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderChatRule->isMatch("body", "from", "nick", HighlightRule::MUCMessage), false);
+
+ CPPUNIT_ASSERT_EQUAL(senderChatRule->isMatch("body", "sender1", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(senderChatRule->isMatch("body", "sender1", "nick", HighlightRule::MUCMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderRule->isMatch("body", "sender1", "nick", HighlightRule::ChatMessage), false);
+
+ CPPUNIT_ASSERT_EQUAL(senderRule->isMatch("body contains sender1", "from", "nick", HighlightRule::ChatMessage), false);
+
+ CPPUNIT_ASSERT_EQUAL(senderChatRule->isMatch("body", "abc sender1 xyz", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(senderChatRule->isMatch("body", "abcsender1xyz", "nick", HighlightRule::ChatMessage), true);
+
+ CPPUNIT_ASSERT_EQUAL(senderChatRule->isMatch("body", "SENDer1", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(senderChatRule->isMatch("body", "abc SENDer1 xyz", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(senderChatRule->isMatch("body", "abcSENDer1xyz", "nick", HighlightRule::ChatMessage), true);
+
+ CPPUNIT_ASSERT_EQUAL(senderChatRule->isMatch("body", "sender2", "nick", HighlightRule::ChatMessage), true);
+ }
+
+ void testSenderAndKeyword() {
+ CPPUNIT_ASSERT_EQUAL(senderKeywordChatRule->isMatch("body", "from", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordChatRule->isMatch("keyword1", "from", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordChatRule->isMatch("body", "sender1", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordChatRule->isMatch("keyword1", "sender1", "nick", HighlightRule::ChatMessage), true);
+ }
+
+ void testWholeWords() {
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickWordChatRule->isMatch("body", "from", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickWordChatRule->isMatch("keyword1", "from", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickWordChatRule->isMatch("body", "sender1", "nick", HighlightRule::ChatMessage), false);
+
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickWordChatRule->isMatch("keyword1", "sender1", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickWordChatRule->isMatch("xkeyword1", "sender1", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickWordChatRule->isMatch("keyword1", "xsender1", "nick", HighlightRule::ChatMessage), false);
+
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickWordChatRule->isMatch("body contains nick", "sender1", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickWordChatRule->isMatch("body contains xnick", "sender1", "nick", HighlightRule::ChatMessage), false);
+
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickWordChatRule->isMatch("KEYword1", "SENDer1", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickWordChatRule->isMatch("body contains NiCk", "sender1", "nick", HighlightRule::ChatMessage), true);
+ }
+
+ void testCase() {
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseChatRule->isMatch("body", "from", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseChatRule->isMatch("keyword1", "from", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseChatRule->isMatch("body", "sender1", "nick", HighlightRule::ChatMessage), false);
+
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseChatRule->isMatch("keyword1", "sender1", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseChatRule->isMatch("xkeyword1", "xsender1", "nick", HighlightRule::ChatMessage), true);
+
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseChatRule->isMatch("body contains nick", "sender1", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseChatRule->isMatch("body contains xnick", "sender1", "nick", HighlightRule::ChatMessage), true);
+
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseChatRule->isMatch("KEYword1", "SENDer1", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseChatRule->isMatch("keyword1", "SENDer1", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseChatRule->isMatch("KEYword1", "sender1", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseChatRule->isMatch("body contains NiCk", "sender1", "nick", HighlightRule::ChatMessage), false);
+ }
+
+ void testWholeWordsAndCase() {
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseWordChatRule->isMatch("body", "from", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseWordChatRule->isMatch("keyword1", "from", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseWordChatRule->isMatch("body", "sender1", "nick", HighlightRule::ChatMessage), false);
+
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseWordChatRule->isMatch("keyword1", "sender1", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseWordChatRule->isMatch("xkeyword1", "sender1", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseWordChatRule->isMatch("keyword1", "xsender1", "nick", HighlightRule::ChatMessage), false);
+
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseWordChatRule->isMatch("body contains nick", "sender1", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseWordChatRule->isMatch("body contains xnick", "sender1", "nick", HighlightRule::ChatMessage), false);
+
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseWordChatRule->isMatch("KEYword1", "SENDer1", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseWordChatRule->isMatch("keyword1", "SENDer1", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseWordChatRule->isMatch("KEYword1", "sender1", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseWordChatRule->isMatch("body contains NiCk", "sender1", "nick", HighlightRule::ChatMessage), false);
+ }
+
+ void testMUC() {
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickMUCRule->isMatch("body", "from", "nick", HighlightRule::ChatMessage), false);
+
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickMUCRule->isMatch("keyword1", "sender1", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickMUCRule->isMatch("keyword1", "sender1", "nick", HighlightRule::MUCMessage), true);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickMUCRule->isMatch("body contains nick", "sender1", "nick", HighlightRule::MUCMessage), true);
+ }
+
+ private:
+ HighlightRule* emptyRule;
+
+ HighlightRule* keywordRule;
+ HighlightRule* keywordChatRule;
+ HighlightRule* keywordNickChatRule;
+ HighlightRule* nickChatRule;
+ HighlightRule* nickRule;
+
+ HighlightRule* senderRule;
+ HighlightRule* senderChatRule;
+ HighlightRule* senderKeywordChatRule;
+ HighlightRule* senderKeywordNickChatRule;
+
+ HighlightRule* senderKeywordNickWordChatRule;
+ HighlightRule* senderKeywordNickCaseChatRule;
+ HighlightRule* senderKeywordNickCaseWordChatRule;
+
+ HighlightRule* senderKeywordNickMUCRule;
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(HighlightRuleTest);
diff --git a/Swift/Controllers/UnitTest/MockChatWindow.h b/Swift/Controllers/UnitTest/MockChatWindow.h
index 998a4eb..84aaa04 100644
--- a/Swift/Controllers/UnitTest/MockChatWindow.h
+++ b/Swift/Controllers/UnitTest/MockChatWindow.h
@@ -11,53 +11,53 @@
namespace Swift {
class MockChatWindow : public ChatWindow {
public:
- MockChatWindow() : labelsEnabled_(false) {};
+ MockChatWindow() : labelsEnabled_(false) {}
virtual ~MockChatWindow();
- virtual std::string addMessage(const std::string& message, const std::string& /*senderName*/, bool /*senderIsSelf*/, boost::shared_ptr<SecurityLabel> /*label*/, const std::string& /*avatarPath*/, const boost::posix_time::ptime&) {lastMessageBody_ = message; return "";};
- virtual std::string addAction(const std::string& message, const std::string& /*senderName*/, bool /*senderIsSelf*/, boost::shared_ptr<SecurityLabel> /*label*/, const std::string& /*avatarPath*/, const boost::posix_time::ptime&) {lastMessageBody_ = message; return "";};
- virtual void addSystemMessage(const std::string& /*message*/) {};
- virtual void addErrorMessage(const std::string& /*message*/) {};
- virtual void addPresenceMessage(const std::string& /*message*/) {};
+ virtual std::string addMessage(const std::string& message, const std::string& /*senderName*/, bool /*senderIsSelf*/, boost::shared_ptr<SecurityLabel> /*label*/, const std::string& /*avatarPath*/, const boost::posix_time::ptime&, const HighlightAction&) {lastMessageBody_ = message; return "";}
+ virtual std::string addAction(const std::string& message, const std::string& /*senderName*/, bool /*senderIsSelf*/, boost::shared_ptr<SecurityLabel> /*label*/, const std::string& /*avatarPath*/, const boost::posix_time::ptime&, const HighlightAction&) {lastMessageBody_ = message; return "";}
+ virtual void addSystemMessage(const std::string& /*message*/) {}
+ virtual void addErrorMessage(const std::string& /*message*/) {}
+ virtual void addPresenceMessage(const std::string& /*message*/) {}
// File transfer related stuff
- virtual std::string addFileTransfer(const std::string& /*senderName*/, bool /*senderIsSelf*/,const std::string& /*filename*/, const boost::uintmax_t /*sizeInBytes*/) { return 0; };
- virtual void setFileTransferProgress(std::string /*id*/, const int /*alreadyTransferedBytes*/) { };
- virtual void setFileTransferStatus(std::string /*id*/, const FileTransferState /*state*/, const std::string& /*msg*/) { };
+ virtual std::string addFileTransfer(const std::string& /*senderName*/, bool /*senderIsSelf*/,const std::string& /*filename*/, const boost::uintmax_t /*sizeInBytes*/) { return 0; }
+ virtual void setFileTransferProgress(std::string /*id*/, const int /*alreadyTransferedBytes*/) { }
+ virtual void setFileTransferStatus(std::string /*id*/, const FileTransferState /*state*/, const std::string& /*msg*/) { }
virtual void setMessageReceiptState(const std::string &/* id */, ReceiptState /* state */) { }
- virtual void setContactChatState(ChatState::ChatStateType /*state*/) {};
- virtual void setName(const std::string& name) {name_ = name;};
- virtual void show() {};
- virtual void activate() {};
- virtual void setAvailableSecurityLabels(const std::vector<SecurityLabelsCatalog::Item>& labels) {labels_ = labels;};
- virtual void setSecurityLabelsEnabled(bool enabled) {labelsEnabled_ = enabled;};
- virtual void setUnreadMessageCount(int /*count*/) {};
- virtual void convertToMUC() {};
- virtual void setSecurityLabelsError() {};
+ virtual void setContactChatState(ChatState::ChatStateType /*state*/) {}
+ virtual void setName(const std::string& name) {name_ = name;}
+ virtual void show() {}
+ virtual void activate() {}
+ virtual void setAvailableSecurityLabels(const std::vector<SecurityLabelsCatalog::Item>& labels) {labels_ = labels;}
+ virtual void setSecurityLabelsEnabled(bool enabled) {labelsEnabled_ = enabled;}
+ virtual void setUnreadMessageCount(int /*count*/) {}
+ virtual void convertToMUC() {}
+ virtual void setSecurityLabelsError() {}
virtual SecurityLabelsCatalog::Item getSelectedSecurityLabel() {return label_;}
- virtual void setInputEnabled(bool /*enabled*/) {};
- virtual void setRosterModel(Roster* /*roster*/) {};
- virtual void setTabComplete(TabComplete*) {};
- virtual void replaceLastMessage(const std::string&) {};
- virtual void replaceMessage(const std::string&, const std::string&, const boost::posix_time::ptime&) {};
- virtual void replaceWithAction(const std::string& /*message*/, const std::string& /*id*/, const boost::posix_time::ptime& /*time*/) {};
- void setAckState(const std::string& /*id*/, AckState /*state*/) {};
- virtual void flash() {};
- virtual void setAlert(const std::string& /*alertText*/, const std::string& /*buttonText*/) {};
- virtual void cancelAlert() {};
+ virtual void setInputEnabled(bool /*enabled*/) {}
+ virtual void setRosterModel(Roster* /*roster*/) {}
+ virtual void setTabComplete(TabComplete*) {}
+ virtual void replaceLastMessage(const std::string&) {}
+ virtual void replaceMessage(const std::string&, const std::string&, const boost::posix_time::ptime&, const HighlightAction&) {}
+ virtual void replaceWithAction(const std::string& /*message*/, const std::string& /*id*/, const boost::posix_time::ptime& /*time*/, const HighlightAction&) {}
+ void setAckState(const std::string& /*id*/, AckState /*state*/) {}
+ virtual void flash() {}
+ virtual void setAlert(const std::string& /*alertText*/, const std::string& /*buttonText*/) {}
+ virtual void cancelAlert() {}
virtual void setCorrectionEnabled(Tristate /*enabled*/) {}
void setAvailableOccupantActions(const std::vector<OccupantAction>&/* actions*/) {}
void setSubject(const std::string& /*subject*/) {}
virtual void showRoomConfigurationForm(Form::ref) {}
- virtual void addMUCInvitation(const std::string& /*senderName*/, const JID& /*jid*/, const std::string& /*reason*/, const std::string& /*password*/, bool = true) {};
+ virtual void addMUCInvitation(const std::string& /*senderName*/, const JID& /*jid*/, const std::string& /*reason*/, const std::string& /*password*/, bool = true) {}
- virtual std::string addWhiteboardRequest(bool) {return "";};
- virtual void setWhiteboardSessionStatus(std::string, const ChatWindow::WhiteboardSessionState){};
+ virtual std::string addWhiteboardRequest(bool) {return "";}
+ virtual void setWhiteboardSessionStatus(std::string, const ChatWindow::WhiteboardSessionState){}
virtual void setAffiliations(MUCOccupant::Affiliation, const std::vector<JID>&) {}
- virtual void setAvailableRoomActions(const std::vector<RoomAction> &) {};
+ virtual void setAvailableRoomActions(const std::vector<RoomAction> &) {}
virtual InviteToChatWindow* createInviteToChatWindow() {return NULL;}
std::string name_;
diff --git a/Swift/Controllers/UnitTest/MockMainWindow.h b/Swift/Controllers/UnitTest/MockMainWindow.h
index be1a932..19ab522 100644
--- a/Swift/Controllers/UnitTest/MockMainWindow.h
+++ b/Swift/Controllers/UnitTest/MockMainWindow.h
@@ -12,16 +12,16 @@ namespace Swift {
class Roster;
class MockMainWindow : public MainWindow {
public:
- MockMainWindow() : roster(NULL) {};
- virtual ~MockMainWindow() {};
- virtual void setRosterModel(Roster* roster) {this->roster = roster;};
- virtual void setMyNick(const std::string& /*name*/) {};;
- virtual void setMyJID(const JID& /*jid*/) {};;
- virtual void setMyAvatarPath(const std::string& /*path*/) {};
- virtual void setMyStatusText(const std::string& /*status*/) {};
- virtual void setMyStatusType(StatusShow::Type /*type*/) {};
- virtual void setAvailableAdHocCommands(const std::vector<DiscoItems::Item>& /*commands*/) {};
- virtual void setConnecting() {};
+ MockMainWindow() : roster(NULL) {}
+ virtual ~MockMainWindow() {}
+ virtual void setRosterModel(Roster* roster) {this->roster = roster;}
+ virtual void setMyNick(const std::string& /*name*/) {}
+ virtual void setMyJID(const JID& /*jid*/) {}
+ virtual void setMyAvatarPath(const std::string& /*path*/) {}
+ virtual void setMyStatusText(const std::string& /*status*/) {}
+ virtual void setMyStatusType(StatusShow::Type /*type*/) {}
+ virtual void setAvailableAdHocCommands(const std::vector<DiscoItems::Item>& /*commands*/) {}
+ virtual void setConnecting() {}
virtual void setStreamEncryptionStatus(bool /*tlsInPlaceAndValid*/) {}
virtual void openCertificateDialog(const std::vector<Certificate::ref>& /*chain*/) {}
Roster* roster;
diff --git a/Swift/Controllers/UnitTest/MockMainWindowFactory.h b/Swift/Controllers/UnitTest/MockMainWindowFactory.h
index d130b39..279a6dd 100644
--- a/Swift/Controllers/UnitTest/MockMainWindowFactory.h
+++ b/Swift/Controllers/UnitTest/MockMainWindowFactory.h
@@ -13,14 +13,14 @@ namespace Swift {
class MockMainWindowFactory : public MainWindowFactory {
public:
- MockMainWindowFactory() : last(NULL) {};
+ MockMainWindowFactory() : last(NULL) {}
- virtual ~MockMainWindowFactory() {};
+ virtual ~MockMainWindowFactory() {}
/**
* Transfers ownership of result.
*/
- virtual MainWindow* createMainWindow(UIEventStream*) {last = new MockMainWindow();return last;};
+ virtual MainWindow* createMainWindow(UIEventStream*) {last = new MockMainWindow();return last;}
MockMainWindow* last;
};
}
diff --git a/Swift/Controllers/XMPPEvents/ErrorEvent.h b/Swift/Controllers/XMPPEvents/ErrorEvent.h
index cbfc471..ac09de9 100644
--- a/Swift/Controllers/XMPPEvents/ErrorEvent.h
+++ b/Swift/Controllers/XMPPEvents/ErrorEvent.h
@@ -18,10 +18,10 @@
namespace Swift {
class ErrorEvent : public StanzaEvent {
public:
- ErrorEvent(const JID& jid, const std::string& text) : jid_(jid), text_(text){};
- virtual ~ErrorEvent(){};
- const JID& getJID() const {return jid_;};
- const std::string& getText() const {return text_;};
+ ErrorEvent(const JID& jid, const std::string& text) : jid_(jid), text_(text){}
+ virtual ~ErrorEvent(){}
+ const JID& getJID() const {return jid_;}
+ const std::string& getText() const {return text_;}
private:
JID jid_;
diff --git a/Swift/Controllers/XMPPEvents/EventController.cpp b/Swift/Controllers/XMPPEvents/EventController.cpp
index d84dfe3..8cb259b 100644
--- a/Swift/Controllers/XMPPEvents/EventController.cpp
+++ b/Swift/Controllers/XMPPEvents/EventController.cpp
@@ -7,6 +7,7 @@
#include <Swift/Controllers/XMPPEvents/EventController.h>
#include <boost/bind.hpp>
+#include <boost/numeric/conversion/cast.hpp>
#include <algorithm>
#include <Swiften/Base/foreach.h>
@@ -48,7 +49,7 @@ void EventController::handleIncomingEvent(boost::shared_ptr<StanzaEvent> sourceE
if ((messageEvent && messageEvent->isReadable()) || subscriptionEvent || errorEvent || mucInviteEvent) {
events_.push_back(sourceEvent);
sourceEvent->onConclusion.connect(boost::bind(&EventController::handleEventConcluded, this, sourceEvent));
- onEventQueueLengthChange(events_.size());
+ onEventQueueLengthChange(boost::numeric_cast<int>(events_.size()));
onEventQueueEventAdded(sourceEvent);
if (sourceEvent->getConcluded()) {
handleEventConcluded(sourceEvent);
@@ -59,7 +60,7 @@ void EventController::handleIncomingEvent(boost::shared_ptr<StanzaEvent> sourceE
void EventController::handleEventConcluded(boost::shared_ptr<StanzaEvent> event) {
event->onConclusion.disconnect(boost::bind(&EventController::handleEventConcluded, this, event));
events_.erase(std::remove(events_.begin(), events_.end(), event), events_.end());
- onEventQueueLengthChange(events_.size());
+ onEventQueueLengthChange(boost::numeric_cast<int>(events_.size()));
}
void EventController::disconnectAll() {
diff --git a/Swift/Controllers/XMPPEvents/MessageEvent.h b/Swift/Controllers/XMPPEvents/MessageEvent.h
index 1093470..a9214f5 100644
--- a/Swift/Controllers/XMPPEvents/MessageEvent.h
+++ b/Swift/Controllers/XMPPEvents/MessageEvent.h
@@ -17,7 +17,7 @@ namespace Swift {
public:
typedef boost::shared_ptr<MessageEvent> ref;
- MessageEvent(boost::shared_ptr<Message> stanza) : stanza_(stanza), targetsMe_(true) {};
+ MessageEvent(boost::shared_ptr<Message> stanza) : stanza_(stanza), targetsMe_(true) {}
boost::shared_ptr<Message> getStanza() {return stanza_;}
diff --git a/Swift/Controllers/XMPPEvents/StanzaEvent.h b/Swift/Controllers/XMPPEvents/StanzaEvent.h
index 321d23d..a15afc1 100644
--- a/Swift/Controllers/XMPPEvents/StanzaEvent.h
+++ b/Swift/Controllers/XMPPEvents/StanzaEvent.h
@@ -14,13 +14,13 @@
namespace Swift {
class StanzaEvent {
public:
- StanzaEvent() : time_(boost::posix_time::microsec_clock::universal_time()) {concluded_ = false;};
- virtual ~StanzaEvent() {};
- void conclude() {concluded_ = true; onConclusion();};
+ StanzaEvent() : time_(boost::posix_time::microsec_clock::universal_time()) {concluded_ = false;}
+ virtual ~StanzaEvent() {}
+ void conclude() {concluded_ = true; onConclusion();}
/** Do not call this directly from outside the class.
* If you connect to this signal, you *must* disconnect from it manually. */
boost::signal<void()> onConclusion;
- bool getConcluded() {return concluded_;};
+ bool getConcluded() {return concluded_;}
boost::posix_time::ptime getTime() {return time_;}
private:
bool concluded_;
diff --git a/Swift/Controllers/XMPPEvents/SubscriptionRequestEvent.h b/Swift/Controllers/XMPPEvents/SubscriptionRequestEvent.h
index 1f7812e..fb7a05e 100644
--- a/Swift/Controllers/XMPPEvents/SubscriptionRequestEvent.h
+++ b/Swift/Controllers/XMPPEvents/SubscriptionRequestEvent.h
@@ -18,21 +18,21 @@
namespace Swift {
class SubscriptionRequestEvent : public StanzaEvent {
public:
- SubscriptionRequestEvent(const JID& jid, const std::string& reason) : jid_(jid), reason_(reason){};
- virtual ~SubscriptionRequestEvent(){};
- const JID& getJID() const {return jid_;};
- const std::string& getReason() const {return reason_;};
+ SubscriptionRequestEvent(const JID& jid, const std::string& reason) : jid_(jid), reason_(reason){}
+ virtual ~SubscriptionRequestEvent(){}
+ const JID& getJID() const {return jid_;}
+ const std::string& getReason() const {return reason_;}
boost::signal<void()> onAccept;
boost::signal<void()> onDecline;
void accept() {
onAccept();
conclude();
- };
+ }
void decline() {
onDecline();
conclude();
- };
+ }
void defer() {
conclude();