diff options
Diffstat (limited to 'Swift/Controllers')
245 files changed, 13426 insertions, 13426 deletions
diff --git a/Swift/Controllers/AdHocController.cpp b/Swift/Controllers/AdHocController.cpp index 38b0fc5..4b93f2b 100644 --- a/Swift/Controllers/AdHocController.cpp +++ b/Swift/Controllers/AdHocController.cpp @@ -13,21 +13,21 @@ namespace Swift { AdHocController::AdHocController(AdHocCommandWindowFactory* factory, boost::shared_ptr<OutgoingAdHocCommandSession> command) { - window_ = factory->createAdHocCommandWindow(command); - window_->onClosing.connect(boost::bind(&AdHocController::handleWindowClosed, this)); + window_ = factory->createAdHocCommandWindow(command); + window_->onClosing.connect(boost::bind(&AdHocController::handleWindowClosed, this)); } AdHocController::~AdHocController() { - window_->onClosing.disconnect(boost::bind(&AdHocController::handleWindowClosed, this)); - delete window_; + window_->onClosing.disconnect(boost::bind(&AdHocController::handleWindowClosed, this)); + delete window_; } void AdHocController::setOnline(bool online) { - window_->setOnline(online); + window_->setOnline(online); } void AdHocController::handleWindowClosed() { - onDeleting(); + onDeleting(); } } diff --git a/Swift/Controllers/AdHocController.h b/Swift/Controllers/AdHocController.h index e2b93df..4694991 100644 --- a/Swift/Controllers/AdHocController.h +++ b/Swift/Controllers/AdHocController.h @@ -17,13 +17,13 @@ class AdHocCommandWindow; class AdHocController { public: - AdHocController(AdHocCommandWindowFactory* factory, boost::shared_ptr<OutgoingAdHocCommandSession> command); - ~AdHocController(); - boost::signal<void ()> onDeleting; - void setOnline(bool online); + AdHocController(AdHocCommandWindowFactory* factory, boost::shared_ptr<OutgoingAdHocCommandSession> command); + ~AdHocController(); + boost::signal<void ()> onDeleting; + void setOnline(bool online); private: - void handleWindowClosed(); - AdHocCommandWindow* window_; + void handleWindowClosed(); + AdHocCommandWindow* window_; }; } diff --git a/Swift/Controllers/AdHocManager.cpp b/Swift/Controllers/AdHocManager.cpp index 4733b57..1dcefbd 100644 --- a/Swift/Controllers/AdHocManager.cpp +++ b/Swift/Controllers/AdHocManager.cpp @@ -23,73 +23,73 @@ namespace Swift { AdHocManager::AdHocManager(const JID& jid, AdHocCommandWindowFactory* factory, IQRouter* iqRouter, UIEventStream* uiEventStream, MainWindow* mainWindow) : jid_(jid) { - iqRouter_ = iqRouter; - uiEventStream_ = uiEventStream; - mainWindow_ = mainWindow; - factory_ = factory; + iqRouter_ = iqRouter; + uiEventStream_ = uiEventStream; + mainWindow_ = mainWindow; + factory_ = factory; - uiEventStream_->onUIEvent.connect(boost::bind(&AdHocManager::handleUIEvent, this, _1)); + uiEventStream_->onUIEvent.connect(boost::bind(&AdHocManager::handleUIEvent, this, _1)); } AdHocManager::~AdHocManager() { - uiEventStream_->onUIEvent.disconnect(boost::bind(&AdHocManager::handleUIEvent, this, _1)); - for (size_t i = 0; i < controllers_.size(); ++i) { - controllers_[i]->onDeleting.disconnect(boost::bind(&AdHocManager::removeController, this, controllers_[i])); - } + uiEventStream_->onUIEvent.disconnect(boost::bind(&AdHocManager::handleUIEvent, this, _1)); + for (size_t i = 0; i < controllers_.size(); ++i) { + controllers_[i]->onDeleting.disconnect(boost::bind(&AdHocManager::removeController, this, controllers_[i])); + } } void AdHocManager::removeController(boost::shared_ptr<AdHocController> controller) { - controller->onDeleting.disconnect(boost::bind(&AdHocManager::removeController, this, controller)); - controllers_.erase(std::find(controllers_.begin(), controllers_.end(), controller)); + controller->onDeleting.disconnect(boost::bind(&AdHocManager::removeController, this, controller)); + controllers_.erase(std::find(controllers_.begin(), controllers_.end(), controller)); } void AdHocManager::setServerDiscoInfo(boost::shared_ptr<DiscoInfo> info) { - if (iqRouter_->isAvailable() && info->hasFeature(DiscoInfo::CommandsFeature)) { - if (discoItemsRequest_) { - discoItemsRequest_->onResponse.disconnect(boost::bind(&AdHocManager::handleServerDiscoItemsResponse, this, _1, _2)); - discoItemsRequest_.reset(); - } - discoItemsRequest_ = GetDiscoItemsRequest::create(JID(jid_.getDomain()), DiscoInfo::CommandsFeature, iqRouter_); - discoItemsRequest_->onResponse.connect(boost::bind(&AdHocManager::handleServerDiscoItemsResponse, this, _1, _2)); - discoItemsRequest_->send(); - } else { - mainWindow_->setAvailableAdHocCommands(std::vector<DiscoItems::Item>()); - } + if (iqRouter_->isAvailable() && info->hasFeature(DiscoInfo::CommandsFeature)) { + if (discoItemsRequest_) { + discoItemsRequest_->onResponse.disconnect(boost::bind(&AdHocManager::handleServerDiscoItemsResponse, this, _1, _2)); + discoItemsRequest_.reset(); + } + discoItemsRequest_ = GetDiscoItemsRequest::create(JID(jid_.getDomain()), DiscoInfo::CommandsFeature, iqRouter_); + discoItemsRequest_->onResponse.connect(boost::bind(&AdHocManager::handleServerDiscoItemsResponse, this, _1, _2)); + discoItemsRequest_->send(); + } else { + mainWindow_->setAvailableAdHocCommands(std::vector<DiscoItems::Item>()); + } } void AdHocManager::setOnline(bool online) { - foreach (boost::shared_ptr<AdHocController> controller, controllers_) { - controller->setOnline(online); - } + foreach (boost::shared_ptr<AdHocController> controller, controllers_) { + controller->setOnline(online); + } } void AdHocManager::handleServerDiscoItemsResponse(boost::shared_ptr<DiscoItems> items, ErrorPayload::ref error) { - std::vector<DiscoItems::Item> commands; - if (!error) { - foreach (DiscoItems::Item item, items->getItems()) { - if (item.getNode() != "http://isode.com/xmpp/commands#test") { - commands.push_back(item); - } - } - } - mainWindow_->setAvailableAdHocCommands(commands); + std::vector<DiscoItems::Item> commands; + if (!error) { + foreach (DiscoItems::Item item, items->getItems()) { + if (item.getNode() != "http://isode.com/xmpp/commands#test") { + commands.push_back(item); + } + } + } + mainWindow_->setAvailableAdHocCommands(commands); } void AdHocManager::handleUIEvent(boost::shared_ptr<UIEvent> event) { - boost::shared_ptr<RequestAdHocUIEvent> adHocEvent = boost::dynamic_pointer_cast<RequestAdHocUIEvent>(event); - if (adHocEvent) { - boost::shared_ptr<OutgoingAdHocCommandSession> command = boost::make_shared<OutgoingAdHocCommandSession>(adHocEvent->getCommand().getJID(), adHocEvent->getCommand().getNode(), iqRouter_); - boost::shared_ptr<AdHocController> controller = boost::make_shared<AdHocController>(factory_, command); - controller->onDeleting.connect(boost::bind(&AdHocManager::removeController, this, controller)); - controllers_.push_back(controller); - } - boost::shared_ptr<RequestAdHocWithJIDUIEvent> adHocJIDEvent = boost::dynamic_pointer_cast<RequestAdHocWithJIDUIEvent>(event); - if (!!adHocJIDEvent) { - boost::shared_ptr<OutgoingAdHocCommandSession> command = boost::make_shared<OutgoingAdHocCommandSession>(adHocJIDEvent->getJID(), adHocJIDEvent->getNode(), iqRouter_); - boost::shared_ptr<AdHocController> controller = boost::make_shared<AdHocController>(factory_, command); - controller->onDeleting.connect(boost::bind(&AdHocManager::removeController, this, controller)); - controllers_.push_back(controller); - } + boost::shared_ptr<RequestAdHocUIEvent> adHocEvent = boost::dynamic_pointer_cast<RequestAdHocUIEvent>(event); + if (adHocEvent) { + boost::shared_ptr<OutgoingAdHocCommandSession> command = boost::make_shared<OutgoingAdHocCommandSession>(adHocEvent->getCommand().getJID(), adHocEvent->getCommand().getNode(), iqRouter_); + boost::shared_ptr<AdHocController> controller = boost::make_shared<AdHocController>(factory_, command); + controller->onDeleting.connect(boost::bind(&AdHocManager::removeController, this, controller)); + controllers_.push_back(controller); + } + boost::shared_ptr<RequestAdHocWithJIDUIEvent> adHocJIDEvent = boost::dynamic_pointer_cast<RequestAdHocWithJIDUIEvent>(event); + if (!!adHocJIDEvent) { + boost::shared_ptr<OutgoingAdHocCommandSession> command = boost::make_shared<OutgoingAdHocCommandSession>(adHocJIDEvent->getJID(), adHocJIDEvent->getNode(), iqRouter_); + boost::shared_ptr<AdHocController> controller = boost::make_shared<AdHocController>(factory_, command); + controller->onDeleting.connect(boost::bind(&AdHocManager::removeController, this, controller)); + controllers_.push_back(controller); + } } } diff --git a/Swift/Controllers/AdHocManager.h b/Swift/Controllers/AdHocManager.h index 00289b0..73c057c 100644 --- a/Swift/Controllers/AdHocManager.h +++ b/Swift/Controllers/AdHocManager.h @@ -23,22 +23,22 @@ class UIEventStream; class AdHocCommandWindowFactory; class AdHocManager { public: - AdHocManager(const JID& jid, AdHocCommandWindowFactory* factory, IQRouter* iqRouter, UIEventStream* uiEventStream, MainWindow* mainWindow); - ~AdHocManager(); - void removeController(boost::shared_ptr<AdHocController> contoller); - void setServerDiscoInfo(boost::shared_ptr<DiscoInfo> info); - void setOnline(bool online); + AdHocManager(const JID& jid, AdHocCommandWindowFactory* factory, IQRouter* iqRouter, UIEventStream* uiEventStream, MainWindow* mainWindow); + ~AdHocManager(); + void removeController(boost::shared_ptr<AdHocController> contoller); + void setServerDiscoInfo(boost::shared_ptr<DiscoInfo> info); + void setOnline(bool online); private: - void handleServerDiscoItemsResponse(boost::shared_ptr<DiscoItems>, ErrorPayload::ref error); - void handleUIEvent(boost::shared_ptr<UIEvent> event); - boost::signal<void (const AdHocController&)> onControllerComplete; - JID jid_; - IQRouter* iqRouter_; - UIEventStream* uiEventStream_; - MainWindow* mainWindow_; - AdHocCommandWindowFactory* factory_; - GetDiscoItemsRequest::ref discoItemsRequest_; - std::vector<boost::shared_ptr<AdHocController> > controllers_; + void handleServerDiscoItemsResponse(boost::shared_ptr<DiscoItems>, ErrorPayload::ref error); + void handleUIEvent(boost::shared_ptr<UIEvent> event); + boost::signal<void (const AdHocController&)> onControllerComplete; + JID jid_; + IQRouter* iqRouter_; + UIEventStream* uiEventStream_; + MainWindow* mainWindow_; + AdHocCommandWindowFactory* factory_; + GetDiscoItemsRequest::ref discoItemsRequest_; + std::vector<boost::shared_ptr<AdHocController> > controllers_; }; } diff --git a/Swift/Controllers/BlockListController.cpp b/Swift/Controllers/BlockListController.cpp index 2c8d401..6fbf6b3 100644 --- a/Swift/Controllers/BlockListController.cpp +++ b/Swift/Controllers/BlockListController.cpp @@ -28,159 +28,159 @@ namespace Swift { BlockListController::BlockListController(ClientBlockListManager* blockListManager, UIEventStream* uiEventStream, BlockListEditorWidgetFactory* blockListEditorWidgetFactory, EventController* eventController) : blockListManager_(blockListManager), blockListEditorWidgetFactory_(blockListEditorWidgetFactory), blockListEditorWidget_(0), eventController_(eventController), remainingRequests_(0), uiEventStream_(uiEventStream) { - uiEventStream->onUIEvent.connect(boost::bind(&BlockListController::handleUIEvent, this, _1)); - blockListManager_->getBlockList()->onItemAdded.connect(boost::bind(&BlockListController::handleBlockListChanged, this)); - blockListManager_->getBlockList()->onItemRemoved.connect(boost::bind(&BlockListController::handleBlockListChanged, this)); + uiEventStream->onUIEvent.connect(boost::bind(&BlockListController::handleUIEvent, this, _1)); + blockListManager_->getBlockList()->onItemAdded.connect(boost::bind(&BlockListController::handleBlockListChanged, this)); + blockListManager_->getBlockList()->onItemRemoved.connect(boost::bind(&BlockListController::handleBlockListChanged, this)); } BlockListController::~BlockListController() { - uiEventStream_->onUIEvent.disconnect(boost::bind(&BlockListController::handleUIEvent, this, _1)); - blockListManager_->getBlockList()->onItemAdded.disconnect(boost::bind(&BlockListController::handleBlockListChanged, this)); - blockListManager_->getBlockList()->onItemRemoved.disconnect(boost::bind(&BlockListController::handleBlockListChanged, this)); + uiEventStream_->onUIEvent.disconnect(boost::bind(&BlockListController::handleUIEvent, this, _1)); + blockListManager_->getBlockList()->onItemAdded.disconnect(boost::bind(&BlockListController::handleBlockListChanged, this)); + blockListManager_->getBlockList()->onItemRemoved.disconnect(boost::bind(&BlockListController::handleBlockListChanged, this)); } void BlockListController::blockListDifferences(const std::vector<JID> &newBlockList, std::vector<JID> &jidsToUnblock, std::vector<JID> &jidsToBlock) const { - foreach (const JID& jid, blockListBeforeEdit) { - if (std::find(newBlockList.begin(), newBlockList.end(), jid) == newBlockList.end()) { - jidsToUnblock.push_back(jid); - } - } - - foreach (const JID& jid, newBlockList) { - if (std::find(blockListBeforeEdit.begin(), blockListBeforeEdit.end(), jid) == blockListBeforeEdit.end()) { - jidsToBlock.push_back(jid); - } - } + foreach (const JID& jid, blockListBeforeEdit) { + if (std::find(newBlockList.begin(), newBlockList.end(), jid) == newBlockList.end()) { + jidsToUnblock.push_back(jid); + } + } + + foreach (const JID& jid, newBlockList) { + if (std::find(blockListBeforeEdit.begin(), blockListBeforeEdit.end(), jid) == blockListBeforeEdit.end()) { + jidsToBlock.push_back(jid); + } + } } void BlockListController::handleUIEvent(boost::shared_ptr<UIEvent> rawEvent) { - // handle UI dialog - boost::shared_ptr<RequestBlockListDialogUIEvent> requestDialogEvent = boost::dynamic_pointer_cast<RequestBlockListDialogUIEvent>(rawEvent); - if (requestDialogEvent != NULL) { - if (blockListEditorWidget_ == NULL) { - blockListEditorWidget_ = blockListEditorWidgetFactory_->createBlockListEditorWidget(); - blockListEditorWidget_->onSetNewBlockList.connect(boost::bind(&BlockListController::handleSetNewBlockList, this, _1)); - } - blockListBeforeEdit = blockListManager_->getBlockList()->getItems(); - blockListEditorWidget_->setCurrentBlockList(blockListBeforeEdit); - blockListEditorWidget_->setError(""); - blockListEditorWidget_->show(); - return; - } - - // handle block state change - boost::shared_ptr<RequestChangeBlockStateUIEvent> changeStateEvent = boost::dynamic_pointer_cast<RequestChangeBlockStateUIEvent>(rawEvent); - if (changeStateEvent != NULL) { - if (changeStateEvent->getBlockState() == RequestChangeBlockStateUIEvent::Blocked) { - GenericRequest<BlockPayload>::ref blockRequest = blockListManager_->createBlockJIDRequest(changeStateEvent->getContact()); - blockRequest->onResponse.connect(boost::bind(&BlockListController::handleBlockResponse, this, blockRequest, _1, _2, std::vector<JID>(1, changeStateEvent->getContact()), false)); - blockRequest->send(); - } else if (changeStateEvent->getBlockState() == RequestChangeBlockStateUIEvent::Unblocked) { - GenericRequest<UnblockPayload>::ref unblockRequest = blockListManager_->createUnblockJIDRequest(changeStateEvent->getContact()); - unblockRequest->onResponse.connect(boost::bind(&BlockListController::handleUnblockResponse, this, unblockRequest, _1, _2, std::vector<JID>(1, changeStateEvent->getContact()), false)); - unblockRequest->send(); - } - return; - } + // handle UI dialog + boost::shared_ptr<RequestBlockListDialogUIEvent> requestDialogEvent = boost::dynamic_pointer_cast<RequestBlockListDialogUIEvent>(rawEvent); + if (requestDialogEvent != NULL) { + if (blockListEditorWidget_ == NULL) { + blockListEditorWidget_ = blockListEditorWidgetFactory_->createBlockListEditorWidget(); + blockListEditorWidget_->onSetNewBlockList.connect(boost::bind(&BlockListController::handleSetNewBlockList, this, _1)); + } + blockListBeforeEdit = blockListManager_->getBlockList()->getItems(); + blockListEditorWidget_->setCurrentBlockList(blockListBeforeEdit); + blockListEditorWidget_->setError(""); + blockListEditorWidget_->show(); + return; + } + + // handle block state change + boost::shared_ptr<RequestChangeBlockStateUIEvent> changeStateEvent = boost::dynamic_pointer_cast<RequestChangeBlockStateUIEvent>(rawEvent); + if (changeStateEvent != NULL) { + if (changeStateEvent->getBlockState() == RequestChangeBlockStateUIEvent::Blocked) { + GenericRequest<BlockPayload>::ref blockRequest = blockListManager_->createBlockJIDRequest(changeStateEvent->getContact()); + blockRequest->onResponse.connect(boost::bind(&BlockListController::handleBlockResponse, this, blockRequest, _1, _2, std::vector<JID>(1, changeStateEvent->getContact()), false)); + blockRequest->send(); + } else if (changeStateEvent->getBlockState() == RequestChangeBlockStateUIEvent::Unblocked) { + GenericRequest<UnblockPayload>::ref unblockRequest = blockListManager_->createUnblockJIDRequest(changeStateEvent->getContact()); + unblockRequest->onResponse.connect(boost::bind(&BlockListController::handleUnblockResponse, this, unblockRequest, _1, _2, std::vector<JID>(1, changeStateEvent->getContact()), false)); + unblockRequest->send(); + } + return; + } } void BlockListController::handleBlockResponse(GenericRequest<BlockPayload>::ref request, boost::shared_ptr<BlockPayload>, ErrorPayload::ref error, const std::vector<JID>& jids, bool originEditor) { - if (error) { - std::string errorMessage; - // FIXME: Handle reporting of list of JIDs in a translatable way. - errorMessage = str(format(QT_TRANSLATE_NOOP("", "Failed to block %1%.")) % jids.at(0).toString()); - if (!error->getText().empty()) { - errorMessage = str(format(QT_TRANSLATE_NOOP("", "%1%: %2%.")) % errorMessage % error->getText()); - } - if (blockListEditorWidget_ && originEditor) { - blockListEditorWidget_->setError(errorMessage); - blockListEditorWidget_->setBusy(false); - } - else { - eventController_->handleIncomingEvent(boost::make_shared<ErrorEvent>(request->getReceiver(), errorMessage)); - } - } - if (originEditor) { - remainingRequests_--; - if (blockListEditorWidget_ && (remainingRequests_ == 0) && !error) { - blockListEditorWidget_->setBusy(false); - blockListEditorWidget_->hide(); - } - } + if (error) { + std::string errorMessage; + // FIXME: Handle reporting of list of JIDs in a translatable way. + errorMessage = str(format(QT_TRANSLATE_NOOP("", "Failed to block %1%.")) % jids.at(0).toString()); + if (!error->getText().empty()) { + errorMessage = str(format(QT_TRANSLATE_NOOP("", "%1%: %2%.")) % errorMessage % error->getText()); + } + if (blockListEditorWidget_ && originEditor) { + blockListEditorWidget_->setError(errorMessage); + blockListEditorWidget_->setBusy(false); + } + else { + eventController_->handleIncomingEvent(boost::make_shared<ErrorEvent>(request->getReceiver(), errorMessage)); + } + } + if (originEditor) { + remainingRequests_--; + if (blockListEditorWidget_ && (remainingRequests_ == 0) && !error) { + blockListEditorWidget_->setBusy(false); + blockListEditorWidget_->hide(); + } + } } void BlockListController::handleUnblockResponse(GenericRequest<UnblockPayload>::ref request, boost::shared_ptr<UnblockPayload>, ErrorPayload::ref error, const std::vector<JID>& jids, bool originEditor) { - if (error) { - std::string errorMessage; - // FIXME: Handle reporting of list of JIDs in a translatable way. - errorMessage = str(format(QT_TRANSLATE_NOOP("", "Failed to unblock %1%.")) % jids.at(0).toString()); - if (!error->getText().empty()) { - errorMessage = str(format(QT_TRANSLATE_NOOP("", "%1%: %2%.")) % errorMessage % error->getText()); - } - if (blockListEditorWidget_ && originEditor) { - blockListEditorWidget_->setError(errorMessage); - blockListEditorWidget_->setBusy(false); - } - else { - eventController_->handleIncomingEvent(boost::make_shared<ErrorEvent>(request->getReceiver(), errorMessage)); - } - } - if (originEditor) { - remainingRequests_--; - if (blockListEditorWidget_ && (remainingRequests_ == 0) && !error) { - blockListEditorWidget_->setBusy(false); - blockListEditorWidget_->hide(); - } - } + if (error) { + std::string errorMessage; + // FIXME: Handle reporting of list of JIDs in a translatable way. + errorMessage = str(format(QT_TRANSLATE_NOOP("", "Failed to unblock %1%.")) % jids.at(0).toString()); + if (!error->getText().empty()) { + errorMessage = str(format(QT_TRANSLATE_NOOP("", "%1%: %2%.")) % errorMessage % error->getText()); + } + if (blockListEditorWidget_ && originEditor) { + blockListEditorWidget_->setError(errorMessage); + blockListEditorWidget_->setBusy(false); + } + else { + eventController_->handleIncomingEvent(boost::make_shared<ErrorEvent>(request->getReceiver(), errorMessage)); + } + } + if (originEditor) { + remainingRequests_--; + if (blockListEditorWidget_ && (remainingRequests_ == 0) && !error) { + blockListEditorWidget_->setBusy(false); + blockListEditorWidget_->hide(); + } + } } void BlockListController::handleSetNewBlockList(const std::vector<JID> &newBlockList) { - std::vector<JID> jidsToBlock; - std::vector<JID> jidsToUnblock; - - blockListDifferences(newBlockList, jidsToUnblock, jidsToBlock); - - if (!jidsToBlock.empty()) { - remainingRequests_++; - GenericRequest<BlockPayload>::ref blockRequest = blockListManager_->createBlockJIDsRequest(jidsToBlock); - blockRequest->onResponse.connect(boost::bind(&BlockListController::handleBlockResponse, this, blockRequest, _1, _2, jidsToBlock, true)); - blockRequest->send(); - } - if (!jidsToUnblock.empty()) { - remainingRequests_++; - GenericRequest<UnblockPayload>::ref unblockRequest = blockListManager_->createUnblockJIDsRequest(jidsToUnblock); - unblockRequest->onResponse.connect(boost::bind(&BlockListController::handleUnblockResponse, this, unblockRequest, _1, _2, jidsToUnblock, true)); - unblockRequest->send(); - } - if (!jidsToBlock.empty() || !jidsToUnblock.empty()) { - assert(blockListEditorWidget_); - blockListEditorWidget_->setBusy(true); - blockListEditorWidget_->setError(""); - } else { - blockListEditorWidget_->hide(); - } + std::vector<JID> jidsToBlock; + std::vector<JID> jidsToUnblock; + + blockListDifferences(newBlockList, jidsToUnblock, jidsToBlock); + + if (!jidsToBlock.empty()) { + remainingRequests_++; + GenericRequest<BlockPayload>::ref blockRequest = blockListManager_->createBlockJIDsRequest(jidsToBlock); + blockRequest->onResponse.connect(boost::bind(&BlockListController::handleBlockResponse, this, blockRequest, _1, _2, jidsToBlock, true)); + blockRequest->send(); + } + if (!jidsToUnblock.empty()) { + remainingRequests_++; + GenericRequest<UnblockPayload>::ref unblockRequest = blockListManager_->createUnblockJIDsRequest(jidsToUnblock); + unblockRequest->onResponse.connect(boost::bind(&BlockListController::handleUnblockResponse, this, unblockRequest, _1, _2, jidsToUnblock, true)); + unblockRequest->send(); + } + if (!jidsToBlock.empty() || !jidsToUnblock.empty()) { + assert(blockListEditorWidget_); + blockListEditorWidget_->setBusy(true); + blockListEditorWidget_->setError(""); + } else { + blockListEditorWidget_->hide(); + } } void BlockListController::handleBlockListChanged() { - if (blockListEditorWidget_) { - std::vector<JID> jidsToBlock; - std::vector<JID> jidsToUnblock; + if (blockListEditorWidget_) { + std::vector<JID> jidsToBlock; + std::vector<JID> jidsToUnblock; - blockListDifferences(blockListEditorWidget_->getCurrentBlockList(), jidsToUnblock, jidsToBlock); - blockListBeforeEdit = blockListManager_->getBlockList()->getItems(); + blockListDifferences(blockListEditorWidget_->getCurrentBlockList(), jidsToUnblock, jidsToBlock); + blockListBeforeEdit = blockListManager_->getBlockList()->getItems(); - foreach (const JID& jid, jidsToBlock) { - if (std::find(blockListBeforeEdit.begin(), blockListBeforeEdit.end(), jid) == blockListBeforeEdit.end()) { - blockListBeforeEdit.push_back(jid); - } - } + foreach (const JID& jid, jidsToBlock) { + if (std::find(blockListBeforeEdit.begin(), blockListBeforeEdit.end(), jid) == blockListBeforeEdit.end()) { + blockListBeforeEdit.push_back(jid); + } + } - foreach (const JID& jid, jidsToUnblock) { - blockListBeforeEdit.erase(std::remove(blockListBeforeEdit.begin(), blockListBeforeEdit.end(), jid), blockListBeforeEdit.end()); - } + foreach (const JID& jid, jidsToUnblock) { + blockListBeforeEdit.erase(std::remove(blockListBeforeEdit.begin(), blockListBeforeEdit.end(), jid), blockListBeforeEdit.end()); + } - blockListEditorWidget_->setCurrentBlockList(blockListBeforeEdit); - } + blockListEditorWidget_->setCurrentBlockList(blockListBeforeEdit); + } } } diff --git a/Swift/Controllers/BlockListController.h b/Swift/Controllers/BlockListController.h index c911344..f9ee5a6 100644 --- a/Swift/Controllers/BlockListController.h +++ b/Swift/Controllers/BlockListController.h @@ -28,29 +28,29 @@ class EventController; class BlockListController { public: - BlockListController(ClientBlockListManager* blockListManager, UIEventStream* uiEventStream, BlockListEditorWidgetFactory* blockListEditorWidgetFactory, EventController* eventController); - ~BlockListController(); + BlockListController(ClientBlockListManager* blockListManager, UIEventStream* uiEventStream, BlockListEditorWidgetFactory* blockListEditorWidgetFactory, EventController* eventController); + ~BlockListController(); private: - void blockListDifferences(const std::vector<JID> &newBlockList, std::vector<JID>& jidsToUnblock, std::vector<JID>& jidsToBlock) const; + void blockListDifferences(const std::vector<JID> &newBlockList, std::vector<JID>& jidsToUnblock, std::vector<JID>& jidsToBlock) const; - void handleUIEvent(boost::shared_ptr<UIEvent> event); + void handleUIEvent(boost::shared_ptr<UIEvent> event); - void handleBlockResponse(GenericRequest<BlockPayload>::ref, boost::shared_ptr<BlockPayload>, ErrorPayload::ref error, const std::vector<JID>& jids, bool originEditor); - void handleUnblockResponse(GenericRequest<UnblockPayload>::ref, boost::shared_ptr<UnblockPayload>, ErrorPayload::ref error, const std::vector<JID>& jids, bool originEditor); + void handleBlockResponse(GenericRequest<BlockPayload>::ref, boost::shared_ptr<BlockPayload>, ErrorPayload::ref error, const std::vector<JID>& jids, bool originEditor); + void handleUnblockResponse(GenericRequest<UnblockPayload>::ref, boost::shared_ptr<UnblockPayload>, ErrorPayload::ref error, const std::vector<JID>& jids, bool originEditor); - void handleSetNewBlockList(const std::vector<JID>& newBlockList); + void handleSetNewBlockList(const std::vector<JID>& newBlockList); - void handleBlockListChanged(); + void handleBlockListChanged(); private: - ClientBlockListManager* blockListManager_; - BlockListEditorWidgetFactory* blockListEditorWidgetFactory_; - BlockListEditorWidget* blockListEditorWidget_; - EventController* eventController_; - std::vector<JID> blockListBeforeEdit; - int remainingRequests_; - UIEventStream* uiEventStream_; + ClientBlockListManager* blockListManager_; + BlockListEditorWidgetFactory* blockListEditorWidgetFactory_; + BlockListEditorWidget* blockListEditorWidget_; + EventController* eventController_; + std::vector<JID> blockListBeforeEdit; + int remainingRequests_; + UIEventStream* uiEventStream_; }; } diff --git a/Swift/Controllers/CertificateMemoryStorageFactory.h b/Swift/Controllers/CertificateMemoryStorageFactory.h index de9f3fe..080b157 100644 --- a/Swift/Controllers/CertificateMemoryStorageFactory.h +++ b/Swift/Controllers/CertificateMemoryStorageFactory.h @@ -10,19 +10,19 @@ #include <Swift/Controllers/Storages/CertificateStorageFactory.h> namespace Swift { - class CertificateFactory; + class CertificateFactory; - class CertificateMemoryStorageFactory : public CertificateStorageFactory { - public: - CertificateMemoryStorageFactory() { - } + class CertificateMemoryStorageFactory : public CertificateStorageFactory { + public: + CertificateMemoryStorageFactory() { + } - virtual CertificateStorage* createCertificateStorage(const JID&) const { - return new CertificateMemoryStorage(); - } + virtual CertificateStorage* createCertificateStorage(const JID&) const { + return new CertificateMemoryStorage(); + } - private: - boost::filesystem::path basePath; - CertificateFactory* certificateFactory; - }; + private: + boost::filesystem::path basePath; + CertificateFactory* certificateFactory; + }; } diff --git a/Swift/Controllers/Chat/AutoAcceptMUCInviteDecider.h b/Swift/Controllers/Chat/AutoAcceptMUCInviteDecider.h index 8ea6dff..646612b 100644 --- a/Swift/Controllers/Chat/AutoAcceptMUCInviteDecider.h +++ b/Swift/Controllers/Chat/AutoAcceptMUCInviteDecider.h @@ -19,36 +19,36 @@ #include <Swift/Controllers/Settings/SettingsProvider.h> namespace Swift { - class AutoAcceptMUCInviteDecider { - public: - AutoAcceptMUCInviteDecider(const JID& domain, XMPPRoster* roster, SettingsProvider* settings) : domain_(domain), roster_(roster), settings_(settings) { - } - - bool isAutoAcceptedInvite(const JID& from, MUCInvitationPayload::ref invite) { - if (!invite->getIsImpromptu()) { - return false; /* always ask the user for normal MUC invites */ - } - - if (invite->getIsContinuation()) { - return true; - } - - std::string auto_accept_mode = settings_->getSetting(SettingConstants::INVITE_AUTO_ACCEPT_MODE); - if (auto_accept_mode == "no") { - return false; - } else if (auto_accept_mode == "presence") { - return roster_->getSubscriptionStateForJID(from) == RosterItemPayload::From || roster_->getSubscriptionStateForJID(from) == RosterItemPayload::Both; - } else if (auto_accept_mode == "domain") { - return roster_->getSubscriptionStateForJID(from) == RosterItemPayload::From || roster_->getSubscriptionStateForJID(from) == RosterItemPayload::Both || from.getDomain() == domain_; - } else { - assert(false); - return false; - } - } - - private: - JID domain_; - XMPPRoster* roster_; - SettingsProvider* settings_; - }; + class AutoAcceptMUCInviteDecider { + public: + AutoAcceptMUCInviteDecider(const JID& domain, XMPPRoster* roster, SettingsProvider* settings) : domain_(domain), roster_(roster), settings_(settings) { + } + + bool isAutoAcceptedInvite(const JID& from, MUCInvitationPayload::ref invite) { + if (!invite->getIsImpromptu()) { + return false; /* always ask the user for normal MUC invites */ + } + + if (invite->getIsContinuation()) { + return true; + } + + std::string auto_accept_mode = settings_->getSetting(SettingConstants::INVITE_AUTO_ACCEPT_MODE); + if (auto_accept_mode == "no") { + return false; + } else if (auto_accept_mode == "presence") { + return roster_->getSubscriptionStateForJID(from) == RosterItemPayload::From || roster_->getSubscriptionStateForJID(from) == RosterItemPayload::Both; + } else if (auto_accept_mode == "domain") { + return roster_->getSubscriptionStateForJID(from) == RosterItemPayload::From || roster_->getSubscriptionStateForJID(from) == RosterItemPayload::Both || from.getDomain() == domain_; + } else { + assert(false); + return false; + } + } + + private: + JID domain_; + XMPPRoster* roster_; + SettingsProvider* settings_; + }; } diff --git a/Swift/Controllers/Chat/ChatController.cpp b/Swift/Controllers/Chat/ChatController.cpp index 7f62c36..5302492 100644 --- a/Swift/Controllers/Chat/ChatController.cpp +++ b/Swift/Controllers/Chat/ChatController.cpp @@ -45,489 +45,489 @@ #include <Swift/Controllers/XMPPEvents/EventController.h> 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, HighlightManager* highlightManager, ClientBlockListManager* clientBlockListManager, boost::shared_ptr<ChatMessageParser> chatMessageParser, AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider) - : ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, contact, presenceOracle, avatarManager, useDelayForLatency, eventStream, eventController, timerFactory, entityCapsProvider, historyController, mucRegistry, highlightManager, chatMessageParser, autoAcceptMUCInviteDecider), eventStream_(eventStream), userWantsReceipts_(userWantsReceipts), settings_(settings), clientBlockListManager_(clientBlockListManager) { - isInMUC_ = isInMUC; - lastWasPresence_ = false; - chatStateNotifier_ = new ChatStateNotifier(stanzaChannel, contact, entityCapsProvider); - chatStateTracker_ = new ChatStateTracker(); - nickResolver_ = nickResolver; - presenceOracle_->onPresenceChange.connect(boost::bind(&ChatController::handlePresenceChange, this, _1)); - chatStateTracker_->onChatStateChange.connect(boost::bind(&ChatWindow::setContactChatState, chatWindow_, _1)); - stanzaChannel_->onStanzaAcked.connect(boost::bind(&ChatController::handleStanzaAcked, this, _1)); - nickResolver_->onNickChanged.connect(boost::bind(&ChatController::handleContactNickChanged, this, _1, _2)); - std::string nick = nickResolver_->jidToNick(toJID_); - chatWindow_->setName(nick); - std::string startMessage; - Presence::ref theirPresence; - if (isInMUC) { - startMessage = str(format(QT_TRANSLATE_NOOP("", "Starting chat with %1% in chatroom %2%")) % nick % contact.toBare().toString()); - theirPresence = presenceOracle->getLastPresence(contact); - } else { - startMessage = str(format(QT_TRANSLATE_NOOP("", "Starting chat with %1% - %2%")) % nick % contact.toBare().toString()); - theirPresence = contact.isBare() ? presenceOracle->getAccountPresence(contact) : presenceOracle->getLastPresence(contact); - } - Idle::ref idle; - if (theirPresence && (idle = theirPresence->getPayload<Idle>())) { - startMessage += str(format(QT_TRANSLATE_NOOP("", ", who has been idle since %1%")) % dateTimeToLocalString(idle->getSince())); - } - startMessage += ": " + statusShowTypeToFriendlyName(theirPresence ? theirPresence->getShow() : StatusShow::None); - if (theirPresence && !theirPresence->getStatus().empty()) { - startMessage += " (" + theirPresence->getStatus() + ")"; - } - lastShownStatus_ = theirPresence ? theirPresence->getShow() : StatusShow::None; - chatStateNotifier_->setContactIsOnline(theirPresence && theirPresence->getType() == Presence::Available); - startMessage += "."; - chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(startMessage), ChatWindow::DefaultDirection); - chatWindow_->onUserTyping.connect(boost::bind(&ChatStateNotifier::setUserIsTyping, chatStateNotifier_)); - chatWindow_->onUserCancelsTyping.connect(boost::bind(&ChatStateNotifier::userCancelledNewMessage, chatStateNotifier_)); - chatWindow_->onFileTransferStart.connect(boost::bind(&ChatController::handleFileTransferStart, this, _1, _2)); - chatWindow_->onFileTransferAccept.connect(boost::bind(&ChatController::handleFileTransferAccept, this, _1, _2)); - chatWindow_->onFileTransferCancel.connect(boost::bind(&ChatController::handleFileTransferCancel, this, _1)); - chatWindow_->onSendFileRequest.connect(boost::bind(&ChatController::handleSendFileRequest, this, _1)); - chatWindow_->onWhiteboardSessionAccept.connect(boost::bind(&ChatController::handleWhiteboardSessionAccept, this)); - chatWindow_->onWhiteboardSessionCancel.connect(boost::bind(&ChatController::handleWhiteboardSessionCancel, this)); - chatWindow_->onWhiteboardWindowShow.connect(boost::bind(&ChatController::handleWhiteboardWindowShow, this)); - chatWindow_->onBlockUserRequest.connect(boost::bind(&ChatController::handleBlockUserRequest, this)); - chatWindow_->onUnblockUserRequest.connect(boost::bind(&ChatController::handleUnblockUserRequest, this)); - chatWindow_->onInviteToChat.connect(boost::bind(&ChatController::handleInviteToChat, this, _1)); - chatWindow_->onClosed.connect(boost::bind(&ChatController::handleWindowClosed, this)); - ChatController::handleBareJIDCapsChanged(toJID_); - - settings_->onSettingChanged.connect(boost::bind(&ChatController::handleSettingChanged, this, _1)); - eventStream_->onUIEvent.connect(boost::bind(&ChatController::handleUIEvent, this, _1)); + : ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, contact, presenceOracle, avatarManager, useDelayForLatency, eventStream, eventController, timerFactory, entityCapsProvider, historyController, mucRegistry, highlightManager, chatMessageParser, autoAcceptMUCInviteDecider), eventStream_(eventStream), userWantsReceipts_(userWantsReceipts), settings_(settings), clientBlockListManager_(clientBlockListManager) { + isInMUC_ = isInMUC; + lastWasPresence_ = false; + chatStateNotifier_ = new ChatStateNotifier(stanzaChannel, contact, entityCapsProvider); + chatStateTracker_ = new ChatStateTracker(); + nickResolver_ = nickResolver; + presenceOracle_->onPresenceChange.connect(boost::bind(&ChatController::handlePresenceChange, this, _1)); + chatStateTracker_->onChatStateChange.connect(boost::bind(&ChatWindow::setContactChatState, chatWindow_, _1)); + stanzaChannel_->onStanzaAcked.connect(boost::bind(&ChatController::handleStanzaAcked, this, _1)); + nickResolver_->onNickChanged.connect(boost::bind(&ChatController::handleContactNickChanged, this, _1, _2)); + std::string nick = nickResolver_->jidToNick(toJID_); + chatWindow_->setName(nick); + std::string startMessage; + Presence::ref theirPresence; + if (isInMUC) { + startMessage = str(format(QT_TRANSLATE_NOOP("", "Starting chat with %1% in chatroom %2%")) % nick % contact.toBare().toString()); + theirPresence = presenceOracle->getLastPresence(contact); + } else { + startMessage = str(format(QT_TRANSLATE_NOOP("", "Starting chat with %1% - %2%")) % nick % contact.toBare().toString()); + theirPresence = contact.isBare() ? presenceOracle->getAccountPresence(contact) : presenceOracle->getLastPresence(contact); + } + Idle::ref idle; + if (theirPresence && (idle = theirPresence->getPayload<Idle>())) { + startMessage += str(format(QT_TRANSLATE_NOOP("", ", who has been idle since %1%")) % dateTimeToLocalString(idle->getSince())); + } + startMessage += ": " + statusShowTypeToFriendlyName(theirPresence ? theirPresence->getShow() : StatusShow::None); + if (theirPresence && !theirPresence->getStatus().empty()) { + startMessage += " (" + theirPresence->getStatus() + ")"; + } + lastShownStatus_ = theirPresence ? theirPresence->getShow() : StatusShow::None; + chatStateNotifier_->setContactIsOnline(theirPresence && theirPresence->getType() == Presence::Available); + startMessage += "."; + chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(startMessage), ChatWindow::DefaultDirection); + chatWindow_->onUserTyping.connect(boost::bind(&ChatStateNotifier::setUserIsTyping, chatStateNotifier_)); + chatWindow_->onUserCancelsTyping.connect(boost::bind(&ChatStateNotifier::userCancelledNewMessage, chatStateNotifier_)); + chatWindow_->onFileTransferStart.connect(boost::bind(&ChatController::handleFileTransferStart, this, _1, _2)); + chatWindow_->onFileTransferAccept.connect(boost::bind(&ChatController::handleFileTransferAccept, this, _1, _2)); + chatWindow_->onFileTransferCancel.connect(boost::bind(&ChatController::handleFileTransferCancel, this, _1)); + chatWindow_->onSendFileRequest.connect(boost::bind(&ChatController::handleSendFileRequest, this, _1)); + chatWindow_->onWhiteboardSessionAccept.connect(boost::bind(&ChatController::handleWhiteboardSessionAccept, this)); + chatWindow_->onWhiteboardSessionCancel.connect(boost::bind(&ChatController::handleWhiteboardSessionCancel, this)); + chatWindow_->onWhiteboardWindowShow.connect(boost::bind(&ChatController::handleWhiteboardWindowShow, this)); + chatWindow_->onBlockUserRequest.connect(boost::bind(&ChatController::handleBlockUserRequest, this)); + chatWindow_->onUnblockUserRequest.connect(boost::bind(&ChatController::handleUnblockUserRequest, this)); + chatWindow_->onInviteToChat.connect(boost::bind(&ChatController::handleInviteToChat, this, _1)); + chatWindow_->onClosed.connect(boost::bind(&ChatController::handleWindowClosed, this)); + ChatController::handleBareJIDCapsChanged(toJID_); + + settings_->onSettingChanged.connect(boost::bind(&ChatController::handleSettingChanged, this, _1)); + eventStream_->onUIEvent.connect(boost::bind(&ChatController::handleUIEvent, this, _1)); } void ChatController::handleContactNickChanged(const JID& jid, const std::string& /*oldNick*/) { - if (jid.toBare() == toJID_.toBare()) { - chatWindow_->setName(nickResolver_->jidToNick(toJID_)); - } + if (jid.toBare() == toJID_.toBare()) { + chatWindow_->setName(nickResolver_->jidToNick(toJID_)); + } } ChatController::~ChatController() { - eventStream_->onUIEvent.disconnect(boost::bind(&ChatController::handleUIEvent, this, _1)); - settings_->onSettingChanged.disconnect(boost::bind(&ChatController::handleSettingChanged, this, _1)); - nickResolver_->onNickChanged.disconnect(boost::bind(&ChatController::handleContactNickChanged, this, _1, _2)); - delete chatStateNotifier_; - delete chatStateTracker_; + eventStream_->onUIEvent.disconnect(boost::bind(&ChatController::handleUIEvent, this, _1)); + settings_->onSettingChanged.disconnect(boost::bind(&ChatController::handleSettingChanged, this, _1)); + nickResolver_->onNickChanged.disconnect(boost::bind(&ChatController::handleContactNickChanged, this, _1, _2)); + delete chatStateNotifier_; + delete chatStateTracker_; } JID ChatController::getBaseJID() { - return isInMUC_ ? toJID_ : ChatControllerBase::getBaseJID(); + return isInMUC_ ? toJID_ : ChatControllerBase::getBaseJID(); } void ChatController::cancelReplaces() { - lastWasPresence_ = false; + lastWasPresence_ = false; } void ChatController::handleBareJIDCapsChanged(const JID& /*jid*/) { - FeatureOracle featureOracle(entityCapsProvider_, presenceOracle_); + FeatureOracle featureOracle(entityCapsProvider_, presenceOracle_); - chatWindow_->setCorrectionEnabled(featureOracle.isMessageCorrectionSupported(toJID_)); - chatWindow_->setFileTransferEnabled(isInMUC_ ? No : featureOracle.isFileTransferSupported(toJID_)); - contactSupportsReceipts_ = featureOracle.isMessageReceiptsSupported(toJID_); + chatWindow_->setCorrectionEnabled(featureOracle.isMessageCorrectionSupported(toJID_)); + chatWindow_->setFileTransferEnabled(isInMUC_ ? No : featureOracle.isFileTransferSupported(toJID_)); + contactSupportsReceipts_ = featureOracle.isMessageReceiptsSupported(toJID_); - checkForDisplayingDisplayReceiptsAlert(); + checkForDisplayingDisplayReceiptsAlert(); } void ChatController::setToJID(const JID& jid) { - chatStateNotifier_->setContact(jid); - ChatControllerBase::setToJID(jid); - Presence::ref presence; - if (isInMUC_) { - presence = presenceOracle_->getLastPresence(jid); - } else { - presence = jid.isBare() ? presenceOracle_->getAccountPresence(jid.toBare()) : presenceOracle_->getLastPresence(jid); - } - chatStateNotifier_->setContactIsOnline(presence && presence->getType() == Presence::Available); - handleBareJIDCapsChanged(toJID_); + chatStateNotifier_->setContact(jid); + ChatControllerBase::setToJID(jid); + Presence::ref presence; + if (isInMUC_) { + presence = presenceOracle_->getLastPresence(jid); + } else { + presence = jid.isBare() ? presenceOracle_->getAccountPresence(jid.toBare()) : presenceOracle_->getLastPresence(jid); + } + chatStateNotifier_->setContactIsOnline(presence && presence->getType() == Presence::Available); + handleBareJIDCapsChanged(toJID_); } void ChatController::setAvailableServerFeatures(boost::shared_ptr<DiscoInfo> info) { - ChatControllerBase::setAvailableServerFeatures(info); - if (iqRouter_->isAvailable() && info->hasFeature(DiscoInfo::BlockingCommandFeature)) { - boost::shared_ptr<BlockList> blockList = clientBlockListManager_->getBlockList(); + ChatControllerBase::setAvailableServerFeatures(info); + if (iqRouter_->isAvailable() && info->hasFeature(DiscoInfo::BlockingCommandFeature)) { + boost::shared_ptr<BlockList> blockList = clientBlockListManager_->getBlockList(); - blockingOnStateChangedConnection_ = blockList->onStateChanged.connect(boost::bind(&ChatController::handleBlockingStateChanged, this)); - blockingOnItemAddedConnection_ = blockList->onItemAdded.connect(boost::bind(&ChatController::handleBlockingStateChanged, this)); - blockingOnItemRemovedConnection_ = blockList->onItemRemoved.connect(boost::bind(&ChatController::handleBlockingStateChanged, this)); + blockingOnStateChangedConnection_ = blockList->onStateChanged.connect(boost::bind(&ChatController::handleBlockingStateChanged, this)); + blockingOnItemAddedConnection_ = blockList->onItemAdded.connect(boost::bind(&ChatController::handleBlockingStateChanged, this)); + blockingOnItemRemovedConnection_ = blockList->onItemRemoved.connect(boost::bind(&ChatController::handleBlockingStateChanged, this)); - handleBlockingStateChanged(); - } + handleBlockingStateChanged(); + } } bool ChatController::isIncomingMessageFromMe(boost::shared_ptr<Message>) { - return false; + return false; } void ChatController::preHandleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent) { - if (messageEvent->isReadable()) { - chatWindow_->flash(); - lastWasPresence_ = false; - } - boost::shared_ptr<Message> message = messageEvent->getStanza(); - JID from = message->getFrom(); - if (!from.equals(toJID_, JID::WithResource)) { - if (toJID_.equals(from, JID::WithoutResource) && toJID_.isBare()){ - // Bind controller to a full JID if message contains body text or is a typing chat state. - ChatState::ref chatState = message->getPayload<ChatState>(); - if (!message->getBody().get_value_or("").empty() || (chatState && chatState->getChatState() == ChatState::Composing)) { - setToJID(from); - } - } - } - chatStateTracker_->handleMessageReceived(message); - chatStateNotifier_->receivedMessageFromContact(!!message->getPayload<ChatState>()); - - // handle XEP-0184 Message Receipts - // incomming receipts - if (boost::shared_ptr<DeliveryReceipt> receipt = message->getPayload<DeliveryReceipt>()) { - SWIFT_LOG(debug) << "received receipt for id: " << receipt->getReceivedID() << std::endl; - if (requestedReceipts_.find(receipt->getReceivedID()) != requestedReceipts_.end()) { - chatWindow_->setMessageReceiptState(requestedReceipts_[receipt->getReceivedID()], ChatWindow::ReceiptReceived); - requestedReceipts_.erase(receipt->getReceivedID()); - } - // incomming errors in response to send out receipts - } else if (message->getPayload<DeliveryReceiptRequest>() && (message->getType() == Message::Error)) { - if (requestedReceipts_.find(message->getID()) != requestedReceipts_.end()) { - chatWindow_->setMessageReceiptState(requestedReceipts_[message->getID()], ChatWindow::ReceiptFailed); - requestedReceipts_.erase(message->getID()); - } - // incoming receipt requests - } else if (message->getPayload<DeliveryReceiptRequest>()) { - if (receivingPresenceFromUs_) { - boost::shared_ptr<Message> receiptMessage = boost::make_shared<Message>(); - receiptMessage->setTo(toJID_); - receiptMessage->addPayload(boost::make_shared<DeliveryReceipt>(message->getID())); - stanzaChannel_->sendMessage(receiptMessage); - } - } + if (messageEvent->isReadable()) { + chatWindow_->flash(); + lastWasPresence_ = false; + } + boost::shared_ptr<Message> message = messageEvent->getStanza(); + JID from = message->getFrom(); + if (!from.equals(toJID_, JID::WithResource)) { + if (toJID_.equals(from, JID::WithoutResource) && toJID_.isBare()){ + // Bind controller to a full JID if message contains body text or is a typing chat state. + ChatState::ref chatState = message->getPayload<ChatState>(); + if (!message->getBody().get_value_or("").empty() || (chatState && chatState->getChatState() == ChatState::Composing)) { + setToJID(from); + } + } + } + chatStateTracker_->handleMessageReceived(message); + chatStateNotifier_->receivedMessageFromContact(!!message->getPayload<ChatState>()); + + // handle XEP-0184 Message Receipts + // incomming receipts + if (boost::shared_ptr<DeliveryReceipt> receipt = message->getPayload<DeliveryReceipt>()) { + SWIFT_LOG(debug) << "received receipt for id: " << receipt->getReceivedID() << std::endl; + if (requestedReceipts_.find(receipt->getReceivedID()) != requestedReceipts_.end()) { + chatWindow_->setMessageReceiptState(requestedReceipts_[receipt->getReceivedID()], ChatWindow::ReceiptReceived); + requestedReceipts_.erase(receipt->getReceivedID()); + } + // incomming errors in response to send out receipts + } else if (message->getPayload<DeliveryReceiptRequest>() && (message->getType() == Message::Error)) { + if (requestedReceipts_.find(message->getID()) != requestedReceipts_.end()) { + chatWindow_->setMessageReceiptState(requestedReceipts_[message->getID()], ChatWindow::ReceiptFailed); + requestedReceipts_.erase(message->getID()); + } + // incoming receipt requests + } else if (message->getPayload<DeliveryReceiptRequest>()) { + if (receivingPresenceFromUs_) { + boost::shared_ptr<Message> receiptMessage = boost::make_shared<Message>(); + receiptMessage->setTo(toJID_); + receiptMessage->addPayload(boost::make_shared<DeliveryReceipt>(message->getID())); + stanzaChannel_->sendMessage(receiptMessage); + } + } } void ChatController::postHandleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent, const ChatWindow::ChatMessage& chatMessage) { - eventController_->handleIncomingEvent(messageEvent); - if (!messageEvent->getConcluded()) { - handleHighlightActions(chatMessage); - } + eventController_->handleIncomingEvent(messageEvent); + if (!messageEvent->getConcluded()) { + handleHighlightActions(chatMessage); + } } void ChatController::preSendMessageRequest(boost::shared_ptr<Message> message) { - chatStateNotifier_->addChatStateRequest(message); - if (userWantsReceipts_ && (contactSupportsReceipts_ != No) && message) { - message->addPayload(boost::make_shared<DeliveryReceiptRequest>()); - } + chatStateNotifier_->addChatStateRequest(message); + if (userWantsReceipts_ && (contactSupportsReceipts_ != No) && message) { + message->addPayload(boost::make_shared<DeliveryReceiptRequest>()); + } } void ChatController::setContactIsReceivingPresence(bool isReceivingPresence) { - receivingPresenceFromUs_ = isReceivingPresence; + receivingPresenceFromUs_ = isReceivingPresence; } void ChatController::handleSettingChanged(const std::string& settingPath) { - if (settingPath == SettingConstants::REQUEST_DELIVERYRECEIPTS.getKey()) { - userWantsReceipts_ = settings_->getSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS); - checkForDisplayingDisplayReceiptsAlert(); - } + if (settingPath == SettingConstants::REQUEST_DELIVERYRECEIPTS.getKey()) { + userWantsReceipts_ = settings_->getSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS); + checkForDisplayingDisplayReceiptsAlert(); + } } void ChatController::checkForDisplayingDisplayReceiptsAlert() { - boost::optional<ChatWindow::AlertID> newDeliverReceiptAlert; - if (userWantsReceipts_ && (contactSupportsReceipts_ == No)) { - newDeliverReceiptAlert = chatWindow_->addAlert(QT_TRANSLATE_NOOP("", "This chat doesn't support delivery receipts.")); - } else if (userWantsReceipts_ && (contactSupportsReceipts_ == Maybe)) { - newDeliverReceiptAlert = chatWindow_->addAlert(QT_TRANSLATE_NOOP("", "This chat may not support delivery receipts. You might not receive delivery receipts for the messages you send.")); - } else { - if (deliveryReceiptAlert_) { - chatWindow_->removeAlert(*deliveryReceiptAlert_); - deliveryReceiptAlert_.reset(); - } - } - if (newDeliverReceiptAlert) { - if (deliveryReceiptAlert_) { - chatWindow_->removeAlert(*deliveryReceiptAlert_); - } - deliveryReceiptAlert_ = newDeliverReceiptAlert; - } + boost::optional<ChatWindow::AlertID> newDeliverReceiptAlert; + if (userWantsReceipts_ && (contactSupportsReceipts_ == No)) { + newDeliverReceiptAlert = chatWindow_->addAlert(QT_TRANSLATE_NOOP("", "This chat doesn't support delivery receipts.")); + } else if (userWantsReceipts_ && (contactSupportsReceipts_ == Maybe)) { + newDeliverReceiptAlert = chatWindow_->addAlert(QT_TRANSLATE_NOOP("", "This chat may not support delivery receipts. You might not receive delivery receipts for the messages you send.")); + } else { + if (deliveryReceiptAlert_) { + chatWindow_->removeAlert(*deliveryReceiptAlert_); + deliveryReceiptAlert_.reset(); + } + } + if (newDeliverReceiptAlert) { + if (deliveryReceiptAlert_) { + chatWindow_->removeAlert(*deliveryReceiptAlert_); + } + deliveryReceiptAlert_ = newDeliverReceiptAlert; + } } void ChatController::handleBlockingStateChanged() { - boost::shared_ptr<BlockList> blockList = clientBlockListManager_->getBlockList(); - if (blockList->getState() == BlockList::Available) { - if (isInMUC_ ? blockList->isBlocked(toJID_) : blockList->isBlocked(toJID_.toBare())) { - if (!blockedContactAlert_) { - blockedContactAlert_ = chatWindow_->addAlert(QT_TRANSLATE_NOOP("", "You've currently blocked this contact. To continue your conversation you have to unblock the contact first.")); - } - chatWindow_->setBlockingState(ChatWindow::IsBlocked); - - // disconnect typing events to prevent chat state notifciations to blocked contacts - chatWindow_->onUserTyping.disconnect(boost::bind(&ChatStateNotifier::setUserIsTyping, chatStateNotifier_)); - chatWindow_->onUserCancelsTyping.disconnect(boost::bind(&ChatStateNotifier::userCancelledNewMessage, chatStateNotifier_)); - } else { - if (blockedContactAlert_) { - chatWindow_->removeAlert(*blockedContactAlert_); - blockedContactAlert_.reset(); - } - chatWindow_->setBlockingState(ChatWindow::IsUnblocked); - - chatWindow_->onUserTyping.connect(boost::bind(&ChatStateNotifier::setUserIsTyping, chatStateNotifier_)); - chatWindow_->onUserCancelsTyping.connect(boost::bind(&ChatStateNotifier::userCancelledNewMessage, chatStateNotifier_)); - } - } + boost::shared_ptr<BlockList> blockList = clientBlockListManager_->getBlockList(); + if (blockList->getState() == BlockList::Available) { + if (isInMUC_ ? blockList->isBlocked(toJID_) : blockList->isBlocked(toJID_.toBare())) { + if (!blockedContactAlert_) { + blockedContactAlert_ = chatWindow_->addAlert(QT_TRANSLATE_NOOP("", "You've currently blocked this contact. To continue your conversation you have to unblock the contact first.")); + } + chatWindow_->setBlockingState(ChatWindow::IsBlocked); + + // disconnect typing events to prevent chat state notifciations to blocked contacts + chatWindow_->onUserTyping.disconnect(boost::bind(&ChatStateNotifier::setUserIsTyping, chatStateNotifier_)); + chatWindow_->onUserCancelsTyping.disconnect(boost::bind(&ChatStateNotifier::userCancelledNewMessage, chatStateNotifier_)); + } else { + if (blockedContactAlert_) { + chatWindow_->removeAlert(*blockedContactAlert_); + blockedContactAlert_.reset(); + } + chatWindow_->setBlockingState(ChatWindow::IsUnblocked); + + chatWindow_->onUserTyping.connect(boost::bind(&ChatStateNotifier::setUserIsTyping, chatStateNotifier_)); + chatWindow_->onUserCancelsTyping.connect(boost::bind(&ChatStateNotifier::userCancelledNewMessage, chatStateNotifier_)); + } + } } void ChatController::handleBlockUserRequest() { - if (isInMUC_) { - eventStream_->send(boost::make_shared<RequestChangeBlockStateUIEvent>(RequestChangeBlockStateUIEvent::Blocked, toJID_)); - } else { - eventStream_->send(boost::make_shared<RequestChangeBlockStateUIEvent>(RequestChangeBlockStateUIEvent::Blocked, toJID_.toBare())); - } + if (isInMUC_) { + eventStream_->send(boost::make_shared<RequestChangeBlockStateUIEvent>(RequestChangeBlockStateUIEvent::Blocked, toJID_)); + } else { + eventStream_->send(boost::make_shared<RequestChangeBlockStateUIEvent>(RequestChangeBlockStateUIEvent::Blocked, toJID_.toBare())); + } } void ChatController::handleUnblockUserRequest() { - if (isInMUC_) { - eventStream_->send(boost::make_shared<RequestChangeBlockStateUIEvent>(RequestChangeBlockStateUIEvent::Unblocked, toJID_)); - } else { - eventStream_->send(boost::make_shared<RequestChangeBlockStateUIEvent>(RequestChangeBlockStateUIEvent::Unblocked, toJID_.toBare())); - } + if (isInMUC_) { + eventStream_->send(boost::make_shared<RequestChangeBlockStateUIEvent>(RequestChangeBlockStateUIEvent::Unblocked, toJID_)); + } else { + eventStream_->send(boost::make_shared<RequestChangeBlockStateUIEvent>(RequestChangeBlockStateUIEvent::Unblocked, toJID_.toBare())); + } } void ChatController::handleInviteToChat(const std::vector<JID>& droppedJIDs) { - boost::shared_ptr<UIEvent> event(new RequestInviteToMUCUIEvent(toJID_.toBare(), droppedJIDs, RequestInviteToMUCUIEvent::Impromptu)); - eventStream_->send(event); + boost::shared_ptr<UIEvent> event(new RequestInviteToMUCUIEvent(toJID_.toBare(), droppedJIDs, RequestInviteToMUCUIEvent::Impromptu)); + eventStream_->send(event); } void ChatController::handleWindowClosed() { - onWindowClosed(); + onWindowClosed(); } void ChatController::handleUIEvent(boost::shared_ptr<UIEvent> event) { - boost::shared_ptr<InviteToMUCUIEvent> inviteEvent = boost::dynamic_pointer_cast<InviteToMUCUIEvent>(event); - if (inviteEvent && inviteEvent->getRoom() == toJID_.toBare()) { - onConvertToMUC(detachChatWindow(), inviteEvent->getInvites(), inviteEvent->getReason()); - } + boost::shared_ptr<InviteToMUCUIEvent> inviteEvent = boost::dynamic_pointer_cast<InviteToMUCUIEvent>(event); + if (inviteEvent && inviteEvent->getRoom() == toJID_.toBare()) { + onConvertToMUC(detachChatWindow(), inviteEvent->getInvites(), inviteEvent->getReason()); + } } void ChatController::postSendMessage(const std::string& body, boost::shared_ptr<Stanza> sentStanza) { - boost::shared_ptr<Replace> replace = sentStanza->getPayload<Replace>(); - if (replace) { - eraseIf(unackedStanzas_, PairSecondEquals<boost::shared_ptr<Stanza>, std::string>(myLastMessageUIID_)); - replaceMessage(chatMessageParser_->parseMessageBody(body, "", true), myLastMessageUIID_, boost::posix_time::microsec_clock::universal_time()); - } else { - myLastMessageUIID_ = addMessage(chatMessageParser_->parseMessageBody(body, "", true), QT_TRANSLATE_NOOP("", "me"), true, labelsEnabled_ ? chatWindow_->getSelectedSecurityLabel().getLabel() : boost::shared_ptr<SecurityLabel>(), avatarManager_->getAvatarPath(selfJID_), boost::posix_time::microsec_clock::universal_time()); - } + boost::shared_ptr<Replace> replace = sentStanza->getPayload<Replace>(); + if (replace) { + eraseIf(unackedStanzas_, PairSecondEquals<boost::shared_ptr<Stanza>, std::string>(myLastMessageUIID_)); + replaceMessage(chatMessageParser_->parseMessageBody(body, "", true), myLastMessageUIID_, boost::posix_time::microsec_clock::universal_time()); + } else { + myLastMessageUIID_ = addMessage(chatMessageParser_->parseMessageBody(body, "", true), QT_TRANSLATE_NOOP("", "me"), true, labelsEnabled_ ? chatWindow_->getSelectedSecurityLabel().getLabel() : boost::shared_ptr<SecurityLabel>(), avatarManager_->getAvatarPath(selfJID_), boost::posix_time::microsec_clock::universal_time()); + } - if (stanzaChannel_->getStreamManagementEnabled() && !myLastMessageUIID_.empty() ) { - chatWindow_->setAckState(myLastMessageUIID_, ChatWindow::Pending); - unackedStanzas_[sentStanza] = myLastMessageUIID_; - } + if (stanzaChannel_->getStreamManagementEnabled() && !myLastMessageUIID_.empty() ) { + chatWindow_->setAckState(myLastMessageUIID_, ChatWindow::Pending); + unackedStanzas_[sentStanza] = myLastMessageUIID_; + } - if (sentStanza->getPayload<DeliveryReceiptRequest>()) { - requestedReceipts_[sentStanza->getID()] = myLastMessageUIID_; - chatWindow_->setMessageReceiptState(myLastMessageUIID_, ChatWindow::ReceiptRequested); - } + if (sentStanza->getPayload<DeliveryReceiptRequest>()) { + requestedReceipts_[sentStanza->getID()] = myLastMessageUIID_; + chatWindow_->setMessageReceiptState(myLastMessageUIID_, ChatWindow::ReceiptRequested); + } - lastWasPresence_ = false; - chatStateNotifier_->userSentMessage(); + lastWasPresence_ = false; + chatStateNotifier_->userSentMessage(); } void ChatController::handleStanzaAcked(boost::shared_ptr<Stanza> stanza) { - std::map<boost::shared_ptr<Stanza>, std::string>::iterator unackedStanza = unackedStanzas_.find(stanza); - if (unackedStanza != unackedStanzas_.end()) { - chatWindow_->setAckState(unackedStanza->second, ChatWindow::Received); - unackedStanzas_.erase(unackedStanza); - } + std::map<boost::shared_ptr<Stanza>, std::string>::iterator unackedStanza = unackedStanzas_.find(stanza); + if (unackedStanza != unackedStanzas_.end()) { + chatWindow_->setAckState(unackedStanza->second, ChatWindow::Received); + unackedStanzas_.erase(unackedStanza); + } } void ChatController::setOnline(bool online) { - if (!online) { - std::map<boost::shared_ptr<Stanza>, std::string>::iterator it = unackedStanzas_.begin(); - for ( ; it != unackedStanzas_.end(); ++it) { - chatWindow_->setAckState(it->second, ChatWindow::Failed); - } - unackedStanzas_.clear(); + if (!online) { + std::map<boost::shared_ptr<Stanza>, std::string>::iterator it = unackedStanzas_.begin(); + for ( ; it != unackedStanzas_.end(); ++it) { + chatWindow_->setAckState(it->second, ChatWindow::Failed); + } + unackedStanzas_.clear(); - Presence::ref fakeOffline(new Presence()); - fakeOffline->setFrom(toJID_); - fakeOffline->setType(Presence::Unavailable); - chatStateTracker_->handlePresenceChange(fakeOffline); - } - ChatControllerBase::setOnline(online); + Presence::ref fakeOffline(new Presence()); + fakeOffline->setFrom(toJID_); + fakeOffline->setType(Presence::Unavailable); + chatStateTracker_->handlePresenceChange(fakeOffline); + } + ChatControllerBase::setOnline(online); } void ChatController::handleNewFileTransferController(FileTransferController* ftc) { - std::string nick = senderDisplayNameFromMessage(ftc->getOtherParty()); - std::string ftID = ftc->setChatWindow(chatWindow_, nick); - ftControllers[ftID] = ftc; - lastWasPresence_ = false; + std::string nick = senderDisplayNameFromMessage(ftc->getOtherParty()); + std::string ftID = ftc->setChatWindow(chatWindow_, nick); + ftControllers[ftID] = ftc; + lastWasPresence_ = false; } void ChatController::handleWhiteboardSessionRequest(bool senderIsSelf) { - lastWbID_ = chatWindow_->addWhiteboardRequest(senderIsSelf); + lastWbID_ = chatWindow_->addWhiteboardRequest(senderIsSelf); } void ChatController::handleWhiteboardStateChange(const ChatWindow::WhiteboardSessionState state) { - chatWindow_->setWhiteboardSessionStatus(lastWbID_, state); + chatWindow_->setWhiteboardSessionStatus(lastWbID_, state); } void ChatController::handleFileTransferCancel(std::string id) { - SWIFT_LOG(debug) << "handleFileTransferCancel(" << id << ")" << std::endl; - if (ftControllers.find(id) != ftControllers.end()) { - ftControllers[id]->cancel(); - } else { - std::cerr << "unknown file transfer UI id" << std::endl; - } + SWIFT_LOG(debug) << "handleFileTransferCancel(" << id << ")" << std::endl; + if (ftControllers.find(id) != ftControllers.end()) { + ftControllers[id]->cancel(); + } else { + std::cerr << "unknown file transfer UI id" << std::endl; + } } void ChatController::handleFileTransferStart(std::string id, std::string description) { - SWIFT_LOG(debug) << "handleFileTransferStart(" << id << ", " << description << ")" << std::endl; - if (ftControllers.find(id) != ftControllers.end()) { - ftControllers[id]->start(description); - } else { - std::cerr << "unknown file transfer UI id" << std::endl; - } + SWIFT_LOG(debug) << "handleFileTransferStart(" << id << ", " << description << ")" << std::endl; + if (ftControllers.find(id) != ftControllers.end()) { + ftControllers[id]->start(description); + } else { + std::cerr << "unknown file transfer UI id" << std::endl; + } } void ChatController::handleFileTransferAccept(std::string id, std::string filename) { - SWIFT_LOG(debug) << "handleFileTransferAccept(" << id << ", " << filename << ")" << std::endl; - if (ftControllers.find(id) != ftControllers.end()) { - ftControllers[id]->accept(filename); - } else { - std::cerr << "unknown file transfer UI id" << std::endl; - } + SWIFT_LOG(debug) << "handleFileTransferAccept(" << id << ", " << filename << ")" << std::endl; + if (ftControllers.find(id) != ftControllers.end()) { + ftControllers[id]->accept(filename); + } else { + std::cerr << "unknown file transfer UI id" << std::endl; + } } void ChatController::handleSendFileRequest(std::string filename) { - SWIFT_LOG(debug) << "ChatController::handleSendFileRequest(" << filename << ")" << std::endl; - eventStream_->send(boost::make_shared<SendFileUIEvent>(getToJID(), filename)); + SWIFT_LOG(debug) << "ChatController::handleSendFileRequest(" << filename << ")" << std::endl; + eventStream_->send(boost::make_shared<SendFileUIEvent>(getToJID(), filename)); } void ChatController::handleWhiteboardSessionAccept() { - eventStream_->send(boost::make_shared<AcceptWhiteboardSessionUIEvent>(toJID_)); + eventStream_->send(boost::make_shared<AcceptWhiteboardSessionUIEvent>(toJID_)); } void ChatController::handleWhiteboardSessionCancel() { - eventStream_->send(boost::make_shared<CancelWhiteboardSessionUIEvent>(toJID_)); + eventStream_->send(boost::make_shared<CancelWhiteboardSessionUIEvent>(toJID_)); } void ChatController::handleWhiteboardWindowShow() { - eventStream_->send(boost::make_shared<ShowWhiteboardUIEvent>(toJID_)); + eventStream_->send(boost::make_shared<ShowWhiteboardUIEvent>(toJID_)); } std::string ChatController::senderHighlightNameFromMessage(const JID& from) { - if (isInMUC_) { - return nickResolver_->jidToNick(from); - } - else { - return from.toBare().toString(); - } + if (isInMUC_) { + return nickResolver_->jidToNick(from); + } + else { + return from.toBare().toString(); + } } std::string ChatController::senderDisplayNameFromMessage(const JID& from) { - return nickResolver_->jidToNick(from); + return nickResolver_->jidToNick(from); } std::string ChatController::getStatusChangeString(boost::shared_ptr<Presence> presence) { - std::string nick = senderDisplayNameFromMessage(presence->getFrom()); - std::string response; - if (!presence || presence->getType() == Presence::Unavailable || presence->getType() == Presence::Error) { - response = QT_TRANSLATE_NOOP("", "%1% has gone offline"); - } else if (presence->getType() == Presence::Available) { - StatusShow::Type show = presence->getShow(); - if (show == StatusShow::Online || show == StatusShow::FFC) { - response = QT_TRANSLATE_NOOP("", "%1% has become available"); - } else if (show == StatusShow::Away || show == StatusShow::XA) { - response = QT_TRANSLATE_NOOP("", "%1% has gone away"); - } else if (show == StatusShow::DND) { - response = QT_TRANSLATE_NOOP("", "%1% is now busy"); - } - } - Idle::ref idle; - if ((idle = presence->getPayload<Idle>())) { - response += str(format(QT_TRANSLATE_NOOP("", " and has been idle since %1%")) % dateTimeToLocalString(idle->getSince())); - } - - if (!response.empty()) { - response = str(format(response) % nick); - } - - if (!presence->getStatus().empty()) { - response += " (" + presence->getStatus() + ")"; - } - return response + "."; + std::string nick = senderDisplayNameFromMessage(presence->getFrom()); + std::string response; + if (!presence || presence->getType() == Presence::Unavailable || presence->getType() == Presence::Error) { + response = QT_TRANSLATE_NOOP("", "%1% has gone offline"); + } else if (presence->getType() == Presence::Available) { + StatusShow::Type show = presence->getShow(); + if (show == StatusShow::Online || show == StatusShow::FFC) { + response = QT_TRANSLATE_NOOP("", "%1% has become available"); + } else if (show == StatusShow::Away || show == StatusShow::XA) { + response = QT_TRANSLATE_NOOP("", "%1% has gone away"); + } else if (show == StatusShow::DND) { + response = QT_TRANSLATE_NOOP("", "%1% is now busy"); + } + } + Idle::ref idle; + if ((idle = presence->getPayload<Idle>())) { + response += str(format(QT_TRANSLATE_NOOP("", " and has been idle since %1%")) % dateTimeToLocalString(idle->getSince())); + } + + if (!response.empty()) { + response = str(format(response) % nick); + } + + if (!presence->getStatus().empty()) { + response += " (" + presence->getStatus() + ")"; + } + return response + "."; } void ChatController::handlePresenceChange(boost::shared_ptr<Presence> newPresence) { - bool relevantPresence = false; - - if (isInMUC_) { - // For MUC participants we only have a single presence to choose one and - // even for multi-session nicknames multiple resources are not distinguishable - // to other participants. - if (toJID_.equals(newPresence->getFrom(), JID::WithResource)) { - relevantPresence = true; - } - } - else { - // For standard chats we retrieve the account presence from the PresenceOracle, - // as there can be multiple presences to choose from. - if (toJID_.equals(newPresence->getFrom(), JID::WithoutResource)) { - // Presence matches ChatController JID. - newPresence = presenceOracle_->getAccountPresence(toJID_); - relevantPresence = true; - } - } - - if (!relevantPresence) { - return; - } - - if (!newPresence) { - newPresence = boost::make_shared<Presence>(); - newPresence->setType(Presence::Unavailable); - } - lastShownStatus_ = newPresence->getShow(); - - chatStateTracker_->handlePresenceChange(newPresence); - chatStateNotifier_->setContactIsOnline(newPresence->getType() == Presence::Available); - std::string newStatusChangeString = getStatusChangeString(newPresence); - if (newStatusChangeString != lastStatusChangeString_) { - if (lastWasPresence_) { - chatWindow_->replaceLastMessage(chatMessageParser_->parseMessageBody(newStatusChangeString), ChatWindow::UpdateTimestamp); - } else { - chatWindow_->addPresenceMessage(chatMessageParser_->parseMessageBody(newStatusChangeString), ChatWindow::DefaultDirection); - } - lastStatusChangeString_ = newStatusChangeString; - lastWasPresence_ = true; - } + bool relevantPresence = false; + + if (isInMUC_) { + // For MUC participants we only have a single presence to choose one and + // even for multi-session nicknames multiple resources are not distinguishable + // to other participants. + if (toJID_.equals(newPresence->getFrom(), JID::WithResource)) { + relevantPresence = true; + } + } + else { + // For standard chats we retrieve the account presence from the PresenceOracle, + // as there can be multiple presences to choose from. + if (toJID_.equals(newPresence->getFrom(), JID::WithoutResource)) { + // Presence matches ChatController JID. + newPresence = presenceOracle_->getAccountPresence(toJID_); + relevantPresence = true; + } + } + + if (!relevantPresence) { + return; + } + + if (!newPresence) { + newPresence = boost::make_shared<Presence>(); + newPresence->setType(Presence::Unavailable); + } + lastShownStatus_ = newPresence->getShow(); + + chatStateTracker_->handlePresenceChange(newPresence); + chatStateNotifier_->setContactIsOnline(newPresence->getType() == Presence::Available); + std::string newStatusChangeString = getStatusChangeString(newPresence); + if (newStatusChangeString != lastStatusChangeString_) { + if (lastWasPresence_) { + chatWindow_->replaceLastMessage(chatMessageParser_->parseMessageBody(newStatusChangeString), ChatWindow::UpdateTimestamp); + } else { + chatWindow_->addPresenceMessage(chatMessageParser_->parseMessageBody(newStatusChangeString), ChatWindow::DefaultDirection); + } + lastStatusChangeString_ = newStatusChangeString; + lastWasPresence_ = true; + } } boost::optional<boost::posix_time::ptime> ChatController::getMessageTimestamp(boost::shared_ptr<Message> message) const { - return message->getTimestamp(); + return message->getTimestamp(); } void ChatController::logMessage(const std::string& message, const JID& fromJID, const JID& toJID, const boost::posix_time::ptime& timeStamp, bool /* isIncoming */) { - HistoryMessage::Type type; - if (mucRegistry_->isMUC(fromJID.toBare()) || mucRegistry_->isMUC(toJID.toBare())) { - type = HistoryMessage::PrivateMessage; - } - else { - type = HistoryMessage::Chat; - } + HistoryMessage::Type type; + if (mucRegistry_->isMUC(fromJID.toBare()) || mucRegistry_->isMUC(toJID.toBare())) { + type = HistoryMessage::PrivateMessage; + } + else { + type = HistoryMessage::Chat; + } - if (historyController_) { - historyController_->addMessage(message, fromJID, toJID, type, timeStamp); - } + if (historyController_) { + historyController_->addMessage(message, fromJID, toJID, type, timeStamp); + } } ChatWindow* ChatController::detachChatWindow() { - chatWindow_->onUserTyping.disconnect(boost::bind(&ChatStateNotifier::setUserIsTyping, chatStateNotifier_)); - chatWindow_->onUserCancelsTyping.disconnect(boost::bind(&ChatStateNotifier::userCancelledNewMessage, chatStateNotifier_)); - return ChatControllerBase::detachChatWindow(); + chatWindow_->onUserTyping.disconnect(boost::bind(&ChatStateNotifier::setUserIsTyping, chatStateNotifier_)); + chatWindow_->onUserCancelsTyping.disconnect(boost::bind(&ChatStateNotifier::userCancelledNewMessage, chatStateNotifier_)); + return ChatControllerBase::detachChatWindow(); } } diff --git a/Swift/Controllers/Chat/ChatController.h b/Swift/Controllers/Chat/ChatController.h index 6ec19df..aa2b203 100644 --- a/Swift/Controllers/Chat/ChatController.h +++ b/Swift/Controllers/Chat/ChatController.h @@ -16,101 +16,101 @@ #include <Swift/Controllers/UIInterfaces/ChatWindow.h> namespace Swift { - class AvatarManager; - class ChatStateNotifier; - class ChatStateTracker; - class NickResolver; - class EntityCapsProvider; - class FileTransferController; - class SettingsProvider; - class HistoryController; - class HighlightManager; - class ClientBlockListManager; - class UIEvent; - - 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, HighlightManager* highlightManager, ClientBlockListManager* clientBlockListManager, boost::shared_ptr<ChatMessageParser> chatMessageParser, AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider); - virtual ~ChatController(); - virtual void setToJID(const JID& jid) SWIFTEN_OVERRIDE; - virtual void setAvailableServerFeatures(boost::shared_ptr<DiscoInfo> info) SWIFTEN_OVERRIDE; - virtual void setOnline(bool online) SWIFTEN_OVERRIDE; - virtual void handleNewFileTransferController(FileTransferController* ftc); - virtual void handleWhiteboardSessionRequest(bool senderIsSelf); - virtual void handleWhiteboardStateChange(const ChatWindow::WhiteboardSessionState state); - virtual void setContactIsReceivingPresence(bool /*isReceivingPresence*/) SWIFTEN_OVERRIDE; - virtual ChatWindow* detachChatWindow() SWIFTEN_OVERRIDE; - - protected: - virtual void cancelReplaces() SWIFTEN_OVERRIDE; - virtual JID getBaseJID() SWIFTEN_OVERRIDE; - virtual void logMessage(const std::string& message, const JID& fromJID, const JID& toJID, const boost::posix_time::ptime& timeStamp, bool isIncoming) SWIFTEN_OVERRIDE; - - private: - void handlePresenceChange(boost::shared_ptr<Presence> newPresence); - std::string getStatusChangeString(boost::shared_ptr<Presence> presence); - virtual bool isIncomingMessageFromMe(boost::shared_ptr<Message> message) SWIFTEN_OVERRIDE; - virtual void postSendMessage(const std::string &body, boost::shared_ptr<Stanza> sentStanza) SWIFTEN_OVERRIDE; - virtual void preHandleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent) SWIFTEN_OVERRIDE; - virtual void postHandleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent, const ChatWindow::ChatMessage& chatMessage) SWIFTEN_OVERRIDE; - virtual void preSendMessageRequest(boost::shared_ptr<Message>) SWIFTEN_OVERRIDE; - virtual std::string senderHighlightNameFromMessage(const JID& from) SWIFTEN_OVERRIDE; - virtual std::string senderDisplayNameFromMessage(const JID& from) SWIFTEN_OVERRIDE; - virtual boost::optional<boost::posix_time::ptime> getMessageTimestamp(boost::shared_ptr<Message>) const SWIFTEN_OVERRIDE; - void handleStanzaAcked(boost::shared_ptr<Stanza> stanza); - virtual void dayTicked() SWIFTEN_OVERRIDE { lastWasPresence_ = false; } - void handleContactNickChanged(const JID& jid, const std::string& /*oldNick*/); - virtual void handleBareJIDCapsChanged(const JID& jid) SWIFTEN_OVERRIDE; - - void handleFileTransferCancel(std::string /* id */); - void handleFileTransferStart(std::string /* id */, std::string /* description */); - void handleFileTransferAccept(std::string /* id */, std::string /* filename */); - void handleSendFileRequest(std::string filename); - - void handleWhiteboardSessionAccept(); - void handleWhiteboardSessionCancel(); - void handleWhiteboardWindowShow(); - - void handleSettingChanged(const std::string& settingPath); - void checkForDisplayingDisplayReceiptsAlert(); - - void handleBlockingStateChanged(); - void handleBlockUserRequest(); - void handleUnblockUserRequest(); - - void handleInviteToChat(const std::vector<JID>& droppedJIDs); - - void handleWindowClosed(); - - void handleUIEvent(boost::shared_ptr<UIEvent> event); - - private: - NickResolver* nickResolver_; - ChatStateNotifier* chatStateNotifier_; - ChatStateTracker* chatStateTracker_; - std::string myLastMessageUIID_; - bool isInMUC_; - bool lastWasPresence_; - std::string lastStatusChangeString_; - std::map<boost::shared_ptr<Stanza>, std::string> unackedStanzas_; - std::map<std::string, std::string> requestedReceipts_; - StatusShow::Type lastShownStatus_; - UIEventStream* eventStream_; - - Tristate contactSupportsReceipts_; - bool receivingPresenceFromUs_; - bool userWantsReceipts_; - std::map<std::string, FileTransferController*> ftControllers; - SettingsProvider* settings_; - std::string lastWbID_; - - ClientBlockListManager* clientBlockListManager_; - boost::bsignals::scoped_connection blockingOnStateChangedConnection_; - boost::bsignals::scoped_connection blockingOnItemAddedConnection_; - boost::bsignals::scoped_connection blockingOnItemRemovedConnection_; - - boost::optional<ChatWindow::AlertID> deliveryReceiptAlert_; - boost::optional<ChatWindow::AlertID> blockedContactAlert_; - }; + class AvatarManager; + class ChatStateNotifier; + class ChatStateTracker; + class NickResolver; + class EntityCapsProvider; + class FileTransferController; + class SettingsProvider; + class HistoryController; + class HighlightManager; + class ClientBlockListManager; + class UIEvent; + + 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, HighlightManager* highlightManager, ClientBlockListManager* clientBlockListManager, boost::shared_ptr<ChatMessageParser> chatMessageParser, AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider); + virtual ~ChatController(); + virtual void setToJID(const JID& jid) SWIFTEN_OVERRIDE; + virtual void setAvailableServerFeatures(boost::shared_ptr<DiscoInfo> info) SWIFTEN_OVERRIDE; + virtual void setOnline(bool online) SWIFTEN_OVERRIDE; + virtual void handleNewFileTransferController(FileTransferController* ftc); + virtual void handleWhiteboardSessionRequest(bool senderIsSelf); + virtual void handleWhiteboardStateChange(const ChatWindow::WhiteboardSessionState state); + virtual void setContactIsReceivingPresence(bool /*isReceivingPresence*/) SWIFTEN_OVERRIDE; + virtual ChatWindow* detachChatWindow() SWIFTEN_OVERRIDE; + + protected: + virtual void cancelReplaces() SWIFTEN_OVERRIDE; + virtual JID getBaseJID() SWIFTEN_OVERRIDE; + virtual void logMessage(const std::string& message, const JID& fromJID, const JID& toJID, const boost::posix_time::ptime& timeStamp, bool isIncoming) SWIFTEN_OVERRIDE; + + private: + void handlePresenceChange(boost::shared_ptr<Presence> newPresence); + std::string getStatusChangeString(boost::shared_ptr<Presence> presence); + virtual bool isIncomingMessageFromMe(boost::shared_ptr<Message> message) SWIFTEN_OVERRIDE; + virtual void postSendMessage(const std::string &body, boost::shared_ptr<Stanza> sentStanza) SWIFTEN_OVERRIDE; + virtual void preHandleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent) SWIFTEN_OVERRIDE; + virtual void postHandleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent, const ChatWindow::ChatMessage& chatMessage) SWIFTEN_OVERRIDE; + virtual void preSendMessageRequest(boost::shared_ptr<Message>) SWIFTEN_OVERRIDE; + virtual std::string senderHighlightNameFromMessage(const JID& from) SWIFTEN_OVERRIDE; + virtual std::string senderDisplayNameFromMessage(const JID& from) SWIFTEN_OVERRIDE; + virtual boost::optional<boost::posix_time::ptime> getMessageTimestamp(boost::shared_ptr<Message>) const SWIFTEN_OVERRIDE; + void handleStanzaAcked(boost::shared_ptr<Stanza> stanza); + virtual void dayTicked() SWIFTEN_OVERRIDE { lastWasPresence_ = false; } + void handleContactNickChanged(const JID& jid, const std::string& /*oldNick*/); + virtual void handleBareJIDCapsChanged(const JID& jid) SWIFTEN_OVERRIDE; + + void handleFileTransferCancel(std::string /* id */); + void handleFileTransferStart(std::string /* id */, std::string /* description */); + void handleFileTransferAccept(std::string /* id */, std::string /* filename */); + void handleSendFileRequest(std::string filename); + + void handleWhiteboardSessionAccept(); + void handleWhiteboardSessionCancel(); + void handleWhiteboardWindowShow(); + + void handleSettingChanged(const std::string& settingPath); + void checkForDisplayingDisplayReceiptsAlert(); + + void handleBlockingStateChanged(); + void handleBlockUserRequest(); + void handleUnblockUserRequest(); + + void handleInviteToChat(const std::vector<JID>& droppedJIDs); + + void handleWindowClosed(); + + void handleUIEvent(boost::shared_ptr<UIEvent> event); + + private: + NickResolver* nickResolver_; + ChatStateNotifier* chatStateNotifier_; + ChatStateTracker* chatStateTracker_; + std::string myLastMessageUIID_; + bool isInMUC_; + bool lastWasPresence_; + std::string lastStatusChangeString_; + std::map<boost::shared_ptr<Stanza>, std::string> unackedStanzas_; + std::map<std::string, std::string> requestedReceipts_; + StatusShow::Type lastShownStatus_; + UIEventStream* eventStream_; + + Tristate contactSupportsReceipts_; + bool receivingPresenceFromUs_; + bool userWantsReceipts_; + std::map<std::string, FileTransferController*> ftControllers; + SettingsProvider* settings_; + std::string lastWbID_; + + ClientBlockListManager* clientBlockListManager_; + boost::bsignals::scoped_connection blockingOnStateChangedConnection_; + boost::bsignals::scoped_connection blockingOnItemAddedConnection_; + boost::bsignals::scoped_connection blockingOnItemRemovedConnection_; + + boost::optional<ChatWindow::AlertID> deliveryReceiptAlert_; + boost::optional<ChatWindow::AlertID> blockedContactAlert_; + }; } diff --git a/Swift/Controllers/Chat/ChatControllerBase.cpp b/Swift/Controllers/Chat/ChatControllerBase.cpp index c790cce..d478e2a 100644 --- a/Swift/Controllers/Chat/ChatControllerBase.cpp +++ b/Swift/Controllers/Chat/ChatControllerBase.cpp @@ -43,378 +43,378 @@ 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, HighlightManager* highlightManager, boost::shared_ptr<ChatMessageParser> chatMessageParser, AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider) : 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), chatMessageParser_(chatMessageParser), autoAcceptMUCInviteDecider_(autoAcceptMUCInviteDecider), eventStream_(eventStream) { - 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(); - ChatControllerBase::setOnline(stanzaChannel->isAvailable() && iqRouter->isAvailable()); - createDayChangeTimer(); + 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(); + ChatControllerBase::setOnline(stanzaChannel->isAvailable() && iqRouter->isAvailable()); + createDayChangeTimer(); } ChatControllerBase::~ChatControllerBase() { - if (dateChangeTimer_) { - dateChangeTimer_->onTick.disconnect(boost::bind(&ChatControllerBase::handleDayChangeTick, this)); - dateChangeTimer_->stop(); - } + if (dateChangeTimer_) { + dateChangeTimer_->onTick.disconnect(boost::bind(&ChatControllerBase::handleDayChangeTick, this)); + dateChangeTimer_->stop(); + } - delete highlighter_; - delete chatWindow_; + delete highlighter_; + delete chatWindow_; } void ChatControllerBase::handleLogCleared() { - cancelReplaces(); + cancelReplaces(); } ChatWindow* ChatControllerBase::detachChatWindow() { - ChatWindow* chatWindow = chatWindow_; - chatWindow_ = NULL; - return chatWindow; + ChatWindow* chatWindow = chatWindow_; + chatWindow_ = NULL; + return chatWindow; } void ChatControllerBase::handleCapsChanged(const JID& jid) { - if (jid.compare(toJID_, JID::WithoutResource) == 0) { - handleBareJIDCapsChanged(jid); - } + if (jid.compare(toJID_, JID::WithoutResource) == 0) { + handleBareJIDCapsChanged(jid); + } } void ChatControllerBase::setCanStartImpromptuChats(bool supportsImpromptu) { - if (chatWindow_) { - chatWindow_->setCanInitiateImpromptuChats(supportsImpromptu); - } + if (chatWindow_) { + chatWindow_->setCanInitiateImpromptuChats(supportsImpromptu); + } } void ChatControllerBase::createDayChangeTimer() { - if (timerFactory_) { - boost::posix_time::ptime now = boost::posix_time::second_clock::local_time(); - boost::posix_time::ptime midnight(now.date() + boost::gregorian::days(1)); - int millisecondsUntilMidnight = boost::numeric_cast<int>((midnight - now).total_milliseconds()); - dateChangeTimer_ = timerFactory_->createTimer(millisecondsUntilMidnight); - dateChangeTimer_->onTick.connect(boost::bind(&ChatControllerBase::handleDayChangeTick, this)); - dateChangeTimer_->start(); - } + if (timerFactory_) { + boost::posix_time::ptime now = boost::posix_time::second_clock::local_time(); + boost::posix_time::ptime midnight(now.date() + boost::gregorian::days(1)); + int millisecondsUntilMidnight = boost::numeric_cast<int>((midnight - now).total_milliseconds()); + dateChangeTimer_ = timerFactory_->createTimer(millisecondsUntilMidnight); + dateChangeTimer_->onTick.connect(boost::bind(&ChatControllerBase::handleDayChangeTick, this)); + dateChangeTimer_->start(); + } } void ChatControllerBase::handleDayChangeTick() { - dateChangeTimer_->stop(); - boost::posix_time::ptime now = boost::posix_time::second_clock::local_time(); - chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(str(format(QT_TRANSLATE_NOOP("", "The day is now %1%")) % std::string(boost::posix_time::to_iso_extended_string(now)).substr(0,10))), ChatWindow::DefaultDirection); - dayTicked(); - createDayChangeTimer(); + dateChangeTimer_->stop(); + boost::posix_time::ptime now = boost::posix_time::second_clock::local_time(); + chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(str(format(QT_TRANSLATE_NOOP("", "The day is now %1%")) % std::string(boost::posix_time::to_iso_extended_string(now)).substr(0,10))), ChatWindow::DefaultDirection); + dayTicked(); + createDayChangeTimer(); } void ChatControllerBase::setEnabled(bool enabled) { - chatWindow_->setOnline(enabled); - chatWindow_->setCanInitiateImpromptuChats(false); + chatWindow_->setOnline(enabled); + chatWindow_->setCanInitiateImpromptuChats(false); } void ChatControllerBase::setOnline(bool online) { - setEnabled(online); + setEnabled(online); } JID ChatControllerBase::getBaseJID() { - return JID(toJID_.toBare()); + return JID(toJID_.toBare()); } void ChatControllerBase::setAvailableServerFeatures(boost::shared_ptr<DiscoInfo> info) { - if (iqRouter_->isAvailable() && info->hasFeature(DiscoInfo::SecurityLabelsCatalogFeature)) { - GetSecurityLabelsCatalogRequest::ref request = GetSecurityLabelsCatalogRequest::create(getBaseJID(), iqRouter_); - request->onResponse.connect(boost::bind(&ChatControllerBase::handleSecurityLabelsCatalogResponse, this, _1, _2)); - request->send(); - } else { - chatWindow_->setSecurityLabelsEnabled(false); - labelsEnabled_ = false; - } + if (iqRouter_->isAvailable() && info->hasFeature(DiscoInfo::SecurityLabelsCatalogFeature)) { + GetSecurityLabelsCatalogRequest::ref request = GetSecurityLabelsCatalogRequest::create(getBaseJID(), iqRouter_); + request->onResponse.connect(boost::bind(&ChatControllerBase::handleSecurityLabelsCatalogResponse, this, _1, _2)); + request->send(); + } else { + chatWindow_->setSecurityLabelsEnabled(false); + labelsEnabled_ = false; + } } void ChatControllerBase::handleAllMessagesRead() { - if (!unreadMessages_.empty()) { - targetedUnreadMessages_.clear(); - foreach (boost::shared_ptr<StanzaEvent> stanzaEvent, unreadMessages_) { - stanzaEvent->conclude(); - } - unreadMessages_.clear(); - chatWindow_->setUnreadMessageCount(0); - onUnreadCountChanged(); - } + if (!unreadMessages_.empty()) { + targetedUnreadMessages_.clear(); + foreach (boost::shared_ptr<StanzaEvent> stanzaEvent, unreadMessages_) { + stanzaEvent->conclude(); + } + unreadMessages_.clear(); + chatWindow_->setUnreadMessageCount(0); + onUnreadCountChanged(); + } } int ChatControllerBase::getUnreadCount() { - return boost::numeric_cast<int>(targetedUnreadMessages_.size()); + return boost::numeric_cast<int>(targetedUnreadMessages_.size()); } void ChatControllerBase::handleSendMessageRequest(const std::string &body, bool isCorrectionMessage) { - if (!stanzaChannel_->isAvailable() || body.empty()) { - return; - } - boost::shared_ptr<Message> message(new Message()); - message->setTo(toJID_); - message->setType(Swift::Message::Chat); - message->setBody(body); - if (labelsEnabled_) { - if (!isCorrectionMessage) { - lastLabel_ = chatWindow_->getSelectedSecurityLabel(); - } - SecurityLabelsCatalog::Item labelItem = lastLabel_; - if (labelItem.getLabel()) { - message->addPayload(labelItem.getLabel()); - } - } - preSendMessageRequest(message); - - boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time(); - if (useDelayForLatency_) { - message->addPayload(boost::make_shared<Delay>(now, selfJID_)); - } - if (isCorrectionMessage) { - message->addPayload(boost::shared_ptr<Replace> (new Replace(lastSentMessageStanzaID_))); - } - message->setID(lastSentMessageStanzaID_ = idGenerator_.generateID()); - stanzaChannel_->sendMessage(message); - postSendMessage(message->getBody().get(), boost::dynamic_pointer_cast<Stanza>(message)); - onActivity(message->getBody().get()); + if (!stanzaChannel_->isAvailable() || body.empty()) { + return; + } + boost::shared_ptr<Message> message(new Message()); + message->setTo(toJID_); + message->setType(Swift::Message::Chat); + message->setBody(body); + if (labelsEnabled_) { + if (!isCorrectionMessage) { + lastLabel_ = chatWindow_->getSelectedSecurityLabel(); + } + SecurityLabelsCatalog::Item labelItem = lastLabel_; + if (labelItem.getLabel()) { + message->addPayload(labelItem.getLabel()); + } + } + preSendMessageRequest(message); + + boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time(); + if (useDelayForLatency_) { + message->addPayload(boost::make_shared<Delay>(now, selfJID_)); + } + if (isCorrectionMessage) { + message->addPayload(boost::shared_ptr<Replace> (new Replace(lastSentMessageStanzaID_))); + } + message->setID(lastSentMessageStanzaID_ = idGenerator_.generateID()); + stanzaChannel_->sendMessage(message); + postSendMessage(message->getBody().get(), boost::dynamic_pointer_cast<Stanza>(message)); + onActivity(message->getBody().get()); #ifdef SWIFT_EXPERIMENTAL_HISTORY - logMessage(body, selfJID_, toJID_, now, false); + logMessage(body, selfJID_, toJID_, now, false); #endif } void ChatControllerBase::handleSecurityLabelsCatalogResponse(boost::shared_ptr<SecurityLabelsCatalog> catalog, ErrorPayload::ref error) { - if (catalog && !error) { - if (catalog->getItems().size() == 0) { - chatWindow_->setSecurityLabelsEnabled(false); - labelsEnabled_ = false; - } else { - labelsEnabled_ = true; - chatWindow_->setAvailableSecurityLabels(catalog->getItems()); - chatWindow_->setSecurityLabelsEnabled(true); - } - } else { - labelsEnabled_ = false; - chatWindow_->setSecurityLabelsError(); - } + if (catalog && !error) { + if (catalog->getItems().size() == 0) { + chatWindow_->setSecurityLabelsEnabled(false); + labelsEnabled_ = false; + } else { + labelsEnabled_ = true; + chatWindow_->setAvailableSecurityLabels(catalog->getItems()); + chatWindow_->setSecurityLabelsEnabled(true); + } + } else { + labelsEnabled_ = false; + chatWindow_->setSecurityLabelsError(); + } } void ChatControllerBase::showChatWindow() { - chatWindow_->show(); + chatWindow_->show(); } void ChatControllerBase::activateChatWindow() { - chatWindow_->activate(); + chatWindow_->activate(); } bool ChatControllerBase::hasOpenWindow() const { - return chatWindow_ && chatWindow_->isVisible(); + return chatWindow_ && chatWindow_->isVisible(); } ChatWindow::ChatMessage ChatControllerBase::buildChatWindowChatMessage(const std::string& message, bool senderIsSelf, const HighlightAction& fullMessageHighlightAction) { - ChatWindow::ChatMessage chatMessage; - if (boost::starts_with(message, "/me ")) { - chatMessage = chatMessageParser_->parseMessageBody(String::getSplittedAtFirst(message, ' ').second); - } - else { - chatMessage = chatMessageParser_->parseMessageBody(message, highlighter_->getNick(), senderIsSelf); - } - chatMessage.setFullMessageHighlightAction(fullMessageHighlightAction); - return chatMessage; + ChatWindow::ChatMessage chatMessage; + if (boost::starts_with(message, "/me ")) { + chatMessage = chatMessageParser_->parseMessageBody(String::getSplittedAtFirst(message, ' ').second); + } + else { + chatMessage = chatMessageParser_->parseMessageBody(message, highlighter_->getNick(), senderIsSelf); + } + chatMessage.setFullMessageHighlightAction(fullMessageHighlightAction); + return chatMessage; } void ChatControllerBase::handleHighlightActions(const ChatWindow::ChatMessage& chatMessage) { - std::set<std::string> playedSounds; - if (chatMessage.getFullMessageHighlightAction().playSound()) { - highlighter_->handleHighlightAction(chatMessage.getFullMessageHighlightAction()); - playedSounds.insert(chatMessage.getFullMessageHighlightAction().getSoundFile()); - } - foreach(boost::shared_ptr<ChatWindow::ChatMessagePart> part, chatMessage.getParts()) { - boost::shared_ptr<ChatWindow::ChatHighlightingMessagePart> highlightMessage = boost::dynamic_pointer_cast<ChatWindow::ChatHighlightingMessagePart>(part); - if (highlightMessage && highlightMessage->action.playSound()) { - if (playedSounds.find(highlightMessage->action.getSoundFile()) == playedSounds.end()) { - highlighter_->handleHighlightAction(highlightMessage->action); - playedSounds.insert(highlightMessage->action.getSoundFile()); - } - } - } + std::set<std::string> playedSounds; + if (chatMessage.getFullMessageHighlightAction().playSound()) { + highlighter_->handleHighlightAction(chatMessage.getFullMessageHighlightAction()); + playedSounds.insert(chatMessage.getFullMessageHighlightAction().getSoundFile()); + } + foreach(boost::shared_ptr<ChatWindow::ChatMessagePart> part, chatMessage.getParts()) { + boost::shared_ptr<ChatWindow::ChatHighlightingMessagePart> highlightMessage = boost::dynamic_pointer_cast<ChatWindow::ChatHighlightingMessagePart>(part); + if (highlightMessage && highlightMessage->action.playSound()) { + if (playedSounds.find(highlightMessage->action.getSoundFile()) == playedSounds.end()) { + highlighter_->handleHighlightAction(highlightMessage->action); + playedSounds.insert(highlightMessage->action.getSoundFile()); + } + } + } } std::string ChatControllerBase::addMessage(const ChatWindow::ChatMessage& chatMessage, const std::string& senderName, bool senderIsSelf, const boost::shared_ptr<SecurityLabel> label, const boost::filesystem::path& avatarPath, const boost::posix_time::ptime& time) { - if (chatMessage.isMeCommand()) { - return chatWindow_->addAction(chatMessage, senderName, senderIsSelf, label, pathToString(avatarPath), time); - } - else { - return chatWindow_->addMessage(chatMessage, senderName, senderIsSelf, label, pathToString(avatarPath), time); - } + if (chatMessage.isMeCommand()) { + return chatWindow_->addAction(chatMessage, senderName, senderIsSelf, label, pathToString(avatarPath), time); + } + else { + return chatWindow_->addMessage(chatMessage, senderName, senderIsSelf, label, pathToString(avatarPath), time); + } } void ChatControllerBase::replaceMessage(const ChatWindow::ChatMessage& chatMessage, const std::string& id, const boost::posix_time::ptime& time) { - if (chatMessage.isMeCommand()) { - chatWindow_->replaceWithAction(chatMessage, id, time); - } - else { - chatWindow_->replaceMessage(chatMessage, id, time); - } + if (chatMessage.isMeCommand()) { + chatWindow_->replaceWithAction(chatMessage, id, time); + } + else { + chatWindow_->replaceMessage(chatMessage, id, time); + } } bool ChatControllerBase::isFromContact(const JID& from) { - return from.toBare() == toJID_.toBare(); + return from.toBare() == toJID_.toBare(); } void ChatControllerBase::handleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent) { - preHandleIncomingMessage(messageEvent); - if (messageEvent->isReadable() && !messageEvent->getConcluded()) { - unreadMessages_.push_back(messageEvent); - if (messageEvent->targetsMe()) { - targetedUnreadMessages_.push_back(messageEvent); - } - } - - boost::shared_ptr<Message> message = messageEvent->getStanza(); - ChatWindow::ChatMessage chatMessage; - boost::optional<std::string> optionalBody = message->getBody(); - std::string body = optionalBody.get_value_or(""); - if (message->isError()) { - if (!message->getTo().getResource().empty()) { - std::string errorMessage = str(format(QT_TRANSLATE_NOOP("", "Couldn't send message: %1%")) % getErrorMessage(message->getPayload<ErrorPayload>())); - chatWindow_->addErrorMessage(chatMessageParser_->parseMessageBody(errorMessage)); - } - } - else if (messageEvent->getStanza()->getPayload<MUCInvitationPayload>()) { - handleMUCInvitation(messageEvent->getStanza()); - return; - } - else if (messageEvent->getStanza()->getPayload<MUCUserPayload>() && messageEvent->getStanza()->getPayload<MUCUserPayload>()->getInvite()) { - handleMediatedMUCInvitation(messageEvent->getStanza()); - return; - } - else { - if (!messageEvent->isReadable()) { - return; - } - showChatWindow(); - JID from = message->getFrom(); - std::vector<boost::shared_ptr<Delay> > delayPayloads = message->getPayloads<Delay>(); - for (size_t i = 0; useDelayForLatency_ && i < delayPayloads.size(); i++) { - if (!delayPayloads[i]->getFrom()) { - continue; - } - boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time(); - std::ostringstream s; - s << "The following message took " << (now - delayPayloads[i]->getStamp()).total_milliseconds() / 1000.0 << " seconds to be delivered from " << delayPayloads[i]->getFrom()->toString() << "."; - chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(std::string(s.str())), ChatWindow::DefaultDirection); - } - boost::shared_ptr<SecurityLabel> label = message->getPayload<SecurityLabel>(); - - // Determine the timestamp - boost::posix_time::ptime timeStamp = boost::posix_time::microsec_clock::universal_time(); - boost::optional<boost::posix_time::ptime> messageTimeStamp = getMessageTimestamp(message); - if (messageTimeStamp) { - timeStamp = *messageTimeStamp; - } - onActivity(body); - - // Highlight - HighlightAction fullMessageHighlight; - if (!isIncomingMessageFromMe(message)) { - fullMessageHighlight = highlighter_->findFirstFullMessageMatchAction(body, senderHighlightNameFromMessage(from)); - } - - boost::shared_ptr<Replace> replace = message->getPayload<Replace>(); - bool senderIsSelf = isIncomingMessageFromMe(message); - if (replace) { - // Should check if the user has a previous message - std::map<JID, std::string>::iterator lastMessage; - lastMessage = lastMessagesUIID_.find(from); - if (lastMessage != lastMessagesUIID_.end()) { - chatMessage = buildChatWindowChatMessage(body, senderIsSelf, fullMessageHighlight); - replaceMessage(chatMessage, lastMessagesUIID_[from], timeStamp); - } - } - else { - chatMessage = buildChatWindowChatMessage(body, senderIsSelf, fullMessageHighlight); - addMessageHandleIncomingMessage(from, chatMessage, senderIsSelf, label, timeStamp); - } - - logMessage(body, from, selfJID_, timeStamp, true); - } - chatWindow_->show(); - chatWindow_->setUnreadMessageCount(boost::numeric_cast<int>(unreadMessages_.size())); - onUnreadCountChanged(); - postHandleIncomingMessage(messageEvent, chatMessage); + preHandleIncomingMessage(messageEvent); + if (messageEvent->isReadable() && !messageEvent->getConcluded()) { + unreadMessages_.push_back(messageEvent); + if (messageEvent->targetsMe()) { + targetedUnreadMessages_.push_back(messageEvent); + } + } + + boost::shared_ptr<Message> message = messageEvent->getStanza(); + ChatWindow::ChatMessage chatMessage; + boost::optional<std::string> optionalBody = message->getBody(); + std::string body = optionalBody.get_value_or(""); + if (message->isError()) { + if (!message->getTo().getResource().empty()) { + std::string errorMessage = str(format(QT_TRANSLATE_NOOP("", "Couldn't send message: %1%")) % getErrorMessage(message->getPayload<ErrorPayload>())); + chatWindow_->addErrorMessage(chatMessageParser_->parseMessageBody(errorMessage)); + } + } + else if (messageEvent->getStanza()->getPayload<MUCInvitationPayload>()) { + handleMUCInvitation(messageEvent->getStanza()); + return; + } + else if (messageEvent->getStanza()->getPayload<MUCUserPayload>() && messageEvent->getStanza()->getPayload<MUCUserPayload>()->getInvite()) { + handleMediatedMUCInvitation(messageEvent->getStanza()); + return; + } + else { + if (!messageEvent->isReadable()) { + return; + } + showChatWindow(); + JID from = message->getFrom(); + std::vector<boost::shared_ptr<Delay> > delayPayloads = message->getPayloads<Delay>(); + for (size_t i = 0; useDelayForLatency_ && i < delayPayloads.size(); i++) { + if (!delayPayloads[i]->getFrom()) { + continue; + } + boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time(); + std::ostringstream s; + s << "The following message took " << (now - delayPayloads[i]->getStamp()).total_milliseconds() / 1000.0 << " seconds to be delivered from " << delayPayloads[i]->getFrom()->toString() << "."; + chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(std::string(s.str())), ChatWindow::DefaultDirection); + } + boost::shared_ptr<SecurityLabel> label = message->getPayload<SecurityLabel>(); + + // Determine the timestamp + boost::posix_time::ptime timeStamp = boost::posix_time::microsec_clock::universal_time(); + boost::optional<boost::posix_time::ptime> messageTimeStamp = getMessageTimestamp(message); + if (messageTimeStamp) { + timeStamp = *messageTimeStamp; + } + onActivity(body); + + // Highlight + HighlightAction fullMessageHighlight; + if (!isIncomingMessageFromMe(message)) { + fullMessageHighlight = highlighter_->findFirstFullMessageMatchAction(body, senderHighlightNameFromMessage(from)); + } + + boost::shared_ptr<Replace> replace = message->getPayload<Replace>(); + bool senderIsSelf = isIncomingMessageFromMe(message); + if (replace) { + // Should check if the user has a previous message + std::map<JID, std::string>::iterator lastMessage; + lastMessage = lastMessagesUIID_.find(from); + if (lastMessage != lastMessagesUIID_.end()) { + chatMessage = buildChatWindowChatMessage(body, senderIsSelf, fullMessageHighlight); + replaceMessage(chatMessage, lastMessagesUIID_[from], timeStamp); + } + } + else { + chatMessage = buildChatWindowChatMessage(body, senderIsSelf, fullMessageHighlight); + addMessageHandleIncomingMessage(from, chatMessage, senderIsSelf, label, timeStamp); + } + + logMessage(body, from, selfJID_, timeStamp, true); + } + chatWindow_->show(); + chatWindow_->setUnreadMessageCount(boost::numeric_cast<int>(unreadMessages_.size())); + onUnreadCountChanged(); + postHandleIncomingMessage(messageEvent, chatMessage); } void ChatControllerBase::addMessageHandleIncomingMessage(const JID& from, const ChatWindow::ChatMessage& message, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const boost::posix_time::ptime& timeStamp) { - lastMessagesUIID_[from] = addMessage(message, senderDisplayNameFromMessage(from), senderIsSelf, label, avatarManager_->getAvatarPath(from), timeStamp); + lastMessagesUIID_[from] = addMessage(message, senderDisplayNameFromMessage(from), senderIsSelf, label, avatarManager_->getAvatarPath(from), timeStamp); } std::string ChatControllerBase::getErrorMessage(boost::shared_ptr<ErrorPayload> error) { - std::string defaultMessage = QT_TRANSLATE_NOOP("", "Error sending message"); - if (!error->getText().empty()) { - return error->getText(); - } - else { - switch (error->getCondition()) { - case ErrorPayload::BadRequest: return QT_TRANSLATE_NOOP("", "Bad request"); - case ErrorPayload::Conflict: return QT_TRANSLATE_NOOP("", "Conflict"); - case ErrorPayload::FeatureNotImplemented: return QT_TRANSLATE_NOOP("", "This feature is not implemented"); - case ErrorPayload::Forbidden: return QT_TRANSLATE_NOOP("", "Forbidden"); - case ErrorPayload::Gone: return QT_TRANSLATE_NOOP("", "Recipient can no longer be contacted"); - case ErrorPayload::InternalServerError: return QT_TRANSLATE_NOOP("", "Internal server error"); - case ErrorPayload::ItemNotFound: return QT_TRANSLATE_NOOP("", "Item not found"); - case ErrorPayload::JIDMalformed: return QT_TRANSLATE_NOOP("", "JID Malformed"); - case ErrorPayload::NotAcceptable: return QT_TRANSLATE_NOOP("", "Message was rejected"); - case ErrorPayload::NotAllowed: return QT_TRANSLATE_NOOP("", "Not allowed"); - case ErrorPayload::NotAuthorized: return QT_TRANSLATE_NOOP("", "Not authorized"); - case ErrorPayload::PaymentRequired: return QT_TRANSLATE_NOOP("", "Payment is required"); - case ErrorPayload::RecipientUnavailable: return QT_TRANSLATE_NOOP("", "Recipient is unavailable"); - case ErrorPayload::Redirect: return QT_TRANSLATE_NOOP("", "Redirect"); - case ErrorPayload::RegistrationRequired: return QT_TRANSLATE_NOOP("", "Registration required"); - case ErrorPayload::RemoteServerNotFound: return QT_TRANSLATE_NOOP("", "Recipient's server not found"); - case ErrorPayload::RemoteServerTimeout: return QT_TRANSLATE_NOOP("", "Remote server timeout"); - case ErrorPayload::ResourceConstraint: return QT_TRANSLATE_NOOP("", "The server is low on resources"); - case ErrorPayload::ServiceUnavailable: return QT_TRANSLATE_NOOP("", "The service is unavailable"); - case ErrorPayload::SubscriptionRequired: return QT_TRANSLATE_NOOP("", "A subscription is required"); - case ErrorPayload::UndefinedCondition: return QT_TRANSLATE_NOOP("", "Undefined condition"); - case ErrorPayload::UnexpectedRequest: return QT_TRANSLATE_NOOP("", "Unexpected request"); - } - } - assert(false); - return defaultMessage; + std::string defaultMessage = QT_TRANSLATE_NOOP("", "Error sending message"); + if (!error->getText().empty()) { + return error->getText(); + } + else { + switch (error->getCondition()) { + case ErrorPayload::BadRequest: return QT_TRANSLATE_NOOP("", "Bad request"); + case ErrorPayload::Conflict: return QT_TRANSLATE_NOOP("", "Conflict"); + case ErrorPayload::FeatureNotImplemented: return QT_TRANSLATE_NOOP("", "This feature is not implemented"); + case ErrorPayload::Forbidden: return QT_TRANSLATE_NOOP("", "Forbidden"); + case ErrorPayload::Gone: return QT_TRANSLATE_NOOP("", "Recipient can no longer be contacted"); + case ErrorPayload::InternalServerError: return QT_TRANSLATE_NOOP("", "Internal server error"); + case ErrorPayload::ItemNotFound: return QT_TRANSLATE_NOOP("", "Item not found"); + case ErrorPayload::JIDMalformed: return QT_TRANSLATE_NOOP("", "JID Malformed"); + case ErrorPayload::NotAcceptable: return QT_TRANSLATE_NOOP("", "Message was rejected"); + case ErrorPayload::NotAllowed: return QT_TRANSLATE_NOOP("", "Not allowed"); + case ErrorPayload::NotAuthorized: return QT_TRANSLATE_NOOP("", "Not authorized"); + case ErrorPayload::PaymentRequired: return QT_TRANSLATE_NOOP("", "Payment is required"); + case ErrorPayload::RecipientUnavailable: return QT_TRANSLATE_NOOP("", "Recipient is unavailable"); + case ErrorPayload::Redirect: return QT_TRANSLATE_NOOP("", "Redirect"); + case ErrorPayload::RegistrationRequired: return QT_TRANSLATE_NOOP("", "Registration required"); + case ErrorPayload::RemoteServerNotFound: return QT_TRANSLATE_NOOP("", "Recipient's server not found"); + case ErrorPayload::RemoteServerTimeout: return QT_TRANSLATE_NOOP("", "Remote server timeout"); + case ErrorPayload::ResourceConstraint: return QT_TRANSLATE_NOOP("", "The server is low on resources"); + case ErrorPayload::ServiceUnavailable: return QT_TRANSLATE_NOOP("", "The service is unavailable"); + case ErrorPayload::SubscriptionRequired: return QT_TRANSLATE_NOOP("", "A subscription is required"); + case ErrorPayload::UndefinedCondition: return QT_TRANSLATE_NOOP("", "Undefined condition"); + 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(boost::numeric_cast<int>(unreadMessages_.size())); - onUnreadCountChanged(); - chatWindow_->addMUCInvitation(senderDisplayNameFromMessage(event->getInviter()), event->getRoomJID(), event->getReason(), event->getPassword(), event->getDirect(), event->getImpromptu()); - eventController_->handleIncomingEvent(event); + unreadMessages_.push_back(event); + chatWindow_->show(); + chatWindow_->setUnreadMessageCount(boost::numeric_cast<int>(unreadMessages_.size())); + onUnreadCountChanged(); + chatWindow_->addMUCInvitation(senderDisplayNameFromMessage(event->getInviter()), event->getRoomJID(), event->getReason(), event->getPassword(), event->getDirect(), event->getImpromptu()); + eventController_->handleIncomingEvent(event); } void ChatControllerBase::handleMUCInvitation(Message::ref message) { - MUCInvitationPayload::ref invite = message->getPayload<MUCInvitationPayload>(); - - if (autoAcceptMUCInviteDecider_->isAutoAcceptedInvite(message->getFrom(), invite)) { - eventStream_->send(boost::make_shared<JoinMUCUIEvent>(invite->getJID(), boost::optional<std::string>(), boost::optional<std::string>(), false, false, true)); - } else { - MUCInviteEvent::ref inviteEvent = boost::make_shared<MUCInviteEvent>(toJID_, invite->getJID(), invite->getReason(), invite->getPassword(), true, invite->getIsImpromptu()); - handleGeneralMUCInvitation(inviteEvent); - } + MUCInvitationPayload::ref invite = message->getPayload<MUCInvitationPayload>(); + + if (autoAcceptMUCInviteDecider_->isAutoAcceptedInvite(message->getFrom(), invite)) { + eventStream_->send(boost::make_shared<JoinMUCUIEvent>(invite->getJID(), boost::optional<std::string>(), boost::optional<std::string>(), false, false, true)); + } else { + MUCInviteEvent::ref inviteEvent = boost::make_shared<MUCInviteEvent>(toJID_, invite->getJID(), invite->getReason(), invite->getPassword(), true, invite->getIsImpromptu()); + handleGeneralMUCInvitation(inviteEvent); + } } void ChatControllerBase::handleMediatedMUCInvitation(Message::ref message) { - MUCUserPayload::Invite invite = *message->getPayload<MUCUserPayload>()->getInvite(); - JID from = message->getFrom(); - std::string reason; - if (!invite.reason.empty()) { - reason = invite.reason; - } - std::string password; - if (message->getPayload<MUCUserPayload>()->getPassword()) { - password = *message->getPayload<MUCUserPayload>()->getPassword(); - } - - MUCInviteEvent::ref inviteEvent = boost::make_shared<MUCInviteEvent>(invite.from, from, reason, password, false, false); - handleGeneralMUCInvitation(inviteEvent); + MUCUserPayload::Invite invite = *message->getPayload<MUCUserPayload>()->getInvite(); + JID from = message->getFrom(); + std::string reason; + if (!invite.reason.empty()) { + reason = invite.reason; + } + std::string password; + if (message->getPayload<MUCUserPayload>()->getPassword()) { + password = *message->getPayload<MUCUserPayload>()->getPassword(); + } + + MUCInviteEvent::ref inviteEvent = boost::make_shared<MUCInviteEvent>(invite.from, from, reason, password, false, false); + handleGeneralMUCInvitation(inviteEvent); } } diff --git a/Swift/Controllers/Chat/ChatControllerBase.h b/Swift/Controllers/Chat/ChatControllerBase.h index 98f0ab0..bd8ba0f 100644 --- a/Swift/Controllers/Chat/ChatControllerBase.h +++ b/Swift/Controllers/Chat/ChatControllerBase.h @@ -35,107 +35,107 @@ #include <Swift/Controllers/XMPPEvents/MessageEvent.h> namespace Swift { - class IQRouter; - class StanzaChannel; - class ChatWindowFactory; - class AvatarManager; - class UIEventStream; - class EventController; - class EntityCapsProvider; - class HighlightManager; - class Highlighter; - class ChatMessageParser; - class AutoAcceptMUCInviteDecider; + class IQRouter; + class StanzaChannel; + class ChatWindowFactory; + class AvatarManager; + class UIEventStream; + class EventController; + class EntityCapsProvider; + class HighlightManager; + class Highlighter; + class ChatMessageParser; + class AutoAcceptMUCInviteDecider; - class ChatControllerBase : public boost::bsignals::trackable { - public: - virtual ~ChatControllerBase(); - void showChatWindow(); - void activateChatWindow(); - bool hasOpenWindow() const; - virtual void setAvailableServerFeatures(boost::shared_ptr<DiscoInfo> info); - void handleIncomingMessage(boost::shared_ptr<MessageEvent> message); - std::string addMessage(const ChatWindow::ChatMessage& chatMessage, const std::string& senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const boost::filesystem::path& avatarPath, const boost::posix_time::ptime& time); - void replaceMessage(const ChatWindow::ChatMessage& chatMessage, const std::string& id, const boost::posix_time::ptime& time); - virtual void setOnline(bool online); - void setEnabled(bool enabled); - 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; - boost::signal<void ()> onWindowClosed; - int getUnreadCount(); - const JID& getToJID() {return toJID_;} - void handleCapsChanged(const JID& jid); - void setCanStartImpromptuChats(bool supportsImpromptu); - virtual ChatWindow* detachChatWindow(); - boost::signal<void(ChatWindow* /*window to reuse*/, const std::vector<JID>& /*invite people*/, const std::string& /*reason*/)> onConvertToMUC; + class ChatControllerBase : public boost::bsignals::trackable { + public: + virtual ~ChatControllerBase(); + void showChatWindow(); + void activateChatWindow(); + bool hasOpenWindow() const; + virtual void setAvailableServerFeatures(boost::shared_ptr<DiscoInfo> info); + void handleIncomingMessage(boost::shared_ptr<MessageEvent> message); + std::string addMessage(const ChatWindow::ChatMessage& chatMessage, const std::string& senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const boost::filesystem::path& avatarPath, const boost::posix_time::ptime& time); + void replaceMessage(const ChatWindow::ChatMessage& chatMessage, const std::string& id, const boost::posix_time::ptime& time); + virtual void setOnline(bool online); + void setEnabled(bool enabled); + 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; + boost::signal<void ()> onWindowClosed; + int getUnreadCount(); + const JID& getToJID() {return toJID_;} + void handleCapsChanged(const JID& jid); + void setCanStartImpromptuChats(bool supportsImpromptu); + virtual ChatWindow* detachChatWindow(); + boost::signal<void(ChatWindow* /*window to reuse*/, const std::vector<JID>& /*invite people*/, const std::string& /*reason*/)> onConvertToMUC; - 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, HighlightManager* highlightManager, boost::shared_ptr<ChatMessageParser> chatMessageParser, AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider); + 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, HighlightManager* highlightManager, boost::shared_ptr<ChatMessageParser> chatMessageParser, AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider); - /** - * Pass the Message appended, and the stanza used to send it. - */ - virtual void postSendMessage(const std::string&, boost::shared_ptr<Stanza>) {} - virtual std::string senderDisplayNameFromMessage(const JID& from) = 0; - virtual std::string senderHighlightNameFromMessage(const JID& from) = 0; - virtual bool isIncomingMessageFromMe(boost::shared_ptr<Message>) = 0; - virtual void preHandleIncomingMessage(boost::shared_ptr<MessageEvent>) {} - virtual void addMessageHandleIncomingMessage(const JID& from, const ChatWindow::ChatMessage& message, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const boost::posix_time::ptime& time); - virtual void postHandleIncomingMessage(boost::shared_ptr<MessageEvent>, const ChatWindow::ChatMessage&) {} - 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 handleBareJIDCapsChanged(const JID& jid) = 0; - std::string getErrorMessage(boost::shared_ptr<ErrorPayload>); - virtual void setContactIsReceivingPresence(bool /* isReceivingPresence */) {} - virtual void cancelReplaces() = 0; - /** JID any iq for account should go to - bare except for PMs */ - virtual JID getBaseJID(); - virtual void logMessage(const std::string& message, const JID& fromJID, const JID& toJID, const boost::posix_time::ptime& timeStamp, bool isIncoming) = 0; - ChatWindow::ChatMessage buildChatWindowChatMessage(const std::string& message, bool senderIsSelf, const HighlightAction& fullMessageHighlightAction); - void handleHighlightActions(const ChatWindow::ChatMessage& chatMessage); + /** + * Pass the Message appended, and the stanza used to send it. + */ + virtual void postSendMessage(const std::string&, boost::shared_ptr<Stanza>) {} + virtual std::string senderDisplayNameFromMessage(const JID& from) = 0; + virtual std::string senderHighlightNameFromMessage(const JID& from) = 0; + virtual bool isIncomingMessageFromMe(boost::shared_ptr<Message>) = 0; + virtual void preHandleIncomingMessage(boost::shared_ptr<MessageEvent>) {} + virtual void addMessageHandleIncomingMessage(const JID& from, const ChatWindow::ChatMessage& message, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const boost::posix_time::ptime& time); + virtual void postHandleIncomingMessage(boost::shared_ptr<MessageEvent>, const ChatWindow::ChatMessage&) {} + 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 handleBareJIDCapsChanged(const JID& jid) = 0; + std::string getErrorMessage(boost::shared_ptr<ErrorPayload>); + virtual void setContactIsReceivingPresence(bool /* isReceivingPresence */) {} + virtual void cancelReplaces() = 0; + /** JID any iq for account should go to - bare except for PMs */ + virtual JID getBaseJID(); + virtual void logMessage(const std::string& message, const JID& fromJID, const JID& toJID, const boost::posix_time::ptime& timeStamp, bool isIncoming) = 0; + ChatWindow::ChatMessage buildChatWindowChatMessage(const std::string& message, bool senderIsSelf, const HighlightAction& fullMessageHighlightAction); + void handleHighlightActions(const ChatWindow::ChatMessage& chatMessage); - private: - IDGenerator idGenerator_; - std::string lastSentMessageStanzaID_; - void createDayChangeTimer(); + private: + IDGenerator idGenerator_; + std::string lastSentMessageStanzaID_; + void createDayChangeTimer(); - void handleSendMessageRequest(const std::string &body, bool isCorrectionMessage); - void handleAllMessagesRead(); - void handleSecurityLabelsCatalogResponse(boost::shared_ptr<SecurityLabelsCatalog>, ErrorPayload::ref error); - void handleDayChangeTick(); - void handleMUCInvitation(Message::ref message); - void handleMediatedMUCInvitation(Message::ref message); - void handleGeneralMUCInvitation(MUCInviteEvent::ref event); - void handleLogCleared(); + void handleSendMessageRequest(const std::string &body, bool isCorrectionMessage); + void handleAllMessagesRead(); + void handleSecurityLabelsCatalogResponse(boost::shared_ptr<SecurityLabelsCatalog>, ErrorPayload::ref error); + void handleDayChangeTick(); + void handleMUCInvitation(Message::ref message); + void handleMediatedMUCInvitation(Message::ref message); + void handleGeneralMUCInvitation(MUCInviteEvent::ref event); + void handleLogCleared(); - protected: - JID selfJID_; - std::vector<boost::shared_ptr<StanzaEvent> > unreadMessages_; - std::vector<boost::shared_ptr<StanzaEvent> > targetedUnreadMessages_; - StanzaChannel* stanzaChannel_; - IQRouter* iqRouter_; - ChatWindowFactory* chatWindowFactory_; - ChatWindow* chatWindow_; - JID toJID_; - bool labelsEnabled_; - std::map<JID, std::string> lastMessagesUIID_; - PresenceOracle* presenceOracle_; - AvatarManager* avatarManager_; - bool useDelayForLatency_; - EventController* eventController_; - boost::shared_ptr<Timer> dateChangeTimer_; - TimerFactory* timerFactory_; - EntityCapsProvider* entityCapsProvider_; - SecurityLabelsCatalog::Item lastLabel_; - HistoryController* historyController_; - MUCRegistry* mucRegistry_; - Highlighter* highlighter_; - boost::shared_ptr<ChatMessageParser> chatMessageParser_; - AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider_; - UIEventStream* eventStream_; - }; + protected: + JID selfJID_; + std::vector<boost::shared_ptr<StanzaEvent> > unreadMessages_; + std::vector<boost::shared_ptr<StanzaEvent> > targetedUnreadMessages_; + StanzaChannel* stanzaChannel_; + IQRouter* iqRouter_; + ChatWindowFactory* chatWindowFactory_; + ChatWindow* chatWindow_; + JID toJID_; + bool labelsEnabled_; + std::map<JID, std::string> lastMessagesUIID_; + PresenceOracle* presenceOracle_; + AvatarManager* avatarManager_; + bool useDelayForLatency_; + EventController* eventController_; + boost::shared_ptr<Timer> dateChangeTimer_; + TimerFactory* timerFactory_; + EntityCapsProvider* entityCapsProvider_; + SecurityLabelsCatalog::Item lastLabel_; + HistoryController* historyController_; + MUCRegistry* mucRegistry_; + Highlighter* highlighter_; + boost::shared_ptr<ChatMessageParser> chatMessageParser_; + AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider_; + UIEventStream* eventStream_; + }; } diff --git a/Swift/Controllers/Chat/ChatMessageParser.cpp b/Swift/Controllers/Chat/ChatMessageParser.cpp index 53c7588..08e4fcd 100644 --- a/Swift/Controllers/Chat/ChatMessageParser.cpp +++ b/Swift/Controllers/Chat/ChatMessageParser.cpp @@ -19,177 +19,177 @@ namespace Swift { - ChatMessageParser::ChatMessageParser(const std::map<std::string, std::string>& emoticons, HighlightRulesListPtr highlightRules, bool mucMode) - : emoticons_(emoticons), highlightRules_(highlightRules), mucMode_(mucMode) { - } - - typedef std::pair<std::string, std::string> StringPair; - - ChatWindow::ChatMessage ChatMessageParser::parseMessageBody(const std::string& body, const std::string& nick, bool senderIsSelf) { - ChatWindow::ChatMessage parsedMessage; - std::string remaining = body; - /* Parse one, URLs */ - while (!remaining.empty()) { - bool found = false; - std::pair<std::vector<std::string>, size_t> links = Linkify::splitLink(remaining); - remaining = ""; - for (size_t i = 0; i < links.first.size(); i++) { - const std::string& part = links.first[i]; - if (found) { - // Must be on the last part, then - remaining = part; - } - else { - if (i == links.second) { - found = true; - parsedMessage.append(boost::make_shared<ChatWindow::ChatURIMessagePart>(part)); - } - else { - parsedMessage.append(boost::make_shared<ChatWindow::ChatTextMessagePart>(part)); - } - } - } - } - - /* do emoticon substitution */ - parsedMessage = emoticonHighlight(parsedMessage); - - if (!senderIsSelf) { /* do not highlight our own messsages */ - /* do word-based color highlighting */ - parsedMessage = splitHighlight(parsedMessage, nick); - } - - return parsedMessage; - } - - ChatWindow::ChatMessage ChatMessageParser::emoticonHighlight(const ChatWindow::ChatMessage& message) - { - ChatWindow::ChatMessage parsedMessage = message; - - std::string regexString; - /* Parse two, emoticons */ - foreach (StringPair emoticon, emoticons_) { - /* Construct a regexp that finds an instance of any of the emoticons inside a group - * at the start or end of the line, or beside whitespace. - */ - regexString += regexString.empty() ? "" : "|"; - std::string escaped = "(" + Regex::escape(emoticon.first) + ")"; - regexString += "^" + escaped + "|"; - regexString += escaped + "$|"; - regexString += "\\s" + escaped + "|"; - regexString += escaped + "\\s"; - - } - if (!regexString.empty()) { - regexString += ""; - boost::regex emoticonRegex(regexString); - - ChatWindow::ChatMessage newMessage; - foreach (boost::shared_ptr<ChatWindow::ChatMessagePart> part, parsedMessage.getParts()) { - boost::shared_ptr<ChatWindow::ChatTextMessagePart> textPart; - if ((textPart = boost::dynamic_pointer_cast<ChatWindow::ChatTextMessagePart>(part))) { - try { - boost::match_results<std::string::const_iterator> match; - const std::string& text = textPart->text; - std::string::const_iterator start = text.begin(); - while (regex_search(start, text.end(), match, emoticonRegex)) { - int matchIndex = 0; - for (matchIndex = 1; matchIndex < static_cast<int>(match.size()); matchIndex++) { - if (match[matchIndex].length() > 0) { - //This is the matching subgroup - break; - } - } - std::string::const_iterator matchStart = match[matchIndex].first; - std::string::const_iterator matchEnd = match[matchIndex].second; - if (start != matchStart) { - /* If we're skipping over plain text since the previous emoticon, record it as plain text */ - newMessage.append(boost::make_shared<ChatWindow::ChatTextMessagePart>(std::string(start, matchStart))); - } - boost::shared_ptr<ChatWindow::ChatEmoticonMessagePart> emoticonPart = boost::make_shared<ChatWindow::ChatEmoticonMessagePart>(); - std::string matchString = match[matchIndex].str(); - std::map<std::string, std::string>::const_iterator emoticonIterator = emoticons_.find(matchString); - assert (emoticonIterator != emoticons_.end()); - const StringPair& emoticon = *emoticonIterator; - emoticonPart->imagePath = emoticon.second; - emoticonPart->alternativeText = emoticon.first; - newMessage.append(emoticonPart); - start = matchEnd; - } - if (start != text.end()) { - /* If there's plain text after the last emoticon, record it */ - newMessage.append(boost::make_shared<ChatWindow::ChatTextMessagePart>(std::string(start, text.end()))); - } - - } - catch (std::runtime_error) { - /* Basically too expensive to compute the regex results and it gave up, so pass through as text */ - newMessage.append(part); - } - } - else { - newMessage.append(part); - } - } - parsedMessage = newMessage; - - } - return parsedMessage; - } - - ChatWindow::ChatMessage ChatMessageParser::splitHighlight(const ChatWindow::ChatMessage& message, const std::string& nick) - { - ChatWindow::ChatMessage parsedMessage = message; - - for (size_t i = 0; i < highlightRules_->getSize(); ++i) { - const HighlightRule& rule = highlightRules_->getRule(i); - if (rule.getMatchMUC() && !mucMode_) { - continue; /* this rule only applies to MUC's, and this is a CHAT */ - } else if (rule.getMatchChat() && mucMode_) { - continue; /* this rule only applies to CHAT's, and this is a MUC */ - } else if (rule.getAction().getTextBackground().empty() && rule.getAction().getTextColor().empty()) { - continue; /* do not try to highlight text, if no highlight color is specified */ - } - const std::vector<boost::regex> keywordRegex = rule.getKeywordRegex(nick); - foreach(const boost::regex& regex, keywordRegex) { - ChatWindow::ChatMessage newMessage; - foreach (boost::shared_ptr<ChatWindow::ChatMessagePart> part, parsedMessage.getParts()) { - boost::shared_ptr<ChatWindow::ChatTextMessagePart> textPart; - if ((textPart = boost::dynamic_pointer_cast<ChatWindow::ChatTextMessagePart>(part))) { - try { - boost::match_results<std::string::const_iterator> match; - const std::string& text = textPart->text; - std::string::const_iterator start = text.begin(); - while (regex_search(start, text.end(), match, regex)) { - std::string::const_iterator matchStart = match[0].first; - std::string::const_iterator matchEnd = match[0].second; - if (start != matchStart) { - /* If we're skipping over plain text since the previous emoticon, record it as plain text */ - newMessage.append(boost::make_shared<ChatWindow::ChatTextMessagePart>(std::string(start, matchStart))); - } - boost::shared_ptr<ChatWindow::ChatHighlightingMessagePart> highlightPart = boost::make_shared<ChatWindow::ChatHighlightingMessagePart>(); - highlightPart->text = match.str(); - highlightPart->action = rule.getAction(); - newMessage.append(highlightPart); - start = matchEnd; - } - if (start != text.end()) { - /* If there's plain text after the last emoticon, record it */ - newMessage.append(boost::make_shared<ChatWindow::ChatTextMessagePart>(std::string(start, text.end()))); - } - } - catch (std::runtime_error) { - /* Basically too expensive to compute the regex results and it gave up, so pass through as text */ - newMessage.append(part); - } - } else { - newMessage.append(part); - } - } - parsedMessage = newMessage; - } - } - - return parsedMessage; - } + ChatMessageParser::ChatMessageParser(const std::map<std::string, std::string>& emoticons, HighlightRulesListPtr highlightRules, bool mucMode) + : emoticons_(emoticons), highlightRules_(highlightRules), mucMode_(mucMode) { + } + + typedef std::pair<std::string, std::string> StringPair; + + ChatWindow::ChatMessage ChatMessageParser::parseMessageBody(const std::string& body, const std::string& nick, bool senderIsSelf) { + ChatWindow::ChatMessage parsedMessage; + std::string remaining = body; + /* Parse one, URLs */ + while (!remaining.empty()) { + bool found = false; + std::pair<std::vector<std::string>, size_t> links = Linkify::splitLink(remaining); + remaining = ""; + for (size_t i = 0; i < links.first.size(); i++) { + const std::string& part = links.first[i]; + if (found) { + // Must be on the last part, then + remaining = part; + } + else { + if (i == links.second) { + found = true; + parsedMessage.append(boost::make_shared<ChatWindow::ChatURIMessagePart>(part)); + } + else { + parsedMessage.append(boost::make_shared<ChatWindow::ChatTextMessagePart>(part)); + } + } + } + } + + /* do emoticon substitution */ + parsedMessage = emoticonHighlight(parsedMessage); + + if (!senderIsSelf) { /* do not highlight our own messsages */ + /* do word-based color highlighting */ + parsedMessage = splitHighlight(parsedMessage, nick); + } + + return parsedMessage; + } + + ChatWindow::ChatMessage ChatMessageParser::emoticonHighlight(const ChatWindow::ChatMessage& message) + { + ChatWindow::ChatMessage parsedMessage = message; + + std::string regexString; + /* Parse two, emoticons */ + foreach (StringPair emoticon, emoticons_) { + /* Construct a regexp that finds an instance of any of the emoticons inside a group + * at the start or end of the line, or beside whitespace. + */ + regexString += regexString.empty() ? "" : "|"; + std::string escaped = "(" + Regex::escape(emoticon.first) + ")"; + regexString += "^" + escaped + "|"; + regexString += escaped + "$|"; + regexString += "\\s" + escaped + "|"; + regexString += escaped + "\\s"; + + } + if (!regexString.empty()) { + regexString += ""; + boost::regex emoticonRegex(regexString); + + ChatWindow::ChatMessage newMessage; + foreach (boost::shared_ptr<ChatWindow::ChatMessagePart> part, parsedMessage.getParts()) { + boost::shared_ptr<ChatWindow::ChatTextMessagePart> textPart; + if ((textPart = boost::dynamic_pointer_cast<ChatWindow::ChatTextMessagePart>(part))) { + try { + boost::match_results<std::string::const_iterator> match; + const std::string& text = textPart->text; + std::string::const_iterator start = text.begin(); + while (regex_search(start, text.end(), match, emoticonRegex)) { + int matchIndex = 0; + for (matchIndex = 1; matchIndex < static_cast<int>(match.size()); matchIndex++) { + if (match[matchIndex].length() > 0) { + //This is the matching subgroup + break; + } + } + std::string::const_iterator matchStart = match[matchIndex].first; + std::string::const_iterator matchEnd = match[matchIndex].second; + if (start != matchStart) { + /* If we're skipping over plain text since the previous emoticon, record it as plain text */ + newMessage.append(boost::make_shared<ChatWindow::ChatTextMessagePart>(std::string(start, matchStart))); + } + boost::shared_ptr<ChatWindow::ChatEmoticonMessagePart> emoticonPart = boost::make_shared<ChatWindow::ChatEmoticonMessagePart>(); + std::string matchString = match[matchIndex].str(); + std::map<std::string, std::string>::const_iterator emoticonIterator = emoticons_.find(matchString); + assert (emoticonIterator != emoticons_.end()); + const StringPair& emoticon = *emoticonIterator; + emoticonPart->imagePath = emoticon.second; + emoticonPart->alternativeText = emoticon.first; + newMessage.append(emoticonPart); + start = matchEnd; + } + if (start != text.end()) { + /* If there's plain text after the last emoticon, record it */ + newMessage.append(boost::make_shared<ChatWindow::ChatTextMessagePart>(std::string(start, text.end()))); + } + + } + catch (std::runtime_error) { + /* Basically too expensive to compute the regex results and it gave up, so pass through as text */ + newMessage.append(part); + } + } + else { + newMessage.append(part); + } + } + parsedMessage = newMessage; + + } + return parsedMessage; + } + + ChatWindow::ChatMessage ChatMessageParser::splitHighlight(const ChatWindow::ChatMessage& message, const std::string& nick) + { + ChatWindow::ChatMessage parsedMessage = message; + + for (size_t i = 0; i < highlightRules_->getSize(); ++i) { + const HighlightRule& rule = highlightRules_->getRule(i); + if (rule.getMatchMUC() && !mucMode_) { + continue; /* this rule only applies to MUC's, and this is a CHAT */ + } else if (rule.getMatchChat() && mucMode_) { + continue; /* this rule only applies to CHAT's, and this is a MUC */ + } else if (rule.getAction().getTextBackground().empty() && rule.getAction().getTextColor().empty()) { + continue; /* do not try to highlight text, if no highlight color is specified */ + } + const std::vector<boost::regex> keywordRegex = rule.getKeywordRegex(nick); + foreach(const boost::regex& regex, keywordRegex) { + ChatWindow::ChatMessage newMessage; + foreach (boost::shared_ptr<ChatWindow::ChatMessagePart> part, parsedMessage.getParts()) { + boost::shared_ptr<ChatWindow::ChatTextMessagePart> textPart; + if ((textPart = boost::dynamic_pointer_cast<ChatWindow::ChatTextMessagePart>(part))) { + try { + boost::match_results<std::string::const_iterator> match; + const std::string& text = textPart->text; + std::string::const_iterator start = text.begin(); + while (regex_search(start, text.end(), match, regex)) { + std::string::const_iterator matchStart = match[0].first; + std::string::const_iterator matchEnd = match[0].second; + if (start != matchStart) { + /* If we're skipping over plain text since the previous emoticon, record it as plain text */ + newMessage.append(boost::make_shared<ChatWindow::ChatTextMessagePart>(std::string(start, matchStart))); + } + boost::shared_ptr<ChatWindow::ChatHighlightingMessagePart> highlightPart = boost::make_shared<ChatWindow::ChatHighlightingMessagePart>(); + highlightPart->text = match.str(); + highlightPart->action = rule.getAction(); + newMessage.append(highlightPart); + start = matchEnd; + } + if (start != text.end()) { + /* If there's plain text after the last emoticon, record it */ + newMessage.append(boost::make_shared<ChatWindow::ChatTextMessagePart>(std::string(start, text.end()))); + } + } + catch (std::runtime_error) { + /* Basically too expensive to compute the regex results and it gave up, so pass through as text */ + newMessage.append(part); + } + } else { + newMessage.append(part); + } + } + parsedMessage = newMessage; + } + } + + return parsedMessage; + } } diff --git a/Swift/Controllers/Chat/ChatMessageParser.h b/Swift/Controllers/Chat/ChatMessageParser.h index e56d21b..4bed669 100644 --- a/Swift/Controllers/Chat/ChatMessageParser.h +++ b/Swift/Controllers/Chat/ChatMessageParser.h @@ -12,15 +12,15 @@ namespace Swift { - class ChatMessageParser { - public: - ChatMessageParser(const std::map<std::string, std::string>& emoticons, HighlightRulesListPtr highlightRules, bool mucMode = false); - ChatWindow::ChatMessage parseMessageBody(const std::string& body, const std::string& nick = "", bool senderIsSelf = false); - private: - ChatWindow::ChatMessage emoticonHighlight(const ChatWindow::ChatMessage& parsedMessage); - ChatWindow::ChatMessage splitHighlight(const ChatWindow::ChatMessage& parsedMessage, const std::string& nick); - std::map<std::string, std::string> emoticons_; - HighlightRulesListPtr highlightRules_; - bool mucMode_; - }; + class ChatMessageParser { + public: + ChatMessageParser(const std::map<std::string, std::string>& emoticons, HighlightRulesListPtr highlightRules, bool mucMode = false); + ChatWindow::ChatMessage parseMessageBody(const std::string& body, const std::string& nick = "", bool senderIsSelf = false); + private: + ChatWindow::ChatMessage emoticonHighlight(const ChatWindow::ChatMessage& parsedMessage); + ChatWindow::ChatMessage splitHighlight(const ChatWindow::ChatMessage& parsedMessage, const std::string& nick); + std::map<std::string, std::string> emoticons_; + HighlightRulesListPtr highlightRules_; + bool mucMode_; + }; } diff --git a/Swift/Controllers/Chat/ChatsManager.cpp b/Swift/Controllers/Chat/ChatsManager.cpp index 49caee4..32da58a 100644 --- a/Swift/Controllers/Chat/ChatsManager.cpp +++ b/Swift/Controllers/Chat/ChatsManager.cpp @@ -67,32 +67,32 @@ BOOST_CLASS_VERSION(Swift::ChatListWindow::Chat, 1) namespace boost { namespace serialization { - template<class Archive> void save(Archive& ar, const Swift::JID& jid, const unsigned int /*version*/) { - std::string jidStr = jid.toString(); - ar << jidStr; - } - - template<class Archive> void load(Archive& ar, Swift::JID& jid, const unsigned int /*version*/) { - std::string stringJID; - ar >> stringJID; - jid = Swift::JID(stringJID); - } - - template<class Archive> inline void serialize(Archive& ar, Swift::JID& t, const unsigned int file_version){ - split_free(ar, t, file_version); - } - - template<class Archive> void serialize(Archive& ar, Swift::ChatListWindow::Chat& chat, const unsigned int version) { - ar & chat.jid; - ar & chat.chatName; - ar & chat.activity; - ar & chat.isMUC; - ar & chat.nick; - ar & chat.impromptuJIDs; - if (version > 0) { - ar & chat.password; - } - } + template<class Archive> void save(Archive& ar, const Swift::JID& jid, const unsigned int /*version*/) { + std::string jidStr = jid.toString(); + ar << jidStr; + } + + template<class Archive> void load(Archive& ar, Swift::JID& jid, const unsigned int /*version*/) { + std::string stringJID; + ar >> stringJID; + jid = Swift::JID(stringJID); + } + + template<class Archive> inline void serialize(Archive& ar, Swift::JID& t, const unsigned int file_version){ + split_free(ar, t, file_version); + } + + template<class Archive> void serialize(Archive& ar, Swift::ChatListWindow::Chat& chat, const unsigned int version) { + ar & chat.jid; + ar & chat.chatName; + ar & chat.activity; + ar & chat.isMUC; + ar & chat.nick; + ar & chat.impromptuJIDs; + if (version > 0) { + ar & chat.password; + } + } } } @@ -104,950 +104,950 @@ typedef std::pair<JID, MUCController*> JIDMUCControllerPair; #define RECENT_CHATS "recent_chats" ChatsManager::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, - ClientBlockListManager* clientBlockListManager, - const std::map<std::string, std::string>& emoticons, - VCardManager* vcardManager) : - jid_(jid), - joinMUCWindowFactory_(joinMUCWindowFactory), - useDelayForLatency_(useDelayForLatency), - mucRegistry_(mucRegistry), - entityCapsProvider_(entityCapsProvider), - mucManager(mucManager), - ftOverview_(ftOverview), - roster_(roster), - eagleMode_(eagleMode), - settings_(settings), - historyController_(historyController), - whiteboardManager_(whiteboardManager), - highlightManager_(highlightManager), - emoticons_(emoticons), - clientBlockListManager_(clientBlockListManager), - vcardManager_(vcardManager) { - timerFactory_ = timerFactory; - eventController_ = eventController; - stanzaChannel_ = stanzaChannel; - iqRouter_ = iqRouter; - chatWindowFactory_ = chatWindowFactory; - nickResolver_ = nickResolver; - presenceOracle_ = presenceOracle; - avatarManager_ = NULL; - serverDiscoInfo_ = boost::make_shared<DiscoInfo>(); - presenceSender_ = presenceSender; - uiEventStream_ = uiEventStream; - mucBookmarkManager_ = NULL; - profileSettings_ = profileSettings; - presenceOracle_->onPresenceChange.connect(boost::bind(&ChatsManager::handlePresenceChange, this, _1)); - uiEventConnection_ = uiEventStream_->onUIEvent.connect(boost::bind(&ChatsManager::handleUIEvent, this, _1)); - - chatListWindow_ = chatListWindowFactory->createChatListWindow(uiEventStream_); - chatListWindow_->onMUCBookmarkActivated.connect(boost::bind(&ChatsManager::handleMUCBookmarkActivated, this, _1)); - chatListWindow_->onRecentActivated.connect(boost::bind(&ChatsManager::handleRecentActivated, this, _1)); - chatListWindow_->onClearRecentsRequested.connect(boost::bind(&ChatsManager::handleClearRecentsRequested, this)); - - joinMUCWindow_ = NULL; - mucSearchController_ = new MUCSearchController(jid_, mucSearchWindowFactory, iqRouter, profileSettings_); - mucSearchController_->onMUCSelected.connect(boost::bind(&ChatsManager::handleMUCSelectedAfterSearch, this, _1)); - ftOverview_->onNewFileTransferController.connect(boost::bind(&ChatsManager::handleNewFileTransferController, this, _1)); - whiteboardManager_->onSessionRequest.connect(boost::bind(&ChatsManager::handleWhiteboardSessionRequest, this, _1, _2)); - whiteboardManager_->onRequestAccepted.connect(boost::bind(&ChatsManager::handleWhiteboardStateChange, this, _1, ChatWindow::WhiteboardAccepted)); - whiteboardManager_->onSessionTerminate.connect(boost::bind(&ChatsManager::handleWhiteboardStateChange, this, _1, ChatWindow::WhiteboardTerminated)); - whiteboardManager_->onRequestRejected.connect(boost::bind(&ChatsManager::handleWhiteboardStateChange, this, _1, ChatWindow::WhiteboardRejected)); - roster_->onJIDAdded.connect(boost::bind(&ChatsManager::handleJIDAddedToRoster, this, _1)); - roster_->onJIDRemoved.connect(boost::bind(&ChatsManager::handleJIDRemovedFromRoster, this, _1)); - roster_->onJIDUpdated.connect(boost::bind(&ChatsManager::handleJIDUpdatedInRoster, this, _1)); - roster_->onRosterCleared.connect(boost::bind(&ChatsManager::handleRosterCleared, this)); - - settings_->onSettingChanged.connect(boost::bind(&ChatsManager::handleSettingChanged, this, _1)); - - userWantsReceipts_ = settings_->getSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS); - - setupBookmarks(); - loadRecents(); - - autoAcceptMUCInviteDecider_ = new AutoAcceptMUCInviteDecider(jid.getDomain(), roster_, settings_); + 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, + ClientBlockListManager* clientBlockListManager, + const std::map<std::string, std::string>& emoticons, + VCardManager* vcardManager) : + jid_(jid), + joinMUCWindowFactory_(joinMUCWindowFactory), + useDelayForLatency_(useDelayForLatency), + mucRegistry_(mucRegistry), + entityCapsProvider_(entityCapsProvider), + mucManager(mucManager), + ftOverview_(ftOverview), + roster_(roster), + eagleMode_(eagleMode), + settings_(settings), + historyController_(historyController), + whiteboardManager_(whiteboardManager), + highlightManager_(highlightManager), + emoticons_(emoticons), + clientBlockListManager_(clientBlockListManager), + vcardManager_(vcardManager) { + timerFactory_ = timerFactory; + eventController_ = eventController; + stanzaChannel_ = stanzaChannel; + iqRouter_ = iqRouter; + chatWindowFactory_ = chatWindowFactory; + nickResolver_ = nickResolver; + presenceOracle_ = presenceOracle; + avatarManager_ = NULL; + serverDiscoInfo_ = boost::make_shared<DiscoInfo>(); + presenceSender_ = presenceSender; + uiEventStream_ = uiEventStream; + mucBookmarkManager_ = NULL; + profileSettings_ = profileSettings; + presenceOracle_->onPresenceChange.connect(boost::bind(&ChatsManager::handlePresenceChange, this, _1)); + uiEventConnection_ = uiEventStream_->onUIEvent.connect(boost::bind(&ChatsManager::handleUIEvent, this, _1)); + + chatListWindow_ = chatListWindowFactory->createChatListWindow(uiEventStream_); + chatListWindow_->onMUCBookmarkActivated.connect(boost::bind(&ChatsManager::handleMUCBookmarkActivated, this, _1)); + chatListWindow_->onRecentActivated.connect(boost::bind(&ChatsManager::handleRecentActivated, this, _1)); + chatListWindow_->onClearRecentsRequested.connect(boost::bind(&ChatsManager::handleClearRecentsRequested, this)); + + joinMUCWindow_ = NULL; + mucSearchController_ = new MUCSearchController(jid_, mucSearchWindowFactory, iqRouter, profileSettings_); + mucSearchController_->onMUCSelected.connect(boost::bind(&ChatsManager::handleMUCSelectedAfterSearch, this, _1)); + ftOverview_->onNewFileTransferController.connect(boost::bind(&ChatsManager::handleNewFileTransferController, this, _1)); + whiteboardManager_->onSessionRequest.connect(boost::bind(&ChatsManager::handleWhiteboardSessionRequest, this, _1, _2)); + whiteboardManager_->onRequestAccepted.connect(boost::bind(&ChatsManager::handleWhiteboardStateChange, this, _1, ChatWindow::WhiteboardAccepted)); + whiteboardManager_->onSessionTerminate.connect(boost::bind(&ChatsManager::handleWhiteboardStateChange, this, _1, ChatWindow::WhiteboardTerminated)); + whiteboardManager_->onRequestRejected.connect(boost::bind(&ChatsManager::handleWhiteboardStateChange, this, _1, ChatWindow::WhiteboardRejected)); + roster_->onJIDAdded.connect(boost::bind(&ChatsManager::handleJIDAddedToRoster, this, _1)); + roster_->onJIDRemoved.connect(boost::bind(&ChatsManager::handleJIDRemovedFromRoster, this, _1)); + roster_->onJIDUpdated.connect(boost::bind(&ChatsManager::handleJIDUpdatedInRoster, this, _1)); + roster_->onRosterCleared.connect(boost::bind(&ChatsManager::handleRosterCleared, this)); + + settings_->onSettingChanged.connect(boost::bind(&ChatsManager::handleSettingChanged, this, _1)); + + userWantsReceipts_ = settings_->getSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS); + + setupBookmarks(); + loadRecents(); + + autoAcceptMUCInviteDecider_ = new AutoAcceptMUCInviteDecider(jid.getDomain(), roster_, settings_); } ChatsManager::~ChatsManager() { - settings_->onSettingChanged.disconnect(boost::bind(&ChatsManager::handleSettingChanged, this, _1)); - roster_->onJIDAdded.disconnect(boost::bind(&ChatsManager::handleJIDAddedToRoster, this, _1)); - roster_->onJIDRemoved.disconnect(boost::bind(&ChatsManager::handleJIDRemovedFromRoster, this, _1)); - roster_->onJIDUpdated.disconnect(boost::bind(&ChatsManager::handleJIDUpdatedInRoster, this, _1)); - roster_->onRosterCleared.disconnect(boost::bind(&ChatsManager::handleRosterCleared, this)); - delete joinMUCWindow_; - foreach (JIDChatControllerPair controllerPair, chatControllers_) { - delete controllerPair.second; - } - foreach (JIDMUCControllerPair controllerPair, mucControllers_) { - delete controllerPair.second; - } - delete mucBookmarkManager_; - delete mucSearchController_; - delete autoAcceptMUCInviteDecider_; + settings_->onSettingChanged.disconnect(boost::bind(&ChatsManager::handleSettingChanged, this, _1)); + roster_->onJIDAdded.disconnect(boost::bind(&ChatsManager::handleJIDAddedToRoster, this, _1)); + roster_->onJIDRemoved.disconnect(boost::bind(&ChatsManager::handleJIDRemovedFromRoster, this, _1)); + roster_->onJIDUpdated.disconnect(boost::bind(&ChatsManager::handleJIDUpdatedInRoster, this, _1)); + roster_->onRosterCleared.disconnect(boost::bind(&ChatsManager::handleRosterCleared, this)); + delete joinMUCWindow_; + foreach (JIDChatControllerPair controllerPair, chatControllers_) { + delete controllerPair.second; + } + foreach (JIDMUCControllerPair controllerPair, mucControllers_) { + delete controllerPair.second; + } + delete mucBookmarkManager_; + delete mucSearchController_; + delete autoAcceptMUCInviteDecider_; } void ChatsManager::saveRecents() { - std::stringstream serializeStream; - boost::archive::text_oarchive oa(serializeStream); - std::vector<ChatListWindow::Chat> recentsLimited = std::vector<ChatListWindow::Chat>(recentChats_.begin(), recentChats_.end()); - if (recentsLimited.size() > 25) { - recentsLimited.erase(recentsLimited.begin() + 25, recentsLimited.end()); - } - if (eagleMode_) { - foreach(ChatListWindow::Chat& chat, recentsLimited) { - chat.activity = ""; - } - } - - class RemoveRecent { - public: - static bool ifPrivateMessage(const ChatListWindow::Chat& chat) { - return chat.isPrivateMessage; - } - }; - - recentsLimited.erase(std::remove_if(recentsLimited.begin(), recentsLimited.end(), RemoveRecent::ifPrivateMessage), recentsLimited.end()); - - oa << recentsLimited; - std::string serializedStr = Base64::encode(createByteArray(serializeStream.str())); - profileSettings_->storeString(RECENT_CHATS, serializedStr); + std::stringstream serializeStream; + boost::archive::text_oarchive oa(serializeStream); + std::vector<ChatListWindow::Chat> recentsLimited = std::vector<ChatListWindow::Chat>(recentChats_.begin(), recentChats_.end()); + if (recentsLimited.size() > 25) { + recentsLimited.erase(recentsLimited.begin() + 25, recentsLimited.end()); + } + if (eagleMode_) { + foreach(ChatListWindow::Chat& chat, recentsLimited) { + chat.activity = ""; + } + } + + class RemoveRecent { + public: + static bool ifPrivateMessage(const ChatListWindow::Chat& chat) { + return chat.isPrivateMessage; + } + }; + + recentsLimited.erase(std::remove_if(recentsLimited.begin(), recentsLimited.end(), RemoveRecent::ifPrivateMessage), recentsLimited.end()); + + oa << recentsLimited; + std::string serializedStr = Base64::encode(createByteArray(serializeStream.str())); + profileSettings_->storeString(RECENT_CHATS, serializedStr); } void ChatsManager::handleClearRecentsRequested() { - recentChats_.clear(); - saveRecents(); - handleUnreadCountChanged(NULL); + recentChats_.clear(); + saveRecents(); + handleUnreadCountChanged(NULL); } void ChatsManager::handleJIDAddedToRoster(const JID &jid) { - updatePresenceReceivingStateOnChatController(jid); + updatePresenceReceivingStateOnChatController(jid); } void ChatsManager::handleJIDRemovedFromRoster(const JID &jid) { - updatePresenceReceivingStateOnChatController(jid); + updatePresenceReceivingStateOnChatController(jid); } void ChatsManager::handleJIDUpdatedInRoster(const JID &jid) { - updatePresenceReceivingStateOnChatController(jid); + updatePresenceReceivingStateOnChatController(jid); } void ChatsManager::handleRosterCleared() { - /* Setting that all chat controllers aren't receiving presence anymore; - including MUC 1-to-1 chats due to the assumtion that this handler - is only called on log out. */ - foreach(JIDChatControllerPair pair, chatControllers_) { - pair.second->setContactIsReceivingPresence(false); - } + /* Setting that all chat controllers aren't receiving presence anymore; + including MUC 1-to-1 chats due to the assumtion that this handler + is only called on log out. */ + foreach(JIDChatControllerPair pair, chatControllers_) { + pair.second->setContactIsReceivingPresence(false); + } } void ChatsManager::updatePresenceReceivingStateOnChatController(const JID &jid) { - ChatController* controller = getChatControllerIfExists(jid); - if (controller) { - if (!mucRegistry_->isMUC(jid.toBare())) { - RosterItemPayload::Subscription subscription = roster_->getSubscriptionStateForJID(jid); - controller->setContactIsReceivingPresence(subscription == RosterItemPayload::From || subscription == RosterItemPayload::Both); - } else { - controller->setContactIsReceivingPresence(true); - } - } + ChatController* controller = getChatControllerIfExists(jid); + if (controller) { + if (!mucRegistry_->isMUC(jid.toBare())) { + RosterItemPayload::Subscription subscription = roster_->getSubscriptionStateForJID(jid); + controller->setContactIsReceivingPresence(subscription == RosterItemPayload::From || subscription == RosterItemPayload::Both); + } else { + controller->setContactIsReceivingPresence(true); + } + } } ChatListWindow::Chat ChatsManager::updateChatStatusAndAvatarHelper(const ChatListWindow::Chat& chat) const { - ChatListWindow::Chat fixedChat = chat; - if (fixedChat.isMUC) { - if (mucControllers_.find(fixedChat.jid.toBare()) != mucControllers_.end()) { - fixedChat.statusType = StatusShow::Online; - } - } else { - if (avatarManager_) { - fixedChat.avatarPath = avatarManager_->getAvatarPath(fixedChat.jid); - } - Presence::ref presence = presenceOracle_->getAccountPresence(fixedChat.jid.toBare()); - fixedChat.statusType = presence ? presence->getShow() : StatusShow::None; - } - return fixedChat; + ChatListWindow::Chat fixedChat = chat; + if (fixedChat.isMUC) { + if (mucControllers_.find(fixedChat.jid.toBare()) != mucControllers_.end()) { + fixedChat.statusType = StatusShow::Online; + } + } else { + if (avatarManager_) { + fixedChat.avatarPath = avatarManager_->getAvatarPath(fixedChat.jid); + } + Presence::ref presence = presenceOracle_->getAccountPresence(fixedChat.jid.toBare()); + fixedChat.statusType = presence ? presence->getShow() : StatusShow::None; + } + return fixedChat; } void ChatsManager::loadRecents() { - std::string recentsString(profileSettings_->getStringSetting(RECENT_CHATS)); - if (recentsString.find("\t") != std::string::npos) { - // old format - std::vector<std::string> recents; - boost::split(recents, recentsString, boost::is_any_of("\n")); - int i = 0; - foreach (std::string recentString, recents) { - if (i++ > 30) { - break; - } - std::vector<std::string> recent; - boost::split(recent, recentString, boost::is_any_of("\t")); - if (recent.size() < 4) { - continue; - } - JID jid(recent[0]); - if (!jid.isValid()) { - continue; - } - std::string activity(recent[1]); - bool isMUC = recent[2] == "true"; - std::string nick(recent[3]); - StatusShow::Type type = StatusShow::None; - boost::filesystem::path path; - - ChatListWindow::Chat chat(jid, nickResolver_->jidToNick(jid), activity, 0, type, path, isMUC, false, nick); - chat = updateChatStatusAndAvatarHelper(chat); - prependRecent(chat); - } - } else if (!recentsString.empty()){ - // boost searilaize based format - ByteArray debase64 = Base64::decode(recentsString); - std::vector<ChatListWindow::Chat> recentChats; - std::stringstream deserializeStream(std::string(reinterpret_cast<const char*>(vecptr(debase64)), debase64.size())); - try { - boost::archive::text_iarchive ia(deserializeStream); - ia >> recentChats; - } catch (const boost::archive::archive_exception& e) { - SWIFT_LOG(debug) << "Failed to load recents: " << e.what() << std::endl; - return; - } - - foreach(ChatListWindow::Chat chat, recentChats) { - chat.statusType = StatusShow::None; - chat = updateChatStatusAndAvatarHelper(chat); - prependRecent(chat); - } - } - handleUnreadCountChanged(NULL); + std::string recentsString(profileSettings_->getStringSetting(RECENT_CHATS)); + if (recentsString.find("\t") != std::string::npos) { + // old format + std::vector<std::string> recents; + boost::split(recents, recentsString, boost::is_any_of("\n")); + int i = 0; + foreach (std::string recentString, recents) { + if (i++ > 30) { + break; + } + std::vector<std::string> recent; + boost::split(recent, recentString, boost::is_any_of("\t")); + if (recent.size() < 4) { + continue; + } + JID jid(recent[0]); + if (!jid.isValid()) { + continue; + } + std::string activity(recent[1]); + bool isMUC = recent[2] == "true"; + std::string nick(recent[3]); + StatusShow::Type type = StatusShow::None; + boost::filesystem::path path; + + ChatListWindow::Chat chat(jid, nickResolver_->jidToNick(jid), activity, 0, type, path, isMUC, false, nick); + chat = updateChatStatusAndAvatarHelper(chat); + prependRecent(chat); + } + } else if (!recentsString.empty()){ + // boost searilaize based format + ByteArray debase64 = Base64::decode(recentsString); + std::vector<ChatListWindow::Chat> recentChats; + std::stringstream deserializeStream(std::string(reinterpret_cast<const char*>(vecptr(debase64)), debase64.size())); + try { + boost::archive::text_iarchive ia(deserializeStream); + ia >> recentChats; + } catch (const boost::archive::archive_exception& e) { + SWIFT_LOG(debug) << "Failed to load recents: " << e.what() << std::endl; + return; + } + + foreach(ChatListWindow::Chat chat, recentChats) { + chat.statusType = StatusShow::None; + chat = updateChatStatusAndAvatarHelper(chat); + prependRecent(chat); + } + } + handleUnreadCountChanged(NULL); } void ChatsManager::setupBookmarks() { - if (!mucBookmarkManager_) { - mucBookmarkManager_ = new MUCBookmarkManager(iqRouter_); - mucBookmarkManager_->onBookmarksReady.connect(boost::bind(&ChatsManager::handleBookmarksReady, this)); - mucBookmarkManager_->onBookmarkAdded.connect(boost::bind(&ChatsManager::handleMUCBookmarkAdded, this, _1)); - mucBookmarkManager_->onBookmarkRemoved.connect(boost::bind(&ChatsManager::handleMUCBookmarkRemoved, this, _1)); - - if (chatListWindow_) { - chatListWindow_->setBookmarksEnabled(false); - chatListWindow_->clearBookmarks(); - } - } + if (!mucBookmarkManager_) { + mucBookmarkManager_ = new MUCBookmarkManager(iqRouter_); + mucBookmarkManager_->onBookmarksReady.connect(boost::bind(&ChatsManager::handleBookmarksReady, this)); + mucBookmarkManager_->onBookmarkAdded.connect(boost::bind(&ChatsManager::handleMUCBookmarkAdded, this, _1)); + mucBookmarkManager_->onBookmarkRemoved.connect(boost::bind(&ChatsManager::handleMUCBookmarkRemoved, this, _1)); + + if (chatListWindow_) { + chatListWindow_->setBookmarksEnabled(false); + chatListWindow_->clearBookmarks(); + } + } } void ChatsManager::handleBookmarksReady() { - if (chatListWindow_) { - chatListWindow_->setBookmarksEnabled(true); - } + if (chatListWindow_) { + chatListWindow_->setBookmarksEnabled(true); + } } void ChatsManager::handleMUCBookmarkAdded(const MUCBookmark& bookmark) { - std::map<JID, MUCController*>::iterator it = mucControllers_.find(bookmark.getRoom()); - if (it == mucControllers_.end() && bookmark.getAutojoin()) { - handleJoinMUCRequest(bookmark.getRoom(), bookmark.getPassword(), bookmark.getNick(), false, false, false ); - } - chatListWindow_->addMUCBookmark(bookmark); + std::map<JID, MUCController*>::iterator it = mucControllers_.find(bookmark.getRoom()); + if (it == mucControllers_.end() && bookmark.getAutojoin()) { + handleJoinMUCRequest(bookmark.getRoom(), bookmark.getPassword(), bookmark.getNick(), false, false, false ); + } + chatListWindow_->addMUCBookmark(bookmark); } void ChatsManager::handleMUCBookmarkRemoved(const MUCBookmark& bookmark) { - chatListWindow_->removeMUCBookmark(bookmark); + chatListWindow_->removeMUCBookmark(bookmark); } ChatListWindow::Chat ChatsManager::createChatListChatItem(const JID& jid, const std::string& activity, bool privateMessage) { - int unreadCount = 0; - if (mucRegistry_->isMUC(jid)) { - MUCController* controller = mucControllers_[jid.toBare()]; - StatusShow::Type type = StatusShow::None; - std::string nick = ""; - std::string password = ""; - if (controller) { - unreadCount = controller->getUnreadCount(); - if (controller->isJoined()) { - type = StatusShow::Online; - } - nick = controller->getNick(); - - if (controller->getPassword()) { - password = *controller->getPassword(); - } - - if (controller->isImpromptu()) { - ChatListWindow::Chat chat = ChatListWindow::Chat(jid, jid.toString(), activity, unreadCount, type, boost::filesystem::path(), true, privateMessage, nick, password); - std::map<std::string, JID> participants = controller->getParticipantJIDs(); - chat.impromptuJIDs = participants; - return chat; - } - } - return ChatListWindow::Chat(jid, jid.toString(), activity, unreadCount, type, boost::filesystem::path(), true, privateMessage, nick, password); - } else { - ChatController* controller = getChatControllerIfExists(jid, false); - if (controller) { - unreadCount = controller->getUnreadCount(); - } - JID bareishJID = mucRegistry_->isMUC(jid.toBare()) ? jid : jid.toBare(); - Presence::ref presence = presenceOracle_->getAccountPresence(bareishJID); - StatusShow::Type type = presence ? presence->getShow() : StatusShow::None; - boost::filesystem::path avatarPath = avatarManager_ ? avatarManager_->getAvatarPath(bareishJID) : boost::filesystem::path(); - return ChatListWindow::Chat(bareishJID, nickResolver_->jidToNick(bareishJID), activity, unreadCount, type, avatarPath, false, privateMessage); - } + int unreadCount = 0; + if (mucRegistry_->isMUC(jid)) { + MUCController* controller = mucControllers_[jid.toBare()]; + StatusShow::Type type = StatusShow::None; + std::string nick = ""; + std::string password = ""; + if (controller) { + unreadCount = controller->getUnreadCount(); + if (controller->isJoined()) { + type = StatusShow::Online; + } + nick = controller->getNick(); + + if (controller->getPassword()) { + password = *controller->getPassword(); + } + + if (controller->isImpromptu()) { + ChatListWindow::Chat chat = ChatListWindow::Chat(jid, jid.toString(), activity, unreadCount, type, boost::filesystem::path(), true, privateMessage, nick, password); + std::map<std::string, JID> participants = controller->getParticipantJIDs(); + chat.impromptuJIDs = participants; + return chat; + } + } + return ChatListWindow::Chat(jid, jid.toString(), activity, unreadCount, type, boost::filesystem::path(), true, privateMessage, nick, password); + } else { + ChatController* controller = getChatControllerIfExists(jid, false); + if (controller) { + unreadCount = controller->getUnreadCount(); + } + JID bareishJID = mucRegistry_->isMUC(jid.toBare()) ? jid : jid.toBare(); + Presence::ref presence = presenceOracle_->getAccountPresence(bareishJID); + StatusShow::Type type = presence ? presence->getShow() : StatusShow::None; + boost::filesystem::path avatarPath = avatarManager_ ? avatarManager_->getAvatarPath(bareishJID) : boost::filesystem::path(); + return ChatListWindow::Chat(bareishJID, nickResolver_->jidToNick(bareishJID), activity, unreadCount, type, avatarPath, false, privateMessage); + } } void ChatsManager::handleChatActivity(const JID& jid, const std::string& activity, bool isMUC) { - const bool privateMessage = mucRegistry_->isMUC(jid.toBare()) && !isMUC; - ChatListWindow::Chat chat = createChatListChatItem(jid, activity, privateMessage); - /* FIXME: handle nick changes */ - appendRecent(chat); - handleUnreadCountChanged(NULL); - saveRecents(); + const bool privateMessage = mucRegistry_->isMUC(jid.toBare()) && !isMUC; + ChatListWindow::Chat chat = createChatListChatItem(jid, activity, privateMessage); + /* FIXME: handle nick changes */ + appendRecent(chat); + handleUnreadCountChanged(NULL); + saveRecents(); } void ChatsManager::handleChatClosed(const JID& /*jid*/) { - cleanupPrivateMessageRecents(); - chatListWindow_->setRecents(recentChats_); + cleanupPrivateMessageRecents(); + chatListWindow_->setRecents(recentChats_); } void ChatsManager::handleUnreadCountChanged(ChatControllerBase* controller) { - int unreadTotal = 0; - bool controllerIsMUC = dynamic_cast<MUCController*>(controller); - bool isPM = controller && !controllerIsMUC && mucRegistry_->isMUC(controller->getToJID().toBare()); - foreach (ChatListWindow::Chat& chatItem, recentChats_) { - bool match = false; - if (controller) { - /* Matching MUC item */ - match |= chatItem.isMUC == controllerIsMUC && chatItem.jid.toBare() == controller->getToJID().toBare(); - /* Matching PM */ - match |= isPM && chatItem.jid == controller->getToJID(); - /* Matching non-PM */ - match |= !isPM && !controllerIsMUC && chatItem.jid.toBare() == controller->getToJID().toBare(); - } - if (match) { - chatItem.setUnreadCount(controller->getUnreadCount()); - } - unreadTotal += chatItem.unreadCount; - } - chatListWindow_->setRecents(recentChats_); - chatListWindow_->setUnreadCount(unreadTotal); + int unreadTotal = 0; + bool controllerIsMUC = dynamic_cast<MUCController*>(controller); + bool isPM = controller && !controllerIsMUC && mucRegistry_->isMUC(controller->getToJID().toBare()); + foreach (ChatListWindow::Chat& chatItem, recentChats_) { + bool match = false; + if (controller) { + /* Matching MUC item */ + match |= chatItem.isMUC == controllerIsMUC && chatItem.jid.toBare() == controller->getToJID().toBare(); + /* Matching PM */ + match |= isPM && chatItem.jid == controller->getToJID(); + /* Matching non-PM */ + match |= !isPM && !controllerIsMUC && chatItem.jid.toBare() == controller->getToJID().toBare(); + } + if (match) { + chatItem.setUnreadCount(controller->getUnreadCount()); + } + unreadTotal += chatItem.unreadCount; + } + chatListWindow_->setRecents(recentChats_); + chatListWindow_->setUnreadCount(unreadTotal); } boost::optional<ChatListWindow::Chat> ChatsManager::removeExistingChat(const ChatListWindow::Chat& chat) { - std::list<ChatListWindow::Chat>::iterator result = std::find(recentChats_.begin(), recentChats_.end(), chat); - if (result != recentChats_.end()) { - ChatListWindow::Chat existingChat = *result; - recentChats_.erase(std::remove(recentChats_.begin(), recentChats_.end(), chat), recentChats_.end()); - return boost::optional<ChatListWindow::Chat>(existingChat); - } else { - return boost::optional<ChatListWindow::Chat>(); - } + std::list<ChatListWindow::Chat>::iterator result = std::find(recentChats_.begin(), recentChats_.end(), chat); + if (result != recentChats_.end()) { + ChatListWindow::Chat existingChat = *result; + recentChats_.erase(std::remove(recentChats_.begin(), recentChats_.end(), chat), recentChats_.end()); + return boost::optional<ChatListWindow::Chat>(existingChat); + } else { + return boost::optional<ChatListWindow::Chat>(); + } } void ChatsManager::cleanupPrivateMessageRecents() { - /* if we leave a MUC and close a PM, remove it's recent chat entry */ - const std::list<ChatListWindow::Chat> chats = recentChats_; - foreach (const ChatListWindow::Chat& chat, chats) { - if (chat.isPrivateMessage) { - typedef std::map<JID, MUCController*> ControllerMap; - ControllerMap::iterator muc = mucControllers_.find(chat.jid.toBare()); - if (muc == mucControllers_.end() || !muc->second->isJoined()) { - ChatController* chatController = getChatControllerIfExists(chat.jid); - if (!chatController || !chatController->hasOpenWindow()) { - removeExistingChat(chat); - break; - } - } - } - } + /* if we leave a MUC and close a PM, remove it's recent chat entry */ + const std::list<ChatListWindow::Chat> chats = recentChats_; + foreach (const ChatListWindow::Chat& chat, chats) { + if (chat.isPrivateMessage) { + typedef std::map<JID, MUCController*> ControllerMap; + ControllerMap::iterator muc = mucControllers_.find(chat.jid.toBare()); + if (muc == mucControllers_.end() || !muc->second->isJoined()) { + ChatController* chatController = getChatControllerIfExists(chat.jid); + if (!chatController || !chatController->hasOpenWindow()) { + removeExistingChat(chat); + break; + } + } + } + } } void ChatsManager::appendRecent(const ChatListWindow::Chat& chat) { - boost::optional<ChatListWindow::Chat> oldChat = removeExistingChat(chat); - ChatListWindow::Chat mergedChat = chat; - if (oldChat && !oldChat->impromptuJIDs.empty()) { - mergedChat.impromptuJIDs.insert(oldChat->impromptuJIDs.begin(), oldChat->impromptuJIDs.end()); - } - recentChats_.push_front(mergedChat); + boost::optional<ChatListWindow::Chat> oldChat = removeExistingChat(chat); + ChatListWindow::Chat mergedChat = chat; + if (oldChat && !oldChat->impromptuJIDs.empty()) { + mergedChat.impromptuJIDs.insert(oldChat->impromptuJIDs.begin(), oldChat->impromptuJIDs.end()); + } + recentChats_.push_front(mergedChat); } void ChatsManager::prependRecent(const ChatListWindow::Chat& chat) { - boost::optional<ChatListWindow::Chat> oldChat = removeExistingChat(chat); - ChatListWindow::Chat mergedChat = chat; - if (oldChat && !oldChat->impromptuJIDs.empty()) { - mergedChat.impromptuJIDs.insert(oldChat->impromptuJIDs.begin(), oldChat->impromptuJIDs.end()); - } - recentChats_.push_back(mergedChat); + boost::optional<ChatListWindow::Chat> oldChat = removeExistingChat(chat); + ChatListWindow::Chat mergedChat = chat; + if (oldChat && !oldChat->impromptuJIDs.empty()) { + mergedChat.impromptuJIDs.insert(oldChat->impromptuJIDs.begin(), oldChat->impromptuJIDs.end()); + } + recentChats_.push_back(mergedChat); } void ChatsManager::handleUserLeftMUC(MUCController* mucController) { - std::map<JID, MUCController*>::iterator it; - for (it = mucControllers_.begin(); it != mucControllers_.end(); ++it) { - if ((*it).second == mucController) { - foreach (ChatListWindow::Chat& chat, recentChats_) { - if (chat.isMUC && chat.jid == (*it).first) { - chat.statusType = StatusShow::None; - } - } - mucControllers_.erase(it); - delete mucController; - break; - } - } - cleanupPrivateMessageRecents(); - chatListWindow_->setRecents(recentChats_); + std::map<JID, MUCController*>::iterator it; + for (it = mucControllers_.begin(); it != mucControllers_.end(); ++it) { + if ((*it).second == mucController) { + foreach (ChatListWindow::Chat& chat, recentChats_) { + if (chat.isMUC && chat.jid == (*it).first) { + chat.statusType = StatusShow::None; + } + } + mucControllers_.erase(it); + delete mucController; + break; + } + } + cleanupPrivateMessageRecents(); + chatListWindow_->setRecents(recentChats_); } void ChatsManager::handleSettingChanged(const std::string& settingPath) { - if (settingPath == SettingConstants::REQUEST_DELIVERYRECEIPTS.getKey()) { - userWantsReceipts_ = settings_->getSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS); - return; - } + if (settingPath == SettingConstants::REQUEST_DELIVERYRECEIPTS.getKey()) { + userWantsReceipts_ = settings_->getSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS); + return; + } } void ChatsManager::finalizeImpromptuJoin(MUC::ref muc, const std::vector<JID>& jidsToInvite, const std::string& reason, const boost::optional<JID>& reuseChatJID) { - // send impromptu invites for the new MUC - std::vector<JID> missingJIDsToInvite = jidsToInvite; - - typedef std::pair<std::string, MUCOccupant> StringMUCOccupantPair; - std::map<std::string, MUCOccupant> occupants = muc->getOccupants(); - foreach(StringMUCOccupantPair occupant, occupants) { - boost::optional<JID> realJID = occupant.second.getRealJID(); - if (realJID) { - missingJIDsToInvite.erase(std::remove(missingJIDsToInvite.begin(), missingJIDsToInvite.end(), realJID->toBare()), missingJIDsToInvite.end()); - } - } - - if (reuseChatJID) { - muc->invitePerson(reuseChatJID.get(), reason, true, true); - } - foreach(const JID& jid, missingJIDsToInvite) { - muc->invitePerson(jid, reason, true); - } + // send impromptu invites for the new MUC + std::vector<JID> missingJIDsToInvite = jidsToInvite; + + typedef std::pair<std::string, MUCOccupant> StringMUCOccupantPair; + std::map<std::string, MUCOccupant> occupants = muc->getOccupants(); + foreach(StringMUCOccupantPair occupant, occupants) { + boost::optional<JID> realJID = occupant.second.getRealJID(); + if (realJID) { + missingJIDsToInvite.erase(std::remove(missingJIDsToInvite.begin(), missingJIDsToInvite.end(), realJID->toBare()), missingJIDsToInvite.end()); + } + } + + if (reuseChatJID) { + muc->invitePerson(reuseChatJID.get(), reason, true, true); + } + foreach(const JID& jid, missingJIDsToInvite) { + muc->invitePerson(jid, reason, true); + } } void ChatsManager::handleUIEvent(boost::shared_ptr<UIEvent> event) { - boost::shared_ptr<RequestChatUIEvent> chatEvent = boost::dynamic_pointer_cast<RequestChatUIEvent>(event); - if (chatEvent) { - handleChatRequest(chatEvent->getContact()); - return; - } - boost::shared_ptr<RemoveMUCBookmarkUIEvent> removeMUCBookmarkEvent = boost::dynamic_pointer_cast<RemoveMUCBookmarkUIEvent>(event); - if (removeMUCBookmarkEvent) { - mucBookmarkManager_->removeBookmark(removeMUCBookmarkEvent->getBookmark()); - return; - } - boost::shared_ptr<AddMUCBookmarkUIEvent> addMUCBookmarkEvent = boost::dynamic_pointer_cast<AddMUCBookmarkUIEvent>(event); - if (addMUCBookmarkEvent) { - mucBookmarkManager_->addBookmark(addMUCBookmarkEvent->getBookmark()); - return; - } - - boost::shared_ptr<CreateImpromptuMUCUIEvent> createImpromptuMUCEvent = boost::dynamic_pointer_cast<CreateImpromptuMUCUIEvent>(event); - if (createImpromptuMUCEvent) { - assert(!localMUCServiceJID_.toString().empty()); - // create new muc - JID roomJID = createImpromptuMUCEvent->getRoomJID().toString().empty() ? JID(idGenerator_.generateID(), localMUCServiceJID_) : createImpromptuMUCEvent->getRoomJID(); - - // join muc - MUC::ref muc = handleJoinMUCRequest(roomJID, boost::optional<std::string>(), nickResolver_->jidToNick(jid_), false, true, true); - mucControllers_[roomJID]->onImpromptuConfigCompleted.connect(boost::bind(&ChatsManager::finalizeImpromptuJoin, this, muc, createImpromptuMUCEvent->getJIDs(), createImpromptuMUCEvent->getReason(), boost::optional<JID>())); - mucControllers_[roomJID]->activateChatWindow(); - } - - boost::shared_ptr<EditMUCBookmarkUIEvent> editMUCBookmarkEvent = boost::dynamic_pointer_cast<EditMUCBookmarkUIEvent>(event); - if (editMUCBookmarkEvent) { - mucBookmarkManager_->replaceBookmark(editMUCBookmarkEvent->getOldBookmark(), editMUCBookmarkEvent->getNewBookmark()); - } - else if (JoinMUCUIEvent::ref joinEvent = boost::dynamic_pointer_cast<JoinMUCUIEvent>(event)) { - handleJoinMUCRequest(joinEvent->getJID(), joinEvent->getPassword(), joinEvent->getNick(), joinEvent->getShouldJoinAutomatically(), joinEvent->getCreateAsReservedRoomIfNew(), joinEvent->isImpromptu()); - mucControllers_[joinEvent->getJID()]->activateChatWindow(); - } - else if (boost::shared_ptr<RequestJoinMUCUIEvent> joinEvent = boost::dynamic_pointer_cast<RequestJoinMUCUIEvent>(event)) { - if (!joinMUCWindow_) { - joinMUCWindow_ = joinMUCWindowFactory_->createJoinMUCWindow(uiEventStream_); - joinMUCWindow_->onSearchMUC.connect(boost::bind(&ChatsManager::handleSearchMUCRequest, this)); - } - joinMUCWindow_->setMUC(joinEvent->getRoom()); - joinMUCWindow_->setNick(nickResolver_->jidToNick(jid_)); - joinMUCWindow_->show(); - } + boost::shared_ptr<RequestChatUIEvent> chatEvent = boost::dynamic_pointer_cast<RequestChatUIEvent>(event); + if (chatEvent) { + handleChatRequest(chatEvent->getContact()); + return; + } + boost::shared_ptr<RemoveMUCBookmarkUIEvent> removeMUCBookmarkEvent = boost::dynamic_pointer_cast<RemoveMUCBookmarkUIEvent>(event); + if (removeMUCBookmarkEvent) { + mucBookmarkManager_->removeBookmark(removeMUCBookmarkEvent->getBookmark()); + return; + } + boost::shared_ptr<AddMUCBookmarkUIEvent> addMUCBookmarkEvent = boost::dynamic_pointer_cast<AddMUCBookmarkUIEvent>(event); + if (addMUCBookmarkEvent) { + mucBookmarkManager_->addBookmark(addMUCBookmarkEvent->getBookmark()); + return; + } + + boost::shared_ptr<CreateImpromptuMUCUIEvent> createImpromptuMUCEvent = boost::dynamic_pointer_cast<CreateImpromptuMUCUIEvent>(event); + if (createImpromptuMUCEvent) { + assert(!localMUCServiceJID_.toString().empty()); + // create new muc + JID roomJID = createImpromptuMUCEvent->getRoomJID().toString().empty() ? JID(idGenerator_.generateID(), localMUCServiceJID_) : createImpromptuMUCEvent->getRoomJID(); + + // join muc + MUC::ref muc = handleJoinMUCRequest(roomJID, boost::optional<std::string>(), nickResolver_->jidToNick(jid_), false, true, true); + mucControllers_[roomJID]->onImpromptuConfigCompleted.connect(boost::bind(&ChatsManager::finalizeImpromptuJoin, this, muc, createImpromptuMUCEvent->getJIDs(), createImpromptuMUCEvent->getReason(), boost::optional<JID>())); + mucControllers_[roomJID]->activateChatWindow(); + } + + boost::shared_ptr<EditMUCBookmarkUIEvent> editMUCBookmarkEvent = boost::dynamic_pointer_cast<EditMUCBookmarkUIEvent>(event); + if (editMUCBookmarkEvent) { + mucBookmarkManager_->replaceBookmark(editMUCBookmarkEvent->getOldBookmark(), editMUCBookmarkEvent->getNewBookmark()); + } + else if (JoinMUCUIEvent::ref joinEvent = boost::dynamic_pointer_cast<JoinMUCUIEvent>(event)) { + handleJoinMUCRequest(joinEvent->getJID(), joinEvent->getPassword(), joinEvent->getNick(), joinEvent->getShouldJoinAutomatically(), joinEvent->getCreateAsReservedRoomIfNew(), joinEvent->isImpromptu()); + mucControllers_[joinEvent->getJID()]->activateChatWindow(); + } + else if (boost::shared_ptr<RequestJoinMUCUIEvent> joinEvent = boost::dynamic_pointer_cast<RequestJoinMUCUIEvent>(event)) { + if (!joinMUCWindow_) { + joinMUCWindow_ = joinMUCWindowFactory_->createJoinMUCWindow(uiEventStream_); + joinMUCWindow_->onSearchMUC.connect(boost::bind(&ChatsManager::handleSearchMUCRequest, this)); + } + joinMUCWindow_->setMUC(joinEvent->getRoom()); + joinMUCWindow_->setNick(nickResolver_->jidToNick(jid_)); + joinMUCWindow_->show(); + } } void ChatsManager::markAllRecentsOffline() { - foreach (ChatListWindow::Chat& chat, recentChats_) { - chat.setStatusType(StatusShow::None); - } + foreach (ChatListWindow::Chat& chat, recentChats_) { + chat.setStatusType(StatusShow::None); + } - chatListWindow_->setRecents(recentChats_); + chatListWindow_->setRecents(recentChats_); } void ChatsManager::handleTransformChatToMUC(ChatController* chatController, ChatWindow* chatWindow, const std::vector<JID>& jidsToInvite, const std::string& reason) { - JID reuseChatInvite = chatController->getToJID(); - chatControllers_.erase(chatController->getToJID()); - delete chatController; + JID reuseChatInvite = chatController->getToJID(); + chatControllers_.erase(chatController->getToJID()); + delete chatController; - // join new impromptu muc - assert(!localMUCServiceJID_.toString().empty()); + // join new impromptu muc + assert(!localMUCServiceJID_.toString().empty()); - // create new muc - JID roomJID = JID(idGenerator_.generateID(), localMUCServiceJID_); + // create new muc + JID roomJID = JID(idGenerator_.generateID(), localMUCServiceJID_); - // join muc - MUC::ref muc = handleJoinMUCRequest(roomJID, boost::optional<std::string>(), nickResolver_->jidToNick(jid_), false, true, true, chatWindow); - mucControllers_[roomJID]->onImpromptuConfigCompleted.connect(boost::bind(&ChatsManager::finalizeImpromptuJoin, this, muc, jidsToInvite, reason, boost::optional<JID>(reuseChatInvite))); + // join muc + MUC::ref muc = handleJoinMUCRequest(roomJID, boost::optional<std::string>(), nickResolver_->jidToNick(jid_), false, true, true, chatWindow); + mucControllers_[roomJID]->onImpromptuConfigCompleted.connect(boost::bind(&ChatsManager::finalizeImpromptuJoin, this, muc, jidsToInvite, reason, boost::optional<JID>(reuseChatInvite))); } /** * If a resource goes offline, release bound chatdialog to that resource. */ void ChatsManager::handlePresenceChange(boost::shared_ptr<Presence> newPresence) { - if (mucRegistry_->isMUC(newPresence->getFrom().toBare())) return; - - foreach (ChatListWindow::Chat& chat, recentChats_) { - if (newPresence->getFrom().toBare() == chat.jid.toBare() && !chat.isMUC) { - Presence::ref presence = presenceOracle_->getHighestPriorityPresence(chat.jid.toBare()); - chat.setStatusType(presence ? presence->getShow() : StatusShow::None); - chatListWindow_->setRecents(recentChats_); - break; - } - } - - //if (newPresence->getType() != Presence::Unavailable) return; - JID fullJID(newPresence->getFrom()); - std::map<JID, ChatController*>::iterator it = chatControllers_.find(fullJID); - if (it == chatControllers_.end()) return; - JID bareJID(fullJID.toBare()); - //It doesn't make sense to have two unbound dialogs. - if (chatControllers_.find(bareJID) != chatControllers_.end()) return; - rebindControllerJID(fullJID, bareJID); + if (mucRegistry_->isMUC(newPresence->getFrom().toBare())) return; + + foreach (ChatListWindow::Chat& chat, recentChats_) { + if (newPresence->getFrom().toBare() == chat.jid.toBare() && !chat.isMUC) { + Presence::ref presence = presenceOracle_->getHighestPriorityPresence(chat.jid.toBare()); + chat.setStatusType(presence ? presence->getShow() : StatusShow::None); + chatListWindow_->setRecents(recentChats_); + break; + } + } + + //if (newPresence->getType() != Presence::Unavailable) return; + JID fullJID(newPresence->getFrom()); + std::map<JID, ChatController*>::iterator it = chatControllers_.find(fullJID); + if (it == chatControllers_.end()) return; + JID bareJID(fullJID.toBare()); + //It doesn't make sense to have two unbound dialogs. + if (chatControllers_.find(bareJID) != chatControllers_.end()) return; + rebindControllerJID(fullJID, bareJID); } void ChatsManager::setAvatarManager(AvatarManager* avatarManager) { - if (avatarManager_) { - avatarManager_->onAvatarChanged.disconnect(boost::bind(&ChatsManager::handleAvatarChanged, this, _1)); - } - avatarManager_ = avatarManager; - foreach (ChatListWindow::Chat& chat, recentChats_) { - if (!chat.isMUC) { - chat.setAvatarPath(avatarManager_->getAvatarPath(chat.jid)); - } - } - avatarManager_->onAvatarChanged.connect(boost::bind(&ChatsManager::handleAvatarChanged, this, _1)); + if (avatarManager_) { + avatarManager_->onAvatarChanged.disconnect(boost::bind(&ChatsManager::handleAvatarChanged, this, _1)); + } + avatarManager_ = avatarManager; + foreach (ChatListWindow::Chat& chat, recentChats_) { + if (!chat.isMUC) { + chat.setAvatarPath(avatarManager_->getAvatarPath(chat.jid)); + } + } + avatarManager_->onAvatarChanged.connect(boost::bind(&ChatsManager::handleAvatarChanged, this, _1)); } void ChatsManager::handleAvatarChanged(const JID& jid) { - foreach (ChatListWindow::Chat& chat, recentChats_) { - if (!chat.isMUC && jid.toBare() == chat.jid.toBare()) { - chat.setAvatarPath(avatarManager_->getAvatarPath(jid)); - break; - } - } + foreach (ChatListWindow::Chat& chat, recentChats_) { + if (!chat.isMUC && jid.toBare() == chat.jid.toBare()) { + chat.setAvatarPath(avatarManager_->getAvatarPath(jid)); + break; + } + } } void ChatsManager::setServerDiscoInfo(boost::shared_ptr<DiscoInfo> info) { - serverDiscoInfo_ = info; - foreach (JIDChatControllerPair pair, chatControllers_) { - pair.second->setAvailableServerFeatures(info); - } - foreach (JIDMUCControllerPair pair, mucControllers_) { - pair.second->setAvailableServerFeatures(info); - } + serverDiscoInfo_ = info; + foreach (JIDChatControllerPair pair, chatControllers_) { + pair.second->setAvailableServerFeatures(info); + } + foreach (JIDMUCControllerPair pair, mucControllers_) { + pair.second->setAvailableServerFeatures(info); + } } /** * This is to be called on connect/disconnect. - */ + */ void ChatsManager::setOnline(bool enabled) { - foreach (JIDChatControllerPair controllerPair, chatControllers_) { - controllerPair.second->setOnline(enabled); - } - foreach (JIDMUCControllerPair controllerPair, mucControllers_) { - controllerPair.second->setOnline(enabled); - if (enabled) { - controllerPair.second->rejoin(); - } - } - if (!enabled) { - markAllRecentsOffline(); - } else { - setupBookmarks(); - localMUCServiceJID_ = JID(); - localMUCServiceFinderWalker_ = boost::make_shared<DiscoServiceWalker>(jid_.getDomain(), iqRouter_); - localMUCServiceFinderWalker_->onServiceFound.connect(boost::bind(&ChatsManager::handleLocalServiceFound, this, _1, _2)); - localMUCServiceFinderWalker_->onWalkAborted.connect(boost::bind(&ChatsManager::handleLocalServiceWalkFinished, this)); - localMUCServiceFinderWalker_->onWalkComplete.connect(boost::bind(&ChatsManager::handleLocalServiceWalkFinished, this)); - localMUCServiceFinderWalker_->beginWalk(); - } - - if (chatListWindow_) { - chatListWindow_->setBookmarksEnabled(enabled); - } + foreach (JIDChatControllerPair controllerPair, chatControllers_) { + controllerPair.second->setOnline(enabled); + } + foreach (JIDMUCControllerPair controllerPair, mucControllers_) { + controllerPair.second->setOnline(enabled); + if (enabled) { + controllerPair.second->rejoin(); + } + } + if (!enabled) { + markAllRecentsOffline(); + } else { + setupBookmarks(); + localMUCServiceJID_ = JID(); + localMUCServiceFinderWalker_ = boost::make_shared<DiscoServiceWalker>(jid_.getDomain(), iqRouter_); + localMUCServiceFinderWalker_->onServiceFound.connect(boost::bind(&ChatsManager::handleLocalServiceFound, this, _1, _2)); + localMUCServiceFinderWalker_->onWalkAborted.connect(boost::bind(&ChatsManager::handleLocalServiceWalkFinished, this)); + localMUCServiceFinderWalker_->onWalkComplete.connect(boost::bind(&ChatsManager::handleLocalServiceWalkFinished, this)); + localMUCServiceFinderWalker_->beginWalk(); + } + + if (chatListWindow_) { + chatListWindow_->setBookmarksEnabled(enabled); + } } void ChatsManager::handleChatRequest(const std::string &contact) { - ChatController* controller = getChatControllerOrFindAnother(JID(contact)); - controller->activateChatWindow(); + ChatController* controller = getChatControllerOrFindAnother(JID(contact)); + controller->activateChatWindow(); } ChatController* ChatsManager::getChatControllerOrFindAnother(const JID &contact) { - ChatController* controller = getChatControllerIfExists(contact); - if (!controller && !mucRegistry_->isMUC(contact.toBare())) { - foreach (JIDChatControllerPair pair, chatControllers_) { - if (pair.first.toBare() == contact.toBare()) { - controller = pair.second; - break; - } - } - } - return controller ? controller : createNewChatController(contact); + ChatController* controller = getChatControllerIfExists(contact); + if (!controller && !mucRegistry_->isMUC(contact.toBare())) { + foreach (JIDChatControllerPair pair, chatControllers_) { + if (pair.first.toBare() == contact.toBare()) { + controller = pair.second; + break; + } + } + } + return controller ? controller : createNewChatController(contact); } ChatController* ChatsManager::createNewChatController(const JID& contact) { - assert(chatControllers_.find(contact) == chatControllers_.end()); - boost::shared_ptr<ChatMessageParser> chatMessageParser = boost::make_shared<ChatMessageParser>(emoticons_, highlightManager_->getRules(), false); /* a message parser that knows this is a chat (not a room/MUC) */ - ChatController* controller = new ChatController(jid_, stanzaChannel_, iqRouter_, chatWindowFactory_, contact, nickResolver_, presenceOracle_, avatarManager_, mucRegistry_->isMUC(contact.toBare()), useDelayForLatency_, uiEventStream_, eventController_, timerFactory_, entityCapsProvider_, userWantsReceipts_, settings_, historyController_, mucRegistry_, highlightManager_, clientBlockListManager_, chatMessageParser, autoAcceptMUCInviteDecider_); - chatControllers_[contact] = controller; - controller->setAvailableServerFeatures(serverDiscoInfo_); - controller->onActivity.connect(boost::bind(&ChatsManager::handleChatActivity, this, contact, _1, false)); - controller->onWindowClosed.connect(boost::bind(&ChatsManager::handleChatClosed, this, contact)); - controller->onUnreadCountChanged.connect(boost::bind(&ChatsManager::handleUnreadCountChanged, this, controller)); - controller->onConvertToMUC.connect(boost::bind(&ChatsManager::handleTransformChatToMUC, this, controller, _1, _2, _3)); - updatePresenceReceivingStateOnChatController(contact); - controller->setCanStartImpromptuChats(!localMUCServiceJID_.toString().empty()); - return controller; + assert(chatControllers_.find(contact) == chatControllers_.end()); + boost::shared_ptr<ChatMessageParser> chatMessageParser = boost::make_shared<ChatMessageParser>(emoticons_, highlightManager_->getRules(), false); /* a message parser that knows this is a chat (not a room/MUC) */ + ChatController* controller = new ChatController(jid_, stanzaChannel_, iqRouter_, chatWindowFactory_, contact, nickResolver_, presenceOracle_, avatarManager_, mucRegistry_->isMUC(contact.toBare()), useDelayForLatency_, uiEventStream_, eventController_, timerFactory_, entityCapsProvider_, userWantsReceipts_, settings_, historyController_, mucRegistry_, highlightManager_, clientBlockListManager_, chatMessageParser, autoAcceptMUCInviteDecider_); + chatControllers_[contact] = controller; + controller->setAvailableServerFeatures(serverDiscoInfo_); + controller->onActivity.connect(boost::bind(&ChatsManager::handleChatActivity, this, contact, _1, false)); + controller->onWindowClosed.connect(boost::bind(&ChatsManager::handleChatClosed, this, contact)); + controller->onUnreadCountChanged.connect(boost::bind(&ChatsManager::handleUnreadCountChanged, this, controller)); + controller->onConvertToMUC.connect(boost::bind(&ChatsManager::handleTransformChatToMUC, this, controller, _1, _2, _3)); + updatePresenceReceivingStateOnChatController(contact); + controller->setCanStartImpromptuChats(!localMUCServiceJID_.toString().empty()); + return controller; } ChatController* ChatsManager::getChatControllerOrCreate(const JID &contact) { - ChatController* controller = getChatControllerIfExists(contact); - return controller ? controller : createNewChatController(contact); + ChatController* controller = getChatControllerIfExists(contact); + return controller ? controller : createNewChatController(contact); } ChatController* ChatsManager::getChatControllerIfExists(const JID &contact, bool rebindIfNeeded) { - if (chatControllers_.find(contact) == chatControllers_.end()) { - if (mucRegistry_->isMUC(contact.toBare())) { - return NULL; - } - //Need to look for an unbound window to bind first - JID bare(contact.toBare()); - if (chatControllers_.find(bare) != chatControllers_.end()) { - if (rebindIfNeeded) { - rebindControllerJID(bare, contact); - } - else { - return chatControllers_[bare]; - } - } else { - foreach (JIDChatControllerPair pair, chatControllers_) { - if (pair.first.toBare() == contact.toBare()) { - if (rebindIfNeeded) { - rebindControllerJID(pair.first, contact); - return chatControllers_[contact]; - } else { - return pair.second; - } - } - } - return NULL; - } - } - return chatControllers_[contact]; + if (chatControllers_.find(contact) == chatControllers_.end()) { + if (mucRegistry_->isMUC(contact.toBare())) { + return NULL; + } + //Need to look for an unbound window to bind first + JID bare(contact.toBare()); + if (chatControllers_.find(bare) != chatControllers_.end()) { + if (rebindIfNeeded) { + rebindControllerJID(bare, contact); + } + else { + return chatControllers_[bare]; + } + } else { + foreach (JIDChatControllerPair pair, chatControllers_) { + if (pair.first.toBare() == contact.toBare()) { + if (rebindIfNeeded) { + rebindControllerJID(pair.first, contact); + return chatControllers_[contact]; + } else { + return pair.second; + } + } + } + return NULL; + } + } + return chatControllers_[contact]; } void ChatsManager::rebindControllerJID(const JID& from, const JID& to) { - chatControllers_[to] = chatControllers_[from]; - chatControllers_.erase(from); - chatControllers_[to]->setToJID(to); + chatControllers_[to] = chatControllers_[from]; + chatControllers_.erase(from); + chatControllers_[to]->setToJID(to); } MUC::ref ChatsManager::handleJoinMUCRequest(const JID &mucJID, const boost::optional<std::string>& password, const boost::optional<std::string>& nickMaybe, bool addAutoJoin, bool createAsReservedIfNew, bool isImpromptu, ChatWindow* reuseChatwindow) { - MUC::ref muc; - if (addAutoJoin) { - MUCBookmark bookmark(mucJID, mucJID.getNode()); - bookmark.setAutojoin(true); - if (nickMaybe) { - bookmark.setNick(*nickMaybe); - } - if (password) { - bookmark.setPassword(*password); - } - mucBookmarkManager_->addBookmark(bookmark); - } - - std::map<JID, MUCController*>::iterator it = mucControllers_.find(mucJID); - if (it != mucControllers_.end()) { - if (stanzaChannel_->isAvailable()) { - it->second->rejoin(); - } - } else { - std::string nick = (nickMaybe && !(*nickMaybe).empty()) ? nickMaybe.get() : nickResolver_->jidToNick(jid_); - muc = mucManager->createMUC(mucJID); - if (createAsReservedIfNew) { - muc->setCreateAsReservedIfNew(); - } - if (isImpromptu) { - muc->setCreateAsReservedIfNew(); - } - - MUCController* controller = NULL; - SingleChatWindowFactoryAdapter* chatWindowFactoryAdapter = NULL; - if (reuseChatwindow) { - chatWindowFactoryAdapter = new SingleChatWindowFactoryAdapter(reuseChatwindow); - } - boost::shared_ptr<ChatMessageParser> chatMessageParser = boost::make_shared<ChatMessageParser>(emoticons_, highlightManager_->getRules(), true); /* a message parser that knows this is a room/MUC (not a chat) */ - controller = new MUCController(jid_, muc, password, nick, stanzaChannel_, iqRouter_, reuseChatwindow ? chatWindowFactoryAdapter : chatWindowFactory_, presenceOracle_, avatarManager_, uiEventStream_, false, timerFactory_, eventController_, entityCapsProvider_, roster_, historyController_, mucRegistry_, highlightManager_, clientBlockListManager_, chatMessageParser, isImpromptu, autoAcceptMUCInviteDecider_, vcardManager_, mucBookmarkManager_); - if (chatWindowFactoryAdapter) { - /* The adapters are only passed to chat windows, which are deleted in their - * controllers' dtor, which are deleted in ChatManager's dtor. The adapters - * are also deleted there.*/ - chatWindowFactoryAdapters_[controller] = chatWindowFactoryAdapter; - } - - mucControllers_[mucJID] = controller; - controller->setAvailableServerFeatures(serverDiscoInfo_); - controller->onUserLeft.connect(boost::bind(&ChatsManager::handleUserLeftMUC, this, controller)); - controller->onUserJoined.connect(boost::bind(&ChatsManager::handleChatActivity, this, mucJID.toBare(), "", true)); - controller->onUserNicknameChanged.connect(boost::bind(&ChatsManager::handleUserNicknameChanged, this, controller, _1, _2)); - controller->onActivity.connect(boost::bind(&ChatsManager::handleChatActivity, this, mucJID.toBare(), _1, true)); - controller->onUnreadCountChanged.connect(boost::bind(&ChatsManager::handleUnreadCountChanged, this, controller)); - if (!stanzaChannel_->isAvailable()) { - /* When online, the MUC is added to the registry in MUCImpl::internalJoin. This method is not - * called when Swift is offline, so we add it here as only MUCs in the registry are rejoined - * when going back online. - */ - mucRegistry_->addMUC(mucJID.toBare()); - } - handleChatActivity(mucJID.toBare(), "", true); - } - - mucControllers_[mucJID]->showChatWindow(); - return muc; + MUC::ref muc; + if (addAutoJoin) { + MUCBookmark bookmark(mucJID, mucJID.getNode()); + bookmark.setAutojoin(true); + if (nickMaybe) { + bookmark.setNick(*nickMaybe); + } + if (password) { + bookmark.setPassword(*password); + } + mucBookmarkManager_->addBookmark(bookmark); + } + + std::map<JID, MUCController*>::iterator it = mucControllers_.find(mucJID); + if (it != mucControllers_.end()) { + if (stanzaChannel_->isAvailable()) { + it->second->rejoin(); + } + } else { + std::string nick = (nickMaybe && !(*nickMaybe).empty()) ? nickMaybe.get() : nickResolver_->jidToNick(jid_); + muc = mucManager->createMUC(mucJID); + if (createAsReservedIfNew) { + muc->setCreateAsReservedIfNew(); + } + if (isImpromptu) { + muc->setCreateAsReservedIfNew(); + } + + MUCController* controller = NULL; + SingleChatWindowFactoryAdapter* chatWindowFactoryAdapter = NULL; + if (reuseChatwindow) { + chatWindowFactoryAdapter = new SingleChatWindowFactoryAdapter(reuseChatwindow); + } + boost::shared_ptr<ChatMessageParser> chatMessageParser = boost::make_shared<ChatMessageParser>(emoticons_, highlightManager_->getRules(), true); /* a message parser that knows this is a room/MUC (not a chat) */ + controller = new MUCController(jid_, muc, password, nick, stanzaChannel_, iqRouter_, reuseChatwindow ? chatWindowFactoryAdapter : chatWindowFactory_, presenceOracle_, avatarManager_, uiEventStream_, false, timerFactory_, eventController_, entityCapsProvider_, roster_, historyController_, mucRegistry_, highlightManager_, clientBlockListManager_, chatMessageParser, isImpromptu, autoAcceptMUCInviteDecider_, vcardManager_, mucBookmarkManager_); + if (chatWindowFactoryAdapter) { + /* The adapters are only passed to chat windows, which are deleted in their + * controllers' dtor, which are deleted in ChatManager's dtor. The adapters + * are also deleted there.*/ + chatWindowFactoryAdapters_[controller] = chatWindowFactoryAdapter; + } + + mucControllers_[mucJID] = controller; + controller->setAvailableServerFeatures(serverDiscoInfo_); + controller->onUserLeft.connect(boost::bind(&ChatsManager::handleUserLeftMUC, this, controller)); + controller->onUserJoined.connect(boost::bind(&ChatsManager::handleChatActivity, this, mucJID.toBare(), "", true)); + controller->onUserNicknameChanged.connect(boost::bind(&ChatsManager::handleUserNicknameChanged, this, controller, _1, _2)); + controller->onActivity.connect(boost::bind(&ChatsManager::handleChatActivity, this, mucJID.toBare(), _1, true)); + controller->onUnreadCountChanged.connect(boost::bind(&ChatsManager::handleUnreadCountChanged, this, controller)); + if (!stanzaChannel_->isAvailable()) { + /* When online, the MUC is added to the registry in MUCImpl::internalJoin. This method is not + * called when Swift is offline, so we add it here as only MUCs in the registry are rejoined + * when going back online. + */ + mucRegistry_->addMUC(mucJID.toBare()); + } + handleChatActivity(mucJID.toBare(), "", true); + } + + mucControllers_[mucJID]->showChatWindow(); + return muc; } void ChatsManager::handleSearchMUCRequest() { - mucSearchController_->openSearchWindow(); + mucSearchController_->openSearchWindow(); } void ChatsManager::handleUserNicknameChanged(MUCController* mucController, const std::string& oldNickname, const std::string& newNickname) { - JID oldMUCChatJID = mucController->getToJID().withResource(oldNickname); - JID newMUCChatJID = mucController->getToJID().withResource(newNickname); - - SWIFT_LOG(debug) << "nickname change in " << mucController->getToJID().toString() << " from " << oldNickname << " to " << newNickname << std::endl; - - // get current chat controller - ChatController *chatController = getChatControllerIfExists(oldMUCChatJID); - if (chatController) { - // adjust chat controller - chatController->setToJID(newMUCChatJID); - nickResolver_->onNickChanged(newMUCChatJID, oldNickname); - chatControllers_.erase(oldMUCChatJID); - chatControllers_[newMUCChatJID] = chatController; - - chatController->onActivity.disconnect(boost::bind(&ChatsManager::handleChatActivity, this, oldMUCChatJID, _1, false)); - chatController->onActivity.connect(boost::bind(&ChatsManager::handleChatActivity, this, newMUCChatJID, _1, false)); - } + JID oldMUCChatJID = mucController->getToJID().withResource(oldNickname); + JID newMUCChatJID = mucController->getToJID().withResource(newNickname); + + SWIFT_LOG(debug) << "nickname change in " << mucController->getToJID().toString() << " from " << oldNickname << " to " << newNickname << std::endl; + + // get current chat controller + ChatController *chatController = getChatControllerIfExists(oldMUCChatJID); + if (chatController) { + // adjust chat controller + chatController->setToJID(newMUCChatJID); + nickResolver_->onNickChanged(newMUCChatJID, oldNickname); + chatControllers_.erase(oldMUCChatJID); + chatControllers_[newMUCChatJID] = chatController; + + chatController->onActivity.disconnect(boost::bind(&ChatsManager::handleChatActivity, this, oldMUCChatJID, _1, false)); + chatController->onActivity.connect(boost::bind(&ChatsManager::handleChatActivity, this, newMUCChatJID, _1, false)); + } } void ChatsManager::handleIncomingMessage(boost::shared_ptr<Message> message) { - JID jid = message->getFrom(); - boost::shared_ptr<MessageEvent> event(new MessageEvent(message)); - bool isInvite = !!message->getPayload<MUCInvitationPayload>(); - bool isMediatedInvite = (message->getPayload<MUCUserPayload>() && message->getPayload<MUCUserPayload>()->getInvite()); - if (isMediatedInvite) { - jid = (*message->getPayload<MUCUserPayload>()->getInvite()).from; - } - if (!event->isReadable() && !message->getPayload<ChatState>() && !message->getPayload<DeliveryReceipt>() && !message->getPayload<DeliveryReceiptRequest>() && !isInvite && !isMediatedInvite && !message->hasSubject()) { - return; - } - - // Try to deliver it to a MUC - if (message->getType() == Message::Groupchat || message->getType() == Message::Error /*|| (isInvite && message->getType() == Message::Normal)*/) { - std::map<JID, MUCController*>::iterator i = mucControllers_.find(jid.toBare()); - if (i != mucControllers_.end()) { - i->second->handleIncomingMessage(event); - return; - } - else if (message->getType() == Message::Groupchat) { - //FIXME: Error handling - groupchat messages from an unknown muc. - return; - } - } - - // check for impromptu invite to potentially auto-accept - MUCInvitationPayload::ref invite = message->getPayload<MUCInvitationPayload>(); - if (invite && autoAcceptMUCInviteDecider_->isAutoAcceptedInvite(message->getFrom(), invite)) { - if (invite->getIsContinuation()) { - // check for existing chat controller for the from JID - ChatController* controller = getChatControllerIfExists(jid); - if (controller) { - ChatWindow* window = controller->detachChatWindow(); - chatControllers_.erase(jid); - delete controller; - handleJoinMUCRequest(invite->getJID(), boost::optional<std::string>(), boost::optional<std::string>(), false, false, true, window); - return; - } - } else { - handleJoinMUCRequest(invite->getJID(), boost::optional<std::string>(), boost::optional<std::string>(), false, false, true); - return; - } - } - - //if not a mucroom - if (!event->isReadable() && !isInvite && !isMediatedInvite) { - /* Only route such messages if a window exists, don't open new windows for them.*/ - - // Do not bind a controller to a full JID, for delivery receipts or chat state notifications. - bool bindControllerToJID = false; - ChatState::ref chatState = message->getPayload<ChatState>(); - if (!message->getBody().get_value_or("").empty() || (chatState && chatState->getChatState() == ChatState::Composing)) { - bindControllerToJID = true; - } - - ChatController* controller = getChatControllerIfExists(jid, bindControllerToJID); - if (controller) { - controller->handleIncomingMessage(event); - } - } else { - getChatControllerOrCreate(jid)->handleIncomingMessage(event); - } + JID jid = message->getFrom(); + boost::shared_ptr<MessageEvent> event(new MessageEvent(message)); + bool isInvite = !!message->getPayload<MUCInvitationPayload>(); + bool isMediatedInvite = (message->getPayload<MUCUserPayload>() && message->getPayload<MUCUserPayload>()->getInvite()); + if (isMediatedInvite) { + jid = (*message->getPayload<MUCUserPayload>()->getInvite()).from; + } + if (!event->isReadable() && !message->getPayload<ChatState>() && !message->getPayload<DeliveryReceipt>() && !message->getPayload<DeliveryReceiptRequest>() && !isInvite && !isMediatedInvite && !message->hasSubject()) { + return; + } + + // Try to deliver it to a MUC + if (message->getType() == Message::Groupchat || message->getType() == Message::Error /*|| (isInvite && message->getType() == Message::Normal)*/) { + std::map<JID, MUCController*>::iterator i = mucControllers_.find(jid.toBare()); + if (i != mucControllers_.end()) { + i->second->handleIncomingMessage(event); + return; + } + else if (message->getType() == Message::Groupchat) { + //FIXME: Error handling - groupchat messages from an unknown muc. + return; + } + } + + // check for impromptu invite to potentially auto-accept + MUCInvitationPayload::ref invite = message->getPayload<MUCInvitationPayload>(); + if (invite && autoAcceptMUCInviteDecider_->isAutoAcceptedInvite(message->getFrom(), invite)) { + if (invite->getIsContinuation()) { + // check for existing chat controller for the from JID + ChatController* controller = getChatControllerIfExists(jid); + if (controller) { + ChatWindow* window = controller->detachChatWindow(); + chatControllers_.erase(jid); + delete controller; + handleJoinMUCRequest(invite->getJID(), boost::optional<std::string>(), boost::optional<std::string>(), false, false, true, window); + return; + } + } else { + handleJoinMUCRequest(invite->getJID(), boost::optional<std::string>(), boost::optional<std::string>(), false, false, true); + return; + } + } + + //if not a mucroom + if (!event->isReadable() && !isInvite && !isMediatedInvite) { + /* Only route such messages if a window exists, don't open new windows for them.*/ + + // Do not bind a controller to a full JID, for delivery receipts or chat state notifications. + bool bindControllerToJID = false; + ChatState::ref chatState = message->getPayload<ChatState>(); + if (!message->getBody().get_value_or("").empty() || (chatState && chatState->getChatState() == ChatState::Composing)) { + bindControllerToJID = true; + } + + ChatController* controller = getChatControllerIfExists(jid, bindControllerToJID); + if (controller) { + controller->handleIncomingMessage(event); + } + } else { + getChatControllerOrCreate(jid)->handleIncomingMessage(event); + } } void ChatsManager::handleMUCSelectedAfterSearch(const JID& muc) { - if (joinMUCWindow_) { - joinMUCWindow_->setMUC(muc.toString()); - } + if (joinMUCWindow_) { + joinMUCWindow_->setMUC(muc.toString()); + } } void ChatsManager::handleMUCBookmarkActivated(const MUCBookmark& mucBookmark) { - uiEventStream_->send(boost::make_shared<JoinMUCUIEvent>(mucBookmark.getRoom(), mucBookmark.getPassword(), mucBookmark.getNick())); + uiEventStream_->send(boost::make_shared<JoinMUCUIEvent>(mucBookmark.getRoom(), mucBookmark.getPassword(), mucBookmark.getNick())); } void ChatsManager::handleNewFileTransferController(FileTransferController* ftc) { - ChatController* chatController = getChatControllerOrCreate(ftc->getOtherParty()); - chatController->handleNewFileTransferController(ftc); - chatController->activateChatWindow(); - if (ftc->isIncoming()) { - eventController_->handleIncomingEvent(boost::make_shared<IncomingFileTransferEvent>(ftc->getOtherParty())); - } + ChatController* chatController = getChatControllerOrCreate(ftc->getOtherParty()); + chatController->handleNewFileTransferController(ftc); + chatController->activateChatWindow(); + if (ftc->isIncoming()) { + eventController_->handleIncomingEvent(boost::make_shared<IncomingFileTransferEvent>(ftc->getOtherParty())); + } } void ChatsManager::handleWhiteboardSessionRequest(const JID& contact, bool senderIsSelf) { - ChatController* chatController = getChatControllerOrCreate(contact); - chatController->handleWhiteboardSessionRequest(senderIsSelf); - chatController->activateChatWindow(); + ChatController* chatController = getChatControllerOrCreate(contact); + chatController->handleWhiteboardSessionRequest(senderIsSelf); + chatController->activateChatWindow(); } void ChatsManager::handleWhiteboardStateChange(const JID& contact, const ChatWindow::WhiteboardSessionState state) { - ChatController* chatController = getChatControllerOrCreate(contact); - chatController->handleWhiteboardStateChange(state); - chatController->activateChatWindow(); - if (state == ChatWindow::WhiteboardAccepted) { - boost::filesystem::path path; - JID bareJID = contact.toBare(); - if (avatarManager_) { - path = avatarManager_->getAvatarPath(bareJID); - } - ChatListWindow::Chat chat(bareJID, nickResolver_->jidToNick(bareJID), "", 0, StatusShow::None, path, false); - chatListWindow_->addWhiteboardSession(chat); - } else { - chatListWindow_->removeWhiteboardSession(contact.toBare()); - } + ChatController* chatController = getChatControllerOrCreate(contact); + chatController->handleWhiteboardStateChange(state); + chatController->activateChatWindow(); + if (state == ChatWindow::WhiteboardAccepted) { + boost::filesystem::path path; + JID bareJID = contact.toBare(); + if (avatarManager_) { + path = avatarManager_->getAvatarPath(bareJID); + } + ChatListWindow::Chat chat(bareJID, nickResolver_->jidToNick(bareJID), "", 0, StatusShow::None, path, false); + chatListWindow_->addWhiteboardSession(chat); + } else { + chatListWindow_->removeWhiteboardSession(contact.toBare()); + } } void ChatsManager::handleRecentActivated(const ChatListWindow::Chat& chat) { - if (chat.isMUC && !chat.impromptuJIDs.empty()) { - typedef std::pair<std::string, JID> StringJIDPair; - std::vector<JID> inviteJIDs; - foreach(StringJIDPair pair, chat.impromptuJIDs) { - inviteJIDs.push_back(pair.second); - } - uiEventStream_->send(boost::make_shared<CreateImpromptuMUCUIEvent>(inviteJIDs, chat.jid, "")); - } - else if (chat.isMUC) { - /* FIXME: This means that recents requiring passwords will just flat-out not work */ - uiEventStream_->send(boost::make_shared<JoinMUCUIEvent>(chat.jid, boost::optional<std::string>(), chat.nick)); - } - else { - uiEventStream_->send(boost::make_shared<RequestChatUIEvent>(chat.jid)); - } + if (chat.isMUC && !chat.impromptuJIDs.empty()) { + typedef std::pair<std::string, JID> StringJIDPair; + std::vector<JID> inviteJIDs; + foreach(StringJIDPair pair, chat.impromptuJIDs) { + inviteJIDs.push_back(pair.second); + } + uiEventStream_->send(boost::make_shared<CreateImpromptuMUCUIEvent>(inviteJIDs, chat.jid, "")); + } + else if (chat.isMUC) { + /* FIXME: This means that recents requiring passwords will just flat-out not work */ + uiEventStream_->send(boost::make_shared<JoinMUCUIEvent>(chat.jid, boost::optional<std::string>(), chat.nick)); + } + else { + uiEventStream_->send(boost::make_shared<RequestChatUIEvent>(chat.jid)); + } } void ChatsManager::handleLocalServiceFound(const JID& service, boost::shared_ptr<DiscoInfo> info) { - foreach (DiscoInfo::Identity identity, info->getIdentities()) { - if ((identity.getCategory() == "directory" - && identity.getType() == "chatroom") - || (identity.getCategory() == "conference" - && identity.getType() == "text")) { - localMUCServiceJID_ = service; - localMUCServiceFinderWalker_->endWalk(); - SWIFT_LOG(debug) << "Use following MUC service for impromptu chats: " << localMUCServiceJID_ << std::endl; - break; - } - } + foreach (DiscoInfo::Identity identity, info->getIdentities()) { + if ((identity.getCategory() == "directory" + && identity.getType() == "chatroom") + || (identity.getCategory() == "conference" + && identity.getType() == "text")) { + localMUCServiceJID_ = service; + localMUCServiceFinderWalker_->endWalk(); + SWIFT_LOG(debug) << "Use following MUC service for impromptu chats: " << localMUCServiceJID_ << std::endl; + break; + } + } } void ChatsManager::handleLocalServiceWalkFinished() { - bool impromptuMUCSupported = !localMUCServiceJID_.toString().empty(); - foreach (JIDChatControllerPair controllerPair, chatControllers_) { - controllerPair.second->setCanStartImpromptuChats(impromptuMUCSupported); - } - foreach (JIDMUCControllerPair controllerPair, mucControllers_) { - controllerPair.second->setCanStartImpromptuChats(impromptuMUCSupported); - } - onImpromptuMUCServiceDiscovered(impromptuMUCSupported); + bool impromptuMUCSupported = !localMUCServiceJID_.toString().empty(); + foreach (JIDChatControllerPair controllerPair, chatControllers_) { + controllerPair.second->setCanStartImpromptuChats(impromptuMUCSupported); + } + foreach (JIDMUCControllerPair controllerPair, mucControllers_) { + controllerPair.second->setCanStartImpromptuChats(impromptuMUCSupported); + } + onImpromptuMUCServiceDiscovered(impromptuMUCSupported); } std::vector<ChatListWindow::Chat> ChatsManager::getRecentChats() const { - return std::vector<ChatListWindow::Chat>(recentChats_.begin(), recentChats_.end()); + return std::vector<ChatListWindow::Chat>(recentChats_.begin(), recentChats_.end()); } std::vector<Contact::ref> Swift::ChatsManager::getContacts(bool withMUCNicks) { - std::vector<Contact::ref> result; - foreach (ChatListWindow::Chat chat, recentChats_) { - if (!chat.isMUC) { - result.push_back(boost::make_shared<Contact>(chat.chatName.empty() ? chat.jid.toString() : chat.chatName, chat.jid, chat.statusType, chat.avatarPath)); - } - } - if (withMUCNicks) { - /* collect MUC nicks */ - typedef std::map<JID, MUCController*>::value_type Item; - foreach (const Item& item, mucControllers_) { - JID mucJID = item.second->getToJID(); - std::map<std::string, JID> participants = item.second->getParticipantJIDs(); - typedef std::map<std::string, JID>::value_type ParticipantType; - foreach (const ParticipantType& participant, participants) { - const JID nickJID = JID(mucJID.getNode(), mucJID.getDomain(), participant.first); - Presence::ref presence = presenceOracle_->getLastPresence(nickJID); - const boost::filesystem::path avatar = avatarManager_->getAvatarPath(nickJID); - result.push_back(boost::make_shared<Contact>(participant.first, JID(), presence->getShow(), avatar)); - } - } - } - return result; + std::vector<Contact::ref> result; + foreach (ChatListWindow::Chat chat, recentChats_) { + if (!chat.isMUC) { + result.push_back(boost::make_shared<Contact>(chat.chatName.empty() ? chat.jid.toString() : chat.chatName, chat.jid, chat.statusType, chat.avatarPath)); + } + } + if (withMUCNicks) { + /* collect MUC nicks */ + typedef std::map<JID, MUCController*>::value_type Item; + foreach (const Item& item, mucControllers_) { + JID mucJID = item.second->getToJID(); + std::map<std::string, JID> participants = item.second->getParticipantJIDs(); + typedef std::map<std::string, JID>::value_type ParticipantType; + foreach (const ParticipantType& participant, participants) { + const JID nickJID = JID(mucJID.getNode(), mucJID.getDomain(), participant.first); + Presence::ref presence = presenceOracle_->getLastPresence(nickJID); + const boost::filesystem::path avatar = avatarManager_->getAvatarPath(nickJID); + result.push_back(boost::make_shared<Contact>(participant.first, JID(), presence->getShow(), avatar)); + } + } + } + return result; } ChatsManager::SingleChatWindowFactoryAdapter::SingleChatWindowFactoryAdapter(ChatWindow* chatWindow) : chatWindow_(chatWindow) {} ChatsManager::SingleChatWindowFactoryAdapter::~SingleChatWindowFactoryAdapter() {} ChatWindow* ChatsManager::SingleChatWindowFactoryAdapter::createChatWindow(const JID &, UIEventStream*) { - return chatWindow_; + return chatWindow_; } } diff --git a/Swift/Controllers/Chat/ChatsManager.h b/Swift/Controllers/Chat/ChatsManager.h index 58a9017..7bba219 100644 --- a/Swift/Controllers/Chat/ChatsManager.h +++ b/Swift/Controllers/Chat/ChatsManager.h @@ -27,159 +27,159 @@ #include <Swift/Controllers/UIInterfaces/ChatWindowFactory.h> namespace Swift { - class EventController; - class ChatController; - class ChatControllerBase; - class MUCController; - class MUCManager; - class JoinMUCWindow; - class JoinMUCWindowFactory; - class NickResolver; - class PresenceOracle; - class AvatarManager; - class StanzaChannel; - class IQRouter; - class PresenceSender; - class MUCBookmarkManager; - class ChatListWindowFactory; - class TimerFactory; - class EntityCapsProvider; - class DirectedPresenceSender; - class MUCSearchWindowFactory; - class ProfileSettingsProvider; - class MUCSearchController; - class FileTransferOverview; - class FileTransferController; - class XMPPRoster; - class SettingsProvider; - class WhiteboardManager; - class HistoryController; - class HighlightManager; - class ClientBlockListManager; - class ChatMessageParser; - class DiscoServiceWalker; - class AutoAcceptMUCInviteDecider; - class VCardManager; - - class ChatsManager : public ContactProvider { - 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, HighlightManager* highlightManager, ClientBlockListManager* clientBlockListManager, const std::map<std::string, std::string>& emoticons, VCardManager* vcardManager); - virtual ~ChatsManager(); - void setAvatarManager(AvatarManager* avatarManager); - void setOnline(bool enabled); - void setServerDiscoInfo(boost::shared_ptr<DiscoInfo> info); - void handleIncomingMessage(boost::shared_ptr<Message> message); - std::vector<ChatListWindow::Chat> getRecentChats() const; - virtual std::vector<Contact::ref> getContacts(bool withMUCNicks); - - boost::signal<void (bool supportsImpromptu)> onImpromptuMUCServiceDiscovered; - - private: - class SingleChatWindowFactoryAdapter : public ChatWindowFactory { - public: - SingleChatWindowFactoryAdapter(ChatWindow* chatWindow); - virtual ~SingleChatWindowFactoryAdapter(); - virtual ChatWindow* createChatWindow(const JID &, UIEventStream*); - - private: - ChatWindow* chatWindow_; - }; - - private: - ChatListWindow::Chat createChatListChatItem(const JID& jid, const std::string& activity, bool privateMessage); - void handleChatRequest(const std::string& contact); - void finalizeImpromptuJoin(MUC::ref muc, const std::vector<JID>& jidsToInvite, const std::string& reason, const boost::optional<JID>& reuseChatJID = boost::optional<JID>()); - MUC::ref handleJoinMUCRequest(const JID& muc, const boost::optional<std::string>& password, const boost::optional<std::string>& nick, bool addAutoJoin, bool createAsReservedIfNew, bool isImpromptu, ChatWindow* reuseChatwindow = 0); - void handleSearchMUCRequest(); - void handleMUCSelectedAfterSearch(const JID&); - void rebindControllerJID(const JID& from, const JID& to); - void handlePresenceChange(boost::shared_ptr<Presence> newPresence); - void handleUIEvent(boost::shared_ptr<UIEvent> event); - void handleMUCBookmarkAdded(const MUCBookmark& bookmark); - void handleMUCBookmarkRemoved(const MUCBookmark& bookmark); - void handleUserLeftMUC(MUCController* mucController); - void handleUserNicknameChanged(MUCController* mucController, const std::string& oldNickname, const std::string& newNickname); - void handleBookmarksReady(); - void handleChatActivity(const JID& jid, const std::string& activity, bool isMUC); - void handleChatClosed(const JID& jid); - void handleNewFileTransferController(FileTransferController*); - void handleWhiteboardSessionRequest(const JID& contact, bool senderIsSelf); - void handleWhiteboardStateChange(const JID& contact, const ChatWindow::WhiteboardSessionState state); - boost::optional<ChatListWindow::Chat> removeExistingChat(const ChatListWindow::Chat& chat); - void cleanupPrivateMessageRecents(); - void appendRecent(const ChatListWindow::Chat& chat); - void prependRecent(const ChatListWindow::Chat& chat); - void setupBookmarks(); - void loadRecents(); - void saveRecents(); - void handleChatMadeRecent(); - void handleMUCBookmarkActivated(const MUCBookmark&); - void handleRecentActivated(const ChatListWindow::Chat&); - void handleUnreadCountChanged(ChatControllerBase* controller); - void handleAvatarChanged(const JID& jid); - void handleClearRecentsRequested(); - void handleJIDAddedToRoster(const JID&); - void handleJIDRemovedFromRoster(const JID&); - void handleJIDUpdatedInRoster(const JID&); - void handleRosterCleared(); - void handleSettingChanged(const std::string& settingPath); - void markAllRecentsOffline(); - void handleTransformChatToMUC(ChatController* chatController, ChatWindow* chatWindow, const std::vector<JID>& jidsToInvite, const std::string& reason); - - void handleLocalServiceFound(const JID& service, boost::shared_ptr<DiscoInfo> info); - void handleLocalServiceWalkFinished(); - - void updatePresenceReceivingStateOnChatController(const JID&); - ChatListWindow::Chat updateChatStatusAndAvatarHelper(const ChatListWindow::Chat& chat) const; - - - ChatController* getChatControllerOrFindAnother(const JID &contact); - ChatController* createNewChatController(const JID &contact); - ChatController* getChatControllerOrCreate(const JID &contact); - ChatController* getChatControllerIfExists(const JID &contact, bool rebindIfNeeded = true); - - private: - std::map<JID, MUCController*> mucControllers_; - std::map<JID, ChatController*> chatControllers_; - std::map<ChatControllerBase*, SingleChatWindowFactoryAdapter*> chatWindowFactoryAdapters_; - EventController* eventController_; - JID jid_; - StanzaChannel* stanzaChannel_; - IQRouter* iqRouter_; - ChatWindowFactory* chatWindowFactory_; - JoinMUCWindowFactory* joinMUCWindowFactory_; - NickResolver* nickResolver_; - PresenceOracle* presenceOracle_; - AvatarManager* avatarManager_; - PresenceSender* presenceSender_; - UIEventStream* uiEventStream_; - MUCBookmarkManager* mucBookmarkManager_; - boost::shared_ptr<DiscoInfo> serverDiscoInfo_; - ChatListWindow* chatListWindow_; - JoinMUCWindow* joinMUCWindow_; - boost::bsignals::scoped_connection uiEventConnection_; - bool useDelayForLatency_; - TimerFactory* timerFactory_; - MUCRegistry* mucRegistry_; - EntityCapsProvider* entityCapsProvider_; - MUCManager* mucManager; - MUCSearchController* mucSearchController_; - std::list<ChatListWindow::Chat> recentChats_; - ProfileSettingsProvider* profileSettings_; - FileTransferOverview* ftOverview_; - XMPPRoster* roster_; - bool eagleMode_; - bool userWantsReceipts_; - SettingsProvider* settings_; - HistoryController* historyController_; - WhiteboardManager* whiteboardManager_; - HighlightManager* highlightManager_; - std::map<std::string, std::string> emoticons_; - ClientBlockListManager* clientBlockListManager_; - JID localMUCServiceJID_; - boost::shared_ptr<DiscoServiceWalker> localMUCServiceFinderWalker_; - AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider_; - IDGenerator idGenerator_; - VCardManager* vcardManager_; - }; + class EventController; + class ChatController; + class ChatControllerBase; + class MUCController; + class MUCManager; + class JoinMUCWindow; + class JoinMUCWindowFactory; + class NickResolver; + class PresenceOracle; + class AvatarManager; + class StanzaChannel; + class IQRouter; + class PresenceSender; + class MUCBookmarkManager; + class ChatListWindowFactory; + class TimerFactory; + class EntityCapsProvider; + class DirectedPresenceSender; + class MUCSearchWindowFactory; + class ProfileSettingsProvider; + class MUCSearchController; + class FileTransferOverview; + class FileTransferController; + class XMPPRoster; + class SettingsProvider; + class WhiteboardManager; + class HistoryController; + class HighlightManager; + class ClientBlockListManager; + class ChatMessageParser; + class DiscoServiceWalker; + class AutoAcceptMUCInviteDecider; + class VCardManager; + + class ChatsManager : public ContactProvider { + 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, HighlightManager* highlightManager, ClientBlockListManager* clientBlockListManager, const std::map<std::string, std::string>& emoticons, VCardManager* vcardManager); + virtual ~ChatsManager(); + void setAvatarManager(AvatarManager* avatarManager); + void setOnline(bool enabled); + void setServerDiscoInfo(boost::shared_ptr<DiscoInfo> info); + void handleIncomingMessage(boost::shared_ptr<Message> message); + std::vector<ChatListWindow::Chat> getRecentChats() const; + virtual std::vector<Contact::ref> getContacts(bool withMUCNicks); + + boost::signal<void (bool supportsImpromptu)> onImpromptuMUCServiceDiscovered; + + private: + class SingleChatWindowFactoryAdapter : public ChatWindowFactory { + public: + SingleChatWindowFactoryAdapter(ChatWindow* chatWindow); + virtual ~SingleChatWindowFactoryAdapter(); + virtual ChatWindow* createChatWindow(const JID &, UIEventStream*); + + private: + ChatWindow* chatWindow_; + }; + + private: + ChatListWindow::Chat createChatListChatItem(const JID& jid, const std::string& activity, bool privateMessage); + void handleChatRequest(const std::string& contact); + void finalizeImpromptuJoin(MUC::ref muc, const std::vector<JID>& jidsToInvite, const std::string& reason, const boost::optional<JID>& reuseChatJID = boost::optional<JID>()); + MUC::ref handleJoinMUCRequest(const JID& muc, const boost::optional<std::string>& password, const boost::optional<std::string>& nick, bool addAutoJoin, bool createAsReservedIfNew, bool isImpromptu, ChatWindow* reuseChatwindow = 0); + void handleSearchMUCRequest(); + void handleMUCSelectedAfterSearch(const JID&); + void rebindControllerJID(const JID& from, const JID& to); + void handlePresenceChange(boost::shared_ptr<Presence> newPresence); + void handleUIEvent(boost::shared_ptr<UIEvent> event); + void handleMUCBookmarkAdded(const MUCBookmark& bookmark); + void handleMUCBookmarkRemoved(const MUCBookmark& bookmark); + void handleUserLeftMUC(MUCController* mucController); + void handleUserNicknameChanged(MUCController* mucController, const std::string& oldNickname, const std::string& newNickname); + void handleBookmarksReady(); + void handleChatActivity(const JID& jid, const std::string& activity, bool isMUC); + void handleChatClosed(const JID& jid); + void handleNewFileTransferController(FileTransferController*); + void handleWhiteboardSessionRequest(const JID& contact, bool senderIsSelf); + void handleWhiteboardStateChange(const JID& contact, const ChatWindow::WhiteboardSessionState state); + boost::optional<ChatListWindow::Chat> removeExistingChat(const ChatListWindow::Chat& chat); + void cleanupPrivateMessageRecents(); + void appendRecent(const ChatListWindow::Chat& chat); + void prependRecent(const ChatListWindow::Chat& chat); + void setupBookmarks(); + void loadRecents(); + void saveRecents(); + void handleChatMadeRecent(); + void handleMUCBookmarkActivated(const MUCBookmark&); + void handleRecentActivated(const ChatListWindow::Chat&); + void handleUnreadCountChanged(ChatControllerBase* controller); + void handleAvatarChanged(const JID& jid); + void handleClearRecentsRequested(); + void handleJIDAddedToRoster(const JID&); + void handleJIDRemovedFromRoster(const JID&); + void handleJIDUpdatedInRoster(const JID&); + void handleRosterCleared(); + void handleSettingChanged(const std::string& settingPath); + void markAllRecentsOffline(); + void handleTransformChatToMUC(ChatController* chatController, ChatWindow* chatWindow, const std::vector<JID>& jidsToInvite, const std::string& reason); + + void handleLocalServiceFound(const JID& service, boost::shared_ptr<DiscoInfo> info); + void handleLocalServiceWalkFinished(); + + void updatePresenceReceivingStateOnChatController(const JID&); + ChatListWindow::Chat updateChatStatusAndAvatarHelper(const ChatListWindow::Chat& chat) const; + + + ChatController* getChatControllerOrFindAnother(const JID &contact); + ChatController* createNewChatController(const JID &contact); + ChatController* getChatControllerOrCreate(const JID &contact); + ChatController* getChatControllerIfExists(const JID &contact, bool rebindIfNeeded = true); + + private: + std::map<JID, MUCController*> mucControllers_; + std::map<JID, ChatController*> chatControllers_; + std::map<ChatControllerBase*, SingleChatWindowFactoryAdapter*> chatWindowFactoryAdapters_; + EventController* eventController_; + JID jid_; + StanzaChannel* stanzaChannel_; + IQRouter* iqRouter_; + ChatWindowFactory* chatWindowFactory_; + JoinMUCWindowFactory* joinMUCWindowFactory_; + NickResolver* nickResolver_; + PresenceOracle* presenceOracle_; + AvatarManager* avatarManager_; + PresenceSender* presenceSender_; + UIEventStream* uiEventStream_; + MUCBookmarkManager* mucBookmarkManager_; + boost::shared_ptr<DiscoInfo> serverDiscoInfo_; + ChatListWindow* chatListWindow_; + JoinMUCWindow* joinMUCWindow_; + boost::bsignals::scoped_connection uiEventConnection_; + bool useDelayForLatency_; + TimerFactory* timerFactory_; + MUCRegistry* mucRegistry_; + EntityCapsProvider* entityCapsProvider_; + MUCManager* mucManager; + MUCSearchController* mucSearchController_; + std::list<ChatListWindow::Chat> recentChats_; + ProfileSettingsProvider* profileSettings_; + FileTransferOverview* ftOverview_; + XMPPRoster* roster_; + bool eagleMode_; + bool userWantsReceipts_; + SettingsProvider* settings_; + HistoryController* historyController_; + WhiteboardManager* whiteboardManager_; + HighlightManager* highlightManager_; + std::map<std::string, std::string> emoticons_; + ClientBlockListManager* clientBlockListManager_; + JID localMUCServiceJID_; + boost::shared_ptr<DiscoServiceWalker> localMUCServiceFinderWalker_; + AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider_; + IDGenerator idGenerator_; + VCardManager* vcardManager_; + }; } diff --git a/Swift/Controllers/Chat/MUCController.cpp b/Swift/Controllers/Chat/MUCController.cpp index 0bb670d..1e2b7ad 100644 --- a/Swift/Controllers/Chat/MUCController.cpp +++ b/Swift/Controllers/Chat/MUCController.cpp @@ -58,1163 +58,1163 @@ namespace Swift { class MUCBookmarkPredicate { - public: - MUCBookmarkPredicate(const JID& mucJID) : roomJID_(mucJID) { } - bool operator()(const MUCBookmark& operand) { - return operand.getRoom() == roomJID_; - } - - private: - JID roomJID_; + public: + MUCBookmarkPredicate(const JID& mucJID) : roomJID_(mucJID) { } + bool operator()(const MUCBookmark& operand) { + return operand.getRoom() == roomJID_; + } + + private: + JID roomJID_; }; /** * The controller does not gain ownership of the stanzaChannel, nor the factory. */ MUCController::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* uiEventStream, - bool useDelayForLatency, - TimerFactory* timerFactory, - EventController* eventController, - EntityCapsProvider* entityCapsProvider, - XMPPRoster* roster, - HistoryController* historyController, - MUCRegistry* mucRegistry, - HighlightManager* highlightManager, - ClientBlockListManager* clientBlockListManager, - boost::shared_ptr<ChatMessageParser> chatMessageParser, - bool isImpromptu, - AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider, - VCardManager* vcardManager, - MUCBookmarkManager* mucBookmarkManager) : - ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, muc->getJID(), presenceOracle, avatarManager, useDelayForLatency, uiEventStream, eventController, timerFactory, entityCapsProvider, historyController, mucRegistry, highlightManager, chatMessageParser, autoAcceptMUCInviteDecider), muc_(muc), nick_(nick), desiredNick_(nick), password_(password), renameCounter_(0), isImpromptu_(isImpromptu), isImpromptuAlreadyConfigured_(false), clientBlockListManager_(clientBlockListManager), mucBookmarkManager_(mucBookmarkManager) { - parting_ = true; - joined_ = false; - lastWasPresence_ = false; - shouldJoinOnReconnect_ = true; - doneGettingHistory_ = false; - events_ = uiEventStream; - xmppRoster_ = roster; - - roster_ = new Roster(false, true); - rosterVCardProvider_ = new RosterVCardProvider(roster_, vcardManager, JID::WithResource); - completer_ = new TabComplete(); - chatWindow_->setRosterModel(roster_); - chatWindow_->setTabComplete(completer_); - chatWindow_->onClosed.connect(boost::bind(&MUCController::handleWindowClosed, this)); - chatWindow_->onOccupantSelectionChanged.connect(boost::bind(&MUCController::handleWindowOccupantSelectionChanged, this, _1)); - chatWindow_->onOccupantActionSelected.connect(boost::bind(&MUCController::handleActionRequestedOnOccupant, this, _1, _2)); - chatWindow_->onChangeSubjectRequest.connect(boost::bind(&MUCController::handleChangeSubjectRequest, this, _1)); - chatWindow_->onBookmarkRequest.connect(boost::bind(&MUCController::handleBookmarkRequest, this)); - chatWindow_->onConfigureRequest.connect(boost::bind(&MUCController::handleConfigureRequest, this, _1)); - chatWindow_->onConfigurationFormCancelled.connect(boost::bind(&MUCController::handleConfigurationCancelled, this)); - chatWindow_->onDestroyRequest.connect(boost::bind(&MUCController::handleDestroyRoomRequest, this)); - chatWindow_->onInviteToChat.connect(boost::bind(&MUCController::handleInvitePersonToThisMUCRequest, this, _1)); - chatWindow_->onGetAffiliationsRequest.connect(boost::bind(&MUCController::handleGetAffiliationsRequest, this)); - chatWindow_->onChangeAffiliationsRequest.connect(boost::bind(&MUCController::handleChangeAffiliationsRequest, this, _1)); - chatWindow_->onUnblockUserRequest.connect(boost::bind(&MUCController::handleUnblockUserRequest, this)); - muc_->onJoinComplete.connect(boost::bind(&MUCController::handleJoinComplete, this, _1)); - muc_->onJoinFailed.connect(boost::bind(&MUCController::handleJoinFailed, this, _1)); - muc_->onOccupantJoined.connect(boost::bind(&MUCController::handleOccupantJoined, this, _1)); - muc_->onOccupantNicknameChanged.connect(boost::bind(&MUCController::handleOccupantNicknameChanged, this, _1, _2)); - muc_->onOccupantPresenceChange.connect(boost::bind(&MUCController::handleOccupantPresenceChange, this, _1)); - muc_->onOccupantLeft.connect(boost::bind(&MUCController::handleOccupantLeft, this, _1, _2, _3)); - muc_->onRoleChangeFailed.connect(boost::bind(&MUCController::handleOccupantRoleChangeFailed, this, _1, _2, _3)); - muc_->onAffiliationListReceived.connect(boost::bind(&MUCController::handleAffiliationListReceived, this, _1, _2)); - muc_->onConfigurationFailed.connect(boost::bind(&MUCController::handleConfigurationFailed, this, _1)); - muc_->onConfigurationFormReceived.connect(boost::bind(&MUCController::handleConfigurationFormReceived, this, _1)); - highlighter_->setMode(isImpromptu_ ? Highlighter::ChatMode : Highlighter::MUCMode); - highlighter_->setNick(nick_); - if (timerFactory && stanzaChannel_->isAvailable()) { - loginCheckTimer_ = boost::shared_ptr<Timer>(timerFactory->createTimer(MUC_JOIN_WARNING_TIMEOUT_MILLISECONDS)); - loginCheckTimer_->onTick.connect(boost::bind(&MUCController::handleJoinTimeoutTick, this)); - loginCheckTimer_->start(); - } - else { - chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(QT_TRANSLATE_NOOP("", "You are currently offline. You will enter this room when you are connected.")), ChatWindow::DefaultDirection); - } - if (isImpromptu) { - muc_->onUnlocked.connect(boost::bind(&MUCController::handleRoomUnlocked, this)); - chatWindow_->convertToMUC(ChatWindow::ImpromptuMUC); - } else { - muc_->onOccupantRoleChanged.connect(boost::bind(&MUCController::handleOccupantRoleChanged, this, _1, _2, _3)); - muc_->onOccupantAffiliationChanged.connect(boost::bind(&MUCController::handleOccupantAffiliationChanged, this, _1, _2, _3)); - chatWindow_->convertToMUC(ChatWindow::StandardMUC); - chatWindow_->setName(muc->getJID().getNode()); - } - if (stanzaChannel->isAvailable()) { - MUCController::setOnline(true); - } - if (avatarManager_ != NULL) { - avatarChangedConnection_ = (avatarManager_->onAvatarChanged.connect(boost::bind(&MUCController::handleAvatarChanged, this, _1))); - } - MUCController::handleBareJIDCapsChanged(muc->getJID()); - eventStream_->onUIEvent.connect(boost::bind(&MUCController::handleUIEvent, this, _1)); - - - // setup handling of MUC bookmark changes - mucBookmarkManagerBookmarkAddedConnection_ = (mucBookmarkManager_->onBookmarkAdded.connect(boost::bind(&MUCController::handleMUCBookmarkAdded, this, _1))); - mucBookmarkManagerBookmarkRemovedConnection_ = (mucBookmarkManager_->onBookmarkRemoved.connect(boost::bind(&MUCController::handleMUCBookmarkRemoved, this, _1))); - - std::vector<MUCBookmark> mucBookmarks = mucBookmarkManager_->getBookmarks(); - std::vector<MUCBookmark>::iterator bookmarkIterator = std::find_if(mucBookmarks.begin(), mucBookmarks.end(), MUCBookmarkPredicate(muc->getJID())); - if (bookmarkIterator != mucBookmarks.end()) { - updateChatWindowBookmarkStatus(*bookmarkIterator); - } - else { - updateChatWindowBookmarkStatus(boost::optional<MUCBookmark>()); - } + 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* uiEventStream, + bool useDelayForLatency, + TimerFactory* timerFactory, + EventController* eventController, + EntityCapsProvider* entityCapsProvider, + XMPPRoster* roster, + HistoryController* historyController, + MUCRegistry* mucRegistry, + HighlightManager* highlightManager, + ClientBlockListManager* clientBlockListManager, + boost::shared_ptr<ChatMessageParser> chatMessageParser, + bool isImpromptu, + AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider, + VCardManager* vcardManager, + MUCBookmarkManager* mucBookmarkManager) : + ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, muc->getJID(), presenceOracle, avatarManager, useDelayForLatency, uiEventStream, eventController, timerFactory, entityCapsProvider, historyController, mucRegistry, highlightManager, chatMessageParser, autoAcceptMUCInviteDecider), muc_(muc), nick_(nick), desiredNick_(nick), password_(password), renameCounter_(0), isImpromptu_(isImpromptu), isImpromptuAlreadyConfigured_(false), clientBlockListManager_(clientBlockListManager), mucBookmarkManager_(mucBookmarkManager) { + parting_ = true; + joined_ = false; + lastWasPresence_ = false; + shouldJoinOnReconnect_ = true; + doneGettingHistory_ = false; + events_ = uiEventStream; + xmppRoster_ = roster; + + roster_ = new Roster(false, true); + rosterVCardProvider_ = new RosterVCardProvider(roster_, vcardManager, JID::WithResource); + completer_ = new TabComplete(); + chatWindow_->setRosterModel(roster_); + chatWindow_->setTabComplete(completer_); + chatWindow_->onClosed.connect(boost::bind(&MUCController::handleWindowClosed, this)); + chatWindow_->onOccupantSelectionChanged.connect(boost::bind(&MUCController::handleWindowOccupantSelectionChanged, this, _1)); + chatWindow_->onOccupantActionSelected.connect(boost::bind(&MUCController::handleActionRequestedOnOccupant, this, _1, _2)); + chatWindow_->onChangeSubjectRequest.connect(boost::bind(&MUCController::handleChangeSubjectRequest, this, _1)); + chatWindow_->onBookmarkRequest.connect(boost::bind(&MUCController::handleBookmarkRequest, this)); + chatWindow_->onConfigureRequest.connect(boost::bind(&MUCController::handleConfigureRequest, this, _1)); + chatWindow_->onConfigurationFormCancelled.connect(boost::bind(&MUCController::handleConfigurationCancelled, this)); + chatWindow_->onDestroyRequest.connect(boost::bind(&MUCController::handleDestroyRoomRequest, this)); + chatWindow_->onInviteToChat.connect(boost::bind(&MUCController::handleInvitePersonToThisMUCRequest, this, _1)); + chatWindow_->onGetAffiliationsRequest.connect(boost::bind(&MUCController::handleGetAffiliationsRequest, this)); + chatWindow_->onChangeAffiliationsRequest.connect(boost::bind(&MUCController::handleChangeAffiliationsRequest, this, _1)); + chatWindow_->onUnblockUserRequest.connect(boost::bind(&MUCController::handleUnblockUserRequest, this)); + muc_->onJoinComplete.connect(boost::bind(&MUCController::handleJoinComplete, this, _1)); + muc_->onJoinFailed.connect(boost::bind(&MUCController::handleJoinFailed, this, _1)); + muc_->onOccupantJoined.connect(boost::bind(&MUCController::handleOccupantJoined, this, _1)); + muc_->onOccupantNicknameChanged.connect(boost::bind(&MUCController::handleOccupantNicknameChanged, this, _1, _2)); + muc_->onOccupantPresenceChange.connect(boost::bind(&MUCController::handleOccupantPresenceChange, this, _1)); + muc_->onOccupantLeft.connect(boost::bind(&MUCController::handleOccupantLeft, this, _1, _2, _3)); + muc_->onRoleChangeFailed.connect(boost::bind(&MUCController::handleOccupantRoleChangeFailed, this, _1, _2, _3)); + muc_->onAffiliationListReceived.connect(boost::bind(&MUCController::handleAffiliationListReceived, this, _1, _2)); + muc_->onConfigurationFailed.connect(boost::bind(&MUCController::handleConfigurationFailed, this, _1)); + muc_->onConfigurationFormReceived.connect(boost::bind(&MUCController::handleConfigurationFormReceived, this, _1)); + highlighter_->setMode(isImpromptu_ ? Highlighter::ChatMode : Highlighter::MUCMode); + highlighter_->setNick(nick_); + if (timerFactory && stanzaChannel_->isAvailable()) { + loginCheckTimer_ = boost::shared_ptr<Timer>(timerFactory->createTimer(MUC_JOIN_WARNING_TIMEOUT_MILLISECONDS)); + loginCheckTimer_->onTick.connect(boost::bind(&MUCController::handleJoinTimeoutTick, this)); + loginCheckTimer_->start(); + } + else { + chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(QT_TRANSLATE_NOOP("", "You are currently offline. You will enter this room when you are connected.")), ChatWindow::DefaultDirection); + } + if (isImpromptu) { + muc_->onUnlocked.connect(boost::bind(&MUCController::handleRoomUnlocked, this)); + chatWindow_->convertToMUC(ChatWindow::ImpromptuMUC); + } else { + muc_->onOccupantRoleChanged.connect(boost::bind(&MUCController::handleOccupantRoleChanged, this, _1, _2, _3)); + muc_->onOccupantAffiliationChanged.connect(boost::bind(&MUCController::handleOccupantAffiliationChanged, this, _1, _2, _3)); + chatWindow_->convertToMUC(ChatWindow::StandardMUC); + chatWindow_->setName(muc->getJID().getNode()); + } + if (stanzaChannel->isAvailable()) { + MUCController::setOnline(true); + } + if (avatarManager_ != NULL) { + avatarChangedConnection_ = (avatarManager_->onAvatarChanged.connect(boost::bind(&MUCController::handleAvatarChanged, this, _1))); + } + MUCController::handleBareJIDCapsChanged(muc->getJID()); + eventStream_->onUIEvent.connect(boost::bind(&MUCController::handleUIEvent, this, _1)); + + + // setup handling of MUC bookmark changes + mucBookmarkManagerBookmarkAddedConnection_ = (mucBookmarkManager_->onBookmarkAdded.connect(boost::bind(&MUCController::handleMUCBookmarkAdded, this, _1))); + mucBookmarkManagerBookmarkRemovedConnection_ = (mucBookmarkManager_->onBookmarkRemoved.connect(boost::bind(&MUCController::handleMUCBookmarkRemoved, this, _1))); + + std::vector<MUCBookmark> mucBookmarks = mucBookmarkManager_->getBookmarks(); + std::vector<MUCBookmark>::iterator bookmarkIterator = std::find_if(mucBookmarks.begin(), mucBookmarks.end(), MUCBookmarkPredicate(muc->getJID())); + if (bookmarkIterator != mucBookmarks.end()) { + updateChatWindowBookmarkStatus(*bookmarkIterator); + } + else { + updateChatWindowBookmarkStatus(boost::optional<MUCBookmark>()); + } } MUCController::~MUCController() { - eventStream_->onUIEvent.disconnect(boost::bind(&MUCController::handleUIEvent, this, _1)); - chatWindow_->setRosterModel(NULL); - delete rosterVCardProvider_; - delete roster_; - if (loginCheckTimer_) { - loginCheckTimer_->stop(); - } - chatWindow_->setTabComplete(NULL); - delete completer_; + eventStream_->onUIEvent.disconnect(boost::bind(&MUCController::handleUIEvent, this, _1)); + chatWindow_->setRosterModel(NULL); + delete rosterVCardProvider_; + delete roster_; + if (loginCheckTimer_) { + loginCheckTimer_->stop(); + } + chatWindow_->setTabComplete(NULL); + delete completer_; } void MUCController::cancelReplaces() { - lastWasPresence_ = false; + lastWasPresence_ = false; } void MUCController::handleWindowOccupantSelectionChanged(ContactRosterItem* item) { - std::vector<ChatWindow::OccupantAction> actions; - - if (item) { - MUCOccupant::Affiliation affiliation = muc_->getOccupant(getNick()).getAffiliation(); - MUCOccupant::Role role = muc_->getOccupant(getNick()).getRole(); - if (role == MUCOccupant::Moderator && !isImpromptu_) - { - if (affiliation == MUCOccupant::Admin || affiliation == MUCOccupant::Owner) { - actions.push_back(ChatWindow::Ban); - } - - actions.push_back(ChatWindow::Kick); - actions.push_back(ChatWindow::MakeModerator); - actions.push_back(ChatWindow::MakeParticipant); - actions.push_back(ChatWindow::MakeVisitor); - } - // Add contact is available only if the real JID is also available - if (muc_->getOccupant(item->getJID().getResource()).getRealJID()) { - actions.push_back(ChatWindow::AddContact); - } - actions.push_back(ChatWindow::ShowProfile); - } - chatWindow_->setAvailableOccupantActions(actions); + std::vector<ChatWindow::OccupantAction> actions; + + if (item) { + MUCOccupant::Affiliation affiliation = muc_->getOccupant(getNick()).getAffiliation(); + MUCOccupant::Role role = muc_->getOccupant(getNick()).getRole(); + if (role == MUCOccupant::Moderator && !isImpromptu_) + { + if (affiliation == MUCOccupant::Admin || affiliation == MUCOccupant::Owner) { + actions.push_back(ChatWindow::Ban); + } + + actions.push_back(ChatWindow::Kick); + actions.push_back(ChatWindow::MakeModerator); + actions.push_back(ChatWindow::MakeParticipant); + actions.push_back(ChatWindow::MakeVisitor); + } + // Add contact is available only if the real JID is also available + if (muc_->getOccupant(item->getJID().getResource()).getRealJID()) { + actions.push_back(ChatWindow::AddContact); + } + actions.push_back(ChatWindow::ShowProfile); + } + chatWindow_->setAvailableOccupantActions(actions); } void MUCController::handleActionRequestedOnOccupant(ChatWindow::OccupantAction action, ContactRosterItem* item) { - JID mucJID = item->getJID(); - MUCOccupant occupant = muc_->getOccupant(mucJID.getResource()); - JID realJID; - if (occupant.getRealJID()) { - realJID = occupant.getRealJID().get(); - } - switch (action) { - case ChatWindow::Kick: muc_->kickOccupant(mucJID);break; - case ChatWindow::Ban: muc_->changeAffiliation(realJID, MUCOccupant::Outcast);break; - case ChatWindow::MakeModerator: muc_->changeOccupantRole(mucJID, MUCOccupant::Moderator);break; - 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; - } + JID mucJID = item->getJID(); + MUCOccupant occupant = muc_->getOccupant(mucJID.getResource()); + JID realJID; + if (occupant.getRealJID()) { + realJID = occupant.getRealJID().get(); + } + switch (action) { + case ChatWindow::Kick: muc_->kickOccupant(mucJID);break; + case ChatWindow::Ban: muc_->changeAffiliation(realJID, MUCOccupant::Outcast);break; + case ChatWindow::MakeModerator: muc_->changeOccupantRole(mucJID, MUCOccupant::Moderator);break; + 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; + } } void MUCController::handleBareJIDCapsChanged(const JID& /*jid*/) { - Tristate support = Yes; - bool any = false; - foreach (const std::string& nick, currentOccupants_) { - DiscoInfo::ref disco = entityCapsProvider_->getCaps(toJID_.toBare().toString() + "/" + nick); - if (disco && disco->hasFeature(DiscoInfo::MessageCorrectionFeature)) { - any = true; - } else { - support = Maybe; - } - } - if (!any) { - support = No; - } - chatWindow_->setCorrectionEnabled(support); + Tristate support = Yes; + bool any = false; + foreach (const std::string& nick, currentOccupants_) { + DiscoInfo::ref disco = entityCapsProvider_->getCaps(toJID_.toBare().toString() + "/" + nick); + if (disco && disco->hasFeature(DiscoInfo::MessageCorrectionFeature)) { + any = true; + } else { + support = Maybe; + } + } + if (!any) { + support = No; + } + chatWindow_->setCorrectionEnabled(support); } /** * Join the MUC if not already in it. */ void MUCController::rejoin() { - if (parting_) { - joined_ = false; - parting_ = false; - if (password_) { - muc_->setPassword(*password_); - } - //FIXME: check for received activity + if (parting_) { + joined_ = false; + parting_ = false; + if (password_) { + muc_->setPassword(*password_); + } + //FIXME: check for received activity #ifdef SWIFT_EXPERIMENTAL_HISTORY - if (lastActivity_ == boost::posix_time::not_a_date_time && historyController_) { - lastActivity_ = historyController_->getLastTimeStampFromMUC(selfJID_, toJID_); - } + if (lastActivity_ == boost::posix_time::not_a_date_time && historyController_) { + lastActivity_ = historyController_->getLastTimeStampFromMUC(selfJID_, toJID_); + } #endif - if (lastActivity_ == boost::posix_time::not_a_date_time) { - muc_->joinAs(nick_); - } - else { - muc_->joinWithContextSince(nick_, lastActivity_); - } - } + if (lastActivity_ == boost::posix_time::not_a_date_time) { + muc_->joinAs(nick_); + } + else { + muc_->joinWithContextSince(nick_, lastActivity_); + } + } } bool MUCController::isJoined() { - return joined_; + return joined_; } const std::string& MUCController::getNick() { - return nick_; + return nick_; } const boost::optional<std::string> MUCController::getPassword() const { - return password_; + return password_; } bool MUCController::isImpromptu() const { - return isImpromptu_; + return isImpromptu_; } std::map<std::string, JID> MUCController::getParticipantJIDs() const { - std::map<std::string, JID> participants; - typedef std::pair<std::string, MUCOccupant> MUCOccupantPair; - std::map<std::string, MUCOccupant> occupants = muc_->getOccupants(); - foreach(const MUCOccupantPair& occupant, occupants) { - if (occupant.first != nick_) { - participants[occupant.first] = occupant.second.getRealJID().is_initialized() ? occupant.second.getRealJID().get().toBare() : JID(); - } - } - return participants; + std::map<std::string, JID> participants; + typedef std::pair<std::string, MUCOccupant> MUCOccupantPair; + std::map<std::string, MUCOccupant> occupants = muc_->getOccupants(); + foreach(const MUCOccupantPair& occupant, occupants) { + if (occupant.first != nick_) { + participants[occupant.first] = occupant.second.getRealJID().is_initialized() ? occupant.second.getRealJID().get().toBare() : JID(); + } + } + return participants; } void MUCController::sendInvites(const std::vector<JID>& jids, const std::string& reason) const { - foreach (const JID& jid, jids) { - muc_->invitePerson(jid, reason, isImpromptu_); - } + foreach (const JID& jid, jids) { + muc_->invitePerson(jid, reason, isImpromptu_); + } } void MUCController::handleJoinTimeoutTick() { - receivedActivity(); - chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(str(format(QT_TRANSLATE_NOOP("", "Room %1% is not responding. This operation may never complete.")) % toJID_.toString())), ChatWindow::DefaultDirection); + receivedActivity(); + chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(str(format(QT_TRANSLATE_NOOP("", "Room %1% is not responding. This operation may never complete.")) % toJID_.toString())), ChatWindow::DefaultDirection); } void MUCController::receivedActivity() { - if (loginCheckTimer_) { - loginCheckTimer_->stop(); - } + if (loginCheckTimer_) { + loginCheckTimer_->stop(); + } } #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"); - std::string rejoinNick; - if (error) { - switch (error->getCondition()) { - case ErrorPayload::Conflict: - rejoinNick = nick_ + "_"; - errorMessage = str(format(QT_TRANSLATE_NOOP("", "Unable to enter this room as %1%, retrying as %2%")) % nick_ % rejoinNick); - break; - case ErrorPayload::JIDMalformed: - errorMessage += ": "; - errorMessage += QT_TRANSLATE_NOOP("", "No nickname specified"); - break; - case ErrorPayload::NotAuthorized: - errorMessage += ": "; - errorMessage += QT_TRANSLATE_NOOP("", "The correct room password is needed"); - break; - case ErrorPayload::RegistrationRequired: - errorMessage += ": "; - errorMessage += QT_TRANSLATE_NOOP("", "Only members may enter"); - break; - case ErrorPayload::Forbidden: - errorMessage += ": "; - errorMessage += QT_TRANSLATE_NOOP("", "You are banned from the room"); - break; - case ErrorPayload::ServiceUnavailable: - errorMessage += ": "; - errorMessage += QT_TRANSLATE_NOOP("", "The room is full"); - break; - case ErrorPayload::ItemNotFound: - errorMessage += ": "; - errorMessage += QT_TRANSLATE_NOOP("", "The room does not exist"); - break; - - default: break; - } - } - errorMessage = str(format(QT_TRANSLATE_NOOP("", "Couldn't enter room: %1%.")) % errorMessage); - chatWindow_->addErrorMessage(chatMessageParser_->parseMessageBody(errorMessage)); - parting_ = true; - if (!rejoinNick.empty() && renameCounter_ < 10) { - renameCounter_++; - setNick(rejoinNick); - rejoin(); - } + receivedActivity(); + std::string errorMessage = QT_TRANSLATE_NOOP("", "Unable to enter this room"); + std::string rejoinNick; + if (error) { + switch (error->getCondition()) { + case ErrorPayload::Conflict: + rejoinNick = nick_ + "_"; + errorMessage = str(format(QT_TRANSLATE_NOOP("", "Unable to enter this room as %1%, retrying as %2%")) % nick_ % rejoinNick); + break; + case ErrorPayload::JIDMalformed: + errorMessage += ": "; + errorMessage += QT_TRANSLATE_NOOP("", "No nickname specified"); + break; + case ErrorPayload::NotAuthorized: + errorMessage += ": "; + errorMessage += QT_TRANSLATE_NOOP("", "The correct room password is needed"); + break; + case ErrorPayload::RegistrationRequired: + errorMessage += ": "; + errorMessage += QT_TRANSLATE_NOOP("", "Only members may enter"); + break; + case ErrorPayload::Forbidden: + errorMessage += ": "; + errorMessage += QT_TRANSLATE_NOOP("", "You are banned from the room"); + break; + case ErrorPayload::ServiceUnavailable: + errorMessage += ": "; + errorMessage += QT_TRANSLATE_NOOP("", "The room is full"); + break; + case ErrorPayload::ItemNotFound: + errorMessage += ": "; + errorMessage += QT_TRANSLATE_NOOP("", "The room does not exist"); + break; + + default: break; + } + } + errorMessage = str(format(QT_TRANSLATE_NOOP("", "Couldn't enter room: %1%.")) % errorMessage); + chatWindow_->addErrorMessage(chatMessageParser_->parseMessageBody(errorMessage)); + parting_ = true; + if (!rejoinNick.empty() && renameCounter_ < 10) { + renameCounter_++; + setNick(rejoinNick); + rejoin(); + } } #pragma clang diagnostic pop void MUCController::handleJoinComplete(const std::string& nick) { - receivedActivity(); - renameCounter_ = 0; - joined_ = true; - std::string joinMessage; - if (isImpromptu_) { - joinMessage = str(format(QT_TRANSLATE_NOOP("", "You have joined the chat as %1%.")) % nick); - } else { - joinMessage = str(format(QT_TRANSLATE_NOOP("", "You have entered room %1% as %2%.")) % toJID_.toString() % nick); - } - setNick(nick); - chatWindow_->replaceSystemMessage(chatMessageParser_->parseMessageBody(joinMessage), lastJoinMessageUID_, ChatWindow::UpdateTimestamp); - lastJoinMessageUID_ = ""; + receivedActivity(); + renameCounter_ = 0; + joined_ = true; + std::string joinMessage; + if (isImpromptu_) { + joinMessage = str(format(QT_TRANSLATE_NOOP("", "You have joined the chat as %1%.")) % nick); + } else { + joinMessage = str(format(QT_TRANSLATE_NOOP("", "You have entered room %1% as %2%.")) % toJID_.toString() % nick); + } + setNick(nick); + chatWindow_->replaceSystemMessage(chatMessageParser_->parseMessageBody(joinMessage), lastJoinMessageUID_, ChatWindow::UpdateTimestamp); + lastJoinMessageUID_ = ""; #ifdef SWIFT_EXPERIMENTAL_HISTORY - addRecentLogs(); + addRecentLogs(); #endif - clearPresenceQueue(); - shouldJoinOnReconnect_ = true; - setEnabled(true); - if (isImpromptu_) { - setAvailableRoomActions(MUCOccupant::NoAffiliation, MUCOccupant::Participant); - } else { - MUCOccupant occupant = muc_->getOccupant(nick); - setAvailableRoomActions(occupant.getAffiliation(), occupant.getRole()); - } - onUserJoined(); + clearPresenceQueue(); + shouldJoinOnReconnect_ = true; + setEnabled(true); + if (isImpromptu_) { + setAvailableRoomActions(MUCOccupant::NoAffiliation, MUCOccupant::Participant); + } else { + MUCOccupant occupant = muc_->getOccupant(nick); + setAvailableRoomActions(occupant.getAffiliation(), occupant.getRole()); + } + onUserJoined(); - if (isImpromptu_) { - setImpromptuWindowTitle(); - } + if (isImpromptu_) { + setImpromptuWindowTitle(); + } } void MUCController::handleAvatarChanged(const JID& jid) { - if (parting_ || !jid.equals(toJID_, JID::WithoutResource)) { - return; - } - roster_->applyOnItems(SetAvatar(jid, avatarManager_->getAvatarPath(jid), JID::WithResource)); + if (parting_ || !jid.equals(toJID_, JID::WithoutResource)) { + return; + } + roster_->applyOnItems(SetAvatar(jid, avatarManager_->getAvatarPath(jid), JID::WithResource)); } void MUCController::handleWindowClosed() { - parting_ = true; - shouldJoinOnReconnect_ = false; - muc_->part(); - onUserLeft(); + parting_ = true; + shouldJoinOnReconnect_ = false; + muc_->part(); + onUserLeft(); } void MUCController::handleOccupantJoined(const MUCOccupant& occupant) { - if (nick_ != occupant.getNick()) { - completer_->addWord(occupant.getNick()); - } - receivedActivity(); - JID jid(nickToJID(occupant.getNick())); - JID realJID; - if (occupant.getRealJID()) { - realJID = occupant.getRealJID().get(); - } - currentOccupants_.insert(occupant.getNick()); - NickJoinPart event(occupant.getNick(), Join); - appendToJoinParts(joinParts_, event); - MUCOccupant::Role role = MUCOccupant::Participant; - MUCOccupant::Affiliation affiliation = MUCOccupant::NoAffiliation; - if (!isImpromptu_) { - role = occupant.getRole(); - affiliation = occupant.getAffiliation(); - } - std::string groupName(roleToGroupName(role)); - roster_->addContact(jid, realJID, occupant.getNick(), groupName, avatarManager_->getAvatarPath(jid)); - roster_->applyOnItems(SetMUC(jid, role, affiliation)); - roster_->getGroup(groupName)->setManualSort(roleToSortName(role)); - if (joined_) { - std::string joinString; - if (role != MUCOccupant::NoRole && role != MUCOccupant::Participant) { - joinString = str(format(QT_TRANSLATE_NOOP("", "%1% has entered the %3% as a %2%.")) % occupant.getNick() % roleToFriendlyName(role) % (isImpromptu_ ? QT_TRANSLATE_NOOP("", "chat") : QT_TRANSLATE_NOOP("", "room"))); - } - else { - joinString = str(format(QT_TRANSLATE_NOOP("", "%1% has entered the %2%.")) % occupant.getNick() % (isImpromptu_ ? QT_TRANSLATE_NOOP("", "chat") : QT_TRANSLATE_NOOP("", "room"))); - } - if (shouldUpdateJoinParts()) { - updateJoinParts(); - } else { - addPresenceMessage(joinString); - } - - if (isImpromptu_) { - setImpromptuWindowTitle(); - onActivity(""); - } - } - if (avatarManager_ != NULL) { - handleAvatarChanged(jid); - } + if (nick_ != occupant.getNick()) { + completer_->addWord(occupant.getNick()); + } + receivedActivity(); + JID jid(nickToJID(occupant.getNick())); + JID realJID; + if (occupant.getRealJID()) { + realJID = occupant.getRealJID().get(); + } + currentOccupants_.insert(occupant.getNick()); + NickJoinPart event(occupant.getNick(), Join); + appendToJoinParts(joinParts_, event); + MUCOccupant::Role role = MUCOccupant::Participant; + MUCOccupant::Affiliation affiliation = MUCOccupant::NoAffiliation; + if (!isImpromptu_) { + role = occupant.getRole(); + affiliation = occupant.getAffiliation(); + } + std::string groupName(roleToGroupName(role)); + roster_->addContact(jid, realJID, occupant.getNick(), groupName, avatarManager_->getAvatarPath(jid)); + roster_->applyOnItems(SetMUC(jid, role, affiliation)); + roster_->getGroup(groupName)->setManualSort(roleToSortName(role)); + if (joined_) { + std::string joinString; + if (role != MUCOccupant::NoRole && role != MUCOccupant::Participant) { + joinString = str(format(QT_TRANSLATE_NOOP("", "%1% has entered the %3% as a %2%.")) % occupant.getNick() % roleToFriendlyName(role) % (isImpromptu_ ? QT_TRANSLATE_NOOP("", "chat") : QT_TRANSLATE_NOOP("", "room"))); + } + else { + joinString = str(format(QT_TRANSLATE_NOOP("", "%1% has entered the %2%.")) % occupant.getNick() % (isImpromptu_ ? QT_TRANSLATE_NOOP("", "chat") : QT_TRANSLATE_NOOP("", "room"))); + } + if (shouldUpdateJoinParts()) { + updateJoinParts(); + } else { + addPresenceMessage(joinString); + } + + if (isImpromptu_) { + setImpromptuWindowTitle(); + onActivity(""); + } + } + if (avatarManager_ != NULL) { + handleAvatarChanged(jid); + } } void MUCController::addPresenceMessage(const std::string& message) { - lastWasPresence_ = true; - chatWindow_->addPresenceMessage(chatMessageParser_->parseMessageBody(message), ChatWindow::DefaultDirection); + lastWasPresence_ = true; + chatWindow_->addPresenceMessage(chatMessageParser_->parseMessageBody(message), ChatWindow::DefaultDirection); } void MUCController::setAvailableRoomActions(const MUCOccupant::Affiliation& affiliation, const MUCOccupant::Role& role) { - std::vector<ChatWindow::RoomAction> actions; - - if (role <= MUCOccupant::Participant) { - actions.push_back(ChatWindow::ChangeSubject); - } - if (affiliation == MUCOccupant::Owner) { - actions.push_back(ChatWindow::Configure); - } - if (affiliation <= MUCOccupant::Admin) { - actions.push_back(ChatWindow::Affiliations); - } - if (affiliation == MUCOccupant::Owner) { - actions.push_back(ChatWindow::Destroy); - } - if (role <= MUCOccupant::Visitor) { - actions.push_back(ChatWindow::Invite); - } - chatWindow_->setAvailableRoomActions(actions); + std::vector<ChatWindow::RoomAction> actions; + + if (role <= MUCOccupant::Participant) { + actions.push_back(ChatWindow::ChangeSubject); + } + if (affiliation == MUCOccupant::Owner) { + actions.push_back(ChatWindow::Configure); + } + if (affiliation <= MUCOccupant::Admin) { + actions.push_back(ChatWindow::Affiliations); + } + if (affiliation == MUCOccupant::Owner) { + actions.push_back(ChatWindow::Destroy); + } + if (role <= MUCOccupant::Visitor) { + actions.push_back(ChatWindow::Invite); + } + chatWindow_->setAvailableRoomActions(actions); } void MUCController::clearPresenceQueue() { - lastWasPresence_ = false; - joinParts_.clear(); + lastWasPresence_ = false; + joinParts_.clear(); } std::string MUCController::roleToFriendlyName(MUCOccupant::Role role) { - switch (role) { - case MUCOccupant::Moderator: return QT_TRANSLATE_NOOP("", "moderator"); - case MUCOccupant::Participant: return QT_TRANSLATE_NOOP("", "participant"); - case MUCOccupant::Visitor: return QT_TRANSLATE_NOOP("", "visitor"); - case MUCOccupant::NoRole: return ""; - } - assert(false); - return ""; + switch (role) { + case MUCOccupant::Moderator: return QT_TRANSLATE_NOOP("", "moderator"); + case MUCOccupant::Participant: return QT_TRANSLATE_NOOP("", "participant"); + case MUCOccupant::Visitor: return QT_TRANSLATE_NOOP("", "visitor"); + case MUCOccupant::NoRole: return ""; + } + assert(false); + return ""; } std::string MUCController::roleToSortName(MUCOccupant::Role role) { - switch (role) { - case MUCOccupant::Moderator: return "1"; - case MUCOccupant::Participant: return "2"; - case MUCOccupant::Visitor: return "3"; - case MUCOccupant::NoRole: return "4"; - } - assert(false); - return "5"; + switch (role) { + case MUCOccupant::Moderator: return "1"; + case MUCOccupant::Participant: return "2"; + case MUCOccupant::Visitor: return "3"; + case MUCOccupant::NoRole: return "4"; + } + assert(false); + return "5"; } JID MUCController::nickToJID(const std::string& nick) { - return muc_->getJID().withResource(nick); + return muc_->getJID().withResource(nick); } bool MUCController::messageTargetsMe(boost::shared_ptr<Message> message) { - std::string stringRegexp(".*\\b" + boost::to_lower_copy(nick_) + "\\b.*"); - boost::regex myRegexp(stringRegexp); - return boost::regex_match(boost::to_lower_copy(message->getBody().get_value_or("")), myRegexp); + std::string stringRegexp(".*\\b" + boost::to_lower_copy(nick_) + "\\b.*"); + boost::regex myRegexp(stringRegexp); + return boost::regex_match(boost::to_lower_copy(message->getBody().get_value_or("")), myRegexp); } void MUCController::preHandleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent) { - if (messageEvent->getStanza()->getType() == Message::Groupchat) { - lastActivity_ = boost::posix_time::microsec_clock::universal_time(); - } - clearPresenceQueue(); - boost::shared_ptr<Message> message = messageEvent->getStanza(); - if (joined_ && messageEvent->getStanza()->getFrom().getResource() != nick_ && messageTargetsMe(message) && !message->getPayload<Delay>() && messageEvent->isReadable()) { - chatWindow_->flash(); - } - else { - messageEvent->setTargetsMe(false); - } - if (messageEvent->isReadable() && isImpromptu_) { - chatWindow_->flash(); /* behave like a regular char*/ - } - if (joined_) { - std::string nick = message->getFrom().getResource(); - if (nick != nick_ && currentOccupants_.find(nick) != currentOccupants_.end()) { - completer_->addWord(nick); - } - } - /*Buggy implementations never send the status code, so use an incoming message as a hint that joining's done (e.g. the old ejabberd on psi-im.org).*/ - receivedActivity(); - joined_ = true; - - if (message->hasSubject() && !message->getPayload<Body>() && !message->getPayload<Thread>()) { - chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(str(format(QT_TRANSLATE_NOOP("", "The room subject is now: %1%")) % message->getSubject())), ChatWindow::DefaultDirection); - chatWindow_->setSubject(message->getSubject()); - doneGettingHistory_ = true; - } - - if (!doneGettingHistory_ && !message->getPayload<Delay>()) { - doneGettingHistory_ = true; - } - - if (!doneGettingHistory_) { - checkDuplicates(message); - messageEvent->conclude(); - } + if (messageEvent->getStanza()->getType() == Message::Groupchat) { + lastActivity_ = boost::posix_time::microsec_clock::universal_time(); + } + clearPresenceQueue(); + boost::shared_ptr<Message> message = messageEvent->getStanza(); + if (joined_ && messageEvent->getStanza()->getFrom().getResource() != nick_ && messageTargetsMe(message) && !message->getPayload<Delay>() && messageEvent->isReadable()) { + chatWindow_->flash(); + } + else { + messageEvent->setTargetsMe(false); + } + if (messageEvent->isReadable() && isImpromptu_) { + chatWindow_->flash(); /* behave like a regular char*/ + } + if (joined_) { + std::string nick = message->getFrom().getResource(); + if (nick != nick_ && currentOccupants_.find(nick) != currentOccupants_.end()) { + completer_->addWord(nick); + } + } + /*Buggy implementations never send the status code, so use an incoming message as a hint that joining's done (e.g. the old ejabberd on psi-im.org).*/ + receivedActivity(); + joined_ = true; + + if (message->hasSubject() && !message->getPayload<Body>() && !message->getPayload<Thread>()) { + chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(str(format(QT_TRANSLATE_NOOP("", "The room subject is now: %1%")) % message->getSubject())), ChatWindow::DefaultDirection); + chatWindow_->setSubject(message->getSubject()); + doneGettingHistory_ = true; + } + + if (!doneGettingHistory_ && !message->getPayload<Delay>()) { + doneGettingHistory_ = true; + } + + if (!doneGettingHistory_) { + checkDuplicates(message); + messageEvent->conclude(); + } } void MUCController::addMessageHandleIncomingMessage(const JID& from, const ChatWindow::ChatMessage& message, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const boost::posix_time::ptime& time) { - if (from.isBare()) { - chatWindow_->addSystemMessage(message, ChatWindow::DefaultDirection); - } - else { - ChatControllerBase::addMessageHandleIncomingMessage(from, message, senderIsSelf, label, time); - } + if (from.isBare()) { + chatWindow_->addSystemMessage(message, ChatWindow::DefaultDirection); + } + else { + ChatControllerBase::addMessageHandleIncomingMessage(from, message, senderIsSelf, label, time); + } } void MUCController::postHandleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent, const ChatWindow::ChatMessage& chatMessage) { - boost::shared_ptr<Message> message = messageEvent->getStanza(); - if (joined_ && messageEvent->getStanza()->getFrom().getResource() != nick_ && !message->getPayload<Delay>()) { - if (messageTargetsMe(message) || isImpromptu_) { - eventController_->handleIncomingEvent(messageEvent); - } - if (!messageEvent->getConcluded()) { - handleHighlightActions(chatMessage); - } - } + boost::shared_ptr<Message> message = messageEvent->getStanza(); + if (joined_ && messageEvent->getStanza()->getFrom().getResource() != nick_ && !message->getPayload<Delay>()) { + if (messageTargetsMe(message) || isImpromptu_) { + eventController_->handleIncomingEvent(messageEvent); + } + if (!messageEvent->getConcluded()) { + handleHighlightActions(chatMessage); + } + } } void MUCController::handleOccupantRoleChanged(const std::string& nick, const MUCOccupant& occupant, const MUCOccupant::Role& oldRole) { - clearPresenceQueue(); - receivedActivity(); - JID jid(nickToJID(nick)); - roster_->removeContactFromGroup(jid, roleToGroupName(oldRole)); - JID realJID; - if (occupant.getRealJID()) { - realJID = occupant.getRealJID().get(); - } - std::string group(roleToGroupName(occupant.getRole())); - roster_->addContact(jid, realJID, nick, group, avatarManager_->getAvatarPath(jid)); - roster_->getGroup(group)->setManualSort(roleToSortName(occupant.getRole())); - roster_->applyOnItems(SetMUC(jid, occupant.getRole(), occupant.getAffiliation())); - chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(str(format(QT_TRANSLATE_NOOP("", "%1% is now a %2%")) % nick % roleToFriendlyName(occupant.getRole()))), ChatWindow::DefaultDirection); - if (nick == nick_) { - setAvailableRoomActions(occupant.getAffiliation(), occupant.getRole()); - } + clearPresenceQueue(); + receivedActivity(); + JID jid(nickToJID(nick)); + roster_->removeContactFromGroup(jid, roleToGroupName(oldRole)); + JID realJID; + if (occupant.getRealJID()) { + realJID = occupant.getRealJID().get(); + } + std::string group(roleToGroupName(occupant.getRole())); + roster_->addContact(jid, realJID, nick, group, avatarManager_->getAvatarPath(jid)); + roster_->getGroup(group)->setManualSort(roleToSortName(occupant.getRole())); + roster_->applyOnItems(SetMUC(jid, occupant.getRole(), occupant.getAffiliation())); + chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(str(format(QT_TRANSLATE_NOOP("", "%1% is now a %2%")) % nick % roleToFriendlyName(occupant.getRole()))), ChatWindow::DefaultDirection); + if (nick == nick_) { + setAvailableRoomActions(occupant.getAffiliation(), occupant.getRole()); + } } void MUCController::handleOccupantAffiliationChanged(const std::string& nick, const MUCOccupant::Affiliation& affiliation, const MUCOccupant::Affiliation& /*oldAffiliation*/) { - if (nick == nick_) { - setAvailableRoomActions(affiliation, muc_->getOccupant(nick_).getRole()); - } - JID jid(nickToJID(nick)); - MUCOccupant occupant = muc_->getOccupant(nick); - roster_->applyOnItems(SetMUC(jid, occupant.getRole(), affiliation)); + if (nick == nick_) { + setAvailableRoomActions(affiliation, muc_->getOccupant(nick_).getRole()); + } + JID jid(nickToJID(nick)); + MUCOccupant occupant = muc_->getOccupant(nick); + roster_->applyOnItems(SetMUC(jid, occupant.getRole(), affiliation)); } std::string MUCController::roleToGroupName(MUCOccupant::Role role) { - std::string result; - switch (role) { - case MUCOccupant::Moderator: result = QT_TRANSLATE_NOOP("", "Moderators"); break; - 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; - } - return result; + std::string result; + switch (role) { + case MUCOccupant::Moderator: result = QT_TRANSLATE_NOOP("", "Moderators"); break; + 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; + } + return result; } void MUCController::setOnline(bool online) { - ChatControllerBase::setOnline(online); - if (!online) { - muc_->part(); - parting_ = true; - processUserPart(); - } else { - if (shouldJoinOnReconnect_) { - renameCounter_ = 0; - boost::shared_ptr<BlockList> blockList = clientBlockListManager_->getBlockList(); - if (blockList && blockList->isBlocked(muc_->getJID())) { - handleBlockingStateChanged(); - lastJoinMessageUID_ = chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(QT_TRANSLATE_NOOP("", "You've blocked this room. To enter the room, first unblock it using the cog menu and try again")), ChatWindow::DefaultDirection); - } - else { - if (isImpromptu_) { - lastJoinMessageUID_ = chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(QT_TRANSLATE_NOOP("", "Trying to join chat")), ChatWindow::DefaultDirection); - } else { - lastJoinMessageUID_ = chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(str(format(QT_TRANSLATE_NOOP("", "Trying to enter room %1%")) % toJID_.toString())), ChatWindow::DefaultDirection); - } - if (loginCheckTimer_) { - loginCheckTimer_->start(); - } - setNick(desiredNick_); - rejoin(); - } - } - } + ChatControllerBase::setOnline(online); + if (!online) { + muc_->part(); + parting_ = true; + processUserPart(); + } else { + if (shouldJoinOnReconnect_) { + renameCounter_ = 0; + boost::shared_ptr<BlockList> blockList = clientBlockListManager_->getBlockList(); + if (blockList && blockList->isBlocked(muc_->getJID())) { + handleBlockingStateChanged(); + lastJoinMessageUID_ = chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(QT_TRANSLATE_NOOP("", "You've blocked this room. To enter the room, first unblock it using the cog menu and try again")), ChatWindow::DefaultDirection); + } + else { + if (isImpromptu_) { + lastJoinMessageUID_ = chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(QT_TRANSLATE_NOOP("", "Trying to join chat")), ChatWindow::DefaultDirection); + } else { + lastJoinMessageUID_ = chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(str(format(QT_TRANSLATE_NOOP("", "Trying to enter room %1%")) % toJID_.toString())), ChatWindow::DefaultDirection); + } + if (loginCheckTimer_) { + loginCheckTimer_->start(); + } + setNick(desiredNick_); + rejoin(); + } + } + } } void MUCController::processUserPart() { - roster_->removeAll(); - /* handleUserLeft won't throw a part back up unless this is called - when it doesn't yet know we've left - which only happens on - disconnect, so call with disconnect here so if the signal does - bubble back up, it'll be with the right type.*/ - muc_->handleUserLeft(MUC::Disconnect); - setEnabled(false); + roster_->removeAll(); + /* handleUserLeft won't throw a part back up unless this is called + when it doesn't yet know we've left - which only happens on + disconnect, so call with disconnect here so if the signal does + bubble back up, it'll be with the right type.*/ + muc_->handleUserLeft(MUC::Disconnect); + setEnabled(false); } bool MUCController::shouldUpdateJoinParts() { - return lastWasPresence_; + return lastWasPresence_; } void MUCController::handleOccupantLeft(const MUCOccupant& occupant, MUC::LeavingType type, const std::string& reason) { - NickJoinPart event(occupant.getNick(), Part); - appendToJoinParts(joinParts_, event); - currentOccupants_.erase(occupant.getNick()); - completer_->removeWord(occupant.getNick()); - std::string partMessage; - bool clearAfter = false; - if (occupant.getNick() != nick_) { - std::string partType; - switch (type) { - case MUC::LeaveKick: clearPresenceQueue(); clearAfter = true; partType = " (kicked)"; break; - case MUC::LeaveBan: clearPresenceQueue(); clearAfter = true; partType = " (banned)"; break; - case MUC::LeaveNotMember: clearPresenceQueue(); clearAfter = true; partType = " (no longer a member)"; break; - case MUC::LeaveDestroy: - case MUC::Disconnect: - case MUC::LeavePart: break; - } - if (isImpromptu_) { - partMessage = str(format(QT_TRANSLATE_NOOP("", "%1% has left the chat%2%")) % occupant.getNick() % partType); - } else { - partMessage = str(format(QT_TRANSLATE_NOOP("", "%1% has left the room%2%")) % occupant.getNick() % partType); - } - } - else if (isImpromptu_) { - switch (type) { - case MUC::LeaveKick: - case MUC::LeaveBan: clearPresenceQueue(); clearAfter = true; partMessage = QT_TRANSLATE_NOOP("", "You have been removed from this chat"); break; - case MUC::LeaveNotMember: clearPresenceQueue(); clearAfter = true; partMessage = QT_TRANSLATE_NOOP("", "You have been removed from this chat"); break; - case MUC::LeaveDestroy: clearPresenceQueue(); clearAfter = true; partMessage = QT_TRANSLATE_NOOP("", "This chat has ended"); break; - case MUC::Disconnect: - case MUC::LeavePart: partMessage = QT_TRANSLATE_NOOP("", "You have left the chat"); - } - } - else { - switch (type) { - case MUC::LeaveKick: clearPresenceQueue(); clearAfter = true; partMessage = QT_TRANSLATE_NOOP("", "You have been kicked out of the room"); break; - case MUC::LeaveBan: clearPresenceQueue(); clearAfter = true; partMessage = QT_TRANSLATE_NOOP("", "You have been banned from the room"); break; - case MUC::LeaveNotMember: clearPresenceQueue(); clearAfter = true; partMessage = QT_TRANSLATE_NOOP("", "You are no longer a member of the room and have been removed"); break; - case MUC::LeaveDestroy: clearPresenceQueue(); clearAfter = true; partMessage = QT_TRANSLATE_NOOP("", "The room has been destroyed"); break; - case MUC::Disconnect: - case MUC::LeavePart: partMessage = QT_TRANSLATE_NOOP("", "You have left the room"); - } - } - if (!reason.empty()) { - partMessage += " (" + reason + ")"; - } - partMessage += "."; - - if (occupant.getNick() != nick_) { - if (shouldUpdateJoinParts()) { - updateJoinParts(); - } else { - addPresenceMessage(partMessage); - } - roster_->removeContact(JID(toJID_.getNode(), toJID_.getDomain(), occupant.getNick())); - } else { - addPresenceMessage(partMessage); - parting_ = true; - processUserPart(); - } - if (clearAfter) { - clearPresenceQueue(); - } - - if (isImpromptu_) { - setImpromptuWindowTitle(); - } + NickJoinPart event(occupant.getNick(), Part); + appendToJoinParts(joinParts_, event); + currentOccupants_.erase(occupant.getNick()); + completer_->removeWord(occupant.getNick()); + std::string partMessage; + bool clearAfter = false; + if (occupant.getNick() != nick_) { + std::string partType; + switch (type) { + case MUC::LeaveKick: clearPresenceQueue(); clearAfter = true; partType = " (kicked)"; break; + case MUC::LeaveBan: clearPresenceQueue(); clearAfter = true; partType = " (banned)"; break; + case MUC::LeaveNotMember: clearPresenceQueue(); clearAfter = true; partType = " (no longer a member)"; break; + case MUC::LeaveDestroy: + case MUC::Disconnect: + case MUC::LeavePart: break; + } + if (isImpromptu_) { + partMessage = str(format(QT_TRANSLATE_NOOP("", "%1% has left the chat%2%")) % occupant.getNick() % partType); + } else { + partMessage = str(format(QT_TRANSLATE_NOOP("", "%1% has left the room%2%")) % occupant.getNick() % partType); + } + } + else if (isImpromptu_) { + switch (type) { + case MUC::LeaveKick: + case MUC::LeaveBan: clearPresenceQueue(); clearAfter = true; partMessage = QT_TRANSLATE_NOOP("", "You have been removed from this chat"); break; + case MUC::LeaveNotMember: clearPresenceQueue(); clearAfter = true; partMessage = QT_TRANSLATE_NOOP("", "You have been removed from this chat"); break; + case MUC::LeaveDestroy: clearPresenceQueue(); clearAfter = true; partMessage = QT_TRANSLATE_NOOP("", "This chat has ended"); break; + case MUC::Disconnect: + case MUC::LeavePart: partMessage = QT_TRANSLATE_NOOP("", "You have left the chat"); + } + } + else { + switch (type) { + case MUC::LeaveKick: clearPresenceQueue(); clearAfter = true; partMessage = QT_TRANSLATE_NOOP("", "You have been kicked out of the room"); break; + case MUC::LeaveBan: clearPresenceQueue(); clearAfter = true; partMessage = QT_TRANSLATE_NOOP("", "You have been banned from the room"); break; + case MUC::LeaveNotMember: clearPresenceQueue(); clearAfter = true; partMessage = QT_TRANSLATE_NOOP("", "You are no longer a member of the room and have been removed"); break; + case MUC::LeaveDestroy: clearPresenceQueue(); clearAfter = true; partMessage = QT_TRANSLATE_NOOP("", "The room has been destroyed"); break; + case MUC::Disconnect: + case MUC::LeavePart: partMessage = QT_TRANSLATE_NOOP("", "You have left the room"); + } + } + if (!reason.empty()) { + partMessage += " (" + reason + ")"; + } + partMessage += "."; + + if (occupant.getNick() != nick_) { + if (shouldUpdateJoinParts()) { + updateJoinParts(); + } else { + addPresenceMessage(partMessage); + } + roster_->removeContact(JID(toJID_.getNode(), toJID_.getDomain(), occupant.getNick())); + } else { + addPresenceMessage(partMessage); + parting_ = true; + processUserPart(); + } + if (clearAfter) { + clearPresenceQueue(); + } + + if (isImpromptu_) { + setImpromptuWindowTitle(); + } } void MUCController::handleOccupantNicknameChanged(const std::string& oldNickname, const std::string& newNickname) { - addPresenceMessage(generateNicknameChangeString(oldNickname, newNickname)); - JID oldJID = muc_->getJID().withResource(oldNickname); - JID newJID = muc_->getJID().withResource(newNickname); - - // adjust occupants - currentOccupants_.erase(oldNickname); - currentOccupants_.insert(newNickname); - - // adjust completer - completer_->removeWord(oldNickname); - completer_->addWord(newNickname); - - // update contact - roster_->removeContact(oldJID); - MUCOccupant occupant = muc_->getOccupant(newNickname); - - JID realJID; - if (occupant.getRealJID()) { - realJID = occupant.getRealJID().get(); - } - MUCOccupant::Role role = MUCOccupant::Participant; - MUCOccupant::Affiliation affiliation = MUCOccupant::NoAffiliation; - if (!isImpromptu_) { - role = occupant.getRole(); - affiliation = occupant.getAffiliation(); - } - std::string groupName(roleToGroupName(role)); - roster_->addContact(newJID, realJID, newNickname, groupName, avatarManager_->getAvatarPath(newJID)); - roster_->applyOnItems(SetMUC(newJID, role, affiliation)); - if (avatarManager_ != NULL) { - handleAvatarChanged(newJID); - } - - clearPresenceQueue(); - onUserNicknameChanged(oldNickname, newNickname); + addPresenceMessage(generateNicknameChangeString(oldNickname, newNickname)); + JID oldJID = muc_->getJID().withResource(oldNickname); + JID newJID = muc_->getJID().withResource(newNickname); + + // adjust occupants + currentOccupants_.erase(oldNickname); + currentOccupants_.insert(newNickname); + + // adjust completer + completer_->removeWord(oldNickname); + completer_->addWord(newNickname); + + // update contact + roster_->removeContact(oldJID); + MUCOccupant occupant = muc_->getOccupant(newNickname); + + JID realJID; + if (occupant.getRealJID()) { + realJID = occupant.getRealJID().get(); + } + MUCOccupant::Role role = MUCOccupant::Participant; + MUCOccupant::Affiliation affiliation = MUCOccupant::NoAffiliation; + if (!isImpromptu_) { + role = occupant.getRole(); + affiliation = occupant.getAffiliation(); + } + std::string groupName(roleToGroupName(role)); + roster_->addContact(newJID, realJID, newNickname, groupName, avatarManager_->getAvatarPath(newJID)); + roster_->applyOnItems(SetMUC(newJID, role, affiliation)); + if (avatarManager_ != NULL) { + handleAvatarChanged(newJID); + } + + clearPresenceQueue(); + onUserNicknameChanged(oldNickname, newNickname); } void MUCController::handleOccupantPresenceChange(boost::shared_ptr<Presence> presence) { - receivedActivity(); - roster_->applyOnItems(SetPresence(presence, JID::WithResource)); + receivedActivity(); + roster_->applyOnItems(SetPresence(presence, JID::WithResource)); } bool MUCController::isIncomingMessageFromMe(boost::shared_ptr<Message> message) { - JID from = message->getFrom(); - return nick_ == from.getResource(); + JID from = message->getFrom(); + return nick_ == from.getResource(); } std::string MUCController::senderHighlightNameFromMessage(const JID& from) { - return from.getResource(); + return from.getResource(); } std::string MUCController::senderDisplayNameFromMessage(const JID& from) { - return from.getResource(); + return from.getResource(); } void MUCController::preSendMessageRequest(boost::shared_ptr<Message> message) { - message->setType(Swift::Message::Groupchat); + message->setType(Swift::Message::Groupchat); } boost::optional<boost::posix_time::ptime> MUCController::getMessageTimestamp(boost::shared_ptr<Message> message) const { - return message->getTimestampFrom(toJID_); + return message->getTimestampFrom(toJID_); } void MUCController::updateJoinParts() { - chatWindow_->replaceLastMessage(chatMessageParser_->parseMessageBody(generateJoinPartString(joinParts_, isImpromptu())), ChatWindow::UpdateTimestamp); + chatWindow_->replaceLastMessage(chatMessageParser_->parseMessageBody(generateJoinPartString(joinParts_, isImpromptu())), ChatWindow::UpdateTimestamp); } void MUCController::appendToJoinParts(std::vector<NickJoinPart>& joinParts, const NickJoinPart& newEvent) { - std::vector<NickJoinPart>::iterator it = joinParts.begin(); - bool matched = false; - for (; it != joinParts.end(); ++it) { - if ((*it).nick == newEvent.nick) { - matched = true; - JoinPart type = (*it).type; - switch (newEvent.type) { - case Join: type = (type == Part) ? PartThenJoin : Join; break; - case Part: type = (type == Join) ? JoinThenPart : Part; break; - case PartThenJoin: break; - case JoinThenPart: break; - } - (*it).type = type; - break; - } - } - if (!matched) { - joinParts.push_back(newEvent); - } + std::vector<NickJoinPart>::iterator it = joinParts.begin(); + bool matched = false; + for (; it != joinParts.end(); ++it) { + if ((*it).nick == newEvent.nick) { + matched = true; + JoinPart type = (*it).type; + switch (newEvent.type) { + case Join: type = (type == Part) ? PartThenJoin : Join; break; + case Part: type = (type == Join) ? JoinThenPart : Part; break; + case PartThenJoin: break; + case JoinThenPart: break; + } + (*it).type = type; + break; + } + } + if (!matched) { + joinParts.push_back(newEvent); + } } std::string MUCController::concatenateListOfNames(const std::vector<NickJoinPart>& joinParts) { - std::string result; - for (size_t i = 0; i < joinParts.size(); i++) { - if (i > 0) { - if (i < joinParts.size() - 1) { - result += ", "; - } else { - result += QT_TRANSLATE_NOOP("", " and "); - } - } - NickJoinPart event = joinParts[i]; - result += event.nick; - } - return result; + std::string result; + for (size_t i = 0; i < joinParts.size(); i++) { + if (i > 0) { + if (i < joinParts.size() - 1) { + result += ", "; + } else { + result += QT_TRANSLATE_NOOP("", " and "); + } + } + NickJoinPart event = joinParts[i]; + result += event.nick; + } + return result; } std::string MUCController::generateJoinPartString(const std::vector<NickJoinPart>& joinParts, bool isImpromptu) { - std::vector<NickJoinPart> sorted[4]; - std::string eventStrings[4]; - foreach (NickJoinPart event, joinParts) { - sorted[event.type].push_back(event); - } - std::string result; - std::vector<JoinPart> populatedEvents; - for (size_t i = 0; i < 4; i++) { - std::string names = concatenateListOfNames(sorted[i]); - if (!names.empty()) { - std::string eventString; - switch (i) { - case Join: - if (sorted[i].size() > 1) { - eventString = (isImpromptu ? QT_TRANSLATE_NOOP("", "%1% have joined the chat") : QT_TRANSLATE_NOOP("", "%1% have entered the room")); - } - else { - eventString = (isImpromptu ? QT_TRANSLATE_NOOP("", "%1% has joined the chat") : QT_TRANSLATE_NOOP("", "%1% has entered the room")); - } - break; - case Part: - if (sorted[i].size() > 1) { - eventString = (isImpromptu ? QT_TRANSLATE_NOOP("", "%1% have left the chat") : QT_TRANSLATE_NOOP("", "%1% have left the room")); - } - else { - eventString = (isImpromptu ? QT_TRANSLATE_NOOP("", "%1% have left the chat") : QT_TRANSLATE_NOOP("", "%1% has left the room")); - } - break; - case JoinThenPart: - if (sorted[i].size() > 1) { - eventString = (isImpromptu ? QT_TRANSLATE_NOOP("", "%1% have joined then left the chat") : QT_TRANSLATE_NOOP("", "%1% have entered then left the room")); - } - else { - eventString = (isImpromptu ? QT_TRANSLATE_NOOP("", "%1% has joined then left the chat") : QT_TRANSLATE_NOOP("", "%1% has entered then left the room")); - } - break; - case PartThenJoin: - if (sorted[i].size() > 1) { - eventString = (isImpromptu ? QT_TRANSLATE_NOOP("", "%1% have left then returned to the chat") : QT_TRANSLATE_NOOP("", "%1% have left then returned to the room")); - } - else { - eventString = (isImpromptu ? QT_TRANSLATE_NOOP("", "%1% has left then returned to the chat") : QT_TRANSLATE_NOOP("", "%1% has left then returned to the room")); - } - break; - } - populatedEvents.push_back(static_cast<JoinPart>(i)); - eventStrings[i] = str(boost::format(eventString) % names); - } - } - for (size_t i = 0; i < populatedEvents.size(); i++) { - if (i > 0) { - if (i < populatedEvents.size() - 1) { - result += ", "; - } else { - result += QT_TRANSLATE_NOOP("", " and "); - } - } - result += eventStrings[populatedEvents[i]]; - } - return result; + std::vector<NickJoinPart> sorted[4]; + std::string eventStrings[4]; + foreach (NickJoinPart event, joinParts) { + sorted[event.type].push_back(event); + } + std::string result; + std::vector<JoinPart> populatedEvents; + for (size_t i = 0; i < 4; i++) { + std::string names = concatenateListOfNames(sorted[i]); + if (!names.empty()) { + std::string eventString; + switch (i) { + case Join: + if (sorted[i].size() > 1) { + eventString = (isImpromptu ? QT_TRANSLATE_NOOP("", "%1% have joined the chat") : QT_TRANSLATE_NOOP("", "%1% have entered the room")); + } + else { + eventString = (isImpromptu ? QT_TRANSLATE_NOOP("", "%1% has joined the chat") : QT_TRANSLATE_NOOP("", "%1% has entered the room")); + } + break; + case Part: + if (sorted[i].size() > 1) { + eventString = (isImpromptu ? QT_TRANSLATE_NOOP("", "%1% have left the chat") : QT_TRANSLATE_NOOP("", "%1% have left the room")); + } + else { + eventString = (isImpromptu ? QT_TRANSLATE_NOOP("", "%1% have left the chat") : QT_TRANSLATE_NOOP("", "%1% has left the room")); + } + break; + case JoinThenPart: + if (sorted[i].size() > 1) { + eventString = (isImpromptu ? QT_TRANSLATE_NOOP("", "%1% have joined then left the chat") : QT_TRANSLATE_NOOP("", "%1% have entered then left the room")); + } + else { + eventString = (isImpromptu ? QT_TRANSLATE_NOOP("", "%1% has joined then left the chat") : QT_TRANSLATE_NOOP("", "%1% has entered then left the room")); + } + break; + case PartThenJoin: + if (sorted[i].size() > 1) { + eventString = (isImpromptu ? QT_TRANSLATE_NOOP("", "%1% have left then returned to the chat") : QT_TRANSLATE_NOOP("", "%1% have left then returned to the room")); + } + else { + eventString = (isImpromptu ? QT_TRANSLATE_NOOP("", "%1% has left then returned to the chat") : QT_TRANSLATE_NOOP("", "%1% has left then returned to the room")); + } + break; + } + populatedEvents.push_back(static_cast<JoinPart>(i)); + eventStrings[i] = str(boost::format(eventString) % names); + } + } + for (size_t i = 0; i < populatedEvents.size(); i++) { + if (i > 0) { + if (i < populatedEvents.size() - 1) { + result += ", "; + } else { + result += QT_TRANSLATE_NOOP("", " and "); + } + } + result += eventStrings[populatedEvents[i]]; + } + return result; } std::string MUCController::generateNicknameChangeString(const std::string& oldNickname, const std::string& newNickname) { - return str(boost::format(QT_TRANSLATE_NOOP("", "%1% is now known as %2%.")) % oldNickname % newNickname); + return str(boost::format(QT_TRANSLATE_NOOP("", "%1% is now known as %2%.")) % oldNickname % newNickname); } void MUCController::handleChangeSubjectRequest(const std::string& subject) { - muc_->changeSubject(subject); + muc_->changeSubject(subject); } void MUCController::handleBookmarkRequest() { - const JID jid = muc_->getJID(); + const JID jid = muc_->getJID(); - // Prepare new bookmark for this room. - MUCBookmark roomBookmark(jid, jid.toBare().toString()); - roomBookmark.setPassword(password_); - roomBookmark.setNick(nick_); + // Prepare new bookmark for this room. + MUCBookmark roomBookmark(jid, jid.toBare().toString()); + roomBookmark.setPassword(password_); + roomBookmark.setNick(nick_); - // Check for existing bookmark for this room and, if it exists, use it instead. - std::vector<MUCBookmark> bookmarks = mucBookmarkManager_->getBookmarks(); - foreach (const MUCBookmark& bookmark, bookmarks) { - if (bookmark.getRoom() == jid.toBare()) { - roomBookmark = bookmark; - break; - } - } + // Check for existing bookmark for this room and, if it exists, use it instead. + std::vector<MUCBookmark> bookmarks = mucBookmarkManager_->getBookmarks(); + foreach (const MUCBookmark& bookmark, bookmarks) { + if (bookmark.getRoom() == jid.toBare()) { + roomBookmark = bookmark; + break; + } + } - chatWindow_->showBookmarkWindow(roomBookmark); + chatWindow_->showBookmarkWindow(roomBookmark); } void MUCController::handleConfigureRequest(Form::ref form) { - if (form) { - muc_->configureRoom(form); - } - else { - muc_->requestConfigurationForm(); - } + if (form) { + muc_->configureRoom(form); + } + else { + muc_->requestConfigurationForm(); + } } void MUCController::handleConfigurationFailed(ErrorPayload::ref error) { - std::string errorMessage = getErrorMessage(error); - errorMessage = str(format(QT_TRANSLATE_NOOP("", "Room configuration failed: %1%.")) % errorMessage); - chatWindow_->addErrorMessage(chatMessageParser_->parseMessageBody(errorMessage)); + std::string errorMessage = getErrorMessage(error); + errorMessage = str(format(QT_TRANSLATE_NOOP("", "Room configuration failed: %1%.")) % errorMessage); + chatWindow_->addErrorMessage(chatMessageParser_->parseMessageBody(errorMessage)); } void MUCController::handleOccupantRoleChangeFailed(ErrorPayload::ref error, const JID&, MUCOccupant::Role) { - std::string errorMessage = getErrorMessage(error); - errorMessage = str(format(QT_TRANSLATE_NOOP("", "Occupant role change failed: %1%.")) % errorMessage); - chatWindow_->addErrorMessage(chatMessageParser_->parseMessageBody(errorMessage)); + std::string errorMessage = getErrorMessage(error); + errorMessage = str(format(QT_TRANSLATE_NOOP("", "Occupant role change failed: %1%.")) % errorMessage); + chatWindow_->addErrorMessage(chatMessageParser_->parseMessageBody(errorMessage)); } void MUCController::configureAsImpromptuRoom(Form::ref form) { - muc_->configureRoom(buildImpromptuRoomConfiguration(form)); - isImpromptuAlreadyConfigured_ = true; - onImpromptuConfigCompleted(); + muc_->configureRoom(buildImpromptuRoomConfiguration(form)); + isImpromptuAlreadyConfigured_ = true; + onImpromptuConfigCompleted(); } void MUCController::handleConfigurationFormReceived(Form::ref form) { - if (isImpromptu_) { - if (!isImpromptuAlreadyConfigured_) { - configureAsImpromptuRoom(form); - } - } else { - chatWindow_->showRoomConfigurationForm(form); - } + if (isImpromptu_) { + if (!isImpromptuAlreadyConfigured_) { + configureAsImpromptuRoom(form); + } + } else { + chatWindow_->showRoomConfigurationForm(form); + } } void MUCController::handleConfigurationCancelled() { - muc_->cancelConfigureRoom(); + muc_->cancelConfigureRoom(); } void MUCController::handleDestroyRoomRequest() { - muc_->destroyRoom(); + muc_->destroyRoom(); } void MUCController::handleInvitePersonToThisMUCRequest(const std::vector<JID>& jidsToInvite) { - RequestInviteToMUCUIEvent::ImpromptuMode mode = isImpromptu_ ? RequestInviteToMUCUIEvent::Impromptu : RequestInviteToMUCUIEvent::NotImpromptu; - boost::shared_ptr<UIEvent> event(new RequestInviteToMUCUIEvent(muc_->getJID(), jidsToInvite, mode)); - eventStream_->send(event); + RequestInviteToMUCUIEvent::ImpromptuMode mode = isImpromptu_ ? RequestInviteToMUCUIEvent::Impromptu : RequestInviteToMUCUIEvent::NotImpromptu; + boost::shared_ptr<UIEvent> event(new RequestInviteToMUCUIEvent(muc_->getJID(), jidsToInvite, mode)); + eventStream_->send(event); } void MUCController::handleUIEvent(boost::shared_ptr<UIEvent> event) { - boost::shared_ptr<InviteToMUCUIEvent> inviteEvent = boost::dynamic_pointer_cast<InviteToMUCUIEvent>(event); - if (inviteEvent && inviteEvent->getRoom() == muc_->getJID()) { - foreach (const JID& jid, inviteEvent->getInvites()) { - muc_->invitePerson(jid, inviteEvent->getReason(), isImpromptu_); - } - } + boost::shared_ptr<InviteToMUCUIEvent> inviteEvent = boost::dynamic_pointer_cast<InviteToMUCUIEvent>(event); + if (inviteEvent && inviteEvent->getRoom() == muc_->getJID()) { + foreach (const JID& jid, inviteEvent->getInvites()) { + muc_->invitePerson(jid, inviteEvent->getReason(), isImpromptu_); + } + } } void MUCController::handleGetAffiliationsRequest() { - muc_->requestAffiliationList(MUCOccupant::Owner); - muc_->requestAffiliationList(MUCOccupant::Admin); - muc_->requestAffiliationList(MUCOccupant::Member); - muc_->requestAffiliationList(MUCOccupant::Outcast); + muc_->requestAffiliationList(MUCOccupant::Owner); + muc_->requestAffiliationList(MUCOccupant::Admin); + muc_->requestAffiliationList(MUCOccupant::Member); + muc_->requestAffiliationList(MUCOccupant::Outcast); } typedef std::pair<MUCOccupant::Affiliation, JID> AffiliationChangePair; void MUCController::handleChangeAffiliationsRequest(const std::vector<std::pair<MUCOccupant::Affiliation, JID> >& changes) { - std::set<JID> addedJIDs; - foreach (const AffiliationChangePair& change, changes) { - if (change.first != MUCOccupant::NoAffiliation) { - addedJIDs.insert(change.second); - } - } - foreach (const AffiliationChangePair& change, changes) { - if (change.first != MUCOccupant::NoAffiliation || addedJIDs.find(change.second) == addedJIDs.end()) { - muc_->changeAffiliation(change.second, change.first); - } - } + std::set<JID> addedJIDs; + foreach (const AffiliationChangePair& change, changes) { + if (change.first != MUCOccupant::NoAffiliation) { + addedJIDs.insert(change.second); + } + } + foreach (const AffiliationChangePair& change, changes) { + if (change.first != MUCOccupant::NoAffiliation || addedJIDs.find(change.second) == addedJIDs.end()) { + muc_->changeAffiliation(change.second, change.first); + } + } } void MUCController::handleUnblockUserRequest() { - eventStream_->send(boost::make_shared<RequestChangeBlockStateUIEvent>(RequestChangeBlockStateUIEvent::Unblocked, muc_->getJID())); + eventStream_->send(boost::make_shared<RequestChangeBlockStateUIEvent>(RequestChangeBlockStateUIEvent::Unblocked, muc_->getJID())); } void MUCController::handleBlockingStateChanged() { - boost::shared_ptr<BlockList> blockList = clientBlockListManager_->getBlockList(); - if (blockList->getState() == BlockList::Available) { - if (blockList->isBlocked(toJID_)) { - if (!blockedContactAlert_) { - blockedContactAlert_ = chatWindow_->addAlert(QT_TRANSLATE_NOOP("", "You've blocked this room. To enter the room, first unblock it using the cog menu and try again")); - } - chatWindow_->setBlockingState(ChatWindow::IsBlocked); - } else { - if (blockedContactAlert_) { - chatWindow_->removeAlert(*blockedContactAlert_); - blockedContactAlert_.reset(); - } - chatWindow_->setBlockingState(ChatWindow::IsUnblocked); - } - } + boost::shared_ptr<BlockList> blockList = clientBlockListManager_->getBlockList(); + if (blockList->getState() == BlockList::Available) { + if (blockList->isBlocked(toJID_)) { + if (!blockedContactAlert_) { + blockedContactAlert_ = chatWindow_->addAlert(QT_TRANSLATE_NOOP("", "You've blocked this room. To enter the room, first unblock it using the cog menu and try again")); + } + chatWindow_->setBlockingState(ChatWindow::IsBlocked); + } else { + if (blockedContactAlert_) { + chatWindow_->removeAlert(*blockedContactAlert_); + blockedContactAlert_.reset(); + } + chatWindow_->setBlockingState(ChatWindow::IsUnblocked); + } + } } void MUCController::handleAffiliationListReceived(MUCOccupant::Affiliation affiliation, const std::vector<JID>& jids) { - chatWindow_->setAffiliations(affiliation, jids); + chatWindow_->setAffiliations(affiliation, jids); } void MUCController::logMessage(const std::string& message, const JID& fromJID, const JID& toJID, const boost::posix_time::ptime& timeStamp, bool isIncoming) { - // log only incoming messages - if (isIncoming && historyController_) { - historyController_->addMessage(message, fromJID, toJID, HistoryMessage::Groupchat, timeStamp); - } + // log only incoming messages + if (isIncoming && historyController_) { + historyController_->addMessage(message, fromJID, toJID, HistoryMessage::Groupchat, timeStamp); + } } void MUCController::addRecentLogs() { - if (!historyController_) { - return; - } + if (!historyController_) { + return; + } - joinContext_ = historyController_->getMUCContext(selfJID_, toJID_, lastActivity_); + joinContext_ = historyController_->getMUCContext(selfJID_, toJID_, lastActivity_); - foreach (const HistoryMessage& message, joinContext_) { - bool senderIsSelf = nick_ == message.getFromJID().getResource(); + foreach (const HistoryMessage& message, joinContext_) { + bool senderIsSelf = nick_ == message.getFromJID().getResource(); - // the chatWindow uses utc timestamps - addMessage(chatMessageParser_->parseMessageBody(message.getMessage()), senderDisplayNameFromMessage(message.getFromJID()), senderIsSelf, boost::shared_ptr<SecurityLabel>(new SecurityLabel()), avatarManager_->getAvatarPath(message.getFromJID()), message.getTime() - boost::posix_time::hours(message.getOffset())); - } + // the chatWindow uses utc timestamps + addMessage(chatMessageParser_->parseMessageBody(message.getMessage()), senderDisplayNameFromMessage(message.getFromJID()), senderIsSelf, boost::shared_ptr<SecurityLabel>(new SecurityLabel()), avatarManager_->getAvatarPath(message.getFromJID()), message.getTime() - boost::posix_time::hours(message.getOffset())); + } } void MUCController::checkDuplicates(boost::shared_ptr<Message> newMessage) { - std::string body = newMessage->getBody().get_value_or(""); - JID jid = newMessage->getFrom(); - boost::optional<boost::posix_time::ptime> time = newMessage->getTimestamp(); - - reverse_foreach (const HistoryMessage& message, joinContext_) { - boost::posix_time::ptime messageTime = message.getTime() - boost::posix_time::hours(message.getOffset()); - if (time && time < messageTime) { - break; - } - if (time && time != messageTime) { - continue; - } - if (message.getFromJID() != jid) { - continue; - } - if (message.getMessage() != body) { - continue; - } - - // Mark the message as unreadable - newMessage->setBody(""); - } + std::string body = newMessage->getBody().get_value_or(""); + JID jid = newMessage->getFrom(); + boost::optional<boost::posix_time::ptime> time = newMessage->getTimestamp(); + + reverse_foreach (const HistoryMessage& message, joinContext_) { + boost::posix_time::ptime messageTime = message.getTime() - boost::posix_time::hours(message.getOffset()); + if (time && time < messageTime) { + break; + } + if (time && time != messageTime) { + continue; + } + if (message.getFromJID() != jid) { + continue; + } + if (message.getMessage() != body) { + continue; + } + + // Mark the message as unreadable + newMessage->setBody(""); + } } void MUCController::setNick(const std::string& nick) { - nick_ = nick; - highlighter_->setNick(nick_); + nick_ = nick; + highlighter_->setNick(nick_); } Form::ref MUCController::buildImpromptuRoomConfiguration(Form::ref roomConfigurationForm) { - Form::ref result = boost::make_shared<Form>(Form::SubmitType); - std::string impromptuConfigs[] = { "muc#roomconfig_enablelogging", "muc#roomconfig_persistentroom", "muc#roomconfig_publicroom", "muc#roomconfig_whois"}; - std::set<std::string> impromptuConfigsMissing(impromptuConfigs, impromptuConfigs + 4); - foreach (boost::shared_ptr<FormField> field, roomConfigurationForm->getFields()) { - boost::shared_ptr<FormField> resultField; - if (field->getName() == "muc#roomconfig_enablelogging") { - resultField = boost::make_shared<FormField>(FormField::BooleanType, "0"); - } - if (field->getName() == "muc#roomconfig_persistentroom") { - resultField = boost::make_shared<FormField>(FormField::BooleanType, "0"); - } - if (field->getName() == "muc#roomconfig_publicroom") { - resultField = boost::make_shared<FormField>(FormField::BooleanType, "0"); - } - if (field->getName() == "muc#roomconfig_whois") { - resultField = boost::make_shared<FormField>(FormField::ListSingleType, "anyone"); - } - - if (field->getName() == "FORM_TYPE") { - resultField = boost::make_shared<FormField>(FormField::HiddenType, "http://jabber.org/protocol/muc#roomconfig"); - } - - if (resultField) { - impromptuConfigsMissing.erase(field->getName()); - resultField->setName(field->getName()); - result->addField(resultField); - } - } - - foreach (const std::string& config, impromptuConfigsMissing) { - if (config == "muc#roomconfig_publicroom") { - chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(QT_TRANSLATE_NOOP("", "This server doesn't support hiding your chat from other users.")), ChatWindow::DefaultDirection); - } else if (config == "muc#roomconfig_whois") { - chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(QT_TRANSLATE_NOOP("", "This server doesn't support sharing people's real identity in this chat.")), ChatWindow::DefaultDirection); - } - } - - return result; + Form::ref result = boost::make_shared<Form>(Form::SubmitType); + std::string impromptuConfigs[] = { "muc#roomconfig_enablelogging", "muc#roomconfig_persistentroom", "muc#roomconfig_publicroom", "muc#roomconfig_whois"}; + std::set<std::string> impromptuConfigsMissing(impromptuConfigs, impromptuConfigs + 4); + foreach (boost::shared_ptr<FormField> field, roomConfigurationForm->getFields()) { + boost::shared_ptr<FormField> resultField; + if (field->getName() == "muc#roomconfig_enablelogging") { + resultField = boost::make_shared<FormField>(FormField::BooleanType, "0"); + } + if (field->getName() == "muc#roomconfig_persistentroom") { + resultField = boost::make_shared<FormField>(FormField::BooleanType, "0"); + } + if (field->getName() == "muc#roomconfig_publicroom") { + resultField = boost::make_shared<FormField>(FormField::BooleanType, "0"); + } + if (field->getName() == "muc#roomconfig_whois") { + resultField = boost::make_shared<FormField>(FormField::ListSingleType, "anyone"); + } + + if (field->getName() == "FORM_TYPE") { + resultField = boost::make_shared<FormField>(FormField::HiddenType, "http://jabber.org/protocol/muc#roomconfig"); + } + + if (resultField) { + impromptuConfigsMissing.erase(field->getName()); + resultField->setName(field->getName()); + result->addField(resultField); + } + } + + foreach (const std::string& config, impromptuConfigsMissing) { + if (config == "muc#roomconfig_publicroom") { + chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(QT_TRANSLATE_NOOP("", "This server doesn't support hiding your chat from other users.")), ChatWindow::DefaultDirection); + } else if (config == "muc#roomconfig_whois") { + chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(QT_TRANSLATE_NOOP("", "This server doesn't support sharing people's real identity in this chat.")), ChatWindow::DefaultDirection); + } + } + + return result; } void MUCController::setImpromptuWindowTitle() { - std::string title; - typedef std::pair<std::string, MUCOccupant> StringMUCOccupantPair; - std::map<std::string, MUCOccupant> occupants = muc_->getOccupants(); - if (occupants.size() <= 1) { - title = QT_TRANSLATE_NOOP("", "Empty Chat"); - } else { - foreach (StringMUCOccupantPair pair, occupants) { - if (pair.first != nick_) { - title += (title.empty() ? "" : ", ") + pair.first; - } - } - } - chatWindow_->setName(title); + std::string title; + typedef std::pair<std::string, MUCOccupant> StringMUCOccupantPair; + std::map<std::string, MUCOccupant> occupants = muc_->getOccupants(); + if (occupants.size() <= 1) { + title = QT_TRANSLATE_NOOP("", "Empty Chat"); + } else { + foreach (StringMUCOccupantPair pair, occupants) { + if (pair.first != nick_) { + title += (title.empty() ? "" : ", ") + pair.first; + } + } + } + chatWindow_->setName(title); } void MUCController::handleRoomUnlocked() { - // Handle buggy MUC implementations where the joined room already exists and is unlocked. - // Configure the room again in this case. - if (!isImpromptuAlreadyConfigured_) { - if (isImpromptu_ && (muc_->getOccupant(nick_).getAffiliation() == MUCOccupant::Owner)) { - muc_->requestConfigurationForm(); - } else if (isImpromptu_) { - onImpromptuConfigCompleted(); - } - } + // Handle buggy MUC implementations where the joined room already exists and is unlocked. + // Configure the room again in this case. + if (!isImpromptuAlreadyConfigured_) { + if (isImpromptu_ && (muc_->getOccupant(nick_).getAffiliation() == MUCOccupant::Owner)) { + muc_->requestConfigurationForm(); + } else if (isImpromptu_) { + onImpromptuConfigCompleted(); + } + } } void MUCController::setAvailableServerFeatures(boost::shared_ptr<DiscoInfo> info) { - ChatControllerBase::setAvailableServerFeatures(info); - if (iqRouter_->isAvailable() && info->hasFeature(DiscoInfo::BlockingCommandFeature)) { - boost::shared_ptr<BlockList> blockList = clientBlockListManager_->getBlockList(); + ChatControllerBase::setAvailableServerFeatures(info); + if (iqRouter_->isAvailable() && info->hasFeature(DiscoInfo::BlockingCommandFeature)) { + boost::shared_ptr<BlockList> blockList = clientBlockListManager_->getBlockList(); - blockingOnStateChangedConnection_ = blockList->onStateChanged.connect(boost::bind(&MUCController::handleBlockingStateChanged, this)); - blockingOnItemAddedConnection_ = blockList->onItemAdded.connect(boost::bind(&MUCController::handleBlockingStateChanged, this)); - blockingOnItemRemovedConnection_ = blockList->onItemRemoved.connect(boost::bind(&MUCController::handleBlockingStateChanged, this)); + blockingOnStateChangedConnection_ = blockList->onStateChanged.connect(boost::bind(&MUCController::handleBlockingStateChanged, this)); + blockingOnItemAddedConnection_ = blockList->onItemAdded.connect(boost::bind(&MUCController::handleBlockingStateChanged, this)); + blockingOnItemRemovedConnection_ = blockList->onItemRemoved.connect(boost::bind(&MUCController::handleBlockingStateChanged, this)); - handleBlockingStateChanged(); - } + handleBlockingStateChanged(); + } } void MUCController::handleMUCBookmarkAdded(const MUCBookmark& bookmark) { - if (bookmark.getRoom() == muc_->getJID()) { - updateChatWindowBookmarkStatus(bookmark); - } + if (bookmark.getRoom() == muc_->getJID()) { + updateChatWindowBookmarkStatus(bookmark); + } } void MUCController::handleMUCBookmarkRemoved(const MUCBookmark& bookmark) { - if (bookmark.getRoom() == muc_->getJID()) { - updateChatWindowBookmarkStatus(boost::optional<MUCBookmark>()); - } + if (bookmark.getRoom() == muc_->getJID()) { + updateChatWindowBookmarkStatus(boost::optional<MUCBookmark>()); + } } void MUCController::updateChatWindowBookmarkStatus(const boost::optional<MUCBookmark>& bookmark) { - assert(chatWindow_); - if (bookmark) { - if (bookmark->getAutojoin()) { - chatWindow_->setBookmarkState(ChatWindow::RoomAutoJoined); - } - else { - chatWindow_->setBookmarkState(ChatWindow::RoomBookmarked); - } - } - else { - chatWindow_->setBookmarkState(ChatWindow::RoomNotBookmarked); - } + assert(chatWindow_); + if (bookmark) { + if (bookmark->getAutojoin()) { + chatWindow_->setBookmarkState(ChatWindow::RoomAutoJoined); + } + else { + chatWindow_->setBookmarkState(ChatWindow::RoomBookmarked); + } + } + else { + chatWindow_->setBookmarkState(ChatWindow::RoomNotBookmarked); + } } } diff --git a/Swift/Controllers/Chat/MUCController.h b/Swift/Controllers/Chat/MUCController.h index 0fb739a..3a61952 100644 --- a/Swift/Controllers/Chat/MUCController.h +++ b/Swift/Controllers/Chat/MUCController.h @@ -27,159 +27,159 @@ #include <Swift/Controllers/UIInterfaces/ChatWindow.h> namespace Swift { - class StanzaChannel; - class IQRouter; - class ChatWindowFactory; - class Roster; - class AvatarManager; - class UIEventStream; - class TimerFactory; - class TabComplete; - class XMPPRoster; - class HighlightManager; - class UIEvent; - class VCardManager; - class RosterVCardProvider; - class ClientBlockListManager; - class MUCBookmarkManager; - class MUCBookmark; - - enum JoinPart {Join, Part, JoinThenPart, PartThenJoin}; - - struct NickJoinPart { - 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, HighlightManager* highlightManager, ClientBlockListManager* clientBlockListManager, boost::shared_ptr<ChatMessageParser> chatMessageParser, bool isImpromptu, AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider, VCardManager* vcardManager, MUCBookmarkManager* mucBookmarkManager); - virtual ~MUCController(); - boost::signal<void ()> onUserLeft; - boost::signal<void ()> onUserJoined; - boost::signal<void ()> onImpromptuConfigCompleted; - boost::signal<void (const std::string&, const std::string& )> onUserNicknameChanged; - virtual void setOnline(bool online) SWIFTEN_OVERRIDE; - virtual void setAvailableServerFeatures(boost::shared_ptr<DiscoInfo> info) SWIFTEN_OVERRIDE; - void rejoin(); - static void appendToJoinParts(std::vector<NickJoinPart>& joinParts, const NickJoinPart& newEvent); - static std::string generateJoinPartString(const std::vector<NickJoinPart>& joinParts, bool isImpromptu); - static std::string concatenateListOfNames(const std::vector<NickJoinPart>& joinParts); - static std::string generateNicknameChangeString(const std::string& oldNickname, const std::string& newNickname); - bool isJoined(); - const std::string& getNick(); - const boost::optional<std::string> getPassword() const; - bool isImpromptu() const; - std::map<std::string, JID> getParticipantJIDs() const; - void sendInvites(const std::vector<JID>& jids, const std::string& reason) const; - - protected: - virtual void preSendMessageRequest(boost::shared_ptr<Message> message) SWIFTEN_OVERRIDE; - virtual bool isIncomingMessageFromMe(boost::shared_ptr<Message> message) SWIFTEN_OVERRIDE; - virtual std::string senderHighlightNameFromMessage(const JID& from) SWIFTEN_OVERRIDE; - virtual std::string senderDisplayNameFromMessage(const JID& from) SWIFTEN_OVERRIDE; - virtual boost::optional<boost::posix_time::ptime> getMessageTimestamp(boost::shared_ptr<Message> message) const SWIFTEN_OVERRIDE; - virtual void preHandleIncomingMessage(boost::shared_ptr<MessageEvent>) SWIFTEN_OVERRIDE; - virtual void addMessageHandleIncomingMessage(const JID& from, const ChatWindow::ChatMessage& message, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const boost::posix_time::ptime& time) SWIFTEN_OVERRIDE; - virtual void postHandleIncomingMessage(boost::shared_ptr<MessageEvent>, const ChatWindow::ChatMessage& chatMessage) SWIFTEN_OVERRIDE; - virtual void cancelReplaces() SWIFTEN_OVERRIDE; - virtual void logMessage(const std::string& message, const JID& fromJID, const JID& toJID, const boost::posix_time::ptime& timeStamp, bool isIncoming) SWIFTEN_OVERRIDE; - - private: - void setAvailableRoomActions(const MUCOccupant::Affiliation& affiliation, const MUCOccupant::Role& role); - void clearPresenceQueue(); - void addPresenceMessage(const std::string& message); - void handleWindowOccupantSelectionChanged(ContactRosterItem* item); - void handleActionRequestedOnOccupant(ChatWindow::OccupantAction, ContactRosterItem* item); - void handleWindowClosed(); - void handleAvatarChanged(const JID& jid); - void handleOccupantJoined(const MUCOccupant& occupant); - void handleOccupantNicknameChanged(const std::string& oldNickname, const std::string& newNickname); - void handleOccupantLeft(const MUCOccupant& occupant, MUC::LeavingType type, const std::string& reason); - void handleOccupantPresenceChange(boost::shared_ptr<Presence> presence); - void handleOccupantRoleChanged(const std::string& nick, const MUCOccupant& occupant,const MUCOccupant::Role& oldRole); - void handleOccupantAffiliationChanged(const std::string& nick, const MUCOccupant::Affiliation& affiliation,const MUCOccupant::Affiliation& oldAffiliation); - void handleJoinComplete(const std::string& nick); - void handleJoinFailed(boost::shared_ptr<ErrorPayload> error); - void handleJoinTimeoutTick(); - void handleChangeSubjectRequest(const std::string&); - void handleBookmarkRequest(); - std::string roleToGroupName(MUCOccupant::Role role); - std::string roleToSortName(MUCOccupant::Role role); - JID nickToJID(const std::string& nick); - std::string roleToFriendlyName(MUCOccupant::Role role); - void receivedActivity(); - bool messageTargetsMe(boost::shared_ptr<Message> message); - void updateJoinParts(); - bool shouldUpdateJoinParts(); - virtual void dayTicked() SWIFTEN_OVERRIDE { clearPresenceQueue(); } - void processUserPart(); - virtual void handleBareJIDCapsChanged(const JID& jid) SWIFTEN_OVERRIDE; - void handleConfigureRequest(Form::ref); - void handleConfigurationFailed(ErrorPayload::ref); - void handleConfigurationFormReceived(Form::ref); - void handleDestroyRoomRequest(); - void handleInvitePersonToThisMUCRequest(const std::vector<JID>& jidsToInvite); - void handleConfigurationCancelled(); - void handleOccupantRoleChangeFailed(ErrorPayload::ref, const JID&, MUCOccupant::Role); - void handleGetAffiliationsRequest(); - void handleAffiliationListReceived(MUCOccupant::Affiliation affiliation, const std::vector<JID>& jids); - void handleChangeAffiliationsRequest(const std::vector<std::pair<MUCOccupant::Affiliation, JID> >& changes); - void handleInviteToMUCWindowDismissed(); - void handleInviteToMUCWindowCompleted(); - void handleUIEvent(boost::shared_ptr<UIEvent> event); - void addRecentLogs(); - void checkDuplicates(boost::shared_ptr<Message> newMessage); - void setNick(const std::string& nick); - void setImpromptuWindowTitle(); - void handleRoomUnlocked(); - void configureAsImpromptuRoom(Form::ref form); - Form::ref buildImpromptuRoomConfiguration(Form::ref roomConfigurationForm); - - void handleUnblockUserRequest(); - void handleBlockingStateChanged(); - - void handleMUCBookmarkAdded(const MUCBookmark& bookmark); - void handleMUCBookmarkRemoved(const MUCBookmark& bookmark); - void updateChatWindowBookmarkStatus(const boost::optional<MUCBookmark>& bookmark); - - private: - MUC::ref muc_; - UIEventStream* events_; - std::string nick_; - std::string desiredNick_; - Roster* roster_; - TabComplete* completer_; - bool parting_; - bool joined_; - bool lastWasPresence_; - bool shouldJoinOnReconnect_; - bool doneGettingHistory_; - boost::bsignals::scoped_connection avatarChangedConnection_; - boost::shared_ptr<Timer> loginCheckTimer_; - std::set<std::string> currentOccupants_; - std::vector<NickJoinPart> joinParts_; - boost::posix_time::ptime lastActivity_; - boost::optional<std::string> password_; - XMPPRoster* xmppRoster_; - std::vector<HistoryMessage> joinContext_; - size_t renameCounter_; - bool isImpromptu_; - bool isImpromptuAlreadyConfigured_; - RosterVCardProvider* rosterVCardProvider_; - std::string lastJoinMessageUID_; - - ClientBlockListManager* clientBlockListManager_; - boost::bsignals::scoped_connection blockingOnStateChangedConnection_; - boost::bsignals::scoped_connection blockingOnItemAddedConnection_; - boost::bsignals::scoped_connection blockingOnItemRemovedConnection_; - - boost::optional<ChatWindow::AlertID> blockedContactAlert_; - - MUCBookmarkManager* mucBookmarkManager_; - boost::bsignals::scoped_connection mucBookmarkManagerBookmarkAddedConnection_; - boost::bsignals::scoped_connection mucBookmarkManagerBookmarkRemovedConnection_; - }; + class StanzaChannel; + class IQRouter; + class ChatWindowFactory; + class Roster; + class AvatarManager; + class UIEventStream; + class TimerFactory; + class TabComplete; + class XMPPRoster; + class HighlightManager; + class UIEvent; + class VCardManager; + class RosterVCardProvider; + class ClientBlockListManager; + class MUCBookmarkManager; + class MUCBookmark; + + enum JoinPart {Join, Part, JoinThenPart, PartThenJoin}; + + struct NickJoinPart { + 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, HighlightManager* highlightManager, ClientBlockListManager* clientBlockListManager, boost::shared_ptr<ChatMessageParser> chatMessageParser, bool isImpromptu, AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider, VCardManager* vcardManager, MUCBookmarkManager* mucBookmarkManager); + virtual ~MUCController(); + boost::signal<void ()> onUserLeft; + boost::signal<void ()> onUserJoined; + boost::signal<void ()> onImpromptuConfigCompleted; + boost::signal<void (const std::string&, const std::string& )> onUserNicknameChanged; + virtual void setOnline(bool online) SWIFTEN_OVERRIDE; + virtual void setAvailableServerFeatures(boost::shared_ptr<DiscoInfo> info) SWIFTEN_OVERRIDE; + void rejoin(); + static void appendToJoinParts(std::vector<NickJoinPart>& joinParts, const NickJoinPart& newEvent); + static std::string generateJoinPartString(const std::vector<NickJoinPart>& joinParts, bool isImpromptu); + static std::string concatenateListOfNames(const std::vector<NickJoinPart>& joinParts); + static std::string generateNicknameChangeString(const std::string& oldNickname, const std::string& newNickname); + bool isJoined(); + const std::string& getNick(); + const boost::optional<std::string> getPassword() const; + bool isImpromptu() const; + std::map<std::string, JID> getParticipantJIDs() const; + void sendInvites(const std::vector<JID>& jids, const std::string& reason) const; + + protected: + virtual void preSendMessageRequest(boost::shared_ptr<Message> message) SWIFTEN_OVERRIDE; + virtual bool isIncomingMessageFromMe(boost::shared_ptr<Message> message) SWIFTEN_OVERRIDE; + virtual std::string senderHighlightNameFromMessage(const JID& from) SWIFTEN_OVERRIDE; + virtual std::string senderDisplayNameFromMessage(const JID& from) SWIFTEN_OVERRIDE; + virtual boost::optional<boost::posix_time::ptime> getMessageTimestamp(boost::shared_ptr<Message> message) const SWIFTEN_OVERRIDE; + virtual void preHandleIncomingMessage(boost::shared_ptr<MessageEvent>) SWIFTEN_OVERRIDE; + virtual void addMessageHandleIncomingMessage(const JID& from, const ChatWindow::ChatMessage& message, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const boost::posix_time::ptime& time) SWIFTEN_OVERRIDE; + virtual void postHandleIncomingMessage(boost::shared_ptr<MessageEvent>, const ChatWindow::ChatMessage& chatMessage) SWIFTEN_OVERRIDE; + virtual void cancelReplaces() SWIFTEN_OVERRIDE; + virtual void logMessage(const std::string& message, const JID& fromJID, const JID& toJID, const boost::posix_time::ptime& timeStamp, bool isIncoming) SWIFTEN_OVERRIDE; + + private: + void setAvailableRoomActions(const MUCOccupant::Affiliation& affiliation, const MUCOccupant::Role& role); + void clearPresenceQueue(); + void addPresenceMessage(const std::string& message); + void handleWindowOccupantSelectionChanged(ContactRosterItem* item); + void handleActionRequestedOnOccupant(ChatWindow::OccupantAction, ContactRosterItem* item); + void handleWindowClosed(); + void handleAvatarChanged(const JID& jid); + void handleOccupantJoined(const MUCOccupant& occupant); + void handleOccupantNicknameChanged(const std::string& oldNickname, const std::string& newNickname); + void handleOccupantLeft(const MUCOccupant& occupant, MUC::LeavingType type, const std::string& reason); + void handleOccupantPresenceChange(boost::shared_ptr<Presence> presence); + void handleOccupantRoleChanged(const std::string& nick, const MUCOccupant& occupant,const MUCOccupant::Role& oldRole); + void handleOccupantAffiliationChanged(const std::string& nick, const MUCOccupant::Affiliation& affiliation,const MUCOccupant::Affiliation& oldAffiliation); + void handleJoinComplete(const std::string& nick); + void handleJoinFailed(boost::shared_ptr<ErrorPayload> error); + void handleJoinTimeoutTick(); + void handleChangeSubjectRequest(const std::string&); + void handleBookmarkRequest(); + std::string roleToGroupName(MUCOccupant::Role role); + std::string roleToSortName(MUCOccupant::Role role); + JID nickToJID(const std::string& nick); + std::string roleToFriendlyName(MUCOccupant::Role role); + void receivedActivity(); + bool messageTargetsMe(boost::shared_ptr<Message> message); + void updateJoinParts(); + bool shouldUpdateJoinParts(); + virtual void dayTicked() SWIFTEN_OVERRIDE { clearPresenceQueue(); } + void processUserPart(); + virtual void handleBareJIDCapsChanged(const JID& jid) SWIFTEN_OVERRIDE; + void handleConfigureRequest(Form::ref); + void handleConfigurationFailed(ErrorPayload::ref); + void handleConfigurationFormReceived(Form::ref); + void handleDestroyRoomRequest(); + void handleInvitePersonToThisMUCRequest(const std::vector<JID>& jidsToInvite); + void handleConfigurationCancelled(); + void handleOccupantRoleChangeFailed(ErrorPayload::ref, const JID&, MUCOccupant::Role); + void handleGetAffiliationsRequest(); + void handleAffiliationListReceived(MUCOccupant::Affiliation affiliation, const std::vector<JID>& jids); + void handleChangeAffiliationsRequest(const std::vector<std::pair<MUCOccupant::Affiliation, JID> >& changes); + void handleInviteToMUCWindowDismissed(); + void handleInviteToMUCWindowCompleted(); + void handleUIEvent(boost::shared_ptr<UIEvent> event); + void addRecentLogs(); + void checkDuplicates(boost::shared_ptr<Message> newMessage); + void setNick(const std::string& nick); + void setImpromptuWindowTitle(); + void handleRoomUnlocked(); + void configureAsImpromptuRoom(Form::ref form); + Form::ref buildImpromptuRoomConfiguration(Form::ref roomConfigurationForm); + + void handleUnblockUserRequest(); + void handleBlockingStateChanged(); + + void handleMUCBookmarkAdded(const MUCBookmark& bookmark); + void handleMUCBookmarkRemoved(const MUCBookmark& bookmark); + void updateChatWindowBookmarkStatus(const boost::optional<MUCBookmark>& bookmark); + + private: + MUC::ref muc_; + UIEventStream* events_; + std::string nick_; + std::string desiredNick_; + Roster* roster_; + TabComplete* completer_; + bool parting_; + bool joined_; + bool lastWasPresence_; + bool shouldJoinOnReconnect_; + bool doneGettingHistory_; + boost::bsignals::scoped_connection avatarChangedConnection_; + boost::shared_ptr<Timer> loginCheckTimer_; + std::set<std::string> currentOccupants_; + std::vector<NickJoinPart> joinParts_; + boost::posix_time::ptime lastActivity_; + boost::optional<std::string> password_; + XMPPRoster* xmppRoster_; + std::vector<HistoryMessage> joinContext_; + size_t renameCounter_; + bool isImpromptu_; + bool isImpromptuAlreadyConfigured_; + RosterVCardProvider* rosterVCardProvider_; + std::string lastJoinMessageUID_; + + ClientBlockListManager* clientBlockListManager_; + boost::bsignals::scoped_connection blockingOnStateChangedConnection_; + boost::bsignals::scoped_connection blockingOnItemAddedConnection_; + boost::bsignals::scoped_connection blockingOnItemRemovedConnection_; + + boost::optional<ChatWindow::AlertID> blockedContactAlert_; + + MUCBookmarkManager* mucBookmarkManager_; + boost::bsignals::scoped_connection mucBookmarkManagerBookmarkAddedConnection_; + boost::bsignals::scoped_connection mucBookmarkManagerBookmarkRemovedConnection_; + }; } diff --git a/Swift/Controllers/Chat/MUCSearchController.cpp b/Swift/Controllers/Chat/MUCSearchController.cpp index 702a366..884978c 100644 --- a/Swift/Controllers/Chat/MUCSearchController.cpp +++ b/Swift/Controllers/Chat/MUCSearchController.cpp @@ -26,159 +26,159 @@ namespace Swift { static const std::string SEARCHED_SERVICES = "searchedServices"; MUCSearchController::MUCSearchController(const JID& jid, MUCSearchWindowFactory* factory, IQRouter* iqRouter, ProfileSettingsProvider* settings) : jid_(jid), factory_(factory), iqRouter_(iqRouter), settings_(settings), window_(NULL), walker_(NULL) { - itemsInProgress_ = 0; - loadSavedServices(); + itemsInProgress_ = 0; + loadSavedServices(); } MUCSearchController::~MUCSearchController() { - delete walker_; - delete window_; + delete walker_; + delete window_; } void MUCSearchController::openSearchWindow() { - if (!window_) { - window_ = factory_->createMUCSearchWindow(); - window_->onSearchService.connect(boost::bind(&MUCSearchController::handleSearchService, this, _1)); - window_->onFinished.connect(boost::bind(&MUCSearchController::handleMUCSearchFinished, this, _1)); - window_->addSavedServices(savedServices_); - } - handleSearchService(JID(jid_.getDomain())); - window_->show(); + if (!window_) { + window_ = factory_->createMUCSearchWindow(); + window_->onSearchService.connect(boost::bind(&MUCSearchController::handleSearchService, this, _1)); + window_->onFinished.connect(boost::bind(&MUCSearchController::handleMUCSearchFinished, this, _1)); + window_->addSavedServices(savedServices_); + } + handleSearchService(JID(jid_.getDomain())); + window_->show(); } void MUCSearchController::loadSavedServices() { - savedServices_.clear(); - foreach (std::string stringItem, String::split(settings_->getStringSetting(SEARCHED_SERVICES), '\n')) { - savedServices_.push_back(JID(stringItem)); - } + savedServices_.clear(); + foreach (std::string stringItem, String::split(settings_->getStringSetting(SEARCHED_SERVICES), '\n')) { + savedServices_.push_back(JID(stringItem)); + } } void MUCSearchController::addToSavedServices(const JID& jid) { - savedServices_.erase(std::remove(savedServices_.begin(), savedServices_.end(), jid), savedServices_.end()); - savedServices_.push_front(jid); - - std::string collapsed; - int i = 0; - foreach (JID jidItem, savedServices_) { - if (i >= 15) { - break; - } - if (!collapsed.empty()) { - collapsed += "\n"; - } - collapsed += jidItem.toString(); - ++i; - } - settings_->storeString(SEARCHED_SERVICES, collapsed); - window_->addSavedServices(savedServices_); + savedServices_.erase(std::remove(savedServices_.begin(), savedServices_.end(), jid), savedServices_.end()); + savedServices_.push_front(jid); + + std::string collapsed; + int i = 0; + foreach (JID jidItem, savedServices_) { + if (i >= 15) { + break; + } + if (!collapsed.empty()) { + collapsed += "\n"; + } + collapsed += jidItem.toString(); + ++i; + } + settings_->storeString(SEARCHED_SERVICES, collapsed); + window_->addSavedServices(savedServices_); } void MUCSearchController::handleSearchService(const JID& jid) { - if (!jid.isValid()) { - //Set Window to say error this isn't valid - return; - } - addToSavedServices(jid); - - services_.clear(); - serviceDetails_.clear(); - - window_->setSearchInProgress(true); - refreshView(); - - if (walker_) { - walker_->endWalk(); - walker_->onServiceFound.disconnect(boost::bind(&MUCSearchController::handleDiscoServiceFound, this, _1, _2)); - walker_->onWalkComplete.disconnect(boost::bind(&MUCSearchController::handleDiscoWalkFinished, this)); - delete walker_; - } - - SWIFT_LOG(debug) << "Starting walking MUC services" << std::endl; - itemsInProgress_ = 0; - walker_ = new DiscoServiceWalker(jid, iqRouter_); - walker_->onServiceFound.connect(boost::bind(&MUCSearchController::handleDiscoServiceFound, this, _1, _2)); - walker_->onWalkComplete.connect(boost::bind(&MUCSearchController::handleDiscoWalkFinished, this)); - walker_->beginWalk(); + if (!jid.isValid()) { + //Set Window to say error this isn't valid + return; + } + addToSavedServices(jid); + + services_.clear(); + serviceDetails_.clear(); + + window_->setSearchInProgress(true); + refreshView(); + + if (walker_) { + walker_->endWalk(); + walker_->onServiceFound.disconnect(boost::bind(&MUCSearchController::handleDiscoServiceFound, this, _1, _2)); + walker_->onWalkComplete.disconnect(boost::bind(&MUCSearchController::handleDiscoWalkFinished, this)); + delete walker_; + } + + SWIFT_LOG(debug) << "Starting walking MUC services" << std::endl; + itemsInProgress_ = 0; + walker_ = new DiscoServiceWalker(jid, iqRouter_); + walker_->onServiceFound.connect(boost::bind(&MUCSearchController::handleDiscoServiceFound, this, _1, _2)); + walker_->onWalkComplete.connect(boost::bind(&MUCSearchController::handleDiscoWalkFinished, this)); + walker_->beginWalk(); } void MUCSearchController::handleDiscoServiceFound(const JID& jid, boost::shared_ptr<DiscoInfo> info) { - bool isMUC = false; - std::string name; - foreach (DiscoInfo::Identity identity, info->getIdentities()) { - if ((identity.getCategory() == "directory" - && identity.getType() == "chatroom") - || (identity.getCategory() == "conference" - && identity.getType() == "text")) { - isMUC = true; - name = identity.getName(); - } - } - if (isMUC) { - SWIFT_LOG(debug) << "MUC Service found: " << jid << std::endl; - services_.erase(std::remove(services_.begin(), services_.end(), jid), services_.end()); - services_.push_back(jid); - serviceDetails_[jid].setName(name); - serviceDetails_[jid].setJID(jid); - serviceDetails_[jid].setComplete(false); - itemsInProgress_++; - SWIFT_LOG(debug) << "Requesting items of " << jid << " (" << itemsInProgress_ << " item requests in progress)" << std::endl; - GetDiscoItemsRequest::ref discoItemsRequest = GetDiscoItemsRequest::create(jid, iqRouter_); - discoItemsRequest->onResponse.connect(boost::bind(&MUCSearchController::handleRoomsItemsResponse, this, _1, _2, jid)); - discoItemsRequest->send(); - } - else { - removeService(jid); - } - refreshView(); + bool isMUC = false; + std::string name; + foreach (DiscoInfo::Identity identity, info->getIdentities()) { + if ((identity.getCategory() == "directory" + && identity.getType() == "chatroom") + || (identity.getCategory() == "conference" + && identity.getType() == "text")) { + isMUC = true; + name = identity.getName(); + } + } + if (isMUC) { + SWIFT_LOG(debug) << "MUC Service found: " << jid << std::endl; + services_.erase(std::remove(services_.begin(), services_.end(), jid), services_.end()); + services_.push_back(jid); + serviceDetails_[jid].setName(name); + serviceDetails_[jid].setJID(jid); + serviceDetails_[jid].setComplete(false); + itemsInProgress_++; + SWIFT_LOG(debug) << "Requesting items of " << jid << " (" << itemsInProgress_ << " item requests in progress)" << std::endl; + GetDiscoItemsRequest::ref discoItemsRequest = GetDiscoItemsRequest::create(jid, iqRouter_); + discoItemsRequest->onResponse.connect(boost::bind(&MUCSearchController::handleRoomsItemsResponse, this, _1, _2, jid)); + discoItemsRequest->send(); + } + else { + removeService(jid); + } + refreshView(); } void MUCSearchController::handleDiscoWalkFinished() { - SWIFT_LOG(debug) << "MUC Walk finished" << std::endl; - updateInProgressness(); + SWIFT_LOG(debug) << "MUC Walk finished" << std::endl; + updateInProgressness(); } void MUCSearchController::removeService(const JID& jid) { - serviceDetails_.erase(jid); - services_.erase(std::remove(services_.begin(), services_.end(), jid), services_.end()); - refreshView(); + serviceDetails_.erase(jid); + services_.erase(std::remove(services_.begin(), services_.end(), jid), services_.end()); + refreshView(); } void MUCSearchController::handleRoomsItemsResponse(boost::shared_ptr<DiscoItems> items, ErrorPayload::ref error, const JID& jid) { - itemsInProgress_--; - SWIFT_LOG(debug) << "Items received for " << jid << " (" << itemsInProgress_ << " item requests in progress)" << std::endl; - updateInProgressness(); - if (error) { - handleDiscoError(jid, error); - return; - } - serviceDetails_[jid].clearRooms(); - foreach (DiscoItems::Item item, items->getItems()) { - serviceDetails_[jid].addRoom(MUCService::MUCRoom(item.getJID().getNode(), item.getName(), -1)); - } - serviceDetails_[jid].setComplete(true); - refreshView(); + itemsInProgress_--; + SWIFT_LOG(debug) << "Items received for " << jid << " (" << itemsInProgress_ << " item requests in progress)" << std::endl; + updateInProgressness(); + if (error) { + handleDiscoError(jid, error); + return; + } + serviceDetails_[jid].clearRooms(); + foreach (DiscoItems::Item item, items->getItems()) { + serviceDetails_[jid].addRoom(MUCService::MUCRoom(item.getJID().getNode(), item.getName(), -1)); + } + serviceDetails_[jid].setComplete(true); + refreshView(); } void MUCSearchController::handleDiscoError(const JID& jid, ErrorPayload::ref error) { - serviceDetails_[jid].setComplete(true); - serviceDetails_[jid].setError(error->getText()); + serviceDetails_[jid].setComplete(true); + serviceDetails_[jid].setError(error->getText()); } void MUCSearchController::refreshView() { - window_->clearList(); - foreach (JID jid, services_) { - window_->addService(serviceDetails_[jid]); - } + window_->clearList(); + foreach (JID jid, services_) { + window_->addService(serviceDetails_[jid]); + } } void MUCSearchController::updateInProgressness() { - window_->setSearchInProgress((walker_ && walker_->isActive()) || itemsInProgress_ > 0); + window_->setSearchInProgress((walker_ && walker_->isActive()) || itemsInProgress_ > 0); } void MUCSearchController::handleMUCSearchFinished(const boost::optional<JID>& result) { - if (result) { - onMUCSelected(*result); - } + if (result) { + onMUCSelected(*result); + } } } diff --git a/Swift/Controllers/Chat/MUCSearchController.h b/Swift/Controllers/Chat/MUCSearchController.h index 01bcf74..3d2a2ca 100644 --- a/Swift/Controllers/Chat/MUCSearchController.h +++ b/Swift/Controllers/Chat/MUCSearchController.h @@ -22,103 +22,103 @@ #include <Swift/Controllers/UIEvents/UIEvent.h> namespace Swift { - class UIEventStream; - class MUCSearchWindow; - class MUCSearchWindowFactory; - class IQRouter; - class DiscoServiceWalker; - class NickResolver; - - class MUCService { - public: - class MUCRoom { - public: - MUCRoom(const std::string& node, const std::string& name, int occupants) : node_(node), name_(name), occupants_(occupants) {} - std::string getNode() {return node_;} - std::string getName() {return name_;} - int getOccupantCount() {return occupants_;} - private: - std::string node_; - std::string name_; - int occupants_; - }; - - MUCService() {error_ = false; complete_ = false;} - - void setComplete(bool complete) { - complete_ = complete; - } - - void setName(const std::string& name) { - name_ = name; - } - - void setJID(const JID& jid) { - jid_ = jid; - } - - bool getComplete() const { - return complete_; - } - - JID getJID() const { - return jid_; - } - - std::string getName() const { - return name_; - } - - void setError(const std::string& errorText) {error_ = true; errorText_ = errorText;} - - void clearRooms() {rooms_.clear();} - - void addRoom(const MUCRoom& room) {rooms_.push_back(room);} - - std::vector<MUCRoom> getRooms() const {return rooms_;} - private: - std::string name_; - JID jid_; - std::vector<MUCRoom> rooms_; - bool complete_; - bool error_; - std::string errorText_; - }; - - class MUCSearchController { - public: - MUCSearchController(const JID& jid, MUCSearchWindowFactory* mucSearchWindowFactory, IQRouter* iqRouter, ProfileSettingsProvider* settings); - ~MUCSearchController(); - - void openSearchWindow(); - - public: - boost::signal<void (const JID&)> onMUCSelected; - - private: - void handleSearchService(const JID& jid); - void handleRoomsItemsResponse(boost::shared_ptr<DiscoItems> items, ErrorPayload::ref error, const JID& jid); - void handleDiscoError(const JID& jid, ErrorPayload::ref error); - void handleDiscoServiceFound(const JID&, boost::shared_ptr<DiscoInfo>); - void handleDiscoWalkFinished(); - void handleMUCSearchFinished(const boost::optional<JID>& result); - void removeService(const JID& jid); - void refreshView(); - void loadSavedServices(); - void addToSavedServices(const JID& jid); - void updateInProgressness(); - - private: - JID jid_; - MUCSearchWindowFactory* factory_; - IQRouter* iqRouter_; - ProfileSettingsProvider* settings_; - MUCSearchWindow* window_; - DiscoServiceWalker* walker_; - std::list<JID> services_; - std::list<JID> savedServices_; - std::map<JID, MUCService> serviceDetails_; - std::vector<DiscoServiceWalker*> walksInProgress_; - int itemsInProgress_; - }; + class UIEventStream; + class MUCSearchWindow; + class MUCSearchWindowFactory; + class IQRouter; + class DiscoServiceWalker; + class NickResolver; + + class MUCService { + public: + class MUCRoom { + public: + MUCRoom(const std::string& node, const std::string& name, int occupants) : node_(node), name_(name), occupants_(occupants) {} + std::string getNode() {return node_;} + std::string getName() {return name_;} + int getOccupantCount() {return occupants_;} + private: + std::string node_; + std::string name_; + int occupants_; + }; + + MUCService() {error_ = false; complete_ = false;} + + void setComplete(bool complete) { + complete_ = complete; + } + + void setName(const std::string& name) { + name_ = name; + } + + void setJID(const JID& jid) { + jid_ = jid; + } + + bool getComplete() const { + return complete_; + } + + JID getJID() const { + return jid_; + } + + std::string getName() const { + return name_; + } + + void setError(const std::string& errorText) {error_ = true; errorText_ = errorText;} + + void clearRooms() {rooms_.clear();} + + void addRoom(const MUCRoom& room) {rooms_.push_back(room);} + + std::vector<MUCRoom> getRooms() const {return rooms_;} + private: + std::string name_; + JID jid_; + std::vector<MUCRoom> rooms_; + bool complete_; + bool error_; + std::string errorText_; + }; + + class MUCSearchController { + public: + MUCSearchController(const JID& jid, MUCSearchWindowFactory* mucSearchWindowFactory, IQRouter* iqRouter, ProfileSettingsProvider* settings); + ~MUCSearchController(); + + void openSearchWindow(); + + public: + boost::signal<void (const JID&)> onMUCSelected; + + private: + void handleSearchService(const JID& jid); + void handleRoomsItemsResponse(boost::shared_ptr<DiscoItems> items, ErrorPayload::ref error, const JID& jid); + void handleDiscoError(const JID& jid, ErrorPayload::ref error); + void handleDiscoServiceFound(const JID&, boost::shared_ptr<DiscoInfo>); + void handleDiscoWalkFinished(); + void handleMUCSearchFinished(const boost::optional<JID>& result); + void removeService(const JID& jid); + void refreshView(); + void loadSavedServices(); + void addToSavedServices(const JID& jid); + void updateInProgressness(); + + private: + JID jid_; + MUCSearchWindowFactory* factory_; + IQRouter* iqRouter_; + ProfileSettingsProvider* settings_; + MUCSearchWindow* window_; + DiscoServiceWalker* walker_; + std::list<JID> services_; + std::list<JID> savedServices_; + std::map<JID, MUCService> serviceDetails_; + std::vector<DiscoServiceWalker*> walksInProgress_; + int itemsInProgress_; + }; } diff --git a/Swift/Controllers/Chat/UnitTest/ChatMessageParserTest.cpp b/Swift/Controllers/Chat/UnitTest/ChatMessageParserTest.cpp index 6748b9e..9ed8bf4 100644 --- a/Swift/Controllers/Chat/UnitTest/ChatMessageParserTest.cpp +++ b/Swift/Controllers/Chat/UnitTest/ChatMessageParserTest.cpp @@ -13,269 +13,269 @@ using namespace Swift; class ChatMessageParserTest : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(ChatMessageParserTest); - CPPUNIT_TEST(testFullBody); - CPPUNIT_TEST(testOneEmoticon); - CPPUNIT_TEST(testBareEmoticon); - CPPUNIT_TEST(testHiddenEmoticon); - CPPUNIT_TEST(testEndlineEmoticon); - CPPUNIT_TEST(testBoundedEmoticons); - CPPUNIT_TEST(testNoColourNoHighlight); - CPPUNIT_TEST_SUITE_END(); - + CPPUNIT_TEST_SUITE(ChatMessageParserTest); + CPPUNIT_TEST(testFullBody); + CPPUNIT_TEST(testOneEmoticon); + CPPUNIT_TEST(testBareEmoticon); + CPPUNIT_TEST(testHiddenEmoticon); + CPPUNIT_TEST(testEndlineEmoticon); + CPPUNIT_TEST(testBoundedEmoticons); + CPPUNIT_TEST(testNoColourNoHighlight); + CPPUNIT_TEST_SUITE_END(); + public: - void setUp() { - smile1_ = ":)"; - smile1Path_ = "/blah/smile1.png"; - smile2_ = ":("; - smile2Path_ = "/blah/smile2.jpg"; - emoticons_[smile1_] = smile1Path_; - emoticons_[smile2_] = smile2Path_; - } - - void tearDown() { - emoticons_.clear(); - } - - void assertText(const ChatWindow::ChatMessage& result, size_t index, const std::string& text) { - boost::shared_ptr<ChatWindow::ChatTextMessagePart> part = boost::dynamic_pointer_cast<ChatWindow::ChatTextMessagePart>(result.getParts()[index]); - CPPUNIT_ASSERT_EQUAL(text, part->text); - } - - void assertEmoticon(const ChatWindow::ChatMessage& result, size_t index, const std::string& text, const std::string& path) { - boost::shared_ptr<ChatWindow::ChatEmoticonMessagePart> part = boost::dynamic_pointer_cast<ChatWindow::ChatEmoticonMessagePart>(result.getParts()[index]); - CPPUNIT_ASSERT(!!part); - CPPUNIT_ASSERT_EQUAL(text, part->alternativeText); - CPPUNIT_ASSERT_EQUAL(path, part->imagePath); - } + void setUp() { + smile1_ = ":)"; + smile1Path_ = "/blah/smile1.png"; + smile2_ = ":("; + smile2Path_ = "/blah/smile2.jpg"; + emoticons_[smile1_] = smile1Path_; + emoticons_[smile2_] = smile2Path_; + } + + void tearDown() { + emoticons_.clear(); + } + + void assertText(const ChatWindow::ChatMessage& result, size_t index, const std::string& text) { + boost::shared_ptr<ChatWindow::ChatTextMessagePart> part = boost::dynamic_pointer_cast<ChatWindow::ChatTextMessagePart>(result.getParts()[index]); + CPPUNIT_ASSERT_EQUAL(text, part->text); + } + + void assertEmoticon(const ChatWindow::ChatMessage& result, size_t index, const std::string& text, const std::string& path) { + boost::shared_ptr<ChatWindow::ChatEmoticonMessagePart> part = boost::dynamic_pointer_cast<ChatWindow::ChatEmoticonMessagePart>(result.getParts()[index]); + CPPUNIT_ASSERT(!!part); + CPPUNIT_ASSERT_EQUAL(text, part->alternativeText); + CPPUNIT_ASSERT_EQUAL(path, part->imagePath); + } #define assertHighlight(RESULT, INDEX, TEXT, EXPECTED_HIGHLIGHT) \ - { \ - boost::shared_ptr<ChatWindow::ChatHighlightingMessagePart> part = boost::dynamic_pointer_cast<ChatWindow::ChatHighlightingMessagePart>(RESULT.getParts()[INDEX]); \ - CPPUNIT_ASSERT_EQUAL(std::string(TEXT), part->text); \ - CPPUNIT_ASSERT(EXPECTED_HIGHLIGHT == part->action); \ - } - - void assertURL(const ChatWindow::ChatMessage& result, size_t index, const std::string& text) { - boost::shared_ptr<ChatWindow::ChatURIMessagePart> part = boost::dynamic_pointer_cast<ChatWindow::ChatURIMessagePart>(result.getParts()[index]); - CPPUNIT_ASSERT_EQUAL(text, part->target); - } - - static HighlightRule ruleFromKeyword(const std::string& keyword, bool matchCase, bool matchWholeWord) - { - HighlightRule rule; - std::vector<std::string> keywords; - keywords.push_back(keyword); - rule.setKeywords(keywords); - rule.setMatchCase(matchCase); - rule.setMatchWholeWords(matchWholeWord); - rule.setMatchChat(true); - rule.getAction().setTextBackground("white"); - return rule; - } - - static const HighlightRulesListPtr ruleListFromKeyword(const std::string& keyword, bool matchCase, bool matchWholeWord) - { - boost::shared_ptr<HighlightManager::HighlightRulesList> list = boost::make_shared<HighlightManager::HighlightRulesList>(); - list->addRule(ruleFromKeyword(keyword, matchCase, matchWholeWord)); - return list; - } - - static const HighlightRulesListPtr ruleListFromKeywords(const HighlightRule &rule1, const HighlightRule &rule2) - { - boost::shared_ptr<HighlightManager::HighlightRulesList> list = boost::make_shared<HighlightManager::HighlightRulesList>(); - list->addRule(rule1); - list->addRule(rule2); - return list; - } - - static HighlightRulesListPtr ruleListWithNickHighlight(bool withHighlightColour = true) - { - HighlightRule rule; - rule.setMatchChat(true); - rule.setNickIsKeyword(true); - rule.setMatchCase(true); - rule.setMatchWholeWords(true); - if (withHighlightColour) { - rule.getAction().setTextBackground("white"); - } - boost::shared_ptr<HighlightManager::HighlightRulesList> list = boost::make_shared<HighlightManager::HighlightRulesList>(); - list->addRule(rule); - return list; - } - - void testFullBody() { - const std::string no_special_message = "a message with no special content"; - ChatMessageParser testling(emoticons_, boost::make_shared<HighlightManager::HighlightRulesList>()); - ChatWindow::ChatMessage result = testling.parseMessageBody(no_special_message); - assertText(result, 0, no_special_message); - - HighlightRulesListPtr highlightRuleList = ruleListFromKeyword("trigger", false, false); - testling = ChatMessageParser(emoticons_, highlightRuleList); - result = testling.parseMessageBody(":) shiny :( trigger :) http://wonderland.lit/blah http://denmark.lit boom boom"); - assertEmoticon(result, 0, smile1_, smile1Path_); - assertText(result, 1, " shiny "); - assertEmoticon(result, 2, smile2_, smile2Path_); - assertText(result, 3, " "); - assertHighlight(result, 4, "trigger", highlightRuleList->getRule(0).getAction()); - assertText(result, 5, " "); - assertEmoticon(result, 6, smile1_, smile1Path_); - assertText(result, 7, " "); - assertURL(result, 8, "http://wonderland.lit/blah"); - assertText(result, 9, " "); - assertURL(result, 10, "http://denmark.lit"); - assertText(result, 11, " boom boom"); - - testling = ChatMessageParser(emoticons_, ruleListFromKeyword("trigger", false, false)); - result = testling.parseMessageBody("testtriggermessage"); - assertText(result, 0, "test"); - assertHighlight(result, 1, "trigger", highlightRuleList->getRule(0).getAction()); - assertText(result, 2, "message"); - - testling = ChatMessageParser(emoticons_, ruleListFromKeyword("trigger", false, true)); - result = testling.parseMessageBody("testtriggermessage"); - assertText(result, 0, "testtriggermessage"); - - testling = ChatMessageParser(emoticons_, ruleListFromKeyword("trigger", true, false)); - result = testling.parseMessageBody("TrIgGeR"); - assertText(result, 0, "TrIgGeR"); - - testling = ChatMessageParser(emoticons_, ruleListFromKeyword("trigger", false, false)); - result = testling.parseMessageBody("TrIgGeR"); - assertHighlight(result, 0, "TrIgGeR", highlightRuleList->getRule(0).getAction()); - - testling = ChatMessageParser(emoticons_, ruleListFromKeyword("trigger", false, false)); - result = testling.parseMessageBody("partialTrIgGeRmatch"); - assertText(result, 0, "partial"); - assertHighlight(result, 1, "TrIgGeR", highlightRuleList->getRule(0).getAction()); - assertText(result, 2, "match"); - - testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", false, false), ruleFromKeyword("three", false, false))); - result = testling.parseMessageBody("zero one two three"); - assertText(result, 0, "zero "); - assertHighlight(result, 1, "one", highlightRuleList->getRule(0).getAction()); - assertText(result, 2, " two "); - assertHighlight(result, 3, "three", highlightRuleList->getRule(0).getAction()); - - testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", false, false), ruleFromKeyword("three", false, false))); - result = testling.parseMessageBody("zero oNe two tHrEe"); - assertText(result, 0, "zero "); - assertHighlight(result, 1, "oNe", highlightRuleList->getRule(0).getAction()); - assertText(result, 2, " two "); - assertHighlight(result, 3, "tHrEe", highlightRuleList->getRule(0).getAction()); - - testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", false, false), ruleFromKeyword("three", true, false))); - result = testling.parseMessageBody("zero oNe two tHrEe"); - assertText(result, 0, "zero "); - assertHighlight(result, 1, "oNe", highlightRuleList->getRule(0).getAction()); - assertText(result, 2, " two tHrEe"); - - testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", true, false), ruleFromKeyword("three", true, false))); - result = testling.parseMessageBody("zero oNe two tHrEe"); - assertText(result, 0, "zero oNe two tHrEe"); - - testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", false, false), ruleFromKeyword("three", false, false))); - result = testling.parseMessageBody("zeroonetwothree"); - assertText(result, 0, "zero"); - assertHighlight(result, 1, "one", highlightRuleList->getRule(0).getAction()); - assertText(result, 2, "two"); - assertHighlight(result, 3, "three", highlightRuleList->getRule(0).getAction()); - - testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", true, false), ruleFromKeyword("three", false, false))); - result = testling.parseMessageBody("zeroOnEtwoThReE"); - assertText(result, 0, "zeroOnEtwo"); - assertHighlight(result, 1, "ThReE", highlightRuleList->getRule(0).getAction()); - - testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", false, true), ruleFromKeyword("three", false, false))); - result = testling.parseMessageBody("zeroonetwothree"); - assertText(result, 0, "zeroonetwo"); - assertHighlight(result, 1, "three", highlightRuleList->getRule(0).getAction()); - - testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", false, true), ruleFromKeyword("three", false, true))); - result = testling.parseMessageBody("zeroonetwothree"); - assertText(result, 0, "zeroonetwothree"); - - testling = ChatMessageParser(emoticons_, ruleListWithNickHighlight()); - result = testling.parseMessageBody("Alice", "Alice"); - assertHighlight(result, 0, "Alice", highlightRuleList->getRule(0).getAction()); - - testling = ChatMessageParser(emoticons_, ruleListWithNickHighlight()); - result = testling.parseMessageBody("TextAliceText", "Alice"); - assertText(result, 0, "TextAliceText"); - - testling = ChatMessageParser(emoticons_, ruleListWithNickHighlight()); - result = testling.parseMessageBody("Text Alice Text", "Alice"); - assertText(result, 0, "Text "); - assertHighlight(result, 1, "Alice", highlightRuleList->getRule(0).getAction()); - assertText(result, 2, " Text"); - - testling = ChatMessageParser(emoticons_, ruleListWithNickHighlight()); - result = testling.parseMessageBody("Alice Text", "Alice"); - assertHighlight(result, 0, "Alice", highlightRuleList->getRule(0).getAction()); - assertText(result, 1, " Text"); - - testling = ChatMessageParser(emoticons_, ruleListWithNickHighlight()); - result = testling.parseMessageBody("Text Alice", "Alice"); - assertText(result, 0, "Text "); - assertHighlight(result, 1, "Alice", highlightRuleList->getRule(0).getAction()); - } - - void testOneEmoticon() { - ChatMessageParser testling(emoticons_, boost::make_shared<HighlightManager::HighlightRulesList>()); - ChatWindow::ChatMessage result = testling.parseMessageBody(" :) "); - assertText(result, 0, " "); - assertEmoticon(result, 1, smile1_, smile1Path_); - assertText(result, 2, " "); - } - - - void testBareEmoticon() { - ChatMessageParser testling(emoticons_, boost::make_shared<HighlightManager::HighlightRulesList>()); - ChatWindow::ChatMessage result = testling.parseMessageBody(":)"); - assertEmoticon(result, 0, smile1_, smile1Path_); - } - - void testHiddenEmoticon() { - ChatMessageParser testling(emoticons_, boost::make_shared<HighlightManager::HighlightRulesList>()); - ChatWindow::ChatMessage result = testling.parseMessageBody("b:)a"); - assertText(result, 0, "b:)a"); - } - - void testEndlineEmoticon() { - ChatMessageParser testling(emoticons_, boost::make_shared<HighlightManager::HighlightRulesList>()); - ChatWindow::ChatMessage result = testling.parseMessageBody("Lazy:)"); - assertText(result, 0, "Lazy"); - assertEmoticon(result, 1, smile1_, smile1Path_); - } - - void testBoundedEmoticons() { - ChatMessageParser testling(emoticons_, boost::make_shared<HighlightManager::HighlightRulesList>()); - ChatWindow::ChatMessage result = testling.parseMessageBody(":)Lazy:("); - assertEmoticon(result, 0, smile1_, smile1Path_); - assertText(result, 1, "Lazy"); - assertEmoticon(result, 2, smile2_, smile2Path_); - } - - void testEmoticonParenthesis() { - ChatMessageParser testling(emoticons_, boost::make_shared<HighlightManager::HighlightRulesList>()); - ChatWindow::ChatMessage result = testling.parseMessageBody("(Like this :))"); - assertText(result, 0, "(Like this "); - assertEmoticon(result, 1, smile1_, smile1Path_); - assertText(result, 2, ")"); - } - - void testNoColourNoHighlight() { - ChatMessageParser testling(emoticons_, ruleListWithNickHighlight(false)); - ChatWindow::ChatMessage result = testling.parseMessageBody("Alice", "Alice"); - assertText(result, 0, "Alice"); - } + { \ + boost::shared_ptr<ChatWindow::ChatHighlightingMessagePart> part = boost::dynamic_pointer_cast<ChatWindow::ChatHighlightingMessagePart>(RESULT.getParts()[INDEX]); \ + CPPUNIT_ASSERT_EQUAL(std::string(TEXT), part->text); \ + CPPUNIT_ASSERT(EXPECTED_HIGHLIGHT == part->action); \ + } + + void assertURL(const ChatWindow::ChatMessage& result, size_t index, const std::string& text) { + boost::shared_ptr<ChatWindow::ChatURIMessagePart> part = boost::dynamic_pointer_cast<ChatWindow::ChatURIMessagePart>(result.getParts()[index]); + CPPUNIT_ASSERT_EQUAL(text, part->target); + } + + static HighlightRule ruleFromKeyword(const std::string& keyword, bool matchCase, bool matchWholeWord) + { + HighlightRule rule; + std::vector<std::string> keywords; + keywords.push_back(keyword); + rule.setKeywords(keywords); + rule.setMatchCase(matchCase); + rule.setMatchWholeWords(matchWholeWord); + rule.setMatchChat(true); + rule.getAction().setTextBackground("white"); + return rule; + } + + static const HighlightRulesListPtr ruleListFromKeyword(const std::string& keyword, bool matchCase, bool matchWholeWord) + { + boost::shared_ptr<HighlightManager::HighlightRulesList> list = boost::make_shared<HighlightManager::HighlightRulesList>(); + list->addRule(ruleFromKeyword(keyword, matchCase, matchWholeWord)); + return list; + } + + static const HighlightRulesListPtr ruleListFromKeywords(const HighlightRule &rule1, const HighlightRule &rule2) + { + boost::shared_ptr<HighlightManager::HighlightRulesList> list = boost::make_shared<HighlightManager::HighlightRulesList>(); + list->addRule(rule1); + list->addRule(rule2); + return list; + } + + static HighlightRulesListPtr ruleListWithNickHighlight(bool withHighlightColour = true) + { + HighlightRule rule; + rule.setMatchChat(true); + rule.setNickIsKeyword(true); + rule.setMatchCase(true); + rule.setMatchWholeWords(true); + if (withHighlightColour) { + rule.getAction().setTextBackground("white"); + } + boost::shared_ptr<HighlightManager::HighlightRulesList> list = boost::make_shared<HighlightManager::HighlightRulesList>(); + list->addRule(rule); + return list; + } + + void testFullBody() { + const std::string no_special_message = "a message with no special content"; + ChatMessageParser testling(emoticons_, boost::make_shared<HighlightManager::HighlightRulesList>()); + ChatWindow::ChatMessage result = testling.parseMessageBody(no_special_message); + assertText(result, 0, no_special_message); + + HighlightRulesListPtr highlightRuleList = ruleListFromKeyword("trigger", false, false); + testling = ChatMessageParser(emoticons_, highlightRuleList); + result = testling.parseMessageBody(":) shiny :( trigger :) http://wonderland.lit/blah http://denmark.lit boom boom"); + assertEmoticon(result, 0, smile1_, smile1Path_); + assertText(result, 1, " shiny "); + assertEmoticon(result, 2, smile2_, smile2Path_); + assertText(result, 3, " "); + assertHighlight(result, 4, "trigger", highlightRuleList->getRule(0).getAction()); + assertText(result, 5, " "); + assertEmoticon(result, 6, smile1_, smile1Path_); + assertText(result, 7, " "); + assertURL(result, 8, "http://wonderland.lit/blah"); + assertText(result, 9, " "); + assertURL(result, 10, "http://denmark.lit"); + assertText(result, 11, " boom boom"); + + testling = ChatMessageParser(emoticons_, ruleListFromKeyword("trigger", false, false)); + result = testling.parseMessageBody("testtriggermessage"); + assertText(result, 0, "test"); + assertHighlight(result, 1, "trigger", highlightRuleList->getRule(0).getAction()); + assertText(result, 2, "message"); + + testling = ChatMessageParser(emoticons_, ruleListFromKeyword("trigger", false, true)); + result = testling.parseMessageBody("testtriggermessage"); + assertText(result, 0, "testtriggermessage"); + + testling = ChatMessageParser(emoticons_, ruleListFromKeyword("trigger", true, false)); + result = testling.parseMessageBody("TrIgGeR"); + assertText(result, 0, "TrIgGeR"); + + testling = ChatMessageParser(emoticons_, ruleListFromKeyword("trigger", false, false)); + result = testling.parseMessageBody("TrIgGeR"); + assertHighlight(result, 0, "TrIgGeR", highlightRuleList->getRule(0).getAction()); + + testling = ChatMessageParser(emoticons_, ruleListFromKeyword("trigger", false, false)); + result = testling.parseMessageBody("partialTrIgGeRmatch"); + assertText(result, 0, "partial"); + assertHighlight(result, 1, "TrIgGeR", highlightRuleList->getRule(0).getAction()); + assertText(result, 2, "match"); + + testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", false, false), ruleFromKeyword("three", false, false))); + result = testling.parseMessageBody("zero one two three"); + assertText(result, 0, "zero "); + assertHighlight(result, 1, "one", highlightRuleList->getRule(0).getAction()); + assertText(result, 2, " two "); + assertHighlight(result, 3, "three", highlightRuleList->getRule(0).getAction()); + + testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", false, false), ruleFromKeyword("three", false, false))); + result = testling.parseMessageBody("zero oNe two tHrEe"); + assertText(result, 0, "zero "); + assertHighlight(result, 1, "oNe", highlightRuleList->getRule(0).getAction()); + assertText(result, 2, " two "); + assertHighlight(result, 3, "tHrEe", highlightRuleList->getRule(0).getAction()); + + testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", false, false), ruleFromKeyword("three", true, false))); + result = testling.parseMessageBody("zero oNe two tHrEe"); + assertText(result, 0, "zero "); + assertHighlight(result, 1, "oNe", highlightRuleList->getRule(0).getAction()); + assertText(result, 2, " two tHrEe"); + + testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", true, false), ruleFromKeyword("three", true, false))); + result = testling.parseMessageBody("zero oNe two tHrEe"); + assertText(result, 0, "zero oNe two tHrEe"); + + testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", false, false), ruleFromKeyword("three", false, false))); + result = testling.parseMessageBody("zeroonetwothree"); + assertText(result, 0, "zero"); + assertHighlight(result, 1, "one", highlightRuleList->getRule(0).getAction()); + assertText(result, 2, "two"); + assertHighlight(result, 3, "three", highlightRuleList->getRule(0).getAction()); + + testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", true, false), ruleFromKeyword("three", false, false))); + result = testling.parseMessageBody("zeroOnEtwoThReE"); + assertText(result, 0, "zeroOnEtwo"); + assertHighlight(result, 1, "ThReE", highlightRuleList->getRule(0).getAction()); + + testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", false, true), ruleFromKeyword("three", false, false))); + result = testling.parseMessageBody("zeroonetwothree"); + assertText(result, 0, "zeroonetwo"); + assertHighlight(result, 1, "three", highlightRuleList->getRule(0).getAction()); + + testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", false, true), ruleFromKeyword("three", false, true))); + result = testling.parseMessageBody("zeroonetwothree"); + assertText(result, 0, "zeroonetwothree"); + + testling = ChatMessageParser(emoticons_, ruleListWithNickHighlight()); + result = testling.parseMessageBody("Alice", "Alice"); + assertHighlight(result, 0, "Alice", highlightRuleList->getRule(0).getAction()); + + testling = ChatMessageParser(emoticons_, ruleListWithNickHighlight()); + result = testling.parseMessageBody("TextAliceText", "Alice"); + assertText(result, 0, "TextAliceText"); + + testling = ChatMessageParser(emoticons_, ruleListWithNickHighlight()); + result = testling.parseMessageBody("Text Alice Text", "Alice"); + assertText(result, 0, "Text "); + assertHighlight(result, 1, "Alice", highlightRuleList->getRule(0).getAction()); + assertText(result, 2, " Text"); + + testling = ChatMessageParser(emoticons_, ruleListWithNickHighlight()); + result = testling.parseMessageBody("Alice Text", "Alice"); + assertHighlight(result, 0, "Alice", highlightRuleList->getRule(0).getAction()); + assertText(result, 1, " Text"); + + testling = ChatMessageParser(emoticons_, ruleListWithNickHighlight()); + result = testling.parseMessageBody("Text Alice", "Alice"); + assertText(result, 0, "Text "); + assertHighlight(result, 1, "Alice", highlightRuleList->getRule(0).getAction()); + } + + void testOneEmoticon() { + ChatMessageParser testling(emoticons_, boost::make_shared<HighlightManager::HighlightRulesList>()); + ChatWindow::ChatMessage result = testling.parseMessageBody(" :) "); + assertText(result, 0, " "); + assertEmoticon(result, 1, smile1_, smile1Path_); + assertText(result, 2, " "); + } + + + void testBareEmoticon() { + ChatMessageParser testling(emoticons_, boost::make_shared<HighlightManager::HighlightRulesList>()); + ChatWindow::ChatMessage result = testling.parseMessageBody(":)"); + assertEmoticon(result, 0, smile1_, smile1Path_); + } + + void testHiddenEmoticon() { + ChatMessageParser testling(emoticons_, boost::make_shared<HighlightManager::HighlightRulesList>()); + ChatWindow::ChatMessage result = testling.parseMessageBody("b:)a"); + assertText(result, 0, "b:)a"); + } + + void testEndlineEmoticon() { + ChatMessageParser testling(emoticons_, boost::make_shared<HighlightManager::HighlightRulesList>()); + ChatWindow::ChatMessage result = testling.parseMessageBody("Lazy:)"); + assertText(result, 0, "Lazy"); + assertEmoticon(result, 1, smile1_, smile1Path_); + } + + void testBoundedEmoticons() { + ChatMessageParser testling(emoticons_, boost::make_shared<HighlightManager::HighlightRulesList>()); + ChatWindow::ChatMessage result = testling.parseMessageBody(":)Lazy:("); + assertEmoticon(result, 0, smile1_, smile1Path_); + assertText(result, 1, "Lazy"); + assertEmoticon(result, 2, smile2_, smile2Path_); + } + + void testEmoticonParenthesis() { + ChatMessageParser testling(emoticons_, boost::make_shared<HighlightManager::HighlightRulesList>()); + ChatWindow::ChatMessage result = testling.parseMessageBody("(Like this :))"); + assertText(result, 0, "(Like this "); + assertEmoticon(result, 1, smile1_, smile1Path_); + assertText(result, 2, ")"); + } + + void testNoColourNoHighlight() { + ChatMessageParser testling(emoticons_, ruleListWithNickHighlight(false)); + ChatWindow::ChatMessage result = testling.parseMessageBody("Alice", "Alice"); + assertText(result, 0, "Alice"); + } private: - std::map<std::string, std::string> emoticons_; - std::string smile1_; - std::string smile1Path_; - std::string smile2_; - std::string smile2Path_; + std::map<std::string, std::string> emoticons_; + std::string smile1_; + std::string smile1Path_; + std::string smile2_; + std::string smile2Path_; }; CPPUNIT_TEST_SUITE_REGISTRATION(ChatMessageParserTest); diff --git a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp index d29337d..7445c4b 100644 --- a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp +++ b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp @@ -61,808 +61,808 @@ using namespace Swift; class ChatsManagerTest : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(ChatsManagerTest); - CPPUNIT_TEST(testFirstOpenWindowIncoming); - CPPUNIT_TEST(testSecondOpenWindowIncoming); - CPPUNIT_TEST(testFirstOpenWindowOutgoing); - CPPUNIT_TEST(testFirstOpenWindowBareToFull); - CPPUNIT_TEST(testSecondWindow); - CPPUNIT_TEST(testUnbindRebind); - CPPUNIT_TEST(testNoDuplicateUnbind); - CPPUNIT_TEST(testThreeMUCWindows); - CPPUNIT_TEST(testChatControllerPresenceAccessUpdatedOnRemoveFromRoster); - CPPUNIT_TEST(testChatControllerPresenceAccessUpdatedOnAddToRoster); - CPPUNIT_TEST(testChatControllerPresenceAccessUpdatedOnSubscriptionChangeToBoth); - CPPUNIT_TEST(testChatControllerPresenceAccessUpdatedOnSubscriptionChangeToFrom); - CPPUNIT_TEST(testChatControllerFullJIDBindingOnMessageAndNotReceipt); - CPPUNIT_TEST(testChatControllerFullJIDBindingOnTypingAndNotActive); - CPPUNIT_TEST(testChatControllerPMPresenceHandling); - CPPUNIT_TEST(testLocalMUCServiceDiscoveryResetOnDisconnect); - CPPUNIT_TEST(testChatControllerHighlightingNotificationTesting); - CPPUNIT_TEST(testChatControllerHighlightingNotificationDeduplicateSounds); - CPPUNIT_TEST_SUITE_END(); + CPPUNIT_TEST_SUITE(ChatsManagerTest); + CPPUNIT_TEST(testFirstOpenWindowIncoming); + CPPUNIT_TEST(testSecondOpenWindowIncoming); + CPPUNIT_TEST(testFirstOpenWindowOutgoing); + CPPUNIT_TEST(testFirstOpenWindowBareToFull); + CPPUNIT_TEST(testSecondWindow); + CPPUNIT_TEST(testUnbindRebind); + CPPUNIT_TEST(testNoDuplicateUnbind); + CPPUNIT_TEST(testThreeMUCWindows); + CPPUNIT_TEST(testChatControllerPresenceAccessUpdatedOnRemoveFromRoster); + CPPUNIT_TEST(testChatControllerPresenceAccessUpdatedOnAddToRoster); + CPPUNIT_TEST(testChatControllerPresenceAccessUpdatedOnSubscriptionChangeToBoth); + CPPUNIT_TEST(testChatControllerPresenceAccessUpdatedOnSubscriptionChangeToFrom); + CPPUNIT_TEST(testChatControllerFullJIDBindingOnMessageAndNotReceipt); + CPPUNIT_TEST(testChatControllerFullJIDBindingOnTypingAndNotActive); + CPPUNIT_TEST(testChatControllerPMPresenceHandling); + CPPUNIT_TEST(testLocalMUCServiceDiscoveryResetOnDisconnect); + CPPUNIT_TEST(testChatControllerHighlightingNotificationTesting); + CPPUNIT_TEST(testChatControllerHighlightingNotificationDeduplicateSounds); + CPPUNIT_TEST_SUITE_END(); public: - void setUp() { - mocks_ = new MockRepository(); - jid_ = JID("test@test.com/resource"); - stanzaChannel_ = new DummyStanzaChannel(); - iqChannel_ = new DummyIQChannel(); - iqRouter_ = new IQRouter(iqChannel_); -// capsProvider_ = new DummyCapsProvider(); - eventController_ = new EventController(); - chatWindowFactory_ = mocks_->InterfaceMock<ChatWindowFactory>(); - joinMUCWindowFactory_ = mocks_->InterfaceMock<JoinMUCWindowFactory>(); - xmppRoster_ = new XMPPRosterImpl(); - mucRegistry_ = new MUCRegistry(); - nickResolver_ = new NickResolver(jid_.toBare(), xmppRoster_, NULL, mucRegistry_); - presenceOracle_ = new PresenceOracle(stanzaChannel_, xmppRoster_); - serverDiscoInfo_ = boost::make_shared<DiscoInfo>(); - presenceSender_ = new StanzaChannelPresenceSender(stanzaChannel_); - directedPresenceSender_ = new DirectedPresenceSender(presenceSender_); - mucManager_ = new MUCManager(stanzaChannel_, iqRouter_, directedPresenceSender_, mucRegistry_); - uiEventStream_ = new UIEventStream(); -// entityCapsManager_ = new EntityCapsManager(capsProvider_, stanzaChannel_); - entityCapsProvider_ = new DummyEntityCapsProvider(); - chatListWindowFactory_ = mocks_->InterfaceMock<ChatListWindowFactory>(); - mucSearchWindowFactory_ = mocks_->InterfaceMock<MUCSearchWindowFactory>(); - settings_ = new DummySettingsProvider(); - profileSettings_ = new ProfileSettingsProvider("a", settings_); - chatListWindow_ = new MockChatListWindow(); - ftManager_ = new DummyFileTransferManager(); - ftOverview_ = new FileTransferOverview(ftManager_); - avatarManager_ = new NullAvatarManager(); - wbSessionManager_ = new WhiteboardSessionManager(iqRouter_, stanzaChannel_, presenceOracle_, entityCapsProvider_); - wbManager_ = new WhiteboardManager(whiteboardWindowFactory_, uiEventStream_, nickResolver_, wbSessionManager_); - highlightManager_ = new HighlightManager(settings_); - handledHighlightActions_ = 0; - soundsPlayed_.clear(); - highlightManager_->onHighlight.connect(boost::bind(&ChatsManagerTest::handleHighlightAction, this, _1)); - - crypto_ = PlatformCryptoProvider::create(); - vcardStorage_ = new VCardMemoryStorage(crypto_); - vcardManager_ = new VCardManager(jid_, iqRouter_, vcardStorage_); - mocks_->ExpectCall(chatListWindowFactory_, ChatListWindowFactory::createChatListWindow).With(uiEventStream_).Return(chatListWindow_); - clientBlockListManager_ = new ClientBlockListManager(iqRouter_); - manager_ = new ChatsManager(jid_, stanzaChannel_, iqRouter_, eventController_, chatWindowFactory_, joinMUCWindowFactory_, nickResolver_, presenceOracle_, directedPresenceSender_, uiEventStream_, chatListWindowFactory_, true, NULL, mucRegistry_, entityCapsProvider_, mucManager_, mucSearchWindowFactory_, profileSettings_, ftOverview_, xmppRoster_, false, settings_, NULL, wbManager_, highlightManager_, clientBlockListManager_, emoticons_, vcardManager_); - - manager_->setAvatarManager(avatarManager_); - } - - void tearDown() { - delete highlightManager_; - //delete chatListWindowFactory - delete profileSettings_; - delete avatarManager_; - delete manager_; - delete clientBlockListManager_; - delete vcardManager_; - delete vcardStorage_; - delete crypto_; - delete ftOverview_; - delete ftManager_; - delete wbSessionManager_; - delete wbManager_; - delete directedPresenceSender_; - delete presenceSender_; - delete presenceOracle_; - delete nickResolver_; - delete mucRegistry_; - delete stanzaChannel_; - delete eventController_; - delete iqRouter_; - delete iqChannel_; - delete uiEventStream_; - delete mucManager_; - delete xmppRoster_; - delete entityCapsProvider_; - delete chatListWindow_; - delete mocks_; - delete settings_; - } - - void testFirstOpenWindowIncoming() { - JID messageJID("testling@test.com/resource1"); - - MockChatWindow* window = new MockChatWindow(); - mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID, uiEventStream_).Return(window); - - boost::shared_ptr<Message> message(new Message()); - message->setFrom(messageJID); - std::string body("This is a legible message. >HEH@)oeueu"); - message->setBody(body); - manager_->handleIncomingMessage(message); - CPPUNIT_ASSERT_EQUAL(body, window->lastMessageBody_); - } - - void testSecondOpenWindowIncoming() { - JID messageJID1("testling@test.com/resource1"); - - MockChatWindow* window1 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>(); - mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID1, uiEventStream_).Return(window1); - - boost::shared_ptr<Message> message1(new Message()); - message1->setFrom(messageJID1); - std::string body1("This is a legible message. >HEH@)oeueu"); - message1->setBody(body1); - manager_->handleIncomingMessage(message1); - CPPUNIT_ASSERT_EQUAL(body1, window1->lastMessageBody_); - - JID messageJID2("testling@test.com/resource2"); - - //MockChatWindow* window2 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>(); - //mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID2, uiEventStream_).Return(window2); - - boost::shared_ptr<Message> message2(new Message()); - message2->setFrom(messageJID2); - std::string body2("This is a legible message. .cmaulm.chul"); - message2->setBody(body2); - manager_->handleIncomingMessage(message2); - CPPUNIT_ASSERT_EQUAL(body2, window1->lastMessageBody_); - } - - void testFirstOpenWindowOutgoing() { - std::string messageJIDString("testling@test.com"); - - ChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>(); - mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(messageJIDString), uiEventStream_).Return(window); - - uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(JID(messageJIDString)))); - } - - - void testFirstOpenWindowBareToFull() { - std::string bareJIDString("testling@test.com"); - std::string fullJIDString("testling@test.com/resource1"); - - MockChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>(); - mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(bareJIDString), uiEventStream_).Return(window); - uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(JID(bareJIDString)))); - - boost::shared_ptr<Message> message(new Message()); - message->setFrom(JID(fullJIDString)); - std::string body("This is a legible message. mjuga3089gm8G(*>M)@*("); - message->setBody(body); - manager_->handleIncomingMessage(message); - CPPUNIT_ASSERT_EQUAL(body, window->lastMessageBody_); - } - - void testSecondWindow() { - std::string messageJIDString1("testling1@test.com"); - ChatWindow* window1 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>(); - mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(messageJIDString1), uiEventStream_).Return(window1); - uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(JID(messageJIDString1)))); - - std::string messageJIDString2("testling2@test.com"); - ChatWindow* window2 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>(); - mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(messageJIDString2), uiEventStream_).Return(window2); - - uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(JID(messageJIDString2)))); - } - - /** Complete cycle. - Create unbound window. - Bind it. - Unbind it. - Rebind it. - */ - void testUnbindRebind() { - std::string bareJIDString("testling@test.com"); - std::string fullJIDString1("testling@test.com/resource1"); - std::string fullJIDString2("testling@test.com/resource2"); - - MockChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>(); - mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(bareJIDString), uiEventStream_).Return(window); - uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(JID(bareJIDString)))); - - boost::shared_ptr<Message> message1(new Message()); - message1->setFrom(JID(fullJIDString1)); - std::string messageBody1("This is a legible message."); - message1->setBody(messageBody1); - manager_->handleIncomingMessage(message1); - CPPUNIT_ASSERT_EQUAL(messageBody1, window->lastMessageBody_); - - boost::shared_ptr<Presence> jid1Online(new Presence()); - jid1Online->setFrom(JID(fullJIDString1)); - boost::shared_ptr<Presence> jid1Offline(new Presence()); - jid1Offline->setFrom(JID(fullJIDString1)); - jid1Offline->setType(Presence::Unavailable); - presenceOracle_->onPresenceChange(jid1Offline); - - boost::shared_ptr<Message> message2(new Message()); - message2->setFrom(JID(fullJIDString2)); - std::string messageBody2("This is another legible message."); - message2->setBody(messageBody2); - manager_->handleIncomingMessage(message2); - CPPUNIT_ASSERT_EQUAL(messageBody2, window->lastMessageBody_); - } - - /** - * Test that MUC PMs get opened in the right windows - */ - void testThreeMUCWindows() { - JID muc("testling@test.com"); - ChatWindow* mucWindow = new MockChatWindow(); - mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(muc, uiEventStream_).Return(mucWindow); - uiEventStream_->send(boost::make_shared<JoinMUCUIEvent>(muc, std::string("nick"))); - - - std::string messageJIDString1("testling@test.com/1"); - ChatWindow* window1 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>(); - mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(messageJIDString1), uiEventStream_).Return(window1); - uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(JID(messageJIDString1)))); - - std::string messageJIDString2("testling@test.com/2"); - ChatWindow* window2 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>(); - mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(messageJIDString2), uiEventStream_).Return(window2); - - uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(JID(messageJIDString2)))); - - std::string messageJIDString3("testling@test.com/3"); - ChatWindow* window3 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>(); - mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(messageJIDString3), uiEventStream_).Return(window3); - - uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(JID(messageJIDString3)))); - - /* Refetch an earlier window */ - /* We do not expect a new window to be created */ - uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(JID(messageJIDString1)))); - - } - - /** - Test that a second window isn't unbound where there's already an unbound one. - Bind 1 - Bind 2 - Unbind 1 - Unbind 2 (but it doesn't) - Sent to bound 2 - Rebind 1 - */ - void testNoDuplicateUnbind() { - JID messageJID1("testling@test.com/resource1"); - - MockChatWindow* window1 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>(); - mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID1, uiEventStream_).Return(window1); - - boost::shared_ptr<Message> message1(new Message()); - message1->setFrom(messageJID1); - message1->setBody("This is a legible message1."); - manager_->handleIncomingMessage(message1); - - JID messageJID2("testling@test.com/resource2"); - - //MockChatWindow* window2 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>(); - //mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID2, uiEventStream_).Return(window2); - - boost::shared_ptr<Message> message2(new Message()); - message2->setFrom(messageJID2); - message2->setBody("This is a legible message2."); - manager_->handleIncomingMessage(message2); - - boost::shared_ptr<Presence> jid1Online(new Presence()); - jid1Online->setFrom(JID(messageJID1)); - boost::shared_ptr<Presence> jid1Offline(new Presence()); - jid1Offline->setFrom(JID(messageJID1)); - jid1Offline->setType(Presence::Unavailable); - presenceOracle_->onPresenceChange(jid1Offline); - - boost::shared_ptr<Presence> jid2Online(new Presence()); - jid2Online->setFrom(JID(messageJID2)); - boost::shared_ptr<Presence> jid2Offline(new Presence()); - jid2Offline->setFrom(JID(messageJID2)); - jid2Offline->setType(Presence::Unavailable); - presenceOracle_->onPresenceChange(jid2Offline); - - JID messageJID3("testling@test.com/resource3"); - - boost::shared_ptr<Message> message3(new Message()); - message3->setFrom(messageJID3); - std::string body3("This is a legible message3."); - message3->setBody(body3); - manager_->handleIncomingMessage(message3); - CPPUNIT_ASSERT_EQUAL(body3, window1->lastMessageBody_); - - boost::shared_ptr<Message> message2b(new Message()); - message2b->setFrom(messageJID2); - std::string body2b("This is a legible message2b."); - message2b->setBody(body2b); - manager_->handleIncomingMessage(message2b); - CPPUNIT_ASSERT_EQUAL(body2b, window1->lastMessageBody_); - } - - /** - * Test that ChatController doesn't send receipts anymore after removal of the contact from the roster. - */ - void testChatControllerPresenceAccessUpdatedOnRemoveFromRoster() { - JID messageJID("testling@test.com/resource1"); - xmppRoster_->addContact(messageJID, "foo", std::vector<std::string>(), RosterItemPayload::Both); - - MockChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>(); - mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID, uiEventStream_).Return(window); - settings_->storeSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS, true); - - boost::shared_ptr<Message> message = makeDeliveryReceiptTestMessage(messageJID, "1"); - manager_->handleIncomingMessage(message); - Stanza::ref stanzaContactOnRoster = stanzaChannel_->getStanzaAtIndex<Stanza>(0); - CPPUNIT_ASSERT_EQUAL(st(1), stanzaChannel_->sentStanzas.size()); - CPPUNIT_ASSERT(stanzaContactOnRoster->getPayload<DeliveryReceipt>() != 0); - - xmppRoster_->removeContact(messageJID); - - message->setID("2"); - manager_->handleIncomingMessage(message); - CPPUNIT_ASSERT_EQUAL(st(1), stanzaChannel_->sentStanzas.size()); - } - - /** - * Test that ChatController sends receipts after the contact has been added to the roster. - */ - void testChatControllerPresenceAccessUpdatedOnAddToRoster() { - JID messageJID("testling@test.com/resource1"); - - MockChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>(); - mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID, uiEventStream_).Return(window); - settings_->storeSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS, true); - - boost::shared_ptr<Message> message = makeDeliveryReceiptTestMessage(messageJID, "1"); - manager_->handleIncomingMessage(message); - - CPPUNIT_ASSERT_EQUAL(st(0), stanzaChannel_->sentStanzas.size()); - - xmppRoster_->addContact(messageJID, "foo", std::vector<std::string>(), RosterItemPayload::Both); - message->setID("2"); - manager_->handleIncomingMessage(message); - - CPPUNIT_ASSERT_EQUAL(st(1), stanzaChannel_->sentStanzas.size()); - Stanza::ref stanzaContactOnRoster = stanzaChannel_->getStanzaAtIndex<Stanza>(0); - CPPUNIT_ASSERT(stanzaContactOnRoster->getPayload<DeliveryReceipt>() != 0); - } - - /** - * Test that ChatController sends receipts if requested after change from subscription state To to subscription state Both. - */ - void testChatControllerPresenceAccessUpdatedOnSubscriptionChangeToBoth() { - testhelperChatControllerPresenceAccessUpdatedOnSubscriptionChangeReceiptsAllowed(RosterItemPayload::To, RosterItemPayload::Both); - } - - /** - * Test that ChatController sends receipts if requested after change from subscription state To to subscription state From. - */ - void testChatControllerPresenceAccessUpdatedOnSubscriptionChangeToFrom() { - testhelperChatControllerPresenceAccessUpdatedOnSubscriptionChangeReceiptsAllowed(RosterItemPayload::To, RosterItemPayload::From); - } - - void testChatControllerFullJIDBindingOnMessageAndNotReceipt() { - JID ownJID("test@test.com/resource"); - JID sender("foo@test.com"); - std::vector<JID> senderResource; - senderResource.push_back(sender.withResource("resourceA")); - senderResource.push_back(sender.withResource("resourceB")); - - // We support delivery receipts. - settings_->storeSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS, true); - - // Open chat window to a sender. - MockChatWindow* window = new MockChatWindow(); - mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(sender, uiEventStream_).Return(window); - - uiEventStream_->send(boost::make_shared<RequestChatUIEvent>(sender)); - - foreach(const JID& senderJID, senderResource) { - // The sender supports delivery receipts. - DiscoInfo::ref disco = boost::make_shared<DiscoInfo>(); - disco->addFeature(DiscoInfo::MessageDeliveryReceiptsFeature); - entityCapsProvider_->caps[senderJID] = disco; - - // The sender is online. - Presence::ref senderPresence = boost::make_shared<Presence>(); - senderPresence->setFrom(senderJID); - senderPresence->setTo(ownJID); - stanzaChannel_->onPresenceReceived(senderPresence); - - entityCapsProvider_->onCapsChanged(senderJID); - } - - // Send first message. - window->onSendMessageRequest("hello there", false); - - // A bare message is send because no resources is bound. - CPPUNIT_ASSERT_EQUAL(sender, stanzaChannel_->getStanzaAtIndex<Message>(0)->getTo()); - CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(0)->getPayload<DeliveryReceiptRequest>()); - - // Two resources respond with message receipts. - foreach(const JID& senderJID, senderResource) { - Message::ref receiptReply = boost::make_shared<Message>(); - receiptReply->setFrom(senderJID); - receiptReply->setTo(ownJID); - - boost::shared_ptr<DeliveryReceipt> receipt = boost::make_shared<DeliveryReceipt>(); - receipt->setReceivedID(stanzaChannel_->getStanzaAtIndex<Message>(0)->getID()); - receiptReply->addPayload(receipt); - manager_->handleIncomingMessage(receiptReply); - } - - // Send second message. - window->onSendMessageRequest("how are you?", false); - - // A bare message is send because no resources is bound. - CPPUNIT_ASSERT_EQUAL(sender, stanzaChannel_->getStanzaAtIndex<Message>(1)->getTo()); - CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(1)->getPayload<DeliveryReceiptRequest>()); - - // Two resources respond with message receipts. - foreach(const JID& senderJID, senderResource) { - Message::ref receiptReply = boost::make_shared<Message>(); - receiptReply->setFrom(senderJID); - receiptReply->setTo(ownJID); - - boost::shared_ptr<DeliveryReceipt> receipt = boost::make_shared<DeliveryReceipt>(); - receipt->setReceivedID(stanzaChannel_->getStanzaAtIndex<Message>(1)->getID()); - receiptReply->addPayload(receipt); - manager_->handleIncomingMessage(receiptReply); - } - - // Reply with a message including a body text. - Message::ref reply = boost::make_shared<Message>(); - reply->setFrom(senderResource[0]); - reply->setTo(ownJID); - reply->setBody("fine."); - manager_->handleIncomingMessage(reply); - - // Send third message. - window->onSendMessageRequest("great to hear.", false); - - // The chat session is bound to the full JID of the first resource. - CPPUNIT_ASSERT_EQUAL(senderResource[0], stanzaChannel_->getStanzaAtIndex<Message>(2)->getTo()); - CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(2)->getPayload<DeliveryReceiptRequest>()); - - // Receive random receipt from second sender resource. - reply = boost::make_shared<Message>(); - reply->setFrom(senderResource[1]); - reply->setTo(ownJID); - - boost::shared_ptr<DeliveryReceipt> receipt = boost::make_shared<DeliveryReceipt>(); - receipt->setReceivedID(stanzaChannel_->getStanzaAtIndex<Message>(2)->getID()); - reply->addPayload(receipt); - manager_->handleIncomingMessage(reply); - - // Send forth message. - window->onSendMessageRequest("what else is new?", false); - - // The chat session is bound to the full JID of the first resource. - CPPUNIT_ASSERT_EQUAL(senderResource[0], stanzaChannel_->getStanzaAtIndex<Message>(3)->getTo()); - CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(3)->getPayload<DeliveryReceiptRequest>()); - - // Reply with a message including a body text from second resource. - reply = boost::make_shared<Message>(); - reply->setFrom(senderResource[1]); - reply->setTo(ownJID); - reply->setBody("nothing."); - manager_->handleIncomingMessage(reply); - - // Send fifth message. - window->onSendMessageRequest("okay", false); - - // The chat session is now bound to the full JID of the second resource. - CPPUNIT_ASSERT_EQUAL(senderResource[1], stanzaChannel_->getStanzaAtIndex<Message>(4)->getTo()); - CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(4)->getPayload<DeliveryReceiptRequest>()); - } - - void testChatControllerFullJIDBindingOnTypingAndNotActive() { - JID ownJID("test@test.com/resource"); - JID sender("foo@test.com"); - std::vector<JID> senderResource; - senderResource.push_back(sender.withResource("resourceA")); - senderResource.push_back(sender.withResource("resourceB")); - - // We support delivery receipts. - settings_->storeSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS, true); - - // Open chat window to a sender. - MockChatWindow* window = new MockChatWindow(); - mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(sender, uiEventStream_).Return(window); - - uiEventStream_->send(boost::make_shared<RequestChatUIEvent>(sender)); - - foreach(const JID& senderJID, senderResource) { - // The sender supports delivery receipts. - DiscoInfo::ref disco = boost::make_shared<DiscoInfo>(); - disco->addFeature(DiscoInfo::MessageDeliveryReceiptsFeature); - entityCapsProvider_->caps[senderJID] = disco; - - // The sender is online. - Presence::ref senderPresence = boost::make_shared<Presence>(); - senderPresence->setFrom(senderJID); - senderPresence->setTo(ownJID); - stanzaChannel_->onPresenceReceived(senderPresence); - - entityCapsProvider_->onCapsChanged(senderJID); - } - - // Send first message. - window->onSendMessageRequest("hello there", false); - - // A bare message is send because no resources is bound. - CPPUNIT_ASSERT_EQUAL(sender, stanzaChannel_->getStanzaAtIndex<Message>(0)->getTo()); - CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(0)->getPayload<DeliveryReceiptRequest>()); - - // Two resources respond with message receipts. - foreach(const JID& senderJID, senderResource) { - Message::ref reply = boost::make_shared<Message>(); - reply->setFrom(senderJID); - reply->setTo(ownJID); - - boost::shared_ptr<ChatState> csn = boost::make_shared<ChatState>(); - csn->setChatState(ChatState::Active); - reply->addPayload(csn); - manager_->handleIncomingMessage(reply); - } - - // Send second message. - window->onSendMessageRequest("how are you?", false); - - // A bare message is send because no resources is bound. - CPPUNIT_ASSERT_EQUAL(sender, stanzaChannel_->getStanzaAtIndex<Message>(1)->getTo()); - CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(1)->getPayload<DeliveryReceiptRequest>()); - - // Two resources respond with message receipts. - foreach(const JID& senderJID, senderResource) { - Message::ref receiptReply = boost::make_shared<Message>(); - receiptReply->setFrom(senderJID); - receiptReply->setTo(ownJID); - - boost::shared_ptr<DeliveryReceipt> receipt = boost::make_shared<DeliveryReceipt>(); - receipt->setReceivedID(stanzaChannel_->getStanzaAtIndex<Message>(1)->getID()); - receiptReply->addPayload(receipt); - manager_->handleIncomingMessage(receiptReply); - } - - // Reply with a message including a CSN. - Message::ref reply = boost::make_shared<Message>(); - reply->setFrom(senderResource[0]); - reply->setTo(ownJID); - - boost::shared_ptr<ChatState> csn = boost::make_shared<ChatState>(); - csn->setChatState(ChatState::Composing); - reply->addPayload(csn); - manager_->handleIncomingMessage(reply); - - // Send third message. - window->onSendMessageRequest("great to hear.", false); - - // The chat session is now bound to the full JID of the first resource due to its recent composing message. - CPPUNIT_ASSERT_EQUAL(senderResource[0], stanzaChannel_->getStanzaAtIndex<Message>(2)->getTo()); - CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(2)->getPayload<DeliveryReceiptRequest>()); - - // Reply with a message including a CSN from the other resource. - reply = boost::make_shared<Message>(); - reply->setFrom(senderResource[1]); - reply->setTo(ownJID); - - csn = boost::make_shared<ChatState>(); - csn->setChatState(ChatState::Composing); - reply->addPayload(csn); - manager_->handleIncomingMessage(reply); - - // Send third message. - window->onSendMessageRequest("ping.", false); - - // The chat session is now bound to the full JID of the second resource due to its recent composing message. - CPPUNIT_ASSERT_EQUAL(senderResource[1], stanzaChannel_->getStanzaAtIndex<Message>(3)->getTo()); - CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(3)->getPayload<DeliveryReceiptRequest>()); - } - - void testChatControllerPMPresenceHandling() { - JID participantA = JID("test@rooms.test.com/participantA"); - JID participantB = JID("test@rooms.test.com/participantB"); - - mucRegistry_->addMUC("test@rooms.test.com"); - - MockChatWindow* window = new MockChatWindow(); - mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(participantA, uiEventStream_).Return(window); - - uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(JID(participantA)))); - - Presence::ref presence = Presence::create(); - presence->setFrom(participantA); - presence->setShow(StatusShow::Online); - stanzaChannel_->onPresenceReceived(presence); - CPPUNIT_ASSERT_EQUAL(std::string("participantA has become available."), MockChatWindow::bodyFromMessage(window->lastAddedPresence_)); - - presence = Presence::create(); - presence->setFrom(participantB); - presence->setShow(StatusShow::Away); - stanzaChannel_->onPresenceReceived(presence); - - presence = Presence::create(); - presence->setFrom(participantA); - presence->setShow(StatusShow::None); - presence->setType(Presence::Unavailable); - stanzaChannel_->onPresenceReceived(presence); - CPPUNIT_ASSERT_EQUAL(std::string("participantA has gone offline."), MockChatWindow::bodyFromMessage(window->lastReplacedMessage_)); - } - - void testLocalMUCServiceDiscoveryResetOnDisconnect() { - JID ownJID("test@test.com/resource"); - JID sender("foo@test.com"); - - manager_->setOnline(true); - - // Open chat window to a sender. - MockChatWindow* window = new MockChatWindow(); - mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(sender, uiEventStream_).Return(window); - - uiEventStream_->send(boost::make_shared<RequestChatUIEvent>(sender)); - - CPPUNIT_ASSERT_EQUAL(false, window->impromptuMUCSupported_); - - boost::shared_ptr<IQ> infoRequest= iqChannel_->iqs_[1]; - boost::shared_ptr<IQ> infoResponse = IQ::createResult(infoRequest->getFrom(), infoRequest->getTo(), infoRequest->getID()); - - DiscoInfo info; - info.addIdentity(DiscoInfo::Identity("Shakespearean Chat Service", "conference", "text")); - info.addFeature("http://jabber.org/protocol/muc"); - infoResponse->addPayload(boost::make_shared<DiscoInfo>(info)); - iqChannel_->onIQReceived(infoResponse); - - CPPUNIT_ASSERT_EQUAL(true, window->impromptuMUCSupported_); - manager_->setOnline(false); - CPPUNIT_ASSERT_EQUAL(false, window->impromptuMUCSupported_); - } - - void testhelperChatControllerPresenceAccessUpdatedOnSubscriptionChangeReceiptsAllowed(RosterItemPayload::Subscription from, RosterItemPayload::Subscription to) { - JID messageJID("testling@test.com/resource1"); - xmppRoster_->addContact(messageJID, "foo", std::vector<std::string>(), from); - - MockChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>(); - mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID, uiEventStream_).Return(window); - settings_->storeSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS, true); - - boost::shared_ptr<Message> message = makeDeliveryReceiptTestMessage(messageJID, "1"); - manager_->handleIncomingMessage(message); - - CPPUNIT_ASSERT_EQUAL(st(0), stanzaChannel_->sentStanzas.size()); - - xmppRoster_->addContact(messageJID, "foo", std::vector<std::string>(), to); - message->setID("2"); - manager_->handleIncomingMessage(message); - - CPPUNIT_ASSERT_EQUAL(st(1), stanzaChannel_->sentStanzas.size()); - Stanza::ref stanzaContactOnRoster = stanzaChannel_->getStanzaAtIndex<Stanza>(0); - CPPUNIT_ASSERT(stanzaContactOnRoster->getPayload<DeliveryReceipt>() != 0); - } - - void testChatControllerHighlightingNotificationTesting() { - HighlightRule keywordRuleA; - keywordRuleA.setMatchChat(true); - std::vector<std::string> keywordsA; - keywordsA.push_back("Romeo"); - keywordRuleA.setKeywords(keywordsA); - keywordRuleA.getAction().setTextColor("yellow"); - keywordRuleA.getAction().setPlaySound(true); - highlightManager_->insertRule(0, keywordRuleA); - - HighlightRule keywordRuleB; - keywordRuleB.setMatchChat(true); - std::vector<std::string> keywordsB; - keywordsB.push_back("Juliet"); - keywordRuleB.setKeywords(keywordsB); - keywordRuleB.getAction().setTextColor("green"); - keywordRuleB.getAction().setPlaySound(true); - keywordRuleB.getAction().setSoundFile("/tmp/someotherfile.wav"); - highlightManager_->insertRule(0, keywordRuleB); - - JID messageJID = JID("testling@test.com"); - - MockChatWindow* window = new MockChatWindow(); - mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID, uiEventStream_).Return(window); - - boost::shared_ptr<Message> message(new Message()); - message->setFrom(messageJID); - std::string body("This message should cause two sounds: Juliet and Romeo."); - message->setBody(body); - manager_->handleIncomingMessage(message); - - CPPUNIT_ASSERT_EQUAL(2, handledHighlightActions_); - CPPUNIT_ASSERT(soundsPlayed_.find(keywordRuleA.getAction().getSoundFile()) != soundsPlayed_.end()); - CPPUNIT_ASSERT(soundsPlayed_.find(keywordRuleB.getAction().getSoundFile()) != soundsPlayed_.end()); - } - - void testChatControllerHighlightingNotificationDeduplicateSounds() { - HighlightRule keywordRuleA; - keywordRuleA.setMatchChat(true); - std::vector<std::string> keywordsA; - keywordsA.push_back("Romeo"); - keywordRuleA.setKeywords(keywordsA); - keywordRuleA.getAction().setTextColor("yellow"); - keywordRuleA.getAction().setPlaySound(true); - highlightManager_->insertRule(0, keywordRuleA); - - HighlightRule keywordRuleB; - keywordRuleB.setMatchChat(true); - std::vector<std::string> keywordsB; - keywordsB.push_back("Juliet"); - keywordRuleB.setKeywords(keywordsB); - keywordRuleB.getAction().setTextColor("green"); - keywordRuleB.getAction().setPlaySound(true); - highlightManager_->insertRule(0, keywordRuleB); - - JID messageJID = JID("testling@test.com"); - - MockChatWindow* window = new MockChatWindow(); - mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID, uiEventStream_).Return(window); - - boost::shared_ptr<Message> message(new Message()); - message->setFrom(messageJID); - std::string body("This message should cause one sound, because both actions have the same sound: Juliet and Romeo."); - message->setBody(body); - manager_->handleIncomingMessage(message); - - CPPUNIT_ASSERT_EQUAL(1, handledHighlightActions_); - CPPUNIT_ASSERT(soundsPlayed_.find(keywordRuleA.getAction().getSoundFile()) != soundsPlayed_.end()); - CPPUNIT_ASSERT(soundsPlayed_.find(keywordRuleB.getAction().getSoundFile()) != soundsPlayed_.end()); - } + void setUp() { + mocks_ = new MockRepository(); + jid_ = JID("test@test.com/resource"); + stanzaChannel_ = new DummyStanzaChannel(); + iqChannel_ = new DummyIQChannel(); + iqRouter_ = new IQRouter(iqChannel_); +// capsProvider_ = new DummyCapsProvider(); + eventController_ = new EventController(); + chatWindowFactory_ = mocks_->InterfaceMock<ChatWindowFactory>(); + joinMUCWindowFactory_ = mocks_->InterfaceMock<JoinMUCWindowFactory>(); + xmppRoster_ = new XMPPRosterImpl(); + mucRegistry_ = new MUCRegistry(); + nickResolver_ = new NickResolver(jid_.toBare(), xmppRoster_, NULL, mucRegistry_); + presenceOracle_ = new PresenceOracle(stanzaChannel_, xmppRoster_); + serverDiscoInfo_ = boost::make_shared<DiscoInfo>(); + presenceSender_ = new StanzaChannelPresenceSender(stanzaChannel_); + directedPresenceSender_ = new DirectedPresenceSender(presenceSender_); + mucManager_ = new MUCManager(stanzaChannel_, iqRouter_, directedPresenceSender_, mucRegistry_); + uiEventStream_ = new UIEventStream(); +// entityCapsManager_ = new EntityCapsManager(capsProvider_, stanzaChannel_); + entityCapsProvider_ = new DummyEntityCapsProvider(); + chatListWindowFactory_ = mocks_->InterfaceMock<ChatListWindowFactory>(); + mucSearchWindowFactory_ = mocks_->InterfaceMock<MUCSearchWindowFactory>(); + settings_ = new DummySettingsProvider(); + profileSettings_ = new ProfileSettingsProvider("a", settings_); + chatListWindow_ = new MockChatListWindow(); + ftManager_ = new DummyFileTransferManager(); + ftOverview_ = new FileTransferOverview(ftManager_); + avatarManager_ = new NullAvatarManager(); + wbSessionManager_ = new WhiteboardSessionManager(iqRouter_, stanzaChannel_, presenceOracle_, entityCapsProvider_); + wbManager_ = new WhiteboardManager(whiteboardWindowFactory_, uiEventStream_, nickResolver_, wbSessionManager_); + highlightManager_ = new HighlightManager(settings_); + handledHighlightActions_ = 0; + soundsPlayed_.clear(); + highlightManager_->onHighlight.connect(boost::bind(&ChatsManagerTest::handleHighlightAction, this, _1)); + + crypto_ = PlatformCryptoProvider::create(); + vcardStorage_ = new VCardMemoryStorage(crypto_); + vcardManager_ = new VCardManager(jid_, iqRouter_, vcardStorage_); + mocks_->ExpectCall(chatListWindowFactory_, ChatListWindowFactory::createChatListWindow).With(uiEventStream_).Return(chatListWindow_); + clientBlockListManager_ = new ClientBlockListManager(iqRouter_); + manager_ = new ChatsManager(jid_, stanzaChannel_, iqRouter_, eventController_, chatWindowFactory_, joinMUCWindowFactory_, nickResolver_, presenceOracle_, directedPresenceSender_, uiEventStream_, chatListWindowFactory_, true, NULL, mucRegistry_, entityCapsProvider_, mucManager_, mucSearchWindowFactory_, profileSettings_, ftOverview_, xmppRoster_, false, settings_, NULL, wbManager_, highlightManager_, clientBlockListManager_, emoticons_, vcardManager_); + + manager_->setAvatarManager(avatarManager_); + } + + void tearDown() { + delete highlightManager_; + //delete chatListWindowFactory + delete profileSettings_; + delete avatarManager_; + delete manager_; + delete clientBlockListManager_; + delete vcardManager_; + delete vcardStorage_; + delete crypto_; + delete ftOverview_; + delete ftManager_; + delete wbSessionManager_; + delete wbManager_; + delete directedPresenceSender_; + delete presenceSender_; + delete presenceOracle_; + delete nickResolver_; + delete mucRegistry_; + delete stanzaChannel_; + delete eventController_; + delete iqRouter_; + delete iqChannel_; + delete uiEventStream_; + delete mucManager_; + delete xmppRoster_; + delete entityCapsProvider_; + delete chatListWindow_; + delete mocks_; + delete settings_; + } + + void testFirstOpenWindowIncoming() { + JID messageJID("testling@test.com/resource1"); + + MockChatWindow* window = new MockChatWindow(); + mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID, uiEventStream_).Return(window); + + boost::shared_ptr<Message> message(new Message()); + message->setFrom(messageJID); + std::string body("This is a legible message. >HEH@)oeueu"); + message->setBody(body); + manager_->handleIncomingMessage(message); + CPPUNIT_ASSERT_EQUAL(body, window->lastMessageBody_); + } + + void testSecondOpenWindowIncoming() { + JID messageJID1("testling@test.com/resource1"); + + MockChatWindow* window1 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>(); + mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID1, uiEventStream_).Return(window1); + + boost::shared_ptr<Message> message1(new Message()); + message1->setFrom(messageJID1); + std::string body1("This is a legible message. >HEH@)oeueu"); + message1->setBody(body1); + manager_->handleIncomingMessage(message1); + CPPUNIT_ASSERT_EQUAL(body1, window1->lastMessageBody_); + + JID messageJID2("testling@test.com/resource2"); + + //MockChatWindow* window2 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>(); + //mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID2, uiEventStream_).Return(window2); + + boost::shared_ptr<Message> message2(new Message()); + message2->setFrom(messageJID2); + std::string body2("This is a legible message. .cmaulm.chul"); + message2->setBody(body2); + manager_->handleIncomingMessage(message2); + CPPUNIT_ASSERT_EQUAL(body2, window1->lastMessageBody_); + } + + void testFirstOpenWindowOutgoing() { + std::string messageJIDString("testling@test.com"); + + ChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>(); + mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(messageJIDString), uiEventStream_).Return(window); + + uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(JID(messageJIDString)))); + } + + + void testFirstOpenWindowBareToFull() { + std::string bareJIDString("testling@test.com"); + std::string fullJIDString("testling@test.com/resource1"); + + MockChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>(); + mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(bareJIDString), uiEventStream_).Return(window); + uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(JID(bareJIDString)))); + + boost::shared_ptr<Message> message(new Message()); + message->setFrom(JID(fullJIDString)); + std::string body("This is a legible message. mjuga3089gm8G(*>M)@*("); + message->setBody(body); + manager_->handleIncomingMessage(message); + CPPUNIT_ASSERT_EQUAL(body, window->lastMessageBody_); + } + + void testSecondWindow() { + std::string messageJIDString1("testling1@test.com"); + ChatWindow* window1 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>(); + mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(messageJIDString1), uiEventStream_).Return(window1); + uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(JID(messageJIDString1)))); + + std::string messageJIDString2("testling2@test.com"); + ChatWindow* window2 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>(); + mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(messageJIDString2), uiEventStream_).Return(window2); + + uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(JID(messageJIDString2)))); + } + + /** Complete cycle. + Create unbound window. + Bind it. + Unbind it. + Rebind it. + */ + void testUnbindRebind() { + std::string bareJIDString("testling@test.com"); + std::string fullJIDString1("testling@test.com/resource1"); + std::string fullJIDString2("testling@test.com/resource2"); + + MockChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>(); + mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(bareJIDString), uiEventStream_).Return(window); + uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(JID(bareJIDString)))); + + boost::shared_ptr<Message> message1(new Message()); + message1->setFrom(JID(fullJIDString1)); + std::string messageBody1("This is a legible message."); + message1->setBody(messageBody1); + manager_->handleIncomingMessage(message1); + CPPUNIT_ASSERT_EQUAL(messageBody1, window->lastMessageBody_); + + boost::shared_ptr<Presence> jid1Online(new Presence()); + jid1Online->setFrom(JID(fullJIDString1)); + boost::shared_ptr<Presence> jid1Offline(new Presence()); + jid1Offline->setFrom(JID(fullJIDString1)); + jid1Offline->setType(Presence::Unavailable); + presenceOracle_->onPresenceChange(jid1Offline); + + boost::shared_ptr<Message> message2(new Message()); + message2->setFrom(JID(fullJIDString2)); + std::string messageBody2("This is another legible message."); + message2->setBody(messageBody2); + manager_->handleIncomingMessage(message2); + CPPUNIT_ASSERT_EQUAL(messageBody2, window->lastMessageBody_); + } + + /** + * Test that MUC PMs get opened in the right windows + */ + void testThreeMUCWindows() { + JID muc("testling@test.com"); + ChatWindow* mucWindow = new MockChatWindow(); + mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(muc, uiEventStream_).Return(mucWindow); + uiEventStream_->send(boost::make_shared<JoinMUCUIEvent>(muc, std::string("nick"))); + + + std::string messageJIDString1("testling@test.com/1"); + ChatWindow* window1 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>(); + mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(messageJIDString1), uiEventStream_).Return(window1); + uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(JID(messageJIDString1)))); + + std::string messageJIDString2("testling@test.com/2"); + ChatWindow* window2 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>(); + mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(messageJIDString2), uiEventStream_).Return(window2); + + uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(JID(messageJIDString2)))); + + std::string messageJIDString3("testling@test.com/3"); + ChatWindow* window3 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>(); + mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(messageJIDString3), uiEventStream_).Return(window3); + + uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(JID(messageJIDString3)))); + + /* Refetch an earlier window */ + /* We do not expect a new window to be created */ + uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(JID(messageJIDString1)))); + + } + + /** + Test that a second window isn't unbound where there's already an unbound one. + Bind 1 + Bind 2 + Unbind 1 + Unbind 2 (but it doesn't) + Sent to bound 2 + Rebind 1 + */ + void testNoDuplicateUnbind() { + JID messageJID1("testling@test.com/resource1"); + + MockChatWindow* window1 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>(); + mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID1, uiEventStream_).Return(window1); + + boost::shared_ptr<Message> message1(new Message()); + message1->setFrom(messageJID1); + message1->setBody("This is a legible message1."); + manager_->handleIncomingMessage(message1); + + JID messageJID2("testling@test.com/resource2"); + + //MockChatWindow* window2 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>(); + //mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID2, uiEventStream_).Return(window2); + + boost::shared_ptr<Message> message2(new Message()); + message2->setFrom(messageJID2); + message2->setBody("This is a legible message2."); + manager_->handleIncomingMessage(message2); + + boost::shared_ptr<Presence> jid1Online(new Presence()); + jid1Online->setFrom(JID(messageJID1)); + boost::shared_ptr<Presence> jid1Offline(new Presence()); + jid1Offline->setFrom(JID(messageJID1)); + jid1Offline->setType(Presence::Unavailable); + presenceOracle_->onPresenceChange(jid1Offline); + + boost::shared_ptr<Presence> jid2Online(new Presence()); + jid2Online->setFrom(JID(messageJID2)); + boost::shared_ptr<Presence> jid2Offline(new Presence()); + jid2Offline->setFrom(JID(messageJID2)); + jid2Offline->setType(Presence::Unavailable); + presenceOracle_->onPresenceChange(jid2Offline); + + JID messageJID3("testling@test.com/resource3"); + + boost::shared_ptr<Message> message3(new Message()); + message3->setFrom(messageJID3); + std::string body3("This is a legible message3."); + message3->setBody(body3); + manager_->handleIncomingMessage(message3); + CPPUNIT_ASSERT_EQUAL(body3, window1->lastMessageBody_); + + boost::shared_ptr<Message> message2b(new Message()); + message2b->setFrom(messageJID2); + std::string body2b("This is a legible message2b."); + message2b->setBody(body2b); + manager_->handleIncomingMessage(message2b); + CPPUNIT_ASSERT_EQUAL(body2b, window1->lastMessageBody_); + } + + /** + * Test that ChatController doesn't send receipts anymore after removal of the contact from the roster. + */ + void testChatControllerPresenceAccessUpdatedOnRemoveFromRoster() { + JID messageJID("testling@test.com/resource1"); + xmppRoster_->addContact(messageJID, "foo", std::vector<std::string>(), RosterItemPayload::Both); + + MockChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>(); + mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID, uiEventStream_).Return(window); + settings_->storeSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS, true); + + boost::shared_ptr<Message> message = makeDeliveryReceiptTestMessage(messageJID, "1"); + manager_->handleIncomingMessage(message); + Stanza::ref stanzaContactOnRoster = stanzaChannel_->getStanzaAtIndex<Stanza>(0); + CPPUNIT_ASSERT_EQUAL(st(1), stanzaChannel_->sentStanzas.size()); + CPPUNIT_ASSERT(stanzaContactOnRoster->getPayload<DeliveryReceipt>() != 0); + + xmppRoster_->removeContact(messageJID); + + message->setID("2"); + manager_->handleIncomingMessage(message); + CPPUNIT_ASSERT_EQUAL(st(1), stanzaChannel_->sentStanzas.size()); + } + + /** + * Test that ChatController sends receipts after the contact has been added to the roster. + */ + void testChatControllerPresenceAccessUpdatedOnAddToRoster() { + JID messageJID("testling@test.com/resource1"); + + MockChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>(); + mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID, uiEventStream_).Return(window); + settings_->storeSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS, true); + + boost::shared_ptr<Message> message = makeDeliveryReceiptTestMessage(messageJID, "1"); + manager_->handleIncomingMessage(message); + + CPPUNIT_ASSERT_EQUAL(st(0), stanzaChannel_->sentStanzas.size()); + + xmppRoster_->addContact(messageJID, "foo", std::vector<std::string>(), RosterItemPayload::Both); + message->setID("2"); + manager_->handleIncomingMessage(message); + + CPPUNIT_ASSERT_EQUAL(st(1), stanzaChannel_->sentStanzas.size()); + Stanza::ref stanzaContactOnRoster = stanzaChannel_->getStanzaAtIndex<Stanza>(0); + CPPUNIT_ASSERT(stanzaContactOnRoster->getPayload<DeliveryReceipt>() != 0); + } + + /** + * Test that ChatController sends receipts if requested after change from subscription state To to subscription state Both. + */ + void testChatControllerPresenceAccessUpdatedOnSubscriptionChangeToBoth() { + testhelperChatControllerPresenceAccessUpdatedOnSubscriptionChangeReceiptsAllowed(RosterItemPayload::To, RosterItemPayload::Both); + } + + /** + * Test that ChatController sends receipts if requested after change from subscription state To to subscription state From. + */ + void testChatControllerPresenceAccessUpdatedOnSubscriptionChangeToFrom() { + testhelperChatControllerPresenceAccessUpdatedOnSubscriptionChangeReceiptsAllowed(RosterItemPayload::To, RosterItemPayload::From); + } + + void testChatControllerFullJIDBindingOnMessageAndNotReceipt() { + JID ownJID("test@test.com/resource"); + JID sender("foo@test.com"); + std::vector<JID> senderResource; + senderResource.push_back(sender.withResource("resourceA")); + senderResource.push_back(sender.withResource("resourceB")); + + // We support delivery receipts. + settings_->storeSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS, true); + + // Open chat window to a sender. + MockChatWindow* window = new MockChatWindow(); + mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(sender, uiEventStream_).Return(window); + + uiEventStream_->send(boost::make_shared<RequestChatUIEvent>(sender)); + + foreach(const JID& senderJID, senderResource) { + // The sender supports delivery receipts. + DiscoInfo::ref disco = boost::make_shared<DiscoInfo>(); + disco->addFeature(DiscoInfo::MessageDeliveryReceiptsFeature); + entityCapsProvider_->caps[senderJID] = disco; + + // The sender is online. + Presence::ref senderPresence = boost::make_shared<Presence>(); + senderPresence->setFrom(senderJID); + senderPresence->setTo(ownJID); + stanzaChannel_->onPresenceReceived(senderPresence); + + entityCapsProvider_->onCapsChanged(senderJID); + } + + // Send first message. + window->onSendMessageRequest("hello there", false); + + // A bare message is send because no resources is bound. + CPPUNIT_ASSERT_EQUAL(sender, stanzaChannel_->getStanzaAtIndex<Message>(0)->getTo()); + CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(0)->getPayload<DeliveryReceiptRequest>()); + + // Two resources respond with message receipts. + foreach(const JID& senderJID, senderResource) { + Message::ref receiptReply = boost::make_shared<Message>(); + receiptReply->setFrom(senderJID); + receiptReply->setTo(ownJID); + + boost::shared_ptr<DeliveryReceipt> receipt = boost::make_shared<DeliveryReceipt>(); + receipt->setReceivedID(stanzaChannel_->getStanzaAtIndex<Message>(0)->getID()); + receiptReply->addPayload(receipt); + manager_->handleIncomingMessage(receiptReply); + } + + // Send second message. + window->onSendMessageRequest("how are you?", false); + + // A bare message is send because no resources is bound. + CPPUNIT_ASSERT_EQUAL(sender, stanzaChannel_->getStanzaAtIndex<Message>(1)->getTo()); + CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(1)->getPayload<DeliveryReceiptRequest>()); + + // Two resources respond with message receipts. + foreach(const JID& senderJID, senderResource) { + Message::ref receiptReply = boost::make_shared<Message>(); + receiptReply->setFrom(senderJID); + receiptReply->setTo(ownJID); + + boost::shared_ptr<DeliveryReceipt> receipt = boost::make_shared<DeliveryReceipt>(); + receipt->setReceivedID(stanzaChannel_->getStanzaAtIndex<Message>(1)->getID()); + receiptReply->addPayload(receipt); + manager_->handleIncomingMessage(receiptReply); + } + + // Reply with a message including a body text. + Message::ref reply = boost::make_shared<Message>(); + reply->setFrom(senderResource[0]); + reply->setTo(ownJID); + reply->setBody("fine."); + manager_->handleIncomingMessage(reply); + + // Send third message. + window->onSendMessageRequest("great to hear.", false); + + // The chat session is bound to the full JID of the first resource. + CPPUNIT_ASSERT_EQUAL(senderResource[0], stanzaChannel_->getStanzaAtIndex<Message>(2)->getTo()); + CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(2)->getPayload<DeliveryReceiptRequest>()); + + // Receive random receipt from second sender resource. + reply = boost::make_shared<Message>(); + reply->setFrom(senderResource[1]); + reply->setTo(ownJID); + + boost::shared_ptr<DeliveryReceipt> receipt = boost::make_shared<DeliveryReceipt>(); + receipt->setReceivedID(stanzaChannel_->getStanzaAtIndex<Message>(2)->getID()); + reply->addPayload(receipt); + manager_->handleIncomingMessage(reply); + + // Send forth message. + window->onSendMessageRequest("what else is new?", false); + + // The chat session is bound to the full JID of the first resource. + CPPUNIT_ASSERT_EQUAL(senderResource[0], stanzaChannel_->getStanzaAtIndex<Message>(3)->getTo()); + CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(3)->getPayload<DeliveryReceiptRequest>()); + + // Reply with a message including a body text from second resource. + reply = boost::make_shared<Message>(); + reply->setFrom(senderResource[1]); + reply->setTo(ownJID); + reply->setBody("nothing."); + manager_->handleIncomingMessage(reply); + + // Send fifth message. + window->onSendMessageRequest("okay", false); + + // The chat session is now bound to the full JID of the second resource. + CPPUNIT_ASSERT_EQUAL(senderResource[1], stanzaChannel_->getStanzaAtIndex<Message>(4)->getTo()); + CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(4)->getPayload<DeliveryReceiptRequest>()); + } + + void testChatControllerFullJIDBindingOnTypingAndNotActive() { + JID ownJID("test@test.com/resource"); + JID sender("foo@test.com"); + std::vector<JID> senderResource; + senderResource.push_back(sender.withResource("resourceA")); + senderResource.push_back(sender.withResource("resourceB")); + + // We support delivery receipts. + settings_->storeSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS, true); + + // Open chat window to a sender. + MockChatWindow* window = new MockChatWindow(); + mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(sender, uiEventStream_).Return(window); + + uiEventStream_->send(boost::make_shared<RequestChatUIEvent>(sender)); + + foreach(const JID& senderJID, senderResource) { + // The sender supports delivery receipts. + DiscoInfo::ref disco = boost::make_shared<DiscoInfo>(); + disco->addFeature(DiscoInfo::MessageDeliveryReceiptsFeature); + entityCapsProvider_->caps[senderJID] = disco; + + // The sender is online. + Presence::ref senderPresence = boost::make_shared<Presence>(); + senderPresence->setFrom(senderJID); + senderPresence->setTo(ownJID); + stanzaChannel_->onPresenceReceived(senderPresence); + + entityCapsProvider_->onCapsChanged(senderJID); + } + + // Send first message. + window->onSendMessageRequest("hello there", false); + + // A bare message is send because no resources is bound. + CPPUNIT_ASSERT_EQUAL(sender, stanzaChannel_->getStanzaAtIndex<Message>(0)->getTo()); + CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(0)->getPayload<DeliveryReceiptRequest>()); + + // Two resources respond with message receipts. + foreach(const JID& senderJID, senderResource) { + Message::ref reply = boost::make_shared<Message>(); + reply->setFrom(senderJID); + reply->setTo(ownJID); + + boost::shared_ptr<ChatState> csn = boost::make_shared<ChatState>(); + csn->setChatState(ChatState::Active); + reply->addPayload(csn); + manager_->handleIncomingMessage(reply); + } + + // Send second message. + window->onSendMessageRequest("how are you?", false); + + // A bare message is send because no resources is bound. + CPPUNIT_ASSERT_EQUAL(sender, stanzaChannel_->getStanzaAtIndex<Message>(1)->getTo()); + CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(1)->getPayload<DeliveryReceiptRequest>()); + + // Two resources respond with message receipts. + foreach(const JID& senderJID, senderResource) { + Message::ref receiptReply = boost::make_shared<Message>(); + receiptReply->setFrom(senderJID); + receiptReply->setTo(ownJID); + + boost::shared_ptr<DeliveryReceipt> receipt = boost::make_shared<DeliveryReceipt>(); + receipt->setReceivedID(stanzaChannel_->getStanzaAtIndex<Message>(1)->getID()); + receiptReply->addPayload(receipt); + manager_->handleIncomingMessage(receiptReply); + } + + // Reply with a message including a CSN. + Message::ref reply = boost::make_shared<Message>(); + reply->setFrom(senderResource[0]); + reply->setTo(ownJID); + + boost::shared_ptr<ChatState> csn = boost::make_shared<ChatState>(); + csn->setChatState(ChatState::Composing); + reply->addPayload(csn); + manager_->handleIncomingMessage(reply); + + // Send third message. + window->onSendMessageRequest("great to hear.", false); + + // The chat session is now bound to the full JID of the first resource due to its recent composing message. + CPPUNIT_ASSERT_EQUAL(senderResource[0], stanzaChannel_->getStanzaAtIndex<Message>(2)->getTo()); + CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(2)->getPayload<DeliveryReceiptRequest>()); + + // Reply with a message including a CSN from the other resource. + reply = boost::make_shared<Message>(); + reply->setFrom(senderResource[1]); + reply->setTo(ownJID); + + csn = boost::make_shared<ChatState>(); + csn->setChatState(ChatState::Composing); + reply->addPayload(csn); + manager_->handleIncomingMessage(reply); + + // Send third message. + window->onSendMessageRequest("ping.", false); + + // The chat session is now bound to the full JID of the second resource due to its recent composing message. + CPPUNIT_ASSERT_EQUAL(senderResource[1], stanzaChannel_->getStanzaAtIndex<Message>(3)->getTo()); + CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(3)->getPayload<DeliveryReceiptRequest>()); + } + + void testChatControllerPMPresenceHandling() { + JID participantA = JID("test@rooms.test.com/participantA"); + JID participantB = JID("test@rooms.test.com/participantB"); + + mucRegistry_->addMUC("test@rooms.test.com"); + + MockChatWindow* window = new MockChatWindow(); + mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(participantA, uiEventStream_).Return(window); + + uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(JID(participantA)))); + + Presence::ref presence = Presence::create(); + presence->setFrom(participantA); + presence->setShow(StatusShow::Online); + stanzaChannel_->onPresenceReceived(presence); + CPPUNIT_ASSERT_EQUAL(std::string("participantA has become available."), MockChatWindow::bodyFromMessage(window->lastAddedPresence_)); + + presence = Presence::create(); + presence->setFrom(participantB); + presence->setShow(StatusShow::Away); + stanzaChannel_->onPresenceReceived(presence); + + presence = Presence::create(); + presence->setFrom(participantA); + presence->setShow(StatusShow::None); + presence->setType(Presence::Unavailable); + stanzaChannel_->onPresenceReceived(presence); + CPPUNIT_ASSERT_EQUAL(std::string("participantA has gone offline."), MockChatWindow::bodyFromMessage(window->lastReplacedMessage_)); + } + + void testLocalMUCServiceDiscoveryResetOnDisconnect() { + JID ownJID("test@test.com/resource"); + JID sender("foo@test.com"); + + manager_->setOnline(true); + + // Open chat window to a sender. + MockChatWindow* window = new MockChatWindow(); + mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(sender, uiEventStream_).Return(window); + + uiEventStream_->send(boost::make_shared<RequestChatUIEvent>(sender)); + + CPPUNIT_ASSERT_EQUAL(false, window->impromptuMUCSupported_); + + boost::shared_ptr<IQ> infoRequest= iqChannel_->iqs_[1]; + boost::shared_ptr<IQ> infoResponse = IQ::createResult(infoRequest->getFrom(), infoRequest->getTo(), infoRequest->getID()); + + DiscoInfo info; + info.addIdentity(DiscoInfo::Identity("Shakespearean Chat Service", "conference", "text")); + info.addFeature("http://jabber.org/protocol/muc"); + infoResponse->addPayload(boost::make_shared<DiscoInfo>(info)); + iqChannel_->onIQReceived(infoResponse); + + CPPUNIT_ASSERT_EQUAL(true, window->impromptuMUCSupported_); + manager_->setOnline(false); + CPPUNIT_ASSERT_EQUAL(false, window->impromptuMUCSupported_); + } + + void testhelperChatControllerPresenceAccessUpdatedOnSubscriptionChangeReceiptsAllowed(RosterItemPayload::Subscription from, RosterItemPayload::Subscription to) { + JID messageJID("testling@test.com/resource1"); + xmppRoster_->addContact(messageJID, "foo", std::vector<std::string>(), from); + + MockChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>(); + mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID, uiEventStream_).Return(window); + settings_->storeSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS, true); + + boost::shared_ptr<Message> message = makeDeliveryReceiptTestMessage(messageJID, "1"); + manager_->handleIncomingMessage(message); + + CPPUNIT_ASSERT_EQUAL(st(0), stanzaChannel_->sentStanzas.size()); + + xmppRoster_->addContact(messageJID, "foo", std::vector<std::string>(), to); + message->setID("2"); + manager_->handleIncomingMessage(message); + + CPPUNIT_ASSERT_EQUAL(st(1), stanzaChannel_->sentStanzas.size()); + Stanza::ref stanzaContactOnRoster = stanzaChannel_->getStanzaAtIndex<Stanza>(0); + CPPUNIT_ASSERT(stanzaContactOnRoster->getPayload<DeliveryReceipt>() != 0); + } + + void testChatControllerHighlightingNotificationTesting() { + HighlightRule keywordRuleA; + keywordRuleA.setMatchChat(true); + std::vector<std::string> keywordsA; + keywordsA.push_back("Romeo"); + keywordRuleA.setKeywords(keywordsA); + keywordRuleA.getAction().setTextColor("yellow"); + keywordRuleA.getAction().setPlaySound(true); + highlightManager_->insertRule(0, keywordRuleA); + + HighlightRule keywordRuleB; + keywordRuleB.setMatchChat(true); + std::vector<std::string> keywordsB; + keywordsB.push_back("Juliet"); + keywordRuleB.setKeywords(keywordsB); + keywordRuleB.getAction().setTextColor("green"); + keywordRuleB.getAction().setPlaySound(true); + keywordRuleB.getAction().setSoundFile("/tmp/someotherfile.wav"); + highlightManager_->insertRule(0, keywordRuleB); + + JID messageJID = JID("testling@test.com"); + + MockChatWindow* window = new MockChatWindow(); + mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID, uiEventStream_).Return(window); + + boost::shared_ptr<Message> message(new Message()); + message->setFrom(messageJID); + std::string body("This message should cause two sounds: Juliet and Romeo."); + message->setBody(body); + manager_->handleIncomingMessage(message); + + CPPUNIT_ASSERT_EQUAL(2, handledHighlightActions_); + CPPUNIT_ASSERT(soundsPlayed_.find(keywordRuleA.getAction().getSoundFile()) != soundsPlayed_.end()); + CPPUNIT_ASSERT(soundsPlayed_.find(keywordRuleB.getAction().getSoundFile()) != soundsPlayed_.end()); + } + + void testChatControllerHighlightingNotificationDeduplicateSounds() { + HighlightRule keywordRuleA; + keywordRuleA.setMatchChat(true); + std::vector<std::string> keywordsA; + keywordsA.push_back("Romeo"); + keywordRuleA.setKeywords(keywordsA); + keywordRuleA.getAction().setTextColor("yellow"); + keywordRuleA.getAction().setPlaySound(true); + highlightManager_->insertRule(0, keywordRuleA); + + HighlightRule keywordRuleB; + keywordRuleB.setMatchChat(true); + std::vector<std::string> keywordsB; + keywordsB.push_back("Juliet"); + keywordRuleB.setKeywords(keywordsB); + keywordRuleB.getAction().setTextColor("green"); + keywordRuleB.getAction().setPlaySound(true); + highlightManager_->insertRule(0, keywordRuleB); + + JID messageJID = JID("testling@test.com"); + + MockChatWindow* window = new MockChatWindow(); + mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID, uiEventStream_).Return(window); + + boost::shared_ptr<Message> message(new Message()); + message->setFrom(messageJID); + std::string body("This message should cause one sound, because both actions have the same sound: Juliet and Romeo."); + message->setBody(body); + manager_->handleIncomingMessage(message); + + CPPUNIT_ASSERT_EQUAL(1, handledHighlightActions_); + CPPUNIT_ASSERT(soundsPlayed_.find(keywordRuleA.getAction().getSoundFile()) != soundsPlayed_.end()); + CPPUNIT_ASSERT(soundsPlayed_.find(keywordRuleB.getAction().getSoundFile()) != soundsPlayed_.end()); + } private: - boost::shared_ptr<Message> makeDeliveryReceiptTestMessage(const JID& from, const std::string& id) { - boost::shared_ptr<Message> message = boost::make_shared<Message>(); - message->setFrom(from); - message->setID(id); - message->setBody("This will cause the window to open"); - message->addPayload(boost::make_shared<DeliveryReceiptRequest>()); - return message; - } - - size_t st(int i) { - return static_cast<size_t>(i); - } - - void handleHighlightAction(const HighlightAction& action) { - handledHighlightActions_++; - if (action.playSound()) { - soundsPlayed_.insert(action.getSoundFile()); - } - } + boost::shared_ptr<Message> makeDeliveryReceiptTestMessage(const JID& from, const std::string& id) { + boost::shared_ptr<Message> message = boost::make_shared<Message>(); + message->setFrom(from); + message->setID(id); + message->setBody("This will cause the window to open"); + message->addPayload(boost::make_shared<DeliveryReceiptRequest>()); + return message; + } + + size_t st(int i) { + return static_cast<size_t>(i); + } + + void handleHighlightAction(const HighlightAction& action) { + handledHighlightActions_++; + if (action.playSound()) { + soundsPlayed_.insert(action.getSoundFile()); + } + } private: - JID jid_; - ChatsManager* manager_; - DummyStanzaChannel* stanzaChannel_; - DummyIQChannel* iqChannel_; - IQRouter* iqRouter_; - EventController* eventController_; - ChatWindowFactory* chatWindowFactory_; - JoinMUCWindowFactory* joinMUCWindowFactory_; - NickResolver* nickResolver_; - PresenceOracle* presenceOracle_; - AvatarManager* avatarManager_; - boost::shared_ptr<DiscoInfo> serverDiscoInfo_; - XMPPRosterImpl* xmppRoster_; - PresenceSender* presenceSender_; - MockRepository* mocks_; - UIEventStream* uiEventStream_; - ChatListWindowFactory* chatListWindowFactory_; - WhiteboardWindowFactory* whiteboardWindowFactory_; - MUCSearchWindowFactory* mucSearchWindowFactory_; - MUCRegistry* mucRegistry_; - DirectedPresenceSender* directedPresenceSender_; - DummyEntityCapsProvider* entityCapsProvider_; - MUCManager* mucManager_; - DummySettingsProvider* settings_; - ProfileSettingsProvider* profileSettings_; - ChatListWindow* chatListWindow_; - FileTransferOverview* ftOverview_; - FileTransferManager* ftManager_; - WhiteboardSessionManager* wbSessionManager_; - WhiteboardManager* wbManager_; - HighlightManager* highlightManager_; - ClientBlockListManager* clientBlockListManager_; - VCardManager* vcardManager_; - CryptoProvider* crypto_; - VCardStorage* vcardStorage_; - std::map<std::string, std::string> emoticons_; - int handledHighlightActions_; - std::set<std::string> soundsPlayed_; + JID jid_; + ChatsManager* manager_; + DummyStanzaChannel* stanzaChannel_; + DummyIQChannel* iqChannel_; + IQRouter* iqRouter_; + EventController* eventController_; + ChatWindowFactory* chatWindowFactory_; + JoinMUCWindowFactory* joinMUCWindowFactory_; + NickResolver* nickResolver_; + PresenceOracle* presenceOracle_; + AvatarManager* avatarManager_; + boost::shared_ptr<DiscoInfo> serverDiscoInfo_; + XMPPRosterImpl* xmppRoster_; + PresenceSender* presenceSender_; + MockRepository* mocks_; + UIEventStream* uiEventStream_; + ChatListWindowFactory* chatListWindowFactory_; + WhiteboardWindowFactory* whiteboardWindowFactory_; + MUCSearchWindowFactory* mucSearchWindowFactory_; + MUCRegistry* mucRegistry_; + DirectedPresenceSender* directedPresenceSender_; + DummyEntityCapsProvider* entityCapsProvider_; + MUCManager* mucManager_; + DummySettingsProvider* settings_; + ProfileSettingsProvider* profileSettings_; + ChatListWindow* chatListWindow_; + FileTransferOverview* ftOverview_; + FileTransferManager* ftManager_; + WhiteboardSessionManager* wbSessionManager_; + WhiteboardManager* wbManager_; + HighlightManager* highlightManager_; + ClientBlockListManager* clientBlockListManager_; + VCardManager* vcardManager_; + CryptoProvider* crypto_; + VCardStorage* vcardStorage_; + std::map<std::string, std::string> emoticons_; + int handledHighlightActions_; + std::set<std::string> soundsPlayed_; }; CPPUNIT_TEST_SUITE_REGISTRATION(ChatsManagerTest); diff --git a/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp b/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp index e8fc41d..db9bcdc 100644 --- a/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp +++ b/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp @@ -48,509 +48,509 @@ using namespace Swift; class MUCControllerTest : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(MUCControllerTest); - CPPUNIT_TEST(testJoinPartStringContructionSimple); - CPPUNIT_TEST(testJoinPartStringContructionMixed); - CPPUNIT_TEST(testAppendToJoinParts); - CPPUNIT_TEST(testAddressedToSelf); - CPPUNIT_TEST(testNotAddressedToSelf); - CPPUNIT_TEST(testAddressedToSelfBySelf); - CPPUNIT_TEST(testMessageWithEmptyLabelItem); - CPPUNIT_TEST(testMessageWithLabelItem); - CPPUNIT_TEST(testCorrectMessageWithLabelItem); - CPPUNIT_TEST(testRoleAffiliationStates); - CPPUNIT_TEST(testSubjectChangeCorrect); - CPPUNIT_TEST(testSubjectChangeIncorrectA); - CPPUNIT_TEST(testSubjectChangeIncorrectB); - CPPUNIT_TEST(testSubjectChangeIncorrectC); - CPPUNIT_TEST_SUITE_END(); + CPPUNIT_TEST_SUITE(MUCControllerTest); + CPPUNIT_TEST(testJoinPartStringContructionSimple); + CPPUNIT_TEST(testJoinPartStringContructionMixed); + CPPUNIT_TEST(testAppendToJoinParts); + CPPUNIT_TEST(testAddressedToSelf); + CPPUNIT_TEST(testNotAddressedToSelf); + CPPUNIT_TEST(testAddressedToSelfBySelf); + CPPUNIT_TEST(testMessageWithEmptyLabelItem); + CPPUNIT_TEST(testMessageWithLabelItem); + CPPUNIT_TEST(testCorrectMessageWithLabelItem); + CPPUNIT_TEST(testRoleAffiliationStates); + CPPUNIT_TEST(testSubjectChangeCorrect); + CPPUNIT_TEST(testSubjectChangeIncorrectA); + CPPUNIT_TEST(testSubjectChangeIncorrectB); + CPPUNIT_TEST(testSubjectChangeIncorrectC); + CPPUNIT_TEST_SUITE_END(); public: - void setUp() { - crypto_ = boost::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create()); - self_ = JID("girl@wonderland.lit/rabbithole"); - nick_ = "aLiCe"; - mucJID_ = JID("teaparty@rooms.wonderland.lit"); - mocks_ = new MockRepository(); - stanzaChannel_ = new DummyStanzaChannel(); - iqChannel_ = new DummyIQChannel(); - iqRouter_ = new IQRouter(iqChannel_); - eventController_ = new EventController(); - chatWindowFactory_ = mocks_->InterfaceMock<ChatWindowFactory>(); - userSearchWindowFactory_ = mocks_->InterfaceMock<UserSearchWindowFactory>(); - xmppRoster_ = new XMPPRosterImpl(); - presenceOracle_ = new PresenceOracle(stanzaChannel_, xmppRoster_); - presenceSender_ = new StanzaChannelPresenceSender(stanzaChannel_); - directedPresenceSender_ = new DirectedPresenceSender(presenceSender_); - uiEventStream_ = new UIEventStream(); - avatarManager_ = new NullAvatarManager(); - TimerFactory* timerFactory = NULL; - window_ = new MockChatWindow(); - mucRegistry_ = new MUCRegistry(); - entityCapsProvider_ = new DummyEntityCapsProvider(); - settings_ = new DummySettingsProvider(); - highlightManager_ = new HighlightManager(settings_); - muc_ = boost::make_shared<MockMUC>(mucJID_); - mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(muc_->getJID(), uiEventStream_).Return(window_); - chatMessageParser_ = boost::make_shared<ChatMessageParser>(std::map<std::string, std::string>(), highlightManager_->getRules(), true); - vcardStorage_ = new VCardMemoryStorage(crypto_.get()); - vcardManager_ = new VCardManager(self_, iqRouter_, vcardStorage_); - clientBlockListManager_ = new ClientBlockListManager(iqRouter_); - mucBookmarkManager_ = new MUCBookmarkManager(iqRouter_); - controller_ = new MUCController (self_, muc_, boost::optional<std::string>(), nick_, stanzaChannel_, iqRouter_, chatWindowFactory_, presenceOracle_, avatarManager_, uiEventStream_, false, timerFactory, eventController_, entityCapsProvider_, NULL, NULL, mucRegistry_, highlightManager_, clientBlockListManager_, chatMessageParser_, false, NULL, vcardManager_, mucBookmarkManager_); - } - - void tearDown() { - delete controller_; - delete mucBookmarkManager_; - delete clientBlockListManager_; - delete vcardManager_; - delete vcardStorage_; - delete highlightManager_; - delete settings_; - delete entityCapsProvider_; - delete eventController_; - delete presenceOracle_; - delete xmppRoster_; - delete mocks_; - delete uiEventStream_; - delete stanzaChannel_; - delete presenceSender_; - delete directedPresenceSender_; - delete iqRouter_; - delete iqChannel_; - delete mucRegistry_; - delete avatarManager_; - } - - void finishJoin() { - Presence::ref presence(new Presence()); - presence->setFrom(JID(muc_->getJID().toString() + "/" + nick_)); - MUCUserPayload::ref status(new MUCUserPayload()); - MUCUserPayload::StatusCode code; - code.code = 110; - status->addStatusCode(code); - presence->addPayload(status); - stanzaChannel_->onPresenceReceived(presence); - } - - void testAddressedToSelf() { - finishJoin(); - Message::ref message(new Message()); - - message = Message::ref(new Message()); - message->setFrom(JID(muc_->getJID().toString() + "/otherperson")); - message->setBody("basic " + nick_ + " test."); - message->setType(Message::Groupchat); - controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message))); - CPPUNIT_ASSERT_EQUAL((size_t)1, eventController_->getEvents().size()); - - message = Message::ref(new Message()); - message->setFrom(JID(muc_->getJID().toString() + "/otherperson")); - message->setBody(nick_ + ": hi there"); - message->setType(Message::Groupchat); - controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message))); - CPPUNIT_ASSERT_EQUAL((size_t)2, eventController_->getEvents().size()); - - message->setFrom(JID(muc_->getJID().toString() + "/other")); - message->setBody("Hi there " + nick_); - message->setType(Message::Groupchat); - controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message))); - CPPUNIT_ASSERT_EQUAL((size_t)3, eventController_->getEvents().size()); - - message = Message::ref(new Message()); - message->setFrom(JID(muc_->getJID().toString() + "/other2")); - message->setBody("Hi " + boost::to_lower_copy(nick_) + "."); - message->setType(Message::Groupchat); - controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message))); - CPPUNIT_ASSERT_EQUAL((size_t)4, eventController_->getEvents().size()); - - message = Message::ref(new Message()); - message->setFrom(JID(muc_->getJID().toString() + "/other3")); - message->setBody("Hi bert."); - message->setType(Message::Groupchat); - controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message))); - CPPUNIT_ASSERT_EQUAL((size_t)4, eventController_->getEvents().size()); - - message = Message::ref(new Message()); - message->setFrom(JID(muc_->getJID().toString() + "/other2")); - message->setBody("Hi " + boost::to_lower_copy(nick_) + "ie."); - message->setType(Message::Groupchat); - controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message))); - CPPUNIT_ASSERT_EQUAL((size_t)4, eventController_->getEvents().size()); - } - - void testNotAddressedToSelf() { - finishJoin(); - Message::ref message(new Message()); - message->setFrom(JID(muc_->getJID().toString() + "/other3")); - message->setBody("Hi there Hatter"); - message->setType(Message::Groupchat); - controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message))); - CPPUNIT_ASSERT_EQUAL((size_t)0, eventController_->getEvents().size()); - } - - void testAddressedToSelfBySelf() { - finishJoin(); - Message::ref message(new Message()); - message->setFrom(JID(muc_->getJID().toString() + "/" + nick_)); - message->setBody("Hi there " + nick_); - message->setType(Message::Groupchat); - controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message))); - CPPUNIT_ASSERT_EQUAL((size_t)0, eventController_->getEvents().size()); - } - - void testMessageWithEmptyLabelItem() { - SecurityLabelsCatalog::Item label; - label.setSelector("Bob"); - window_->label_ = label; - boost::shared_ptr<DiscoInfo> features = boost::make_shared<DiscoInfo>(); - features->addFeature(DiscoInfo::SecurityLabelsCatalogFeature); - controller_->setAvailableServerFeatures(features); - IQ::ref iq = iqChannel_->iqs_[iqChannel_->iqs_.size() - 1]; - SecurityLabelsCatalog::ref labelPayload = boost::make_shared<SecurityLabelsCatalog>(); - labelPayload->addItem(label); - IQ::ref result = IQ::createResult(self_, iq->getID(), labelPayload); - iqChannel_->onIQReceived(result); - std::string messageBody("agamemnon"); - window_->onSendMessageRequest(messageBody, false); - boost::shared_ptr<Stanza> rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1]; - Message::ref message = boost::dynamic_pointer_cast<Message>(rawStanza); - CPPUNIT_ASSERT_EQUAL(iq->getTo(), result->getFrom()); - CPPUNIT_ASSERT(window_->labelsEnabled_); - CPPUNIT_ASSERT(stanzaChannel_->isAvailable()); /* Otherwise will prevent sends. */ - CPPUNIT_ASSERT(message); - CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody().get()); - CPPUNIT_ASSERT(!message->getPayload<SecurityLabel>()); - } - - void testMessageWithLabelItem() { - boost::shared_ptr<SecurityLabel> label = boost::make_shared<SecurityLabel>(); - label->setLabel("a"); - SecurityLabelsCatalog::Item labelItem; - labelItem.setSelector("Bob"); - labelItem.setLabel(label); - window_->label_ = labelItem; - boost::shared_ptr<DiscoInfo> features = boost::make_shared<DiscoInfo>(); - features->addFeature(DiscoInfo::SecurityLabelsCatalogFeature); - controller_->setAvailableServerFeatures(features); - IQ::ref iq = iqChannel_->iqs_[iqChannel_->iqs_.size() - 1]; - SecurityLabelsCatalog::ref labelPayload = boost::make_shared<SecurityLabelsCatalog>(); - labelPayload->addItem(labelItem); - IQ::ref result = IQ::createResult(self_, iq->getID(), labelPayload); - iqChannel_->onIQReceived(result); - std::string messageBody("agamemnon"); - window_->onSendMessageRequest(messageBody, false); - boost::shared_ptr<Stanza> rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1]; - Message::ref message = boost::dynamic_pointer_cast<Message>(rawStanza); - CPPUNIT_ASSERT_EQUAL(iq->getTo(), result->getFrom()); - CPPUNIT_ASSERT(window_->labelsEnabled_); - CPPUNIT_ASSERT(stanzaChannel_->isAvailable()); /* Otherwise will prevent sends. */ - CPPUNIT_ASSERT(message); - CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody().get()); - CPPUNIT_ASSERT_EQUAL(label, message->getPayload<SecurityLabel>()); - } - - void testCorrectMessageWithLabelItem() { - boost::shared_ptr<SecurityLabel> label = boost::make_shared<SecurityLabel>(); - label->setLabel("a"); - SecurityLabelsCatalog::Item labelItem; - labelItem.setSelector("Bob"); - labelItem.setLabel(label); - boost::shared_ptr<SecurityLabel> label2 = boost::make_shared<SecurityLabel>(); - label->setLabel("b"); - SecurityLabelsCatalog::Item labelItem2; - labelItem2.setSelector("Charlie"); - labelItem2.setLabel(label2); - window_->label_ = labelItem; - boost::shared_ptr<DiscoInfo> features = boost::make_shared<DiscoInfo>(); - features->addFeature(DiscoInfo::SecurityLabelsCatalogFeature); - controller_->setAvailableServerFeatures(features); - IQ::ref iq = iqChannel_->iqs_[iqChannel_->iqs_.size() - 1]; - SecurityLabelsCatalog::ref labelPayload = boost::make_shared<SecurityLabelsCatalog>(); - labelPayload->addItem(labelItem); - IQ::ref result = IQ::createResult(self_, iq->getID(), labelPayload); - iqChannel_->onIQReceived(result); - std::string messageBody("agamemnon"); - window_->onSendMessageRequest(messageBody, false); - boost::shared_ptr<Stanza> rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1]; - Message::ref message = boost::dynamic_pointer_cast<Message>(rawStanza); - CPPUNIT_ASSERT_EQUAL(iq->getTo(), result->getFrom()); - CPPUNIT_ASSERT(window_->labelsEnabled_); - CPPUNIT_ASSERT(stanzaChannel_->isAvailable()); /* Otherwise will prevent sends. */ - CPPUNIT_ASSERT(message); - CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody().get()); - CPPUNIT_ASSERT_EQUAL(label, message->getPayload<SecurityLabel>()); - window_->label_ = labelItem2; - window_->onSendMessageRequest(messageBody, true); - rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1]; - message = boost::dynamic_pointer_cast<Message>(rawStanza); - CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody().get()); - CPPUNIT_ASSERT_EQUAL(label, message->getPayload<SecurityLabel>()); - } - - void checkEqual(const std::vector<NickJoinPart>& expected, const std::vector<NickJoinPart>& actual) { - CPPUNIT_ASSERT_EQUAL(expected.size(), actual.size()); - for (size_t i = 0; i < expected.size(); i++) { - CPPUNIT_ASSERT_EQUAL(expected[i].nick, actual[i].nick); - CPPUNIT_ASSERT_EQUAL(expected[i].type, actual[i].type); - } - } - - void testAppendToJoinParts() { - std::vector<NickJoinPart> list; - std::vector<NickJoinPart> gold; - MUCController::appendToJoinParts(list, NickJoinPart("Kev", Join)); - gold.push_back(NickJoinPart("Kev", Join)); - checkEqual(gold, list); - MUCController::appendToJoinParts(list, NickJoinPart("Remko", Join)); - gold.push_back(NickJoinPart("Remko", Join)); - checkEqual(gold, list); - MUCController::appendToJoinParts(list, NickJoinPart("Bert", Join)); - gold.push_back(NickJoinPart("Bert", Join)); - checkEqual(gold, list); - MUCController::appendToJoinParts(list, NickJoinPart("Bert", Part)); - gold[2].type = JoinThenPart; - checkEqual(gold, list); - MUCController::appendToJoinParts(list, NickJoinPart("Kev", Part)); - gold[0].type = JoinThenPart; - checkEqual(gold, list); - MUCController::appendToJoinParts(list, NickJoinPart("Remko", Part)); - gold[1].type = JoinThenPart; - checkEqual(gold, list); - MUCController::appendToJoinParts(list, NickJoinPart("Ernie", Part)); - gold.push_back(NickJoinPart("Ernie", Part)); - checkEqual(gold, list); - MUCController::appendToJoinParts(list, NickJoinPart("Ernie", Join)); - gold[3].type = PartThenJoin; - checkEqual(gold, list); - MUCController::appendToJoinParts(list, NickJoinPart("Kev", Join)); - gold[0].type = Join; - checkEqual(gold, list); - MUCController::appendToJoinParts(list, NickJoinPart("Ernie", Part)); - gold[3].type = Part; - checkEqual(gold, list); - - } - - void testJoinPartStringContructionSimple() { - std::vector<NickJoinPart> list; - list.push_back(NickJoinPart("Kev", Join)); - CPPUNIT_ASSERT_EQUAL(std::string("Kev has entered the room"), MUCController::generateJoinPartString(list, false)); - list.push_back(NickJoinPart("Remko", Part)); - CPPUNIT_ASSERT_EQUAL(std::string("Kev has entered the room and Remko has left the room"), MUCController::generateJoinPartString(list, false)); - list.push_back(NickJoinPart("Bert", Join)); - CPPUNIT_ASSERT_EQUAL(std::string("Kev and Bert have entered the room and Remko has left the room"), MUCController::generateJoinPartString(list, false)); - list.push_back(NickJoinPart("Ernie", Join)); - CPPUNIT_ASSERT_EQUAL(std::string("Kev, Bert and Ernie have entered the room and Remko has left the room"), MUCController::generateJoinPartString(list, false)); - } - - void testJoinPartStringContructionMixed() { - std::vector<NickJoinPart> list; - list.push_back(NickJoinPart("Kev", JoinThenPart)); - CPPUNIT_ASSERT_EQUAL(std::string("Kev has entered then left the room"), MUCController::generateJoinPartString(list, false)); - list.push_back(NickJoinPart("Remko", Part)); - CPPUNIT_ASSERT_EQUAL(std::string("Remko has left the room and Kev has entered then left the room"), MUCController::generateJoinPartString(list, false)); - list.push_back(NickJoinPart("Bert", PartThenJoin)); - CPPUNIT_ASSERT_EQUAL(std::string("Remko has left the room, Kev has entered then left the room and Bert has left then returned to the room"), MUCController::generateJoinPartString(list, false)); - list.push_back(NickJoinPart("Ernie", JoinThenPart)); - CPPUNIT_ASSERT_EQUAL(std::string("Remko has left the room, Kev and Ernie have entered then left the room and Bert has left then returned to the room"), MUCController::generateJoinPartString(list, false)); - } - - JID jidFromOccupant(const MUCOccupant& occupant) { - return JID(mucJID_.toString()+"/"+occupant.getNick()); - } - - void testRoleAffiliationStates() { - - typedef std::map<std::string, MUCOccupant> occupant_map; - occupant_map occupants; - occupants.insert(occupant_map::value_type("Kev", MUCOccupant("Kev", MUCOccupant::Participant, MUCOccupant::Owner))); - occupants.insert(occupant_map::value_type("Remko", MUCOccupant("Remko", MUCOccupant::Participant, MUCOccupant::Owner))); - occupants.insert(occupant_map::value_type("Bert", MUCOccupant("Bert", MUCOccupant::Participant, MUCOccupant::Owner))); - occupants.insert(occupant_map::value_type("Ernie", MUCOccupant("Ernie", MUCOccupant::Participant, MUCOccupant::Owner))); - - /* populate the MUC with fake users */ - typedef const std::pair<std::string,MUCOccupant> occupantIterator; - foreach(occupantIterator &occupant, occupants) { - muc_->insertOccupant(occupant.second); - } - - std::vector<MUCOccupant> alterations; - alterations.push_back(MUCOccupant("Kev", MUCOccupant::Visitor, MUCOccupant::Admin)); - alterations.push_back(MUCOccupant("Remko", MUCOccupant::Moderator, MUCOccupant::Member)); - alterations.push_back(MUCOccupant("Bert", MUCOccupant::Visitor, MUCOccupant::Outcast)); - alterations.push_back(MUCOccupant("Ernie", MUCOccupant::NoRole, MUCOccupant::Member)); - alterations.push_back(MUCOccupant("Bert", MUCOccupant::Moderator, MUCOccupant::Owner)); - alterations.push_back(MUCOccupant("Kev", MUCOccupant::Participant, MUCOccupant::Outcast)); - alterations.push_back(MUCOccupant("Bert", MUCOccupant::Visitor, MUCOccupant::NoAffiliation)); - alterations.push_back(MUCOccupant("Remko", MUCOccupant::NoRole, MUCOccupant::NoAffiliation)); - alterations.push_back(MUCOccupant("Ernie", MUCOccupant::Visitor, MUCOccupant::Outcast)); - - foreach(const MUCOccupant& alteration, alterations) { - /* perform an alteration to a user's role and affiliation */ - occupant_map::iterator occupant = occupants.find(alteration.getNick()); - CPPUNIT_ASSERT(occupant != occupants.end()); - const JID jid = jidFromOccupant(occupant->second); - /* change the affiliation, leave the role in place */ - muc_->changeAffiliation(jid, alteration.getAffiliation()); - occupant->second = MUCOccupant(occupant->first, occupant->second.getRole(), alteration.getAffiliation()); - testRoleAffiliationStatesVerify(occupants); - /* change the role, leave the affiliation in place */ - muc_->changeOccupantRole(jid, alteration.getRole()); - occupant->second = MUCOccupant(occupant->first, alteration.getRole(), occupant->second.getAffiliation()); - testRoleAffiliationStatesVerify(occupants); - } - } - - void testSubjectChangeCorrect() { - std::string messageBody("test message"); - window_->onSendMessageRequest(messageBody, false); - boost::shared_ptr<Stanza> rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1]; - Message::ref message = boost::dynamic_pointer_cast<Message>(rawStanza); - CPPUNIT_ASSERT(stanzaChannel_->isAvailable()); /* Otherwise will prevent sends. */ - CPPUNIT_ASSERT(message); - CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody().get_value_or("")); - - { - Message::ref message = boost::make_shared<Message>(); - message->setType(Message::Groupchat); - message->setTo(self_); - message->setFrom(mucJID_.withResource("SomeNickname")); - message->setID(iqChannel_->getNewIQID()); - message->setSubject("New Room Subject"); - - controller_->handleIncomingMessage(boost::make_shared<MessageEvent>(message)); - CPPUNIT_ASSERT_EQUAL(std::string("The room subject is now: New Room Subject"), boost::dynamic_pointer_cast<ChatWindow::ChatTextMessagePart>(window_->lastAddedSystemMessage_.getParts()[0])->text); - } - } - - /* - * Test that message stanzas with subject element and non-empty body element do not cause a subject change. - */ - void testSubjectChangeIncorrectA() { - std::string messageBody("test message"); - window_->onSendMessageRequest(messageBody, false); - boost::shared_ptr<Stanza> rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1]; - Message::ref message = boost::dynamic_pointer_cast<Message>(rawStanza); - CPPUNIT_ASSERT(stanzaChannel_->isAvailable()); /* Otherwise will prevent sends. */ - CPPUNIT_ASSERT(message); - CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody().get_value_or("")); - - { - Message::ref message = boost::make_shared<Message>(); - message->setType(Message::Groupchat); - message->setTo(self_); - message->setFrom(mucJID_.withResource("SomeNickname")); - message->setID(iqChannel_->getNewIQID()); - message->setSubject("New Room Subject"); - message->setBody("Some body text that prevents this stanza from being a subject change."); - - controller_->handleIncomingMessage(boost::make_shared<MessageEvent>(message)); - CPPUNIT_ASSERT_EQUAL(std::string("Trying to enter room teaparty@rooms.wonderland.lit"), boost::dynamic_pointer_cast<ChatWindow::ChatTextMessagePart>(window_->lastAddedSystemMessage_.getParts()[0])->text); - } - } - - /* - * Test that message stanzas with subject element and thread element do not cause a subject change. - */ - void testSubjectChangeIncorrectB() { - std::string messageBody("test message"); - window_->onSendMessageRequest(messageBody, false); - boost::shared_ptr<Stanza> rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1]; - Message::ref message = boost::dynamic_pointer_cast<Message>(rawStanza); - CPPUNIT_ASSERT(stanzaChannel_->isAvailable()); /* Otherwise will prevent sends. */ - CPPUNIT_ASSERT(message); - CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody().get_value_or("")); - - { - Message::ref message = boost::make_shared<Message>(); - message->setType(Message::Groupchat); - message->setTo(self_); - message->setFrom(mucJID_.withResource("SomeNickname")); - message->setID(iqChannel_->getNewIQID()); - message->setSubject("New Room Subject"); - message->addPayload(boost::make_shared<Thread>("Thread that prevents the subject change.")); - - controller_->handleIncomingMessage(boost::make_shared<MessageEvent>(message)); - CPPUNIT_ASSERT_EQUAL(std::string("Trying to enter room teaparty@rooms.wonderland.lit"), boost::dynamic_pointer_cast<ChatWindow::ChatTextMessagePart>(window_->lastAddedSystemMessage_.getParts()[0])->text); - } - } - - /* - * Test that message stanzas with subject element and empty body element do not cause a subject change. - */ - void testSubjectChangeIncorrectC() { - std::string messageBody("test message"); - window_->onSendMessageRequest(messageBody, false); - boost::shared_ptr<Stanza> rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1]; - Message::ref message = boost::dynamic_pointer_cast<Message>(rawStanza); - CPPUNIT_ASSERT(stanzaChannel_->isAvailable()); /* Otherwise will prevent sends. */ - CPPUNIT_ASSERT(message); - CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody().get_value_or("")); - - { - Message::ref message = boost::make_shared<Message>(); - message->setType(Message::Groupchat); - message->setTo(self_); - message->setFrom(mucJID_.withResource("SomeNickname")); - message->setID(iqChannel_->getNewIQID()); - message->setSubject("New Room Subject"); - message->setBody(""); - - controller_->handleIncomingMessage(boost::make_shared<MessageEvent>(message)); - CPPUNIT_ASSERT_EQUAL(std::string("Trying to enter room teaparty@rooms.wonderland.lit"), boost::dynamic_pointer_cast<ChatWindow::ChatTextMessagePart>(window_->lastAddedSystemMessage_.getParts()[0])->text); - } - } - - void testRoleAffiliationStatesVerify(const std::map<std::string, MUCOccupant> &occupants) { - /* verify that the roster is in sync */ - GroupRosterItem* group = window_->getRosterModel()->getRoot(); - foreach(RosterItem* rosterItem, group->getChildren()) { - GroupRosterItem* child = dynamic_cast<GroupRosterItem*>(rosterItem); - CPPUNIT_ASSERT(child); - foreach(RosterItem* childItem, child->getChildren()) { - ContactRosterItem* item = dynamic_cast<ContactRosterItem*>(childItem); - CPPUNIT_ASSERT(item); - std::map<std::string, MUCOccupant>::const_iterator occupant = occupants.find(item->getJID().getResource()); - CPPUNIT_ASSERT(occupant != occupants.end()); - CPPUNIT_ASSERT(item->getMUCRole() == occupant->second.getRole()); - CPPUNIT_ASSERT(item->getMUCAffiliation() == occupant->second.getAffiliation()); - } - } - } + void setUp() { + crypto_ = boost::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create()); + self_ = JID("girl@wonderland.lit/rabbithole"); + nick_ = "aLiCe"; + mucJID_ = JID("teaparty@rooms.wonderland.lit"); + mocks_ = new MockRepository(); + stanzaChannel_ = new DummyStanzaChannel(); + iqChannel_ = new DummyIQChannel(); + iqRouter_ = new IQRouter(iqChannel_); + eventController_ = new EventController(); + chatWindowFactory_ = mocks_->InterfaceMock<ChatWindowFactory>(); + userSearchWindowFactory_ = mocks_->InterfaceMock<UserSearchWindowFactory>(); + xmppRoster_ = new XMPPRosterImpl(); + presenceOracle_ = new PresenceOracle(stanzaChannel_, xmppRoster_); + presenceSender_ = new StanzaChannelPresenceSender(stanzaChannel_); + directedPresenceSender_ = new DirectedPresenceSender(presenceSender_); + uiEventStream_ = new UIEventStream(); + avatarManager_ = new NullAvatarManager(); + TimerFactory* timerFactory = NULL; + window_ = new MockChatWindow(); + mucRegistry_ = new MUCRegistry(); + entityCapsProvider_ = new DummyEntityCapsProvider(); + settings_ = new DummySettingsProvider(); + highlightManager_ = new HighlightManager(settings_); + muc_ = boost::make_shared<MockMUC>(mucJID_); + mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(muc_->getJID(), uiEventStream_).Return(window_); + chatMessageParser_ = boost::make_shared<ChatMessageParser>(std::map<std::string, std::string>(), highlightManager_->getRules(), true); + vcardStorage_ = new VCardMemoryStorage(crypto_.get()); + vcardManager_ = new VCardManager(self_, iqRouter_, vcardStorage_); + clientBlockListManager_ = new ClientBlockListManager(iqRouter_); + mucBookmarkManager_ = new MUCBookmarkManager(iqRouter_); + controller_ = new MUCController (self_, muc_, boost::optional<std::string>(), nick_, stanzaChannel_, iqRouter_, chatWindowFactory_, presenceOracle_, avatarManager_, uiEventStream_, false, timerFactory, eventController_, entityCapsProvider_, NULL, NULL, mucRegistry_, highlightManager_, clientBlockListManager_, chatMessageParser_, false, NULL, vcardManager_, mucBookmarkManager_); + } + + void tearDown() { + delete controller_; + delete mucBookmarkManager_; + delete clientBlockListManager_; + delete vcardManager_; + delete vcardStorage_; + delete highlightManager_; + delete settings_; + delete entityCapsProvider_; + delete eventController_; + delete presenceOracle_; + delete xmppRoster_; + delete mocks_; + delete uiEventStream_; + delete stanzaChannel_; + delete presenceSender_; + delete directedPresenceSender_; + delete iqRouter_; + delete iqChannel_; + delete mucRegistry_; + delete avatarManager_; + } + + void finishJoin() { + Presence::ref presence(new Presence()); + presence->setFrom(JID(muc_->getJID().toString() + "/" + nick_)); + MUCUserPayload::ref status(new MUCUserPayload()); + MUCUserPayload::StatusCode code; + code.code = 110; + status->addStatusCode(code); + presence->addPayload(status); + stanzaChannel_->onPresenceReceived(presence); + } + + void testAddressedToSelf() { + finishJoin(); + Message::ref message(new Message()); + + message = Message::ref(new Message()); + message->setFrom(JID(muc_->getJID().toString() + "/otherperson")); + message->setBody("basic " + nick_ + " test."); + message->setType(Message::Groupchat); + controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message))); + CPPUNIT_ASSERT_EQUAL((size_t)1, eventController_->getEvents().size()); + + message = Message::ref(new Message()); + message->setFrom(JID(muc_->getJID().toString() + "/otherperson")); + message->setBody(nick_ + ": hi there"); + message->setType(Message::Groupchat); + controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message))); + CPPUNIT_ASSERT_EQUAL((size_t)2, eventController_->getEvents().size()); + + message->setFrom(JID(muc_->getJID().toString() + "/other")); + message->setBody("Hi there " + nick_); + message->setType(Message::Groupchat); + controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message))); + CPPUNIT_ASSERT_EQUAL((size_t)3, eventController_->getEvents().size()); + + message = Message::ref(new Message()); + message->setFrom(JID(muc_->getJID().toString() + "/other2")); + message->setBody("Hi " + boost::to_lower_copy(nick_) + "."); + message->setType(Message::Groupchat); + controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message))); + CPPUNIT_ASSERT_EQUAL((size_t)4, eventController_->getEvents().size()); + + message = Message::ref(new Message()); + message->setFrom(JID(muc_->getJID().toString() + "/other3")); + message->setBody("Hi bert."); + message->setType(Message::Groupchat); + controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message))); + CPPUNIT_ASSERT_EQUAL((size_t)4, eventController_->getEvents().size()); + + message = Message::ref(new Message()); + message->setFrom(JID(muc_->getJID().toString() + "/other2")); + message->setBody("Hi " + boost::to_lower_copy(nick_) + "ie."); + message->setType(Message::Groupchat); + controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message))); + CPPUNIT_ASSERT_EQUAL((size_t)4, eventController_->getEvents().size()); + } + + void testNotAddressedToSelf() { + finishJoin(); + Message::ref message(new Message()); + message->setFrom(JID(muc_->getJID().toString() + "/other3")); + message->setBody("Hi there Hatter"); + message->setType(Message::Groupchat); + controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message))); + CPPUNIT_ASSERT_EQUAL((size_t)0, eventController_->getEvents().size()); + } + + void testAddressedToSelfBySelf() { + finishJoin(); + Message::ref message(new Message()); + message->setFrom(JID(muc_->getJID().toString() + "/" + nick_)); + message->setBody("Hi there " + nick_); + message->setType(Message::Groupchat); + controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message))); + CPPUNIT_ASSERT_EQUAL((size_t)0, eventController_->getEvents().size()); + } + + void testMessageWithEmptyLabelItem() { + SecurityLabelsCatalog::Item label; + label.setSelector("Bob"); + window_->label_ = label; + boost::shared_ptr<DiscoInfo> features = boost::make_shared<DiscoInfo>(); + features->addFeature(DiscoInfo::SecurityLabelsCatalogFeature); + controller_->setAvailableServerFeatures(features); + IQ::ref iq = iqChannel_->iqs_[iqChannel_->iqs_.size() - 1]; + SecurityLabelsCatalog::ref labelPayload = boost::make_shared<SecurityLabelsCatalog>(); + labelPayload->addItem(label); + IQ::ref result = IQ::createResult(self_, iq->getID(), labelPayload); + iqChannel_->onIQReceived(result); + std::string messageBody("agamemnon"); + window_->onSendMessageRequest(messageBody, false); + boost::shared_ptr<Stanza> rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1]; + Message::ref message = boost::dynamic_pointer_cast<Message>(rawStanza); + CPPUNIT_ASSERT_EQUAL(iq->getTo(), result->getFrom()); + CPPUNIT_ASSERT(window_->labelsEnabled_); + CPPUNIT_ASSERT(stanzaChannel_->isAvailable()); /* Otherwise will prevent sends. */ + CPPUNIT_ASSERT(message); + CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody().get()); + CPPUNIT_ASSERT(!message->getPayload<SecurityLabel>()); + } + + void testMessageWithLabelItem() { + boost::shared_ptr<SecurityLabel> label = boost::make_shared<SecurityLabel>(); + label->setLabel("a"); + SecurityLabelsCatalog::Item labelItem; + labelItem.setSelector("Bob"); + labelItem.setLabel(label); + window_->label_ = labelItem; + boost::shared_ptr<DiscoInfo> features = boost::make_shared<DiscoInfo>(); + features->addFeature(DiscoInfo::SecurityLabelsCatalogFeature); + controller_->setAvailableServerFeatures(features); + IQ::ref iq = iqChannel_->iqs_[iqChannel_->iqs_.size() - 1]; + SecurityLabelsCatalog::ref labelPayload = boost::make_shared<SecurityLabelsCatalog>(); + labelPayload->addItem(labelItem); + IQ::ref result = IQ::createResult(self_, iq->getID(), labelPayload); + iqChannel_->onIQReceived(result); + std::string messageBody("agamemnon"); + window_->onSendMessageRequest(messageBody, false); + boost::shared_ptr<Stanza> rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1]; + Message::ref message = boost::dynamic_pointer_cast<Message>(rawStanza); + CPPUNIT_ASSERT_EQUAL(iq->getTo(), result->getFrom()); + CPPUNIT_ASSERT(window_->labelsEnabled_); + CPPUNIT_ASSERT(stanzaChannel_->isAvailable()); /* Otherwise will prevent sends. */ + CPPUNIT_ASSERT(message); + CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody().get()); + CPPUNIT_ASSERT_EQUAL(label, message->getPayload<SecurityLabel>()); + } + + void testCorrectMessageWithLabelItem() { + boost::shared_ptr<SecurityLabel> label = boost::make_shared<SecurityLabel>(); + label->setLabel("a"); + SecurityLabelsCatalog::Item labelItem; + labelItem.setSelector("Bob"); + labelItem.setLabel(label); + boost::shared_ptr<SecurityLabel> label2 = boost::make_shared<SecurityLabel>(); + label->setLabel("b"); + SecurityLabelsCatalog::Item labelItem2; + labelItem2.setSelector("Charlie"); + labelItem2.setLabel(label2); + window_->label_ = labelItem; + boost::shared_ptr<DiscoInfo> features = boost::make_shared<DiscoInfo>(); + features->addFeature(DiscoInfo::SecurityLabelsCatalogFeature); + controller_->setAvailableServerFeatures(features); + IQ::ref iq = iqChannel_->iqs_[iqChannel_->iqs_.size() - 1]; + SecurityLabelsCatalog::ref labelPayload = boost::make_shared<SecurityLabelsCatalog>(); + labelPayload->addItem(labelItem); + IQ::ref result = IQ::createResult(self_, iq->getID(), labelPayload); + iqChannel_->onIQReceived(result); + std::string messageBody("agamemnon"); + window_->onSendMessageRequest(messageBody, false); + boost::shared_ptr<Stanza> rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1]; + Message::ref message = boost::dynamic_pointer_cast<Message>(rawStanza); + CPPUNIT_ASSERT_EQUAL(iq->getTo(), result->getFrom()); + CPPUNIT_ASSERT(window_->labelsEnabled_); + CPPUNIT_ASSERT(stanzaChannel_->isAvailable()); /* Otherwise will prevent sends. */ + CPPUNIT_ASSERT(message); + CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody().get()); + CPPUNIT_ASSERT_EQUAL(label, message->getPayload<SecurityLabel>()); + window_->label_ = labelItem2; + window_->onSendMessageRequest(messageBody, true); + rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1]; + message = boost::dynamic_pointer_cast<Message>(rawStanza); + CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody().get()); + CPPUNIT_ASSERT_EQUAL(label, message->getPayload<SecurityLabel>()); + } + + void checkEqual(const std::vector<NickJoinPart>& expected, const std::vector<NickJoinPart>& actual) { + CPPUNIT_ASSERT_EQUAL(expected.size(), actual.size()); + for (size_t i = 0; i < expected.size(); i++) { + CPPUNIT_ASSERT_EQUAL(expected[i].nick, actual[i].nick); + CPPUNIT_ASSERT_EQUAL(expected[i].type, actual[i].type); + } + } + + void testAppendToJoinParts() { + std::vector<NickJoinPart> list; + std::vector<NickJoinPart> gold; + MUCController::appendToJoinParts(list, NickJoinPart("Kev", Join)); + gold.push_back(NickJoinPart("Kev", Join)); + checkEqual(gold, list); + MUCController::appendToJoinParts(list, NickJoinPart("Remko", Join)); + gold.push_back(NickJoinPart("Remko", Join)); + checkEqual(gold, list); + MUCController::appendToJoinParts(list, NickJoinPart("Bert", Join)); + gold.push_back(NickJoinPart("Bert", Join)); + checkEqual(gold, list); + MUCController::appendToJoinParts(list, NickJoinPart("Bert", Part)); + gold[2].type = JoinThenPart; + checkEqual(gold, list); + MUCController::appendToJoinParts(list, NickJoinPart("Kev", Part)); + gold[0].type = JoinThenPart; + checkEqual(gold, list); + MUCController::appendToJoinParts(list, NickJoinPart("Remko", Part)); + gold[1].type = JoinThenPart; + checkEqual(gold, list); + MUCController::appendToJoinParts(list, NickJoinPart("Ernie", Part)); + gold.push_back(NickJoinPart("Ernie", Part)); + checkEqual(gold, list); + MUCController::appendToJoinParts(list, NickJoinPart("Ernie", Join)); + gold[3].type = PartThenJoin; + checkEqual(gold, list); + MUCController::appendToJoinParts(list, NickJoinPart("Kev", Join)); + gold[0].type = Join; + checkEqual(gold, list); + MUCController::appendToJoinParts(list, NickJoinPart("Ernie", Part)); + gold[3].type = Part; + checkEqual(gold, list); + + } + + void testJoinPartStringContructionSimple() { + std::vector<NickJoinPart> list; + list.push_back(NickJoinPart("Kev", Join)); + CPPUNIT_ASSERT_EQUAL(std::string("Kev has entered the room"), MUCController::generateJoinPartString(list, false)); + list.push_back(NickJoinPart("Remko", Part)); + CPPUNIT_ASSERT_EQUAL(std::string("Kev has entered the room and Remko has left the room"), MUCController::generateJoinPartString(list, false)); + list.push_back(NickJoinPart("Bert", Join)); + CPPUNIT_ASSERT_EQUAL(std::string("Kev and Bert have entered the room and Remko has left the room"), MUCController::generateJoinPartString(list, false)); + list.push_back(NickJoinPart("Ernie", Join)); + CPPUNIT_ASSERT_EQUAL(std::string("Kev, Bert and Ernie have entered the room and Remko has left the room"), MUCController::generateJoinPartString(list, false)); + } + + void testJoinPartStringContructionMixed() { + std::vector<NickJoinPart> list; + list.push_back(NickJoinPart("Kev", JoinThenPart)); + CPPUNIT_ASSERT_EQUAL(std::string("Kev has entered then left the room"), MUCController::generateJoinPartString(list, false)); + list.push_back(NickJoinPart("Remko", Part)); + CPPUNIT_ASSERT_EQUAL(std::string("Remko has left the room and Kev has entered then left the room"), MUCController::generateJoinPartString(list, false)); + list.push_back(NickJoinPart("Bert", PartThenJoin)); + CPPUNIT_ASSERT_EQUAL(std::string("Remko has left the room, Kev has entered then left the room and Bert has left then returned to the room"), MUCController::generateJoinPartString(list, false)); + list.push_back(NickJoinPart("Ernie", JoinThenPart)); + CPPUNIT_ASSERT_EQUAL(std::string("Remko has left the room, Kev and Ernie have entered then left the room and Bert has left then returned to the room"), MUCController::generateJoinPartString(list, false)); + } + + JID jidFromOccupant(const MUCOccupant& occupant) { + return JID(mucJID_.toString()+"/"+occupant.getNick()); + } + + void testRoleAffiliationStates() { + + typedef std::map<std::string, MUCOccupant> occupant_map; + occupant_map occupants; + occupants.insert(occupant_map::value_type("Kev", MUCOccupant("Kev", MUCOccupant::Participant, MUCOccupant::Owner))); + occupants.insert(occupant_map::value_type("Remko", MUCOccupant("Remko", MUCOccupant::Participant, MUCOccupant::Owner))); + occupants.insert(occupant_map::value_type("Bert", MUCOccupant("Bert", MUCOccupant::Participant, MUCOccupant::Owner))); + occupants.insert(occupant_map::value_type("Ernie", MUCOccupant("Ernie", MUCOccupant::Participant, MUCOccupant::Owner))); + + /* populate the MUC with fake users */ + typedef const std::pair<std::string,MUCOccupant> occupantIterator; + foreach(occupantIterator &occupant, occupants) { + muc_->insertOccupant(occupant.second); + } + + std::vector<MUCOccupant> alterations; + alterations.push_back(MUCOccupant("Kev", MUCOccupant::Visitor, MUCOccupant::Admin)); + alterations.push_back(MUCOccupant("Remko", MUCOccupant::Moderator, MUCOccupant::Member)); + alterations.push_back(MUCOccupant("Bert", MUCOccupant::Visitor, MUCOccupant::Outcast)); + alterations.push_back(MUCOccupant("Ernie", MUCOccupant::NoRole, MUCOccupant::Member)); + alterations.push_back(MUCOccupant("Bert", MUCOccupant::Moderator, MUCOccupant::Owner)); + alterations.push_back(MUCOccupant("Kev", MUCOccupant::Participant, MUCOccupant::Outcast)); + alterations.push_back(MUCOccupant("Bert", MUCOccupant::Visitor, MUCOccupant::NoAffiliation)); + alterations.push_back(MUCOccupant("Remko", MUCOccupant::NoRole, MUCOccupant::NoAffiliation)); + alterations.push_back(MUCOccupant("Ernie", MUCOccupant::Visitor, MUCOccupant::Outcast)); + + foreach(const MUCOccupant& alteration, alterations) { + /* perform an alteration to a user's role and affiliation */ + occupant_map::iterator occupant = occupants.find(alteration.getNick()); + CPPUNIT_ASSERT(occupant != occupants.end()); + const JID jid = jidFromOccupant(occupant->second); + /* change the affiliation, leave the role in place */ + muc_->changeAffiliation(jid, alteration.getAffiliation()); + occupant->second = MUCOccupant(occupant->first, occupant->second.getRole(), alteration.getAffiliation()); + testRoleAffiliationStatesVerify(occupants); + /* change the role, leave the affiliation in place */ + muc_->changeOccupantRole(jid, alteration.getRole()); + occupant->second = MUCOccupant(occupant->first, alteration.getRole(), occupant->second.getAffiliation()); + testRoleAffiliationStatesVerify(occupants); + } + } + + void testSubjectChangeCorrect() { + std::string messageBody("test message"); + window_->onSendMessageRequest(messageBody, false); + boost::shared_ptr<Stanza> rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1]; + Message::ref message = boost::dynamic_pointer_cast<Message>(rawStanza); + CPPUNIT_ASSERT(stanzaChannel_->isAvailable()); /* Otherwise will prevent sends. */ + CPPUNIT_ASSERT(message); + CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody().get_value_or("")); + + { + Message::ref message = boost::make_shared<Message>(); + message->setType(Message::Groupchat); + message->setTo(self_); + message->setFrom(mucJID_.withResource("SomeNickname")); + message->setID(iqChannel_->getNewIQID()); + message->setSubject("New Room Subject"); + + controller_->handleIncomingMessage(boost::make_shared<MessageEvent>(message)); + CPPUNIT_ASSERT_EQUAL(std::string("The room subject is now: New Room Subject"), boost::dynamic_pointer_cast<ChatWindow::ChatTextMessagePart>(window_->lastAddedSystemMessage_.getParts()[0])->text); + } + } + + /* + * Test that message stanzas with subject element and non-empty body element do not cause a subject change. + */ + void testSubjectChangeIncorrectA() { + std::string messageBody("test message"); + window_->onSendMessageRequest(messageBody, false); + boost::shared_ptr<Stanza> rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1]; + Message::ref message = boost::dynamic_pointer_cast<Message>(rawStanza); + CPPUNIT_ASSERT(stanzaChannel_->isAvailable()); /* Otherwise will prevent sends. */ + CPPUNIT_ASSERT(message); + CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody().get_value_or("")); + + { + Message::ref message = boost::make_shared<Message>(); + message->setType(Message::Groupchat); + message->setTo(self_); + message->setFrom(mucJID_.withResource("SomeNickname")); + message->setID(iqChannel_->getNewIQID()); + message->setSubject("New Room Subject"); + message->setBody("Some body text that prevents this stanza from being a subject change."); + + controller_->handleIncomingMessage(boost::make_shared<MessageEvent>(message)); + CPPUNIT_ASSERT_EQUAL(std::string("Trying to enter room teaparty@rooms.wonderland.lit"), boost::dynamic_pointer_cast<ChatWindow::ChatTextMessagePart>(window_->lastAddedSystemMessage_.getParts()[0])->text); + } + } + + /* + * Test that message stanzas with subject element and thread element do not cause a subject change. + */ + void testSubjectChangeIncorrectB() { + std::string messageBody("test message"); + window_->onSendMessageRequest(messageBody, false); + boost::shared_ptr<Stanza> rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1]; + Message::ref message = boost::dynamic_pointer_cast<Message>(rawStanza); + CPPUNIT_ASSERT(stanzaChannel_->isAvailable()); /* Otherwise will prevent sends. */ + CPPUNIT_ASSERT(message); + CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody().get_value_or("")); + + { + Message::ref message = boost::make_shared<Message>(); + message->setType(Message::Groupchat); + message->setTo(self_); + message->setFrom(mucJID_.withResource("SomeNickname")); + message->setID(iqChannel_->getNewIQID()); + message->setSubject("New Room Subject"); + message->addPayload(boost::make_shared<Thread>("Thread that prevents the subject change.")); + + controller_->handleIncomingMessage(boost::make_shared<MessageEvent>(message)); + CPPUNIT_ASSERT_EQUAL(std::string("Trying to enter room teaparty@rooms.wonderland.lit"), boost::dynamic_pointer_cast<ChatWindow::ChatTextMessagePart>(window_->lastAddedSystemMessage_.getParts()[0])->text); + } + } + + /* + * Test that message stanzas with subject element and empty body element do not cause a subject change. + */ + void testSubjectChangeIncorrectC() { + std::string messageBody("test message"); + window_->onSendMessageRequest(messageBody, false); + boost::shared_ptr<Stanza> rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1]; + Message::ref message = boost::dynamic_pointer_cast<Message>(rawStanza); + CPPUNIT_ASSERT(stanzaChannel_->isAvailable()); /* Otherwise will prevent sends. */ + CPPUNIT_ASSERT(message); + CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody().get_value_or("")); + + { + Message::ref message = boost::make_shared<Message>(); + message->setType(Message::Groupchat); + message->setTo(self_); + message->setFrom(mucJID_.withResource("SomeNickname")); + message->setID(iqChannel_->getNewIQID()); + message->setSubject("New Room Subject"); + message->setBody(""); + + controller_->handleIncomingMessage(boost::make_shared<MessageEvent>(message)); + CPPUNIT_ASSERT_EQUAL(std::string("Trying to enter room teaparty@rooms.wonderland.lit"), boost::dynamic_pointer_cast<ChatWindow::ChatTextMessagePart>(window_->lastAddedSystemMessage_.getParts()[0])->text); + } + } + + void testRoleAffiliationStatesVerify(const std::map<std::string, MUCOccupant> &occupants) { + /* verify that the roster is in sync */ + GroupRosterItem* group = window_->getRosterModel()->getRoot(); + foreach(RosterItem* rosterItem, group->getChildren()) { + GroupRosterItem* child = dynamic_cast<GroupRosterItem*>(rosterItem); + CPPUNIT_ASSERT(child); + foreach(RosterItem* childItem, child->getChildren()) { + ContactRosterItem* item = dynamic_cast<ContactRosterItem*>(childItem); + CPPUNIT_ASSERT(item); + std::map<std::string, MUCOccupant>::const_iterator occupant = occupants.find(item->getJID().getResource()); + CPPUNIT_ASSERT(occupant != occupants.end()); + CPPUNIT_ASSERT(item->getMUCRole() == occupant->second.getRole()); + CPPUNIT_ASSERT(item->getMUCAffiliation() == occupant->second.getAffiliation()); + } + } + } private: - JID self_; - JID mucJID_; - MockMUC::ref muc_; - std::string nick_; - DummyStanzaChannel* stanzaChannel_; - DummyIQChannel* iqChannel_; - IQRouter* iqRouter_; - EventController* eventController_; - ChatWindowFactory* chatWindowFactory_; - UserSearchWindowFactory* userSearchWindowFactory_; - MUCController* controller_; -// NickResolver* nickResolver_; - PresenceOracle* presenceOracle_; - AvatarManager* avatarManager_; - StanzaChannelPresenceSender* presenceSender_; - DirectedPresenceSender* directedPresenceSender_; - MockRepository* mocks_; - UIEventStream* uiEventStream_; - MockChatWindow* window_; - MUCRegistry* mucRegistry_; - DummyEntityCapsProvider* entityCapsProvider_; - DummySettingsProvider* settings_; - HighlightManager* highlightManager_; - boost::shared_ptr<ChatMessageParser> chatMessageParser_; - boost::shared_ptr<CryptoProvider> crypto_; - VCardManager* vcardManager_; - VCardMemoryStorage* vcardStorage_; - ClientBlockListManager* clientBlockListManager_; - MUCBookmarkManager* mucBookmarkManager_; - XMPPRoster* xmppRoster_; + JID self_; + JID mucJID_; + MockMUC::ref muc_; + std::string nick_; + DummyStanzaChannel* stanzaChannel_; + DummyIQChannel* iqChannel_; + IQRouter* iqRouter_; + EventController* eventController_; + ChatWindowFactory* chatWindowFactory_; + UserSearchWindowFactory* userSearchWindowFactory_; + MUCController* controller_; +// NickResolver* nickResolver_; + PresenceOracle* presenceOracle_; + AvatarManager* avatarManager_; + StanzaChannelPresenceSender* presenceSender_; + DirectedPresenceSender* directedPresenceSender_; + MockRepository* mocks_; + UIEventStream* uiEventStream_; + MockChatWindow* window_; + MUCRegistry* mucRegistry_; + DummyEntityCapsProvider* entityCapsProvider_; + DummySettingsProvider* settings_; + HighlightManager* highlightManager_; + boost::shared_ptr<ChatMessageParser> chatMessageParser_; + boost::shared_ptr<CryptoProvider> crypto_; + VCardManager* vcardManager_; + VCardMemoryStorage* vcardStorage_; + ClientBlockListManager* clientBlockListManager_; + MUCBookmarkManager* mucBookmarkManager_; + XMPPRoster* xmppRoster_; }; CPPUNIT_TEST_SUITE_REGISTRATION(MUCControllerTest); diff --git a/Swift/Controllers/Chat/UnitTest/MockChatListWindow.h b/Swift/Controllers/Chat/UnitTest/MockChatListWindow.h index 0754749..395b050 100644 --- a/Swift/Controllers/Chat/UnitTest/MockChatListWindow.h +++ b/Swift/Controllers/Chat/UnitTest/MockChatListWindow.h @@ -10,19 +10,19 @@ namespace Swift { - class MockChatListWindow : public ChatListWindow { - public: - 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 setBookmarksEnabled(bool /*enabled*/) {} - void setRecents(const std::list<ChatListWindow::Chat>& /*recents*/) {} - void setUnreadCount(int /*unread*/) {} - void clearBookmarks() {} - void setOnline(bool /*isOnline*/) {} - }; + class MockChatListWindow : public ChatListWindow { + public: + 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 setBookmarksEnabled(bool /*enabled*/) {} + void setRecents(const std::list<ChatListWindow::Chat>& /*recents*/) {} + void setUnreadCount(int /*unread*/) {} + void clearBookmarks() {} + void setOnline(bool /*isOnline*/) {} + }; } diff --git a/Swift/Controllers/Chat/UserSearchController.cpp b/Swift/Controllers/Chat/UserSearchController.cpp index e08912a..216488a 100644 --- a/Swift/Controllers/Chat/UserSearchController.cpp +++ b/Swift/Controllers/Chat/UserSearchController.cpp @@ -36,357 +36,357 @@ namespace Swift { static const std::string SEARCHED_DIRECTORIES = "searchedDirectories"; UserSearchController::UserSearchController(Type type, const JID& jid, UIEventStream* uiEventStream, VCardManager* vcardManager, UserSearchWindowFactory* factory, IQRouter* iqRouter, RosterController* rosterController, ContactSuggester* contactSuggester, AvatarManager* avatarManager, PresenceOracle* presenceOracle, ProfileSettingsProvider* settings) : type_(type), jid_(jid), uiEventStream_(uiEventStream), vcardManager_(vcardManager), factory_(factory), iqRouter_(iqRouter), rosterController_(rosterController), contactSuggester_(contactSuggester), avatarManager_(avatarManager), presenceOracle_(presenceOracle), settings_(settings) { - uiEventStream_->onUIEvent.connect(boost::bind(&UserSearchController::handleUIEvent, this, _1)); - vcardManager_->onVCardChanged.connect(boost::bind(&UserSearchController::handleVCardChanged, this, _1, _2)); - avatarManager_->onAvatarChanged.connect(boost::bind(&UserSearchController::handleAvatarChanged, this, _1)); - presenceOracle_->onPresenceChange.connect(boost::bind(&UserSearchController::handlePresenceChanged, this, _1)); - window_ = NULL; - discoWalker_ = NULL; - loadSavedDirectories(); + uiEventStream_->onUIEvent.connect(boost::bind(&UserSearchController::handleUIEvent, this, _1)); + vcardManager_->onVCardChanged.connect(boost::bind(&UserSearchController::handleVCardChanged, this, _1, _2)); + avatarManager_->onAvatarChanged.connect(boost::bind(&UserSearchController::handleAvatarChanged, this, _1)); + presenceOracle_->onPresenceChange.connect(boost::bind(&UserSearchController::handlePresenceChanged, this, _1)); + window_ = NULL; + discoWalker_ = NULL; + loadSavedDirectories(); } UserSearchController::~UserSearchController() { - endDiscoWalker(); - delete discoWalker_; - if (window_) { - window_->onNameSuggestionRequested.disconnect(boost::bind(&UserSearchController::handleNameSuggestionRequest, this, _1)); - window_->onFormRequested.disconnect(boost::bind(&UserSearchController::handleFormRequested, this, _1)); - window_->onSearchRequested.disconnect(boost::bind(&UserSearchController::handleSearch, this, _1, _2)); - window_->onContactSuggestionsRequested.disconnect(boost::bind(&UserSearchController::handleContactSuggestionsRequested, this, _1)); - window_->onJIDUpdateRequested.disconnect(boost::bind(&UserSearchController::handleJIDUpdateRequested, this, _1)); - window_->onJIDAddRequested.disconnect(boost::bind(&UserSearchController::handleJIDAddRequested, this, _1)); - window_->onJIDEditFieldChanged.disconnect(boost::bind(&UserSearchController::handleJIDEditingFinished, this, _1)); - delete window_; - } - presenceOracle_->onPresenceChange.disconnect(boost::bind(&UserSearchController::handlePresenceChanged, this, _1)); - avatarManager_->onAvatarChanged.disconnect(boost::bind(&UserSearchController::handleAvatarChanged, this, _1)); - vcardManager_->onVCardChanged.disconnect(boost::bind(&UserSearchController::handleVCardChanged, this, _1, _2)); - uiEventStream_->onUIEvent.disconnect(boost::bind(&UserSearchController::handleUIEvent, this, _1)); + endDiscoWalker(); + delete discoWalker_; + if (window_) { + window_->onNameSuggestionRequested.disconnect(boost::bind(&UserSearchController::handleNameSuggestionRequest, this, _1)); + window_->onFormRequested.disconnect(boost::bind(&UserSearchController::handleFormRequested, this, _1)); + window_->onSearchRequested.disconnect(boost::bind(&UserSearchController::handleSearch, this, _1, _2)); + window_->onContactSuggestionsRequested.disconnect(boost::bind(&UserSearchController::handleContactSuggestionsRequested, this, _1)); + window_->onJIDUpdateRequested.disconnect(boost::bind(&UserSearchController::handleJIDUpdateRequested, this, _1)); + window_->onJIDAddRequested.disconnect(boost::bind(&UserSearchController::handleJIDAddRequested, this, _1)); + window_->onJIDEditFieldChanged.disconnect(boost::bind(&UserSearchController::handleJIDEditingFinished, this, _1)); + delete window_; + } + presenceOracle_->onPresenceChange.disconnect(boost::bind(&UserSearchController::handlePresenceChanged, this, _1)); + avatarManager_->onAvatarChanged.disconnect(boost::bind(&UserSearchController::handleAvatarChanged, this, _1)); + vcardManager_->onVCardChanged.disconnect(boost::bind(&UserSearchController::handleVCardChanged, this, _1, _2)); + uiEventStream_->onUIEvent.disconnect(boost::bind(&UserSearchController::handleUIEvent, this, _1)); } UserSearchWindow* UserSearchController::getUserSearchWindow() { - initializeUserWindow(); - assert(window_); - return window_; + initializeUserWindow(); + assert(window_); + return window_; } void UserSearchController::setCanInitiateImpromptuMUC(bool supportsImpromptu) { - if (!window_) { - initializeUserWindow(); - } - if (window_) { - window_->setCanStartImpromptuChats(supportsImpromptu); - } // Else doesn't support search + if (!window_) { + initializeUserWindow(); + } + if (window_) { + window_->setCanStartImpromptuChats(supportsImpromptu); + } // Else doesn't support search } void UserSearchController::handleUIEvent(boost::shared_ptr<UIEvent> event) { - bool handle = false; - boost::shared_ptr<RequestAddUserDialogUIEvent> addUserRequest = boost::shared_ptr<RequestAddUserDialogUIEvent>(); - RequestInviteToMUCUIEvent::ref inviteToMUCRequest = RequestInviteToMUCUIEvent::ref(); - switch (type_) { - case AddContact: - if ((addUserRequest = boost::dynamic_pointer_cast<RequestAddUserDialogUIEvent>(event))) { - handle = true; - } - break; - case StartChat: - if (boost::dynamic_pointer_cast<RequestChatWithUserDialogUIEvent>(event)) { - handle = true; - } - break; - case InviteToChat: - if ((inviteToMUCRequest = boost::dynamic_pointer_cast<RequestInviteToMUCUIEvent>(event))) { - handle = true; - } - break; - } - if (handle) { - initializeUserWindow(); - window_->show(); - window_->addSavedServices(savedDirectories_); - if (addUserRequest) { - const std::string& name = addUserRequest->getPredefinedName(); - const JID& jid = addUserRequest->getPredefinedJID(); - if (!name.empty() && jid.isValid()) { - window_->prepopulateJIDAndName(jid, name); - } - } else if (inviteToMUCRequest) { - window_->setCanSupplyDescription(!inviteToMUCRequest->isImpromptu()); - window_->setJIDs(inviteToMUCRequest->getInvites()); - window_->setRoomJID(inviteToMUCRequest->getRoom()); - } - return; - } + bool handle = false; + boost::shared_ptr<RequestAddUserDialogUIEvent> addUserRequest = boost::shared_ptr<RequestAddUserDialogUIEvent>(); + RequestInviteToMUCUIEvent::ref inviteToMUCRequest = RequestInviteToMUCUIEvent::ref(); + switch (type_) { + case AddContact: + if ((addUserRequest = boost::dynamic_pointer_cast<RequestAddUserDialogUIEvent>(event))) { + handle = true; + } + break; + case StartChat: + if (boost::dynamic_pointer_cast<RequestChatWithUserDialogUIEvent>(event)) { + handle = true; + } + break; + case InviteToChat: + if ((inviteToMUCRequest = boost::dynamic_pointer_cast<RequestInviteToMUCUIEvent>(event))) { + handle = true; + } + break; + } + if (handle) { + initializeUserWindow(); + window_->show(); + window_->addSavedServices(savedDirectories_); + if (addUserRequest) { + const std::string& name = addUserRequest->getPredefinedName(); + const JID& jid = addUserRequest->getPredefinedJID(); + if (!name.empty() && jid.isValid()) { + window_->prepopulateJIDAndName(jid, name); + } + } else if (inviteToMUCRequest) { + window_->setCanSupplyDescription(!inviteToMUCRequest->isImpromptu()); + window_->setJIDs(inviteToMUCRequest->getInvites()); + window_->setRoomJID(inviteToMUCRequest->getRoom()); + } + return; + } } void UserSearchController::handleFormRequested(const JID& service) { - window_->setSearchError(false); - window_->setServerSupportsSearch(true); - - //Abort a previous search if is active - endDiscoWalker(); - delete discoWalker_; - discoWalker_ = new DiscoServiceWalker(service, iqRouter_); - discoWalker_->onServiceFound.connect(boost::bind(&UserSearchController::handleDiscoServiceFound, this, _1, _2)); - discoWalker_->onWalkComplete.connect(boost::bind(&UserSearchController::handleDiscoWalkFinished, this)); - discoWalker_->beginWalk(); + window_->setSearchError(false); + window_->setServerSupportsSearch(true); + + //Abort a previous search if is active + endDiscoWalker(); + delete discoWalker_; + discoWalker_ = new DiscoServiceWalker(service, iqRouter_); + discoWalker_->onServiceFound.connect(boost::bind(&UserSearchController::handleDiscoServiceFound, this, _1, _2)); + discoWalker_->onWalkComplete.connect(boost::bind(&UserSearchController::handleDiscoWalkFinished, this)); + discoWalker_->beginWalk(); } void UserSearchController::endDiscoWalker() { - if (discoWalker_) { - discoWalker_->endWalk(); - discoWalker_->onServiceFound.disconnect(boost::bind(&UserSearchController::handleDiscoServiceFound, this, _1, _2)); - discoWalker_->onWalkComplete.disconnect(boost::bind(&UserSearchController::handleDiscoWalkFinished, this)); - } + if (discoWalker_) { + discoWalker_->endWalk(); + discoWalker_->onServiceFound.disconnect(boost::bind(&UserSearchController::handleDiscoServiceFound, this, _1, _2)); + discoWalker_->onWalkComplete.disconnect(boost::bind(&UserSearchController::handleDiscoWalkFinished, this)); + } } void UserSearchController::handleDiscoServiceFound(const JID& jid, boost::shared_ptr<DiscoInfo> info) { - //bool isUserDirectory = false; - bool supports55 = false; - foreach (DiscoInfo::Identity identity, info->getIdentities()) { - if ((identity.getCategory() == "directory" - && identity.getType() == "user")) { - //isUserDirectory = true; - } - } - std::vector<std::string> features = info->getFeatures(); - supports55 = std::find(features.begin(), features.end(), DiscoInfo::JabberSearchFeature) != features.end(); - if (/*isUserDirectory && */supports55) { //FIXME: once M-Link correctly advertises directoryness. - /* Abort further searches.*/ - endDiscoWalker(); - boost::shared_ptr<GenericRequest<SearchPayload> > searchRequest(new GenericRequest<SearchPayload>(IQ::Get, jid, boost::make_shared<SearchPayload>(), iqRouter_)); - searchRequest->onResponse.connect(boost::bind(&UserSearchController::handleFormResponse, this, _1, _2)); - searchRequest->send(); - } + //bool isUserDirectory = false; + bool supports55 = false; + foreach (DiscoInfo::Identity identity, info->getIdentities()) { + if ((identity.getCategory() == "directory" + && identity.getType() == "user")) { + //isUserDirectory = true; + } + } + std::vector<std::string> features = info->getFeatures(); + supports55 = std::find(features.begin(), features.end(), DiscoInfo::JabberSearchFeature) != features.end(); + if (/*isUserDirectory && */supports55) { //FIXME: once M-Link correctly advertises directoryness. + /* Abort further searches.*/ + endDiscoWalker(); + boost::shared_ptr<GenericRequest<SearchPayload> > searchRequest(new GenericRequest<SearchPayload>(IQ::Get, jid, boost::make_shared<SearchPayload>(), iqRouter_)); + searchRequest->onResponse.connect(boost::bind(&UserSearchController::handleFormResponse, this, _1, _2)); + searchRequest->send(); + } } void UserSearchController::handleFormResponse(boost::shared_ptr<SearchPayload> fields, ErrorPayload::ref error) { - if (error || !fields) { - window_->setServerSupportsSearch(false); - return; - } - window_->setSearchFields(fields); + if (error || !fields) { + window_->setServerSupportsSearch(false); + return; + } + window_->setSearchFields(fields); } void UserSearchController::handleSearch(boost::shared_ptr<SearchPayload> fields, const JID& jid) { - addToSavedDirectories(jid); - boost::shared_ptr<GenericRequest<SearchPayload> > searchRequest(new GenericRequest<SearchPayload>(IQ::Set, jid, fields, iqRouter_)); - searchRequest->onResponse.connect(boost::bind(&UserSearchController::handleSearchResponse, this, _1, _2)); - searchRequest->send(); + addToSavedDirectories(jid); + boost::shared_ptr<GenericRequest<SearchPayload> > searchRequest(new GenericRequest<SearchPayload>(IQ::Set, jid, fields, iqRouter_)); + searchRequest->onResponse.connect(boost::bind(&UserSearchController::handleSearchResponse, this, _1, _2)); + searchRequest->send(); } void UserSearchController::handleSearchResponse(boost::shared_ptr<SearchPayload> resultsPayload, ErrorPayload::ref error) { - if (error || !resultsPayload) { - window_->setSearchError(true); - return; - } - - std::vector<UserSearchResult> results; - - if (resultsPayload->getForm()) { - window_->setResultsForm(resultsPayload->getForm()); - } else { - foreach (SearchPayload::Item item, resultsPayload->getItems()) { - JID jid(item.jid); - std::map<std::string, std::string> fields; - fields["first"] = item.first; - fields["last"] = item.last; - fields["nick"] = item.nick; - fields["email"] = item.email; - UserSearchResult result(jid, fields); - results.push_back(result); - } - window_->setResults(results); - } + if (error || !resultsPayload) { + window_->setSearchError(true); + return; + } + + std::vector<UserSearchResult> results; + + if (resultsPayload->getForm()) { + window_->setResultsForm(resultsPayload->getForm()); + } else { + foreach (SearchPayload::Item item, resultsPayload->getItems()) { + JID jid(item.jid); + std::map<std::string, std::string> fields; + fields["first"] = item.first; + fields["last"] = item.last; + fields["nick"] = item.nick; + fields["email"] = item.email; + UserSearchResult result(jid, fields); + results.push_back(result); + } + window_->setResults(results); + } } void UserSearchController::handleNameSuggestionRequest(const JID &jid) { - suggestionsJID_= jid; - VCard::ref vcard = vcardManager_->getVCardAndRequestWhenNeeded(jid); - if (vcard) { - handleVCardChanged(jid, vcard); - } + suggestionsJID_= jid; + VCard::ref vcard = vcardManager_->getVCardAndRequestWhenNeeded(jid); + if (vcard) { + handleVCardChanged(jid, vcard); + } } void UserSearchController::handleJIDEditingFinished(const JID& jid) { - if (jid.isValid()) { - if (rosterController_->getItem(jid)) { - window_->setWarning(QT_TRANSLATE_NOOP("", "This contact is already on your contact list.")); - } - else if (jid.getNode().empty()) { - window_->setWarning(QT_TRANSLATE_NOOP("", "Part of the address you have entered is missing. An address has a structure of 'user@example.com'.")); - } - else { - window_->setWarning(boost::optional<std::string>()); - } - } - else { - window_->setWarning(QT_TRANSLATE_NOOP("", "The address you have entered is invalid.")); - } + if (jid.isValid()) { + if (rosterController_->getItem(jid)) { + window_->setWarning(QT_TRANSLATE_NOOP("", "This contact is already on your contact list.")); + } + else if (jid.getNode().empty()) { + window_->setWarning(QT_TRANSLATE_NOOP("", "Part of the address you have entered is missing. An address has a structure of 'user@example.com'.")); + } + else { + window_->setWarning(boost::optional<std::string>()); + } + } + else { + window_->setWarning(QT_TRANSLATE_NOOP("", "The address you have entered is invalid.")); + } } void UserSearchController::handleContactSuggestionsRequested(std::string text) { - const std::vector<JID> existingJIDs = window_->getJIDs(); - std::vector<Contact::ref> suggestions = contactSuggester_->getSuggestions(text, false); - /* do not suggest contacts that have already been added to the chat list */ - std::vector<Contact::ref>::iterator i = suggestions.begin(); - while (i != suggestions.end()) { - bool found = false; - foreach (const JID& jid, existingJIDs) { - if ((*i)->jid == jid) { - found = true; - break; - } - } - - // remove contact suggestions which are already on the contact list in add-contact-mode - if (type_ == AddContact) { - if (!found && !!rosterController_->getItem((*i)->jid)) { - found = true; - } - } - - if (found) { - i = suggestions.erase(i); - } else { - i++; - } - } - window_->setContactSuggestions(suggestions); + const std::vector<JID> existingJIDs = window_->getJIDs(); + std::vector<Contact::ref> suggestions = contactSuggester_->getSuggestions(text, false); + /* do not suggest contacts that have already been added to the chat list */ + std::vector<Contact::ref>::iterator i = suggestions.begin(); + while (i != suggestions.end()) { + bool found = false; + foreach (const JID& jid, existingJIDs) { + if ((*i)->jid == jid) { + found = true; + break; + } + } + + // remove contact suggestions which are already on the contact list in add-contact-mode + if (type_ == AddContact) { + if (!found && !!rosterController_->getItem((*i)->jid)) { + found = true; + } + } + + if (found) { + i = suggestions.erase(i); + } else { + i++; + } + } + window_->setContactSuggestions(suggestions); } void UserSearchController::handleVCardChanged(const JID& jid, VCard::ref vcard) { - if (jid == suggestionsJID_) { - window_->setNameSuggestions(ContactEditController::nameSuggestionsFromVCard(vcard)); - suggestionsJID_ = JID(); - } - handleJIDUpdateRequested(std::vector<JID>(1, jid)); + if (jid == suggestionsJID_) { + window_->setNameSuggestions(ContactEditController::nameSuggestionsFromVCard(vcard)); + suggestionsJID_ = JID(); + } + handleJIDUpdateRequested(std::vector<JID>(1, jid)); } void UserSearchController::handleAvatarChanged(const JID& jid) { - handleJIDUpdateRequested(std::vector<JID>(1, jid)); + handleJIDUpdateRequested(std::vector<JID>(1, jid)); } void UserSearchController::handlePresenceChanged(Presence::ref presence) { - handleJIDUpdateRequested(std::vector<JID>(1, presence->getFrom().toBare())); + handleJIDUpdateRequested(std::vector<JID>(1, presence->getFrom().toBare())); } void UserSearchController::handleJIDUpdateRequested(const std::vector<JID>& jids) { - if (window_) { - std::vector<Contact::ref> updates; - foreach(const JID& jid, jids) { - updates.push_back(convertJIDtoContact(jid)); - } - window_->updateContacts(updates); - } + if (window_) { + std::vector<Contact::ref> updates; + foreach(const JID& jid, jids) { + updates.push_back(convertJIDtoContact(jid)); + } + window_->updateContacts(updates); + } } void UserSearchController::handleJIDAddRequested(const std::vector<JID>& jids) { - std::vector<Contact::ref> contacts; - foreach(const JID& jid, jids) { - contacts.push_back(convertJIDtoContact(jid)); - } - window_->addContacts(contacts); + std::vector<Contact::ref> contacts; + foreach(const JID& jid, jids) { + contacts.push_back(convertJIDtoContact(jid)); + } + window_->addContacts(contacts); } Contact::ref UserSearchController::convertJIDtoContact(const JID& jid) { - Contact::ref contact = boost::make_shared<Contact>(); - contact->jid = jid; - - // name lookup - boost::optional<XMPPRosterItem> rosterItem = rosterController_->getItem(jid); - if (rosterItem && !rosterItem->getName().empty()) { - contact->name = rosterItem->getName(); - } else { - VCard::ref vcard = vcardManager_->getVCard(jid); - if (vcard && !vcard->getFullName().empty()) { - contact->name = vcard->getFullName(); - } else { - contact->name = jid.toString(); - } - } - - // presence lookup - Presence::ref presence = presenceOracle_->getAccountPresence(jid); - if (presence) { - contact->statusType = presence->getShow(); - } else { - contact->statusType = StatusShow::None; - } - - // avatar lookup - contact->avatarPath = avatarManager_->getAvatarPath(jid); - return contact; + Contact::ref contact = boost::make_shared<Contact>(); + contact->jid = jid; + + // name lookup + boost::optional<XMPPRosterItem> rosterItem = rosterController_->getItem(jid); + if (rosterItem && !rosterItem->getName().empty()) { + contact->name = rosterItem->getName(); + } else { + VCard::ref vcard = vcardManager_->getVCard(jid); + if (vcard && !vcard->getFullName().empty()) { + contact->name = vcard->getFullName(); + } else { + contact->name = jid.toString(); + } + } + + // presence lookup + Presence::ref presence = presenceOracle_->getAccountPresence(jid); + if (presence) { + contact->statusType = presence->getShow(); + } else { + contact->statusType = StatusShow::None; + } + + // avatar lookup + contact->avatarPath = avatarManager_->getAvatarPath(jid); + return contact; } void UserSearchController::handleDiscoWalkFinished() { - window_->setServerSupportsSearch(false); - endDiscoWalker(); + window_->setServerSupportsSearch(false); + endDiscoWalker(); } void UserSearchController::initializeUserWindow() { - if (!window_) { - UserSearchWindow::Type windowType = UserSearchWindow::AddContact; - switch(type_) { - case AddContact: - windowType = UserSearchWindow::AddContact; - break; - case StartChat: - windowType = UserSearchWindow::ChatToContact; - break; - case InviteToChat: - windowType = UserSearchWindow::InviteToChat; - break; - } - - window_ = factory_->createUserSearchWindow(windowType, uiEventStream_, rosterController_->getGroups()); - if (!window_) { - // UI Doesn't support user search - return; - } - window_->onNameSuggestionRequested.connect(boost::bind(&UserSearchController::handleNameSuggestionRequest, this, _1)); - window_->onFormRequested.connect(boost::bind(&UserSearchController::handleFormRequested, this, _1)); - window_->onSearchRequested.connect(boost::bind(&UserSearchController::handleSearch, this, _1, _2)); - window_->onContactSuggestionsRequested.connect(boost::bind(&UserSearchController::handleContactSuggestionsRequested, this, _1)); - window_->onJIDUpdateRequested.connect(boost::bind(&UserSearchController::handleJIDUpdateRequested, this, _1)); - window_->onJIDAddRequested.connect(boost::bind(&UserSearchController::handleJIDAddRequested, this, _1)); - window_->onJIDEditFieldChanged.connect(boost::bind(&UserSearchController::handleJIDEditingFinished, this, _1)); - window_->setSelectedService(JID(jid_.getDomain())); - window_->clear(); - } + if (!window_) { + UserSearchWindow::Type windowType = UserSearchWindow::AddContact; + switch(type_) { + case AddContact: + windowType = UserSearchWindow::AddContact; + break; + case StartChat: + windowType = UserSearchWindow::ChatToContact; + break; + case InviteToChat: + windowType = UserSearchWindow::InviteToChat; + break; + } + + window_ = factory_->createUserSearchWindow(windowType, uiEventStream_, rosterController_->getGroups()); + if (!window_) { + // UI Doesn't support user search + return; + } + window_->onNameSuggestionRequested.connect(boost::bind(&UserSearchController::handleNameSuggestionRequest, this, _1)); + window_->onFormRequested.connect(boost::bind(&UserSearchController::handleFormRequested, this, _1)); + window_->onSearchRequested.connect(boost::bind(&UserSearchController::handleSearch, this, _1, _2)); + window_->onContactSuggestionsRequested.connect(boost::bind(&UserSearchController::handleContactSuggestionsRequested, this, _1)); + window_->onJIDUpdateRequested.connect(boost::bind(&UserSearchController::handleJIDUpdateRequested, this, _1)); + window_->onJIDAddRequested.connect(boost::bind(&UserSearchController::handleJIDAddRequested, this, _1)); + window_->onJIDEditFieldChanged.connect(boost::bind(&UserSearchController::handleJIDEditingFinished, this, _1)); + window_->setSelectedService(JID(jid_.getDomain())); + window_->clear(); + } } void UserSearchController::loadSavedDirectories() { - savedDirectories_.clear(); - foreach (std::string stringItem, String::split(settings_->getStringSetting(SEARCHED_DIRECTORIES), '\n')) { - if(!stringItem.empty()) { - savedDirectories_.push_back(JID(stringItem)); - } - } + savedDirectories_.clear(); + foreach (std::string stringItem, String::split(settings_->getStringSetting(SEARCHED_DIRECTORIES), '\n')) { + if(!stringItem.empty()) { + savedDirectories_.push_back(JID(stringItem)); + } + } } void UserSearchController::addToSavedDirectories(const JID& jid) { - if (!jid.isValid()) { - return; - } - - savedDirectories_.erase(std::remove(savedDirectories_.begin(), savedDirectories_.end(), jid), savedDirectories_.end()); - savedDirectories_.insert(savedDirectories_.begin(), jid); - - std::string collapsed; - int i = 0; - foreach (JID jidItem, savedDirectories_) { - if (i >= 15) { - break; - } - if (!collapsed.empty()) { - collapsed += "\n"; - } - collapsed += jidItem.toString(); - ++i; - } - settings_->storeString(SEARCHED_DIRECTORIES, collapsed); - window_->addSavedServices(savedDirectories_); + if (!jid.isValid()) { + return; + } + + savedDirectories_.erase(std::remove(savedDirectories_.begin(), savedDirectories_.end(), jid), savedDirectories_.end()); + savedDirectories_.insert(savedDirectories_.begin(), jid); + + std::string collapsed; + int i = 0; + foreach (JID jidItem, savedDirectories_) { + if (i >= 15) { + break; + } + if (!collapsed.empty()) { + collapsed += "\n"; + } + collapsed += jidItem.toString(); + ++i; + } + settings_->storeString(SEARCHED_DIRECTORIES, collapsed); + window_->addSavedServices(savedDirectories_); } } diff --git a/Swift/Controllers/Chat/UserSearchController.h b/Swift/Controllers/Chat/UserSearchController.h index 0423a65..71b8331 100644 --- a/Swift/Controllers/Chat/UserSearchController.h +++ b/Swift/Controllers/Chat/UserSearchController.h @@ -24,76 +24,76 @@ #include <Swift/Controllers/Contact.h> namespace Swift { - class UIEventStream; - class UIEvent; - class UserSearchWindow; - class UserSearchWindowFactory; - class IQRouter; - class DiscoServiceWalker; - class RosterController; - class VCardManager; - class ContactSuggester; - class AvatarManager; - class PresenceOracle; - class ProfileSettingsProvider; + class UIEventStream; + class UIEvent; + class UserSearchWindow; + class UserSearchWindowFactory; + class IQRouter; + class DiscoServiceWalker; + class RosterController; + class VCardManager; + class ContactSuggester; + class AvatarManager; + class PresenceOracle; + class ProfileSettingsProvider; - class UserSearchResult { - public: - UserSearchResult(const JID& jid, const std::map<std::string, std::string>& fields) : jid_(jid), fields_(fields) {} - const JID& getJID() const {return jid_;} - const std::map<std::string, std::string>& getFields() const {return fields_;} - private: - JID jid_; - std::map<std::string, std::string> fields_; - }; + class UserSearchResult { + public: + UserSearchResult(const JID& jid, const std::map<std::string, std::string>& fields) : jid_(jid), fields_(fields) {} + const JID& getJID() const {return jid_;} + const std::map<std::string, std::string>& getFields() const {return fields_;} + private: + JID jid_; + std::map<std::string, std::string> fields_; + }; - class UserSearchController { - public: - enum Type {AddContact, StartChat, InviteToChat}; - UserSearchController(Type type, const JID& jid, UIEventStream* uiEventStream, VCardManager* vcardManager, UserSearchWindowFactory* userSearchWindowFactory, IQRouter* iqRouter, RosterController* rosterController, ContactSuggester* contactSuggester, AvatarManager* avatarManager, PresenceOracle* presenceOracle, ProfileSettingsProvider* settings); - ~UserSearchController(); + class UserSearchController { + public: + enum Type {AddContact, StartChat, InviteToChat}; + UserSearchController(Type type, const JID& jid, UIEventStream* uiEventStream, VCardManager* vcardManager, UserSearchWindowFactory* userSearchWindowFactory, IQRouter* iqRouter, RosterController* rosterController, ContactSuggester* contactSuggester, AvatarManager* avatarManager, PresenceOracle* presenceOracle, ProfileSettingsProvider* settings); + ~UserSearchController(); - UserSearchWindow* getUserSearchWindow(); - void setCanInitiateImpromptuMUC(bool supportsImpromptu); + UserSearchWindow* getUserSearchWindow(); + void setCanInitiateImpromptuMUC(bool supportsImpromptu); - private: - void handleUIEvent(boost::shared_ptr<UIEvent> event); - void handleFormRequested(const JID& service); - void handleDiscoServiceFound(const JID& jid, boost::shared_ptr<DiscoInfo> info); - void handleDiscoWalkFinished(); - void handleFormResponse(boost::shared_ptr<SearchPayload> items, ErrorPayload::ref error); - void handleSearch(boost::shared_ptr<SearchPayload> fields, const JID& jid); - void handleSearchResponse(boost::shared_ptr<SearchPayload> results, ErrorPayload::ref error); - void handleNameSuggestionRequest(const JID& jid); - void handleContactSuggestionsRequested(std::string text); - void handleVCardChanged(const JID& jid, VCard::ref vcard); - void handleAvatarChanged(const JID& jid); - void handlePresenceChanged(Presence::ref presence); - void handleJIDUpdateRequested(const std::vector<JID>& jids); - void handleJIDAddRequested(const std::vector<JID>& jids); - void handleJIDEditingFinished(const JID& jid); - Contact::ref convertJIDtoContact(const JID& jid); - void endDiscoWalker(); - void initializeUserWindow(); + private: + void handleUIEvent(boost::shared_ptr<UIEvent> event); + void handleFormRequested(const JID& service); + void handleDiscoServiceFound(const JID& jid, boost::shared_ptr<DiscoInfo> info); + void handleDiscoWalkFinished(); + void handleFormResponse(boost::shared_ptr<SearchPayload> items, ErrorPayload::ref error); + void handleSearch(boost::shared_ptr<SearchPayload> fields, const JID& jid); + void handleSearchResponse(boost::shared_ptr<SearchPayload> results, ErrorPayload::ref error); + void handleNameSuggestionRequest(const JID& jid); + void handleContactSuggestionsRequested(std::string text); + void handleVCardChanged(const JID& jid, VCard::ref vcard); + void handleAvatarChanged(const JID& jid); + void handlePresenceChanged(Presence::ref presence); + void handleJIDUpdateRequested(const std::vector<JID>& jids); + void handleJIDAddRequested(const std::vector<JID>& jids); + void handleJIDEditingFinished(const JID& jid); + Contact::ref convertJIDtoContact(const JID& jid); + void endDiscoWalker(); + void initializeUserWindow(); - void loadSavedDirectories(); - void addToSavedDirectories(const JID& jid); + void loadSavedDirectories(); + void addToSavedDirectories(const JID& jid); - private: - Type type_; - JID jid_; - JID suggestionsJID_; - UIEventStream* uiEventStream_; - VCardManager* vcardManager_; - UserSearchWindowFactory* factory_; - IQRouter* iqRouter_; - RosterController* rosterController_; - UserSearchWindow* window_; - DiscoServiceWalker* discoWalker_; - ContactSuggester* contactSuggester_; - AvatarManager* avatarManager_; - PresenceOracle* presenceOracle_; - std::vector<JID> savedDirectories_; - ProfileSettingsProvider* settings_; - }; + private: + Type type_; + JID jid_; + JID suggestionsJID_; + UIEventStream* uiEventStream_; + VCardManager* vcardManager_; + UserSearchWindowFactory* factory_; + IQRouter* iqRouter_; + RosterController* rosterController_; + UserSearchWindow* window_; + DiscoServiceWalker* discoWalker_; + ContactSuggester* contactSuggester_; + AvatarManager* avatarManager_; + PresenceOracle* presenceOracle_; + std::vector<JID> savedDirectories_; + ProfileSettingsProvider* settings_; + }; } diff --git a/Swift/Controllers/ChatMessageSummarizer.cpp b/Swift/Controllers/ChatMessageSummarizer.cpp index a0ae6d1..6b630e7 100644 --- a/Swift/Controllers/ChatMessageSummarizer.cpp +++ b/Swift/Controllers/ChatMessageSummarizer.cpp @@ -15,32 +15,32 @@ using namespace Swift; using namespace std; string ChatMessageSummarizer::getSummary(const string& current, const vector<UnreadPair>& unreads) { - vector<UnreadPair> others; - int currentUnread = 0; - int otherCount = 0; - foreach (UnreadPair unread, unreads) { - if (unread.first == current) { - currentUnread += unread.second; - } else { - if (unread.second > 0) { - otherCount += unread.second; - others.push_back(unread); - } - } - } - string myString(current); + vector<UnreadPair> others; + int currentUnread = 0; + int otherCount = 0; + foreach (UnreadPair unread, unreads) { + if (unread.first == current) { + currentUnread += unread.second; + } else { + if (unread.second > 0) { + otherCount += unread.second; + others.push_back(unread); + } + } + } + string myString(current); - if (currentUnread > 0) { - string result(QT_TRANSLATE_NOOP("", "%1% (%2%)")); - myString = str(format(result) % current % currentUnread); - } + if (currentUnread > 0) { + string result(QT_TRANSLATE_NOOP("", "%1% (%2%)")); + myString = str(format(result) % current % currentUnread); + } - if (others.size() > 1) { - string result(QT_TRANSLATE_NOOP("", "%1% and %2% others (%3%)")); - myString = str(format(result) % myString % others.size() % otherCount); - } else if (!others.empty()) { - string result(QT_TRANSLATE_NOOP("", "%1%; %2% (%3%)")); - myString = str(format(result) % myString % others[0].first % otherCount); - } - return myString; + if (others.size() > 1) { + string result(QT_TRANSLATE_NOOP("", "%1% and %2% others (%3%)")); + myString = str(format(result) % myString % others.size() % otherCount); + } else if (!others.empty()) { + string result(QT_TRANSLATE_NOOP("", "%1%; %2% (%3%)")); + myString = str(format(result) % myString % others[0].first % otherCount); + } + return myString; } diff --git a/Swift/Controllers/ChatMessageSummarizer.h b/Swift/Controllers/ChatMessageSummarizer.h index 9ed867d..0b4df21 100644 --- a/Swift/Controllers/ChatMessageSummarizer.h +++ b/Swift/Controllers/ChatMessageSummarizer.h @@ -13,8 +13,8 @@ namespace Swift { typedef std::pair<std::string, int> UnreadPair; - class ChatMessageSummarizer { - public: - std::string getSummary(const std::string& current, const std::vector<UnreadPair>& unreads); - }; + class ChatMessageSummarizer { + public: + std::string getSummary(const std::string& current, const std::vector<UnreadPair>& unreads); + }; } diff --git a/Swift/Controllers/ConnectionSettings.h b/Swift/Controllers/ConnectionSettings.h index 6a2fded..7ce45cd 100644 --- a/Swift/Controllers/ConnectionSettings.h +++ b/Swift/Controllers/ConnectionSettings.h @@ -9,32 +9,32 @@ #include <string> struct ConnectionSettings { - enum Method { - Automatic, - Manual, - BOSH - }; - enum ProxyType { - None, - System, - SOCKS5, - HTTPConnect - }; + enum Method { + Automatic, + Manual, + BOSH + }; + enum ProxyType { + None, + System, + SOCKS5, + HTTPConnect + }; - Method method; - struct { - bool useManualServer; - std::string manualServerHostname; - int manualServerPort; - ProxyType proxyType; - bool useManualProxy; - std::string manualProxyHostname; - int manualProxyPort; - } manualSettings; - struct { - std::string boshURI; - bool useManualProxy; - std::string manualProxyHostname; - int manualProxyPort; - } boshSettings; + Method method; + struct { + bool useManualServer; + std::string manualServerHostname; + int manualServerPort; + ProxyType proxyType; + bool useManualProxy; + std::string manualProxyHostname; + int manualProxyPort; + } manualSettings; + struct { + std::string boshURI; + bool useManualProxy; + std::string manualProxyHostname; + int manualProxyPort; + } boshSettings; }; diff --git a/Swift/Controllers/Contact.cpp b/Swift/Controllers/Contact.cpp index bda1239..b9b98c3 100644 --- a/Swift/Controllers/Contact.cpp +++ b/Swift/Controllers/Contact.cpp @@ -24,54 +24,54 @@ Contact::Contact(const std::string& name, const JID& jid, StatusShow::Type statu } bool Contact::lexicographicalSortPredicate(const Contact::ref& a, const Contact::ref& b) { - if (a->jid.isValid() && b->jid.isValid()) { - return a->jid < b->jid; - } else { - return a->name < b->name; - } + if (a->jid.isValid() && b->jid.isValid()) { + return a->jid < b->jid; + } else { + return a->name < b->name; + } } bool Contact::equalityPredicate(const Contact::ref& a, const Contact::ref& b) { - if (a->jid.isValid() && b->jid.isValid()) { - return a->jid == b->jid; - } else { - return a->name == b->name; - } + if (a->jid.isValid() && b->jid.isValid()) { + return a->jid == b->jid; + } else { + return a->name == b->name; + } } bool Contact::sortPredicate(const Contact::ref& a, const Contact::ref& b, const std::string& search) { - /* perform case insensitive comparisons */ - std::string aLower = a->name; - boost::to_lower(aLower); - std::string bLower = b->name; - boost::to_lower(bLower); - std::string searchLower = search; - boost::to_lower(searchLower); + /* perform case insensitive comparisons */ + std::string aLower = a->name; + boost::to_lower(aLower); + std::string bLower = b->name; + boost::to_lower(bLower); + std::string searchLower = search; + boost::to_lower(searchLower); - /* name starts with the search term */ - if (aLower.find(searchLower) == 0 && bLower.find(searchLower) != 0) { - return true; - } else if (bLower.find(searchLower) == 0 && aLower.find(searchLower) != 0) { - return false; - } + /* name starts with the search term */ + if (aLower.find(searchLower) == 0 && bLower.find(searchLower) != 0) { + return true; + } else if (bLower.find(searchLower) == 0 && aLower.find(searchLower) != 0) { + return false; + } - /* name contains search term */ - if (aLower.find(searchLower) != std::string::npos && bLower.find(searchLower) == std::string::npos) { - return true; - } else if (bLower.find(searchLower) != std::string::npos && aLower.find(searchLower) == std::string::npos) { - return false; - } + /* name contains search term */ + if (aLower.find(searchLower) != std::string::npos && bLower.find(searchLower) == std::string::npos) { + return true; + } else if (bLower.find(searchLower) != std::string::npos && aLower.find(searchLower) == std::string::npos) { + return false; + } - /* Levenshtein should be done here */ - /* if edit distances are equal, fall through to the tests below */ + /* Levenshtein should be done here */ + /* if edit distances are equal, fall through to the tests below */ - /* lexicographical sort */ - if (a->statusType == b->statusType) { - return aLower.compare(bLower) < 0; - } + /* lexicographical sort */ + if (a->statusType == b->statusType) { + return aLower.compare(bLower) < 0; + } - /* online status */ - return a->statusType < b->statusType; + /* online status */ + return a->statusType < b->statusType; } } diff --git a/Swift/Controllers/Contact.h b/Swift/Controllers/Contact.h index b03a118..4aa6999 100644 --- a/Swift/Controllers/Contact.h +++ b/Swift/Controllers/Contact.h @@ -21,21 +21,21 @@ namespace Swift { class Contact : public boost::enable_shared_from_this<Contact> { - public: - typedef boost::shared_ptr<Contact> ref; + public: + typedef boost::shared_ptr<Contact> ref; - Contact(); - Contact(const std::string& name, const JID& jid, StatusShow::Type statusType, const boost::filesystem::path& path); + Contact(); + Contact(const std::string& name, const JID& jid, StatusShow::Type statusType, const boost::filesystem::path& path); - static bool lexicographicalSortPredicate(const Contact::ref& a, const Contact::ref& b); - static bool equalityPredicate(const Contact::ref& a, const Contact::ref& b); - static bool sortPredicate(const Contact::ref& a, const Contact::ref& b, const std::string& search); + static bool lexicographicalSortPredicate(const Contact::ref& a, const Contact::ref& b); + static bool equalityPredicate(const Contact::ref& a, const Contact::ref& b); + static bool sortPredicate(const Contact::ref& a, const Contact::ref& b, const std::string& search); - public: - std::string name; - JID jid; - StatusShow::Type statusType; - boost::filesystem::path avatarPath; + public: + std::string name; + JID jid; + StatusShow::Type statusType; + boost::filesystem::path avatarPath; }; } diff --git a/Swift/Controllers/ContactEditController.cpp b/Swift/Controllers/ContactEditController.cpp index 704e3bc..734ef79 100644 --- a/Swift/Controllers/ContactEditController.cpp +++ b/Swift/Controllers/ContactEditController.cpp @@ -21,89 +21,89 @@ namespace Swift { ContactEditController::ContactEditController(RosterController* rosterController, VCardManager* vcardManager, ContactEditWindowFactory* contactEditWindowFactory, UIEventStream* uiEventStream) : rosterController(rosterController), vcardManager(vcardManager), contactEditWindowFactory(contactEditWindowFactory), uiEventStream(uiEventStream), contactEditWindow(NULL) { - uiEventStream->onUIEvent.connect(boost::bind(&ContactEditController::handleUIEvent, this, _1)); - vcardManager->onVCardChanged.connect(boost::bind(&ContactEditController::handleVCardChanged, this, _1, _2)); + uiEventStream->onUIEvent.connect(boost::bind(&ContactEditController::handleUIEvent, this, _1)); + vcardManager->onVCardChanged.connect(boost::bind(&ContactEditController::handleVCardChanged, this, _1, _2)); } ContactEditController::~ContactEditController() { - if (contactEditWindow) { - contactEditWindow->onChangeContactRequest.disconnect(boost::bind(&ContactEditController::handleChangeContactRequest, this, _1, _2)); - contactEditWindow->onRemoveContactRequest.disconnect(boost::bind(&ContactEditController::handleRemoveContactRequest, this)); - delete contactEditWindow; - } - uiEventStream->onUIEvent.disconnect(boost::bind(&ContactEditController::handleUIEvent, this, _1)); + if (contactEditWindow) { + contactEditWindow->onChangeContactRequest.disconnect(boost::bind(&ContactEditController::handleChangeContactRequest, this, _1, _2)); + contactEditWindow->onRemoveContactRequest.disconnect(boost::bind(&ContactEditController::handleRemoveContactRequest, this)); + delete contactEditWindow; + } + uiEventStream->onUIEvent.disconnect(boost::bind(&ContactEditController::handleUIEvent, this, _1)); } void ContactEditController::handleUIEvent(UIEvent::ref event) { - RequestContactEditorUIEvent::ref editEvent = boost::dynamic_pointer_cast<RequestContactEditorUIEvent>(event); - if (!editEvent) { - return; - } - - if (!contactEditWindow) { - contactEditWindow = contactEditWindowFactory->createContactEditWindow(); - contactEditWindow->onRemoveContactRequest.connect(boost::bind(&ContactEditController::handleRemoveContactRequest, this)); - contactEditWindow->onChangeContactRequest.connect(boost::bind(&ContactEditController::handleChangeContactRequest, this, _1, _2)); - } - currentContact = rosterController->getItem(editEvent->getJID()); - assert(currentContact); - jid = rosterController->getItem(editEvent->getJID())->getJID(); - contactEditWindow->setContact(jid, currentContact->getName(), currentContact->getGroups(), rosterController->getGroups()); - contactEditWindow->show(); - - if (vcardManager) { - VCard::ref vcard = vcardManager->getVCardAndRequestWhenNeeded(jid); - if (vcard) { - handleVCardChanged(jid, vcard); - } - } + RequestContactEditorUIEvent::ref editEvent = boost::dynamic_pointer_cast<RequestContactEditorUIEvent>(event); + if (!editEvent) { + return; + } + + if (!contactEditWindow) { + contactEditWindow = contactEditWindowFactory->createContactEditWindow(); + contactEditWindow->onRemoveContactRequest.connect(boost::bind(&ContactEditController::handleRemoveContactRequest, this)); + contactEditWindow->onChangeContactRequest.connect(boost::bind(&ContactEditController::handleChangeContactRequest, this, _1, _2)); + } + currentContact = rosterController->getItem(editEvent->getJID()); + assert(currentContact); + jid = rosterController->getItem(editEvent->getJID())->getJID(); + contactEditWindow->setContact(jid, currentContact->getName(), currentContact->getGroups(), rosterController->getGroups()); + contactEditWindow->show(); + + if (vcardManager) { + VCard::ref vcard = vcardManager->getVCardAndRequestWhenNeeded(jid); + if (vcard) { + handleVCardChanged(jid, vcard); + } + } } void ContactEditController::handleVCardChanged(const JID &jid, VCard::ref vcard) { - if (jid == this->jid) { - contactEditWindow->setNameSuggestions(nameSuggestionsFromVCard(vcard)); - } + if (jid == this->jid) { + contactEditWindow->setNameSuggestions(nameSuggestionsFromVCard(vcard)); + } } void ContactEditController::setAvailable(bool b) { - if (contactEditWindow) { - contactEditWindow->setEnabled(b); - } + if (contactEditWindow) { + contactEditWindow->setEnabled(b); + } } std::vector<std::string> ContactEditController::nameSuggestionsFromVCard(VCard::ref vcard) { - std::vector<std::string> suggestions; - if (!vcard->getNickname().empty()) { - suggestions.push_back(vcard->getNickname()); - } - if (!vcard->getFullName().empty()) { - suggestions.push_back(vcard->getFullName()); - } - if (!vcard->getGivenName().empty()) { - std::string suggestedName; - suggestedName = vcard->getGivenName(); - boost::algorithm::trim(suggestedName); - suggestions.push_back(suggestedName); - } - return suggestions; + std::vector<std::string> suggestions; + if (!vcard->getNickname().empty()) { + suggestions.push_back(vcard->getNickname()); + } + if (!vcard->getFullName().empty()) { + suggestions.push_back(vcard->getFullName()); + } + if (!vcard->getGivenName().empty()) { + std::string suggestedName; + suggestedName = vcard->getGivenName(); + boost::algorithm::trim(suggestedName); + suggestions.push_back(suggestedName); + } + return suggestions; } void ContactEditController::handleRemoveContactRequest() { - assert(currentContact); - uiEventStream->send(boost::make_shared<RemoveRosterItemUIEvent>(currentContact->getJID())); - contactEditWindow->hide(); + assert(currentContact); + uiEventStream->send(boost::make_shared<RemoveRosterItemUIEvent>(currentContact->getJID())); + contactEditWindow->hide(); } void ContactEditController::handleChangeContactRequest(const std::string& name, const std::set<std::string>& newGroups) { - std::vector<std::string> oldGroupsVector = currentContact->getGroups(); - std::set<std::string> oldGroups(oldGroupsVector.begin(), oldGroupsVector.end()); - if (oldGroups != newGroups || currentContact->getName() != name) { - XMPPRosterItem newContact(*currentContact); - newContact.setName(name); - newContact.setGroups(std::vector<std::string>(newGroups.begin(), newGroups.end())); - rosterController->updateItem(newContact); - } - contactEditWindow->hide(); + std::vector<std::string> oldGroupsVector = currentContact->getGroups(); + std::set<std::string> oldGroups(oldGroupsVector.begin(), oldGroupsVector.end()); + if (oldGroups != newGroups || currentContact->getName() != name) { + XMPPRosterItem newContact(*currentContact); + newContact.setName(name); + newContact.setGroups(std::vector<std::string>(newGroups.begin(), newGroups.end())); + rosterController->updateItem(newContact); + } + contactEditWindow->hide(); } } diff --git a/Swift/Controllers/ContactEditController.h b/Swift/Controllers/ContactEditController.h index 671fe38..ab2b52e 100644 --- a/Swift/Controllers/ContactEditController.h +++ b/Swift/Controllers/ContactEditController.h @@ -19,38 +19,38 @@ #include <Swift/Controllers/UIEvents/UIEvent.h> namespace Swift { - class UIEventStream; - class ContactEditWindowFactory; - class ContactEditWindow; - class RosterController; - class VCardManager; - - class ContactEditController { - public: - ContactEditController(RosterController* rosterController, VCardManager* vcardManager, ContactEditWindowFactory* contactEditWindowFactory, UIEventStream* uiEventStream); - ~ContactEditController(); - - void setAvailable(bool b); - - public: - static std::vector<std::string> nameSuggestionsFromVCard(VCard::ref vcard); - - private: - void handleRemoveContactRequest(); - void handleChangeContactRequest(const std::string& name, const std::set<std::string>& groups); - - private: - void handleUIEvent(UIEvent::ref event); - void handleVCardChanged(const JID& jid, VCard::ref vcard); - - private: - boost::optional<XMPPRosterItem> currentContact; - RosterController* rosterController; - VCardManager* vcardManager; - ContactEditWindowFactory* contactEditWindowFactory; - UIEventStream* uiEventStream; - JID jid; - ContactEditWindow* contactEditWindow; - }; + class UIEventStream; + class ContactEditWindowFactory; + class ContactEditWindow; + class RosterController; + class VCardManager; + + class ContactEditController { + public: + ContactEditController(RosterController* rosterController, VCardManager* vcardManager, ContactEditWindowFactory* contactEditWindowFactory, UIEventStream* uiEventStream); + ~ContactEditController(); + + void setAvailable(bool b); + + public: + static std::vector<std::string> nameSuggestionsFromVCard(VCard::ref vcard); + + private: + void handleRemoveContactRequest(); + void handleChangeContactRequest(const std::string& name, const std::set<std::string>& groups); + + private: + void handleUIEvent(UIEvent::ref event); + void handleVCardChanged(const JID& jid, VCard::ref vcard); + + private: + boost::optional<XMPPRosterItem> currentContact; + RosterController* rosterController; + VCardManager* vcardManager; + ContactEditWindowFactory* contactEditWindowFactory; + UIEventStream* uiEventStream; + JID jid; + ContactEditWindow* contactEditWindow; + }; } diff --git a/Swift/Controllers/ContactProvider.h b/Swift/Controllers/ContactProvider.h index 08812d5..423f8a3 100644 --- a/Swift/Controllers/ContactProvider.h +++ b/Swift/Controllers/ContactProvider.h @@ -19,9 +19,9 @@ namespace Swift { class ContactProvider { - public: - virtual ~ContactProvider(); - virtual std::vector<Contact::ref> getContacts(bool withMUCNicks) = 0; + public: + virtual ~ContactProvider(); + virtual std::vector<Contact::ref> getContacts(bool withMUCNicks) = 0; }; } diff --git a/Swift/Controllers/ContactSuggester.cpp b/Swift/Controllers/ContactSuggester.cpp index a2b605a..04e9dc4 100644 --- a/Swift/Controllers/ContactSuggester.cpp +++ b/Swift/Controllers/ContactSuggester.cpp @@ -39,49 +39,49 @@ ContactSuggester::~ContactSuggester() { } void ContactSuggester::addContactProvider(ContactProvider* provider) { - contactProviders_.push_back(provider); + contactProviders_.push_back(provider); } bool ContactSuggester::matchContact(const std::string& search, const Contact::ref& c) { - if (fuzzyMatch(c->name, search)) { - return true; - } - else if (c->jid.isValid()) { - return fuzzyMatch(c->jid.toString(), search); - } - return false; + if (fuzzyMatch(c->name, search)) { + return true; + } + else if (c->jid.isValid()) { + return fuzzyMatch(c->jid.toString(), search); + } + return false; } std::vector<Contact::ref> ContactSuggester::getSuggestions(const std::string& search, bool withMUCNicks) const { - std::vector<Contact::ref> results; + std::vector<Contact::ref> results; - foreach(ContactProvider* provider, contactProviders_) { - append(results, provider->getContacts(withMUCNicks)); - } + foreach(ContactProvider* provider, contactProviders_) { + append(results, provider->getContacts(withMUCNicks)); + } - std::sort(results.begin(), results.end(), Contact::lexicographicalSortPredicate); - results.erase(std::unique(results.begin(), results.end(), Contact::equalityPredicate), results.end()); - results.erase(std::remove_if(results.begin(), results.end(), !lambda::bind(&matchContact, search, lambda::_1)), - results.end()); - std::sort(results.begin(), results.end(), boost::bind(&Contact::sortPredicate, _1, _2, search)); + std::sort(results.begin(), results.end(), Contact::lexicographicalSortPredicate); + results.erase(std::unique(results.begin(), results.end(), Contact::equalityPredicate), results.end()); + results.erase(std::remove_if(results.begin(), results.end(), !lambda::bind(&matchContact, search, lambda::_1)), + results.end()); + std::sort(results.begin(), results.end(), boost::bind(&Contact::sortPredicate, _1, _2, search)); - return results; + return results; } bool ContactSuggester::fuzzyMatch(std::string text, std::string match) { - std::string lowerText = text; - boost::algorithm::to_lower(lowerText); - std::string lowerMatch = match; - boost::algorithm::to_lower(lowerMatch); - size_t lastMatch = 0; - for (size_t i = 0; i < lowerMatch.length(); ++i) { - size_t where = lowerText.find_first_of(lowerMatch[i], lastMatch); - if (where == std::string::npos) { - return false; - } - lastMatch = where + 1; - } - return true; + std::string lowerText = text; + boost::algorithm::to_lower(lowerText); + std::string lowerMatch = match; + boost::algorithm::to_lower(lowerMatch); + size_t lastMatch = 0; + for (size_t i = 0; i < lowerMatch.length(); ++i) { + size_t where = lowerText.find_first_of(lowerMatch[i], lastMatch); + if (where == std::string::npos) { + return false; + } + lastMatch = where + 1; + } + return true; } } diff --git a/Swift/Controllers/ContactSuggester.h b/Swift/Controllers/ContactSuggester.h index a57f638..f91879d 100644 --- a/Swift/Controllers/ContactSuggester.h +++ b/Swift/Controllers/ContactSuggester.h @@ -20,24 +20,24 @@ class ContactSuggesterTest; namespace Swift { - class ContactProvider; - - class ContactSuggester { - public: - ContactSuggester(); - ~ContactSuggester(); - - void addContactProvider(ContactProvider* provider); - - std::vector<Contact::ref> getSuggestions(const std::string& search, bool withMUCNicks) const; - public: - static bool matchContact(const std::string& search, const Contact::ref& c); - /** - * Performs fuzzy matching on the string text. Matches when each character of match string is present in sequence in text string. - */ - static bool fuzzyMatch(std::string text, std::string match); - - private: - std::vector<ContactProvider*> contactProviders_; - }; + class ContactProvider; + + class ContactSuggester { + public: + ContactSuggester(); + ~ContactSuggester(); + + void addContactProvider(ContactProvider* provider); + + std::vector<Contact::ref> getSuggestions(const std::string& search, bool withMUCNicks) const; + public: + static bool matchContact(const std::string& search, const Contact::ref& c); + /** + * Performs fuzzy matching on the string text. Matches when each character of match string is present in sequence in text string. + */ + static bool fuzzyMatch(std::string text, std::string match); + + private: + std::vector<ContactProvider*> contactProviders_; + }; } diff --git a/Swift/Controllers/ContactsFromXMPPRoster.cpp b/Swift/Controllers/ContactsFromXMPPRoster.cpp index 1cab9b1..1aa4424 100644 --- a/Swift/Controllers/ContactsFromXMPPRoster.cpp +++ b/Swift/Controllers/ContactsFromXMPPRoster.cpp @@ -27,15 +27,15 @@ ContactsFromXMPPRoster::~ContactsFromXMPPRoster() { } std::vector<Contact::ref> ContactsFromXMPPRoster::getContacts(bool /*withMUCNicks*/) { - std::vector<Contact::ref> results; - std::vector<XMPPRosterItem> rosterItems = roster_->getItems(); - foreach(const XMPPRosterItem& rosterItem, rosterItems) { - Contact::ref contact = boost::make_shared<Contact>(rosterItem.getName().empty() ? rosterItem.getJID().toString() : rosterItem.getName(), rosterItem.getJID(), StatusShow::None,""); - contact->statusType = presenceOracle_->getAccountPresence(contact->jid) ? presenceOracle_->getAccountPresence(contact->jid)->getShow() : StatusShow::None; - contact->avatarPath = avatarManager_->getAvatarPath(contact->jid); - results.push_back(contact); - } - return results; + std::vector<Contact::ref> results; + std::vector<XMPPRosterItem> rosterItems = roster_->getItems(); + foreach(const XMPPRosterItem& rosterItem, rosterItems) { + Contact::ref contact = boost::make_shared<Contact>(rosterItem.getName().empty() ? rosterItem.getJID().toString() : rosterItem.getName(), rosterItem.getJID(), StatusShow::None,""); + contact->statusType = presenceOracle_->getAccountPresence(contact->jid) ? presenceOracle_->getAccountPresence(contact->jid)->getShow() : StatusShow::None; + contact->avatarPath = avatarManager_->getAvatarPath(contact->jid); + results.push_back(contact); + } + return results; } } diff --git a/Swift/Controllers/ContactsFromXMPPRoster.h b/Swift/Controllers/ContactsFromXMPPRoster.h index 43d4985..2782dcc 100644 --- a/Swift/Controllers/ContactsFromXMPPRoster.h +++ b/Swift/Controllers/ContactsFromXMPPRoster.h @@ -21,15 +21,15 @@ class AvatarManager; class XMPPRoster; class ContactsFromXMPPRoster : public ContactProvider { - public: - ContactsFromXMPPRoster(XMPPRoster* roster, AvatarManager* avatarManager, PresenceOracle* presenceOracle); - virtual ~ContactsFromXMPPRoster(); - - virtual std::vector<Contact::ref> getContacts(bool withMUCNicks); - private: - XMPPRoster* roster_; - AvatarManager* avatarManager_; - PresenceOracle* presenceOracle_; + public: + ContactsFromXMPPRoster(XMPPRoster* roster, AvatarManager* avatarManager, PresenceOracle* presenceOracle); + virtual ~ContactsFromXMPPRoster(); + + virtual std::vector<Contact::ref> getContacts(bool withMUCNicks); + private: + XMPPRoster* roster_; + AvatarManager* avatarManager_; + PresenceOracle* presenceOracle_; }; } diff --git a/Swift/Controllers/DummySoundPlayer.h b/Swift/Controllers/DummySoundPlayer.h index 2d99fb9..e297cae 100644 --- a/Swift/Controllers/DummySoundPlayer.h +++ b/Swift/Controllers/DummySoundPlayer.h @@ -9,8 +9,8 @@ #include <Swift/Controllers/SoundPlayer.h> namespace Swift { - class DummySoundPlayer : public SoundPlayer { - public: - void playSound(SoundEffect /*sound*/, const std::string& /*soundResource*/) {} - }; + class DummySoundPlayer : public SoundPlayer { + public: + void playSound(SoundEffect /*sound*/, const std::string& /*soundResource*/) {} + }; } diff --git a/Swift/Controllers/DummySystemTray.h b/Swift/Controllers/DummySystemTray.h index b413737..b36ed28 100644 --- a/Swift/Controllers/DummySystemTray.h +++ b/Swift/Controllers/DummySystemTray.h @@ -9,10 +9,10 @@ #include <Swift/Controllers/SystemTray.h> namespace Swift { - class DummySystemTray : public SystemTray { - public: - void setUnreadMessages(bool /*some*/) {} - void setStatusType(StatusShow::Type /*type*/) {} - void setConnecting() {} - }; + class DummySystemTray : public SystemTray { + public: + void setUnreadMessages(bool /*some*/) {} + void setStatusType(StatusShow::Type /*type*/) {} + void setConnecting() {} + }; } diff --git a/Swift/Controllers/EventNotifier.cpp b/Swift/Controllers/EventNotifier.cpp index 6615448..f4a9c2f 100644 --- a/Swift/Controllers/EventNotifier.cpp +++ b/Swift/Controllers/EventNotifier.cpp @@ -28,53 +28,53 @@ namespace Swift { EventNotifier::EventNotifier(EventController* eventController, Notifier* notifier, AvatarManager* avatarManager, NickResolver* nickResolver) : eventController(eventController), notifier(notifier), avatarManager(avatarManager), nickResolver(nickResolver) { - eventController->onEventQueueEventAdded.connect(boost::bind(&EventNotifier::handleEventAdded, this, _1)); + eventController->onEventQueueEventAdded.connect(boost::bind(&EventNotifier::handleEventAdded, this, _1)); } EventNotifier::~EventNotifier() { - notifier->purgeCallbacks(); - eventController->onEventQueueEventAdded.disconnect(boost::bind(&EventNotifier::handleEventAdded, this, _1)); + notifier->purgeCallbacks(); + eventController->onEventQueueEventAdded.disconnect(boost::bind(&EventNotifier::handleEventAdded, this, _1)); } void EventNotifier::handleEventAdded(boost::shared_ptr<StanzaEvent> event) { - if (event->getConcluded()) { - return; - } - if (boost::shared_ptr<MessageEvent> messageEvent = boost::dynamic_pointer_cast<MessageEvent>(event)) { - JID jid = messageEvent->getStanza()->getFrom(); - std::string title = nickResolver->jidToNick(jid); - if (!messageEvent->getStanza()->isError() && !messageEvent->getStanza()->getBody().get_value_or("").empty()) { - JID activationJID = jid; - if (messageEvent->getStanza()->getType() == Message::Groupchat) { - activationJID = jid.toBare(); - } - std::string messageText = messageEvent->getStanza()->getBody().get_value_or(""); - if (boost::starts_with(messageText, "/me ")) { - messageText = "*" + String::getSplittedAtFirst(messageText, ' ').second + "*"; - } - notifier->showMessage(Notifier::IncomingMessage, title, messageText, avatarManager->getAvatarPath(jid), boost::bind(&EventNotifier::handleNotificationActivated, this, activationJID)); - } - } - else if(boost::shared_ptr<SubscriptionRequestEvent> subscriptionEvent = boost::dynamic_pointer_cast<SubscriptionRequestEvent>(event)) { - JID jid = subscriptionEvent->getJID(); - std::string title = jid; - std::string message = str(format(QT_TRANSLATE_NOOP("", "%1% wants to add you to his/her contact list")) % nickResolver->jidToNick(jid)); - notifier->showMessage(Notifier::SystemMessage, title, message, boost::filesystem::path(), boost::function<void()>()); - } - else if(boost::shared_ptr<ErrorEvent> errorEvent = boost::dynamic_pointer_cast<ErrorEvent>(event)) { - notifier->showMessage(Notifier::SystemMessage, QT_TRANSLATE_NOOP("", "Error"), errorEvent->getText(), boost::filesystem::path(), boost::function<void()>()); - } - else if (boost::shared_ptr<MUCInviteEvent> mucInviteEvent = boost::dynamic_pointer_cast<MUCInviteEvent>(event)) { - std::string title = mucInviteEvent->getInviter(); - std::string message = str(format(QT_TRANSLATE_NOOP("", "%1% has invited you to enter the %2% room")) % nickResolver->jidToNick(mucInviteEvent->getInviter()) % mucInviteEvent->getRoomJID()); - // FIXME: not show avatar or greyed out avatar for mediated invites - notifier->showMessage(Notifier::SystemMessage, title, message, avatarManager->getAvatarPath(mucInviteEvent->getInviter()), boost::bind(&EventNotifier::handleNotificationActivated, this, mucInviteEvent->getInviter())); - } + if (event->getConcluded()) { + return; + } + if (boost::shared_ptr<MessageEvent> messageEvent = boost::dynamic_pointer_cast<MessageEvent>(event)) { + JID jid = messageEvent->getStanza()->getFrom(); + std::string title = nickResolver->jidToNick(jid); + if (!messageEvent->getStanza()->isError() && !messageEvent->getStanza()->getBody().get_value_or("").empty()) { + JID activationJID = jid; + if (messageEvent->getStanza()->getType() == Message::Groupchat) { + activationJID = jid.toBare(); + } + std::string messageText = messageEvent->getStanza()->getBody().get_value_or(""); + if (boost::starts_with(messageText, "/me ")) { + messageText = "*" + String::getSplittedAtFirst(messageText, ' ').second + "*"; + } + notifier->showMessage(Notifier::IncomingMessage, title, messageText, avatarManager->getAvatarPath(jid), boost::bind(&EventNotifier::handleNotificationActivated, this, activationJID)); + } + } + else if(boost::shared_ptr<SubscriptionRequestEvent> subscriptionEvent = boost::dynamic_pointer_cast<SubscriptionRequestEvent>(event)) { + JID jid = subscriptionEvent->getJID(); + std::string title = jid; + std::string message = str(format(QT_TRANSLATE_NOOP("", "%1% wants to add you to his/her contact list")) % nickResolver->jidToNick(jid)); + notifier->showMessage(Notifier::SystemMessage, title, message, boost::filesystem::path(), boost::function<void()>()); + } + else if(boost::shared_ptr<ErrorEvent> errorEvent = boost::dynamic_pointer_cast<ErrorEvent>(event)) { + notifier->showMessage(Notifier::SystemMessage, QT_TRANSLATE_NOOP("", "Error"), errorEvent->getText(), boost::filesystem::path(), boost::function<void()>()); + } + else if (boost::shared_ptr<MUCInviteEvent> mucInviteEvent = boost::dynamic_pointer_cast<MUCInviteEvent>(event)) { + std::string title = mucInviteEvent->getInviter(); + std::string message = str(format(QT_TRANSLATE_NOOP("", "%1% has invited you to enter the %2% room")) % nickResolver->jidToNick(mucInviteEvent->getInviter()) % mucInviteEvent->getRoomJID()); + // FIXME: not show avatar or greyed out avatar for mediated invites + notifier->showMessage(Notifier::SystemMessage, title, message, avatarManager->getAvatarPath(mucInviteEvent->getInviter()), boost::bind(&EventNotifier::handleNotificationActivated, this, mucInviteEvent->getInviter())); + } } void EventNotifier::handleNotificationActivated(JID jid) { - onNotificationActivated(jid); + onNotificationActivated(jid); } } diff --git a/Swift/Controllers/EventNotifier.h b/Swift/Controllers/EventNotifier.h index 2ecff6a..4661c46 100644 --- a/Swift/Controllers/EventNotifier.h +++ b/Swift/Controllers/EventNotifier.h @@ -16,29 +16,29 @@ #include <SwifTools/Notifier/Notifier.h> namespace Swift { - class EventController; - class Notifier; - class AvatarManager; - class NickResolver; - class JID; - class UIEventStream; - class SettingsProvider; - - class EventNotifier { - public: - EventNotifier(EventController* eventController, Notifier* notifier, AvatarManager* avatarManager, NickResolver* nickResolver); - ~EventNotifier(); - - boost::signal<void (const JID&)> onNotificationActivated; - - private: - void handleEventAdded(boost::shared_ptr<StanzaEvent>); - void handleNotificationActivated(JID jid); - - private: - EventController* eventController; - Notifier* notifier; - AvatarManager* avatarManager; - NickResolver* nickResolver; - }; + class EventController; + class Notifier; + class AvatarManager; + class NickResolver; + class JID; + class UIEventStream; + class SettingsProvider; + + class EventNotifier { + public: + EventNotifier(EventController* eventController, Notifier* notifier, AvatarManager* avatarManager, NickResolver* nickResolver); + ~EventNotifier(); + + boost::signal<void (const JID&)> onNotificationActivated; + + private: + void handleEventAdded(boost::shared_ptr<StanzaEvent>); + void handleNotificationActivated(JID jid); + + private: + EventController* eventController; + Notifier* notifier; + AvatarManager* avatarManager; + NickResolver* nickResolver; + }; } diff --git a/Swift/Controllers/EventWindowController.cpp b/Swift/Controllers/EventWindowController.cpp index 91fedd2..2739a87 100644 --- a/Swift/Controllers/EventWindowController.cpp +++ b/Swift/Controllers/EventWindowController.cpp @@ -14,41 +14,41 @@ namespace Swift { EventWindowController::EventWindowController(EventController* eventController, EventWindowFactory* windowFactory) { - eventController_ = eventController; - windowFactory_ = windowFactory; - window_ = windowFactory_->createEventWindow(); - eventAddedConnection_ = eventController_->onEventQueueEventAdded.connect(boost::bind(&EventWindowController::handleEventQueueEventAdded, this, _1)); + eventController_ = eventController; + windowFactory_ = windowFactory; + window_ = windowFactory_->createEventWindow(); + eventAddedConnection_ = eventController_->onEventQueueEventAdded.connect(boost::bind(&EventWindowController::handleEventQueueEventAdded, this, _1)); } EventWindowController::~EventWindowController() { - if (window_->canDelete()) { - delete window_; - } + if (window_->canDelete()) { + delete window_; + } } void EventWindowController::handleEventQueueEventAdded(boost::shared_ptr<StanzaEvent> event) { - if (event->getConcluded()) { - handleEventConcluded(event); - } else { - boost::shared_ptr<MessageEvent> message = boost::dynamic_pointer_cast<MessageEvent>(event); - if (!(message && message->isReadable())) { - event->onConclusion.connect(boost::bind(&EventWindowController::handleEventConcluded, this, event)); - window_->addEvent(event, true); - } - } + if (event->getConcluded()) { + handleEventConcluded(event); + } else { + boost::shared_ptr<MessageEvent> message = boost::dynamic_pointer_cast<MessageEvent>(event); + if (!(message && message->isReadable())) { + event->onConclusion.connect(boost::bind(&EventWindowController::handleEventConcluded, this, event)); + window_->addEvent(event, true); + } + } } void EventWindowController::handleEventConcluded(boost::shared_ptr<StanzaEvent> event) { - window_->removeEvent(event); - bool includeAsCompleted = true; - /* Because subscription requests get duplicated, don't add them back */ - if (boost::dynamic_pointer_cast<SubscriptionRequestEvent>(event) || boost::dynamic_pointer_cast<MessageEvent>(event)) { - includeAsCompleted = false; - } - if (includeAsCompleted) { - window_->addEvent(event, false); - } - event->onConclusion.disconnect(boost::bind(&EventWindowController::handleEventConcluded, this, event)); + window_->removeEvent(event); + bool includeAsCompleted = true; + /* Because subscription requests get duplicated, don't add them back */ + if (boost::dynamic_pointer_cast<SubscriptionRequestEvent>(event) || boost::dynamic_pointer_cast<MessageEvent>(event)) { + includeAsCompleted = false; + } + if (includeAsCompleted) { + window_->addEvent(event, false); + } + event->onConclusion.disconnect(boost::bind(&EventWindowController::handleEventConcluded, this, event)); } } diff --git a/Swift/Controllers/EventWindowController.h b/Swift/Controllers/EventWindowController.h index 1c50830..eba07ca 100644 --- a/Swift/Controllers/EventWindowController.h +++ b/Swift/Controllers/EventWindowController.h @@ -12,18 +12,18 @@ namespace Swift { - class EventWindowController { - public: - EventWindowController(EventController* eventController, EventWindowFactory* windowFactory); - ~EventWindowController(); - private: - void handleEventQueueEventAdded(boost::shared_ptr<StanzaEvent> event); - void handleEventConcluded(boost::shared_ptr<StanzaEvent> event); + class EventWindowController { + public: + EventWindowController(EventController* eventController, EventWindowFactory* windowFactory); + ~EventWindowController(); + private: + void handleEventQueueEventAdded(boost::shared_ptr<StanzaEvent> event); + void handleEventConcluded(boost::shared_ptr<StanzaEvent> event); - EventController* eventController_; - EventWindowFactory* windowFactory_; - EventWindow* window_; - boost::bsignals::scoped_connection eventAddedConnection_; - }; + EventController* eventController_; + EventWindowFactory* windowFactory_; + EventWindow* window_; + boost::bsignals::scoped_connection eventAddedConnection_; + }; } diff --git a/Swift/Controllers/FileTransfer/FileTransferController.cpp b/Swift/Controllers/FileTransfer/FileTransferController.cpp index 89e9a91..fd13d99 100644 --- a/Swift/Controllers/FileTransfer/FileTransferController.cpp +++ b/Swift/Controllers/FileTransfer/FileTransferController.cpp @@ -28,135 +28,135 @@ namespace Swift { FileTransferController::FileTransferController(const JID& receipient, const std::string& filename, FileTransferManager* fileTransferManager) : - sending(true), otherParty(receipient), filename(filename), ftManager(fileTransferManager), ftProgressInfo(0), chatWindow(0), currentState(FileTransfer::State::WaitingForStart) { - + sending(true), otherParty(receipient), filename(filename), ftManager(fileTransferManager), ftProgressInfo(0), chatWindow(0), currentState(FileTransfer::State::WaitingForStart) { + } FileTransferController::FileTransferController(IncomingFileTransfer::ref transfer) : - sending(false), otherParty(transfer->getSender()), filename(transfer->getFileName()), transfer(transfer), ftManager(0), ftProgressInfo(0), chatWindow(0), currentState(FileTransfer::State::WaitingForStart) { - transfer->onStateChanged.connect(boost::bind(&FileTransferController::handleFileTransferStateChange, this, _1)); + sending(false), otherParty(transfer->getSender()), filename(transfer->getFileName()), transfer(transfer), ftManager(0), ftProgressInfo(0), chatWindow(0), currentState(FileTransfer::State::WaitingForStart) { + transfer->onStateChanged.connect(boost::bind(&FileTransferController::handleFileTransferStateChange, this, _1)); } FileTransferController::~FileTransferController() { - delete ftProgressInfo; - transfer->onStateChanged.disconnect(boost::bind(&FileTransferController::handleFileTransferStateChange, this, _1)); + delete ftProgressInfo; + transfer->onStateChanged.disconnect(boost::bind(&FileTransferController::handleFileTransferStateChange, this, _1)); } const JID &FileTransferController::getOtherParty() const { - return otherParty; + return otherParty; } std::string FileTransferController::setChatWindow(ChatWindow* wnd, std::string nickname) { - chatWindow = wnd; - if (sending) { - uiID = wnd->addFileTransfer(QT_TRANSLATE_NOOP("", "me"), true, filename, boost::filesystem::file_size(boost::filesystem::path(filename)), ""); - } else { - uiID = wnd->addFileTransfer(nickname, false, filename, transfer->getFileSizeInBytes(), transfer->getDescription()); - } - return uiID; + chatWindow = wnd; + if (sending) { + uiID = wnd->addFileTransfer(QT_TRANSLATE_NOOP("", "me"), true, filename, boost::filesystem::file_size(boost::filesystem::path(filename)), ""); + } else { + uiID = wnd->addFileTransfer(nickname, false, filename, transfer->getFileSizeInBytes(), transfer->getDescription()); + } + return uiID; } void FileTransferController::setReceipient(const JID& receipient) { - this->otherParty = receipient; + this->otherParty = receipient; } bool FileTransferController::isIncoming() const { - return !sending; + return !sending; } FileTransfer::State FileTransferController::getState() const { - return currentState; + return currentState; } int FileTransferController::getProgress() const { - return ftProgressInfo ? ftProgressInfo->getPercentage() : 0; + return ftProgressInfo ? ftProgressInfo->getPercentage() : 0; } boost::uintmax_t FileTransferController::getSize() const { - if (transfer) { - return transfer->getFileSizeInBytes(); - } else { - return 0; - } + if (transfer) { + return transfer->getFileSizeInBytes(); + } else { + return 0; + } } void FileTransferController::start(std::string& description) { - SWIFT_LOG(debug) << "FileTransferController::start" << std::endl; - fileReadStream = boost::make_shared<FileReadBytestream>(boost::filesystem::path(filename)); - OutgoingFileTransfer::ref outgoingTransfer = ftManager->createOutgoingFileTransfer(otherParty, boost::filesystem::path(filename), description, fileReadStream); - if (outgoingTransfer) { - ftProgressInfo = new FileTransferProgressInfo(outgoingTransfer->getFileSizeInBytes()); - ftProgressInfo->onProgressPercentage.connect(boost::bind(&FileTransferController::handleProgressPercentageChange, this, _1)); - outgoingTransfer->onStateChanged.connect(boost::bind(&FileTransferController::handleFileTransferStateChange, this, _1)); - outgoingTransfer->onProcessedBytes.connect(boost::bind(&FileTransferProgressInfo::setBytesProcessed, ftProgressInfo, _1)); - outgoingTransfer->start(); - transfer = outgoingTransfer; - } else { - std::cerr << "File transfer not supported!" << std::endl; - } + SWIFT_LOG(debug) << "FileTransferController::start" << std::endl; + fileReadStream = boost::make_shared<FileReadBytestream>(boost::filesystem::path(filename)); + OutgoingFileTransfer::ref outgoingTransfer = ftManager->createOutgoingFileTransfer(otherParty, boost::filesystem::path(filename), description, fileReadStream); + if (outgoingTransfer) { + ftProgressInfo = new FileTransferProgressInfo(outgoingTransfer->getFileSizeInBytes()); + ftProgressInfo->onProgressPercentage.connect(boost::bind(&FileTransferController::handleProgressPercentageChange, this, _1)); + outgoingTransfer->onStateChanged.connect(boost::bind(&FileTransferController::handleFileTransferStateChange, this, _1)); + outgoingTransfer->onProcessedBytes.connect(boost::bind(&FileTransferProgressInfo::setBytesProcessed, ftProgressInfo, _1)); + outgoingTransfer->start(); + transfer = outgoingTransfer; + } else { + std::cerr << "File transfer not supported!" << std::endl; + } } void FileTransferController::accept(std::string& file) { - SWIFT_LOG(debug) << "FileTransferController::accept" << std::endl; - IncomingFileTransfer::ref incomingTransfer = boost::dynamic_pointer_cast<IncomingFileTransfer>(transfer); - if (incomingTransfer) { - fileWriteStream = boost::make_shared<FileWriteBytestream>(boost::filesystem::path(file)); + SWIFT_LOG(debug) << "FileTransferController::accept" << std::endl; + IncomingFileTransfer::ref incomingTransfer = boost::dynamic_pointer_cast<IncomingFileTransfer>(transfer); + if (incomingTransfer) { + fileWriteStream = boost::make_shared<FileWriteBytestream>(boost::filesystem::path(file)); - ftProgressInfo = new FileTransferProgressInfo(transfer->getFileSizeInBytes()); - ftProgressInfo->onProgressPercentage.connect(boost::bind(&FileTransferController::handleProgressPercentageChange, this, _1)); - transfer->onProcessedBytes.connect(boost::bind(&FileTransferProgressInfo::setBytesProcessed, ftProgressInfo, _1)); - incomingTransfer->accept(fileWriteStream); - } else { - std::cerr << "Expected an incoming transfer in this situation!" << std::endl; - } + ftProgressInfo = new FileTransferProgressInfo(transfer->getFileSizeInBytes()); + ftProgressInfo->onProgressPercentage.connect(boost::bind(&FileTransferController::handleProgressPercentageChange, this, _1)); + transfer->onProcessedBytes.connect(boost::bind(&FileTransferProgressInfo::setBytesProcessed, ftProgressInfo, _1)); + incomingTransfer->accept(fileWriteStream); + } else { + std::cerr << "Expected an incoming transfer in this situation!" << std::endl; + } } void FileTransferController::cancel() { - if (transfer) { - transfer->cancel(); - } else { - chatWindow->setFileTransferStatus(uiID, ChatWindow::Canceled); - } + if (transfer) { + transfer->cancel(); + } else { + chatWindow->setFileTransferStatus(uiID, ChatWindow::Canceled); + } } void FileTransferController::handleFileTransferStateChange(FileTransfer::State state) { - currentState = state; - onStateChanged(); - switch(state.type) { - case FileTransfer::State::Initial: - assert(false); - return; - case FileTransfer::State::Negotiating: - chatWindow->setFileTransferStatus(uiID, ChatWindow::Negotiating); - return; - case FileTransfer::State::Transferring: - chatWindow->setFileTransferStatus(uiID, ChatWindow::Transferring); - return; - case FileTransfer::State::Canceled: - chatWindow->setFileTransferStatus(uiID, ChatWindow::Canceled); - return; - case FileTransfer::State::Finished: - chatWindow->setFileTransferStatus(uiID, ChatWindow::Finished); - if (fileWriteStream) { - fileWriteStream->close(); - } - return; - case FileTransfer::State::Failed: - chatWindow->setFileTransferStatus(uiID, ChatWindow::FTFailed); - return; - case FileTransfer::State::WaitingForAccept: - chatWindow->setFileTransferStatus(uiID, ChatWindow::WaitingForAccept); - return; - case FileTransfer::State::WaitingForStart: - chatWindow->setFileTransferStatus(uiID, ChatWindow::Initialisation); - return; - } - assert(false); + currentState = state; + onStateChanged(); + switch(state.type) { + case FileTransfer::State::Initial: + assert(false); + return; + case FileTransfer::State::Negotiating: + chatWindow->setFileTransferStatus(uiID, ChatWindow::Negotiating); + return; + case FileTransfer::State::Transferring: + chatWindow->setFileTransferStatus(uiID, ChatWindow::Transferring); + return; + case FileTransfer::State::Canceled: + chatWindow->setFileTransferStatus(uiID, ChatWindow::Canceled); + return; + case FileTransfer::State::Finished: + chatWindow->setFileTransferStatus(uiID, ChatWindow::Finished); + if (fileWriteStream) { + fileWriteStream->close(); + } + return; + case FileTransfer::State::Failed: + chatWindow->setFileTransferStatus(uiID, ChatWindow::FTFailed); + return; + case FileTransfer::State::WaitingForAccept: + chatWindow->setFileTransferStatus(uiID, ChatWindow::WaitingForAccept); + return; + case FileTransfer::State::WaitingForStart: + chatWindow->setFileTransferStatus(uiID, ChatWindow::Initialisation); + return; + } + assert(false); } void FileTransferController::handleProgressPercentageChange(int percentage) { - onProgressChange(); - chatWindow->setFileTransferProgress(uiID, percentage); + onProgressChange(); + chatWindow->setFileTransferProgress(uiID, percentage); } } diff --git a/Swift/Controllers/FileTransfer/FileTransferController.h b/Swift/Controllers/FileTransfer/FileTransferController.h index 490773d..a25abee 100644 --- a/Swift/Controllers/FileTransfer/FileTransferController.h +++ b/Swift/Controllers/FileTransfer/FileTransferController.h @@ -32,49 +32,49 @@ class ChatWindow; class FileTransferController { public: - /** - * For outgoing file transfers. It'll create a file transfer via FileTransferManager as soon as the descriptive information is available. - */ - FileTransferController(const JID&, const std::string&, FileTransferManager*); + /** + * For outgoing file transfers. It'll create a file transfer via FileTransferManager as soon as the descriptive information is available. + */ + FileTransferController(const JID&, const std::string&, FileTransferManager*); - /** - * For incoming file transfers. - */ - FileTransferController(IncomingFileTransfer::ref transfer); - ~FileTransferController(); + /** + * For incoming file transfers. + */ + FileTransferController(IncomingFileTransfer::ref transfer); + ~FileTransferController(); - std::string setChatWindow(ChatWindow*, std::string nickname); - void setReceipient(const JID& otherParty); + std::string setChatWindow(ChatWindow*, std::string nickname); + void setReceipient(const JID& otherParty); - void start(std::string& description); - void accept(std::string& file); - void cancel(); + void start(std::string& description); + void accept(std::string& file); + void cancel(); - const JID &getOtherParty() const; - bool isIncoming() const; - FileTransfer::State getState() const; - int getProgress() const; - boost::uintmax_t getSize() const; + const JID &getOtherParty() const; + bool isIncoming() const; + FileTransfer::State getState() const; + int getProgress() const; + boost::uintmax_t getSize() const; - boost::signal<void ()> onStateChanged; - boost::signal<void ()> onProgressChange; + boost::signal<void ()> onStateChanged; + boost::signal<void ()> onProgressChange; private: - void handleFileTransferStateChange(FileTransfer::State); - void handleProgressPercentageChange(int percentage); + void handleFileTransferStateChange(FileTransfer::State); + void handleProgressPercentageChange(int percentage); private: - bool sending; - JID otherParty; - std::string filename; - FileTransfer::ref transfer; - boost::shared_ptr<FileReadBytestream> fileReadStream; - boost::shared_ptr<FileWriteBytestream> fileWriteStream; - FileTransferManager* ftManager; - FileTransferProgressInfo* ftProgressInfo; - ChatWindow* chatWindow; - std::string uiID; - FileTransfer::State currentState; + bool sending; + JID otherParty; + std::string filename; + FileTransfer::ref transfer; + boost::shared_ptr<FileReadBytestream> fileReadStream; + boost::shared_ptr<FileWriteBytestream> fileWriteStream; + FileTransferManager* ftManager; + FileTransferProgressInfo* ftProgressInfo; + ChatWindow* chatWindow; + std::string uiID; + FileTransfer::State currentState; }; } diff --git a/Swift/Controllers/FileTransfer/FileTransferOverview.cpp b/Swift/Controllers/FileTransfer/FileTransferOverview.cpp index 8616c1e..a53b000 100644 --- a/Swift/Controllers/FileTransfer/FileTransferOverview.cpp +++ b/Swift/Controllers/FileTransfer/FileTransferOverview.cpp @@ -23,70 +23,70 @@ namespace Swift { FileTransferOverview::FileTransferOverview(FileTransferManager* ftm) : fileTransferManager(ftm) { - fileTransferManager->onIncomingFileTransfer.connect(boost::bind(&FileTransferOverview::handleIncomingFileTransfer, this, _1)); - onNewFileTransferController.connect(boost::bind(&FileTransferOverview::handleNewFileTransferController, this, _1)); + fileTransferManager->onIncomingFileTransfer.connect(boost::bind(&FileTransferOverview::handleIncomingFileTransfer, this, _1)); + onNewFileTransferController.connect(boost::bind(&FileTransferOverview::handleNewFileTransferController, this, _1)); } FileTransferOverview::~FileTransferOverview() { - onNewFileTransferController.disconnect(boost::bind(&FileTransferOverview::handleNewFileTransferController, this, _1)); - fileTransferManager->onIncomingFileTransfer.disconnect(boost::bind(&FileTransferOverview::handleIncomingFileTransfer, this, _1)); - foreach(FileTransferController* controller, fileTransfers) { - controller->onStateChanged.disconnect(boost::bind(&FileTransferOverview::handleFileTransferStateChanged, this)); - } + onNewFileTransferController.disconnect(boost::bind(&FileTransferOverview::handleNewFileTransferController, this, _1)); + fileTransferManager->onIncomingFileTransfer.disconnect(boost::bind(&FileTransferOverview::handleIncomingFileTransfer, this, _1)); + foreach(FileTransferController* controller, fileTransfers) { + controller->onStateChanged.disconnect(boost::bind(&FileTransferOverview::handleFileTransferStateChanged, this)); + } } - + void FileTransferOverview::sendFile(const JID& jid, const std::string& filename) { - if (boost::filesystem::exists(filename) && boost::filesystem::file_size(filename) > 0) { - FileTransferController* controller = new FileTransferController(jid, filename, fileTransferManager); - onNewFileTransferController(controller); - } + if (boost::filesystem::exists(filename) && boost::filesystem::file_size(filename) > 0) { + FileTransferController* controller = new FileTransferController(jid, filename, fileTransferManager); + onNewFileTransferController(controller); + } } void FileTransferOverview::handleIncomingFileTransfer(IncomingFileTransfer::ref transfer) { - FileTransferController* controller = new FileTransferController(transfer); - onNewFileTransferController(controller); + FileTransferController* controller = new FileTransferController(transfer); + onNewFileTransferController(controller); } void FileTransferOverview::handleNewFileTransferController(FileTransferController* controller) { - fileTransfers.push_back(controller); - controller->onStateChanged.connect(boost::bind(&FileTransferOverview::handleFileTransferStateChanged, this)); + fileTransfers.push_back(controller); + controller->onStateChanged.connect(boost::bind(&FileTransferOverview::handleFileTransferStateChanged, this)); } void FileTransferOverview::handleFileTransferStateChanged() { - onFileTransferListChanged(); + onFileTransferListChanged(); } const std::vector<FileTransferController*>& FileTransferOverview::getFileTransfers() const { - return fileTransfers; + return fileTransfers; } void FileTransferOverview::clearFinished() { - for (std::vector<FileTransferController*>::iterator it = fileTransfers.begin(); it != fileTransfers.end(); ) { - if((*it)->getState().type == FileTransfer::State::Finished - || (*it)->getState().type == FileTransfer::State::Failed - || (*it)->getState().type == FileTransfer::State::Canceled) { - FileTransferController* controller = *it; - it = fileTransfers.erase(it); - controller->onStateChanged.disconnect(boost::bind(&FileTransferOverview::handleFileTransferStateChanged, this)); - delete controller; - } else { - ++it; - } - } - onFileTransferListChanged(); + for (std::vector<FileTransferController*>::iterator it = fileTransfers.begin(); it != fileTransfers.end(); ) { + if((*it)->getState().type == FileTransfer::State::Finished + || (*it)->getState().type == FileTransfer::State::Failed + || (*it)->getState().type == FileTransfer::State::Canceled) { + FileTransferController* controller = *it; + it = fileTransfers.erase(it); + controller->onStateChanged.disconnect(boost::bind(&FileTransferOverview::handleFileTransferStateChanged, this)); + delete controller; + } else { + ++it; + } + } + onFileTransferListChanged(); } bool FileTransferOverview::isClearable() const { - bool isClearable = false; - foreach (FileTransferController* controller, fileTransfers) { - if(controller->getState().type == FileTransfer::State::Finished - || controller->getState().type == FileTransfer::State::Failed - || controller->getState().type == FileTransfer::State::Canceled) { - isClearable = true; - break; - } - } - return isClearable; + bool isClearable = false; + foreach (FileTransferController* controller, fileTransfers) { + if(controller->getState().type == FileTransfer::State::Finished + || controller->getState().type == FileTransfer::State::Failed + || controller->getState().type == FileTransfer::State::Canceled) { + isClearable = true; + break; + } + } + return isClearable; } } diff --git a/Swift/Controllers/FileTransfer/FileTransferOverview.h b/Swift/Controllers/FileTransfer/FileTransferOverview.h index e3cbf81..a55727c 100644 --- a/Swift/Controllers/FileTransfer/FileTransferOverview.h +++ b/Swift/Controllers/FileTransfer/FileTransferOverview.h @@ -25,25 +25,25 @@ class FileTransferManager; class FileTransferOverview { public: - FileTransferOverview(FileTransferManager*); - ~FileTransferOverview(); - - void sendFile(const JID&, const std::string&); - const std::vector<FileTransferController*>& getFileTransfers() const; - void clearFinished(); - bool isClearable() const; + FileTransferOverview(FileTransferManager*); + ~FileTransferOverview(); - boost::signal<void (FileTransferController*)> onNewFileTransferController; - boost::signal<void ()> onFileTransferListChanged; + void sendFile(const JID&, const std::string&); + const std::vector<FileTransferController*>& getFileTransfers() const; + void clearFinished(); + bool isClearable() const; + + boost::signal<void (FileTransferController*)> onNewFileTransferController; + boost::signal<void ()> onFileTransferListChanged; private: - void handleIncomingFileTransfer(IncomingFileTransfer::ref transfer); - void handleNewFileTransferController(FileTransferController* controller); - void handleFileTransferStateChanged(); + void handleIncomingFileTransfer(IncomingFileTransfer::ref transfer); + void handleNewFileTransferController(FileTransferController* controller); + void handleFileTransferStateChanged(); private: - std::vector<FileTransferController*> fileTransfers; - FileTransferManager *fileTransferManager; + std::vector<FileTransferController*> fileTransfers; + FileTransferManager *fileTransferManager; }; } diff --git a/Swift/Controllers/FileTransfer/FileTransferProgressInfo.cpp b/Swift/Controllers/FileTransfer/FileTransferProgressInfo.cpp index a2fff03..b073017 100644 --- a/Swift/Controllers/FileTransfer/FileTransferProgressInfo.cpp +++ b/Swift/Controllers/FileTransfer/FileTransferProgressInfo.cpp @@ -19,21 +19,21 @@ namespace Swift { FileTransferProgressInfo::FileTransferProgressInfo(boost::uintmax_t completeBytes) : completeBytes(completeBytes), completedBytes(0), percentage(0) { - onProgressPercentage(0); + onProgressPercentage(0); } void FileTransferProgressInfo::setBytesProcessed(int processedBytes) { - int oldPercentage = int(double(completedBytes) / double(completeBytes) * 100.0); - completedBytes += boost::numeric_cast<boost::uintmax_t>(processedBytes); - int newPercentage = int(double(completedBytes) / double(completeBytes) * 100.0); - if (oldPercentage != newPercentage) { - onProgressPercentage(newPercentage); - } - percentage = newPercentage; + int oldPercentage = int(double(completedBytes) / double(completeBytes) * 100.0); + completedBytes += boost::numeric_cast<boost::uintmax_t>(processedBytes); + int newPercentage = int(double(completedBytes) / double(completeBytes) * 100.0); + if (oldPercentage != newPercentage) { + onProgressPercentage(newPercentage); + } + percentage = newPercentage; } int FileTransferProgressInfo::getPercentage() const { - return percentage; + return percentage; } } diff --git a/Swift/Controllers/FileTransfer/FileTransferProgressInfo.h b/Swift/Controllers/FileTransfer/FileTransferProgressInfo.h index ea88657..783874a 100644 --- a/Swift/Controllers/FileTransfer/FileTransferProgressInfo.h +++ b/Swift/Controllers/FileTransfer/FileTransferProgressInfo.h @@ -20,18 +20,18 @@ namespace Swift { class FileTransferProgressInfo { public: - FileTransferProgressInfo(boost::uintmax_t completeBytes); + FileTransferProgressInfo(boost::uintmax_t completeBytes); public: - void setBytesProcessed(int processedBytes); + void setBytesProcessed(int processedBytes); - int getPercentage() const; - boost::signal<void (int)> onProgressPercentage; + int getPercentage() const; + boost::signal<void (int)> onProgressPercentage; private: - boost::uintmax_t completeBytes; - boost::uintmax_t completedBytes; - int percentage; + boost::uintmax_t completeBytes; + boost::uintmax_t completedBytes; + int percentage; }; } diff --git a/Swift/Controllers/FileTransferListController.cpp b/Swift/Controllers/FileTransferListController.cpp index 6e84435..a383ae5 100644 --- a/Swift/Controllers/FileTransferListController.cpp +++ b/Swift/Controllers/FileTransferListController.cpp @@ -20,32 +20,32 @@ namespace Swift { FileTransferListController::FileTransferListController(UIEventStream* uiEventStream, FileTransferListWidgetFactory* fileTransferListWidgetFactory) : fileTransferListWidgetFactory(fileTransferListWidgetFactory), fileTransferListWidget(NULL), fileTransferOverview(0) { - uiEventStream->onUIEvent.connect(boost::bind(&FileTransferListController::handleUIEvent, this, _1)); + uiEventStream->onUIEvent.connect(boost::bind(&FileTransferListController::handleUIEvent, this, _1)); } FileTransferListController::~FileTransferListController() { - delete fileTransferListWidget; + delete fileTransferListWidget; } void FileTransferListController::setFileTransferOverview(FileTransferOverview *overview) { - fileTransferOverview = overview; - if (fileTransferListWidget) { - fileTransferListWidget->setFileTransferOverview(fileTransferOverview); - } + fileTransferOverview = overview; + if (fileTransferListWidget) { + fileTransferListWidget->setFileTransferOverview(fileTransferOverview); + } } void FileTransferListController::handleUIEvent(boost::shared_ptr<UIEvent> rawEvent) { - boost::shared_ptr<RequestFileTransferListUIEvent> event = boost::dynamic_pointer_cast<RequestFileTransferListUIEvent>(rawEvent); - if (event != NULL) { - if (fileTransferListWidget == NULL) { - fileTransferListWidget = fileTransferListWidgetFactory->createFileTransferListWidget(); - if (fileTransferOverview) { - fileTransferListWidget->setFileTransferOverview(fileTransferOverview); - } - } - fileTransferListWidget->show(); - fileTransferListWidget->activate(); - } + boost::shared_ptr<RequestFileTransferListUIEvent> event = boost::dynamic_pointer_cast<RequestFileTransferListUIEvent>(rawEvent); + if (event != NULL) { + if (fileTransferListWidget == NULL) { + fileTransferListWidget = fileTransferListWidgetFactory->createFileTransferListWidget(); + if (fileTransferOverview) { + fileTransferListWidget->setFileTransferOverview(fileTransferOverview); + } + } + fileTransferListWidget->show(); + fileTransferListWidget->activate(); + } } } diff --git a/Swift/Controllers/FileTransferListController.h b/Swift/Controllers/FileTransferListController.h index 079cd35..df79d1f 100644 --- a/Swift/Controllers/FileTransferListController.h +++ b/Swift/Controllers/FileTransferListController.h @@ -24,18 +24,18 @@ class FileTransferOverview; class FileTransferListController { public: - FileTransferListController(UIEventStream* uiEventStream, FileTransferListWidgetFactory* fileTransferListWidgetFactory); - ~FileTransferListController(); + FileTransferListController(UIEventStream* uiEventStream, FileTransferListWidgetFactory* fileTransferListWidgetFactory); + ~FileTransferListController(); - void setFileTransferOverview(FileTransferOverview* overview); + void setFileTransferOverview(FileTransferOverview* overview); private: - void handleUIEvent(boost::shared_ptr<UIEvent> event); + void handleUIEvent(boost::shared_ptr<UIEvent> event); private: - FileTransferListWidgetFactory* fileTransferListWidgetFactory; - FileTransferListWidget* fileTransferListWidget; - FileTransferOverview* fileTransferOverview; + FileTransferListWidgetFactory* fileTransferListWidgetFactory; + FileTransferListWidget* fileTransferListWidget; + FileTransferOverview* fileTransferOverview; }; } diff --git a/Swift/Controllers/HighlightAction.cpp b/Swift/Controllers/HighlightAction.cpp index 4603408..3ea2c86 100644 --- a/Swift/Controllers/HighlightAction.cpp +++ b/Swift/Controllers/HighlightAction.cpp @@ -16,47 +16,47 @@ namespace Swift { void HighlightAction::setHighlightWholeMessage(bool highlightText) { - highlightWholeMessage_ = highlightText; - if (!highlightWholeMessage_) { - textColor_.clear(); - textBackground_.clear(); - } + highlightWholeMessage_ = highlightText; + if (!highlightWholeMessage_) { + textColor_.clear(); + textBackground_.clear(); + } } void HighlightAction::setPlaySound(bool playSound) { - playSound_ = playSound; - if (!playSound_) { - soundFile_.clear(); - } + playSound_ = playSound; + if (!playSound_) { + soundFile_.clear(); + } } bool operator ==(HighlightAction const& a, HighlightAction const& b) { - if (a.highlightWholeMessage() != b.highlightWholeMessage()) { - return false; - } + if (a.highlightWholeMessage() != b.highlightWholeMessage()) { + return false; + } - if (a.getTextColor() != b.getTextColor()) { - return false; - } + if (a.getTextColor() != b.getTextColor()) { + return false; + } - if (a.getTextBackground() != b.getTextBackground()) { - return false; - } + if (a.getTextBackground() != b.getTextBackground()) { + return false; + } - if (a.playSound() != b.playSound()) { - return false; - } + if (a.playSound() != b.playSound()) { + return false; + } - if (a.getSoundFile() != b.getSoundFile()) { - return false; - } + if (a.getSoundFile() != b.getSoundFile()) { + return false; + } - return true; + return true; } bool operator !=(HighlightAction const& a, HighlightAction const& b) { - return !(a == b); + return !(a == b); } } diff --git a/Swift/Controllers/HighlightAction.h b/Swift/Controllers/HighlightAction.h index 3930eee..b9d4539 100644 --- a/Swift/Controllers/HighlightAction.h +++ b/Swift/Controllers/HighlightAction.h @@ -19,64 +19,64 @@ namespace Swift { - class HighlightRule; - - class HighlightAction { - public: - HighlightAction() : highlightWholeMessage_(false), playSound_(false) {} - - /** - * Gets the flag that indicates the entire message should be highlighted. - */ - bool highlightWholeMessage() const { return highlightWholeMessage_; } - void setHighlightWholeMessage(bool highlightText); - - /** - * Gets the foreground highlight color. - */ - const std::string& getTextColor() const { return textColor_; } - void setTextColor(const std::string& textColor) { textColor_ = textColor; } - - /** - * Gets the background highlight color. - */ - const std::string& getTextBackground() const { return textBackground_; } - void setTextBackground(const std::string& textBackground) { textBackground_ = textBackground; } - - bool playSound() const { return playSound_; } - void setPlaySound(bool playSound); - - /** - * Gets the sound filename. If the string is empty, assume a default sound file. - */ - const std::string& getSoundFile() const { return soundFile_; } - void setSoundFile(const std::string& soundFile) { soundFile_ = soundFile; } - - bool isEmpty() const { return !highlightWholeMessage_ && !playSound_; } - - private: - friend class boost::serialization::access; - template<class Archive> void serialize(Archive & ar, const unsigned int version); - - bool highlightWholeMessage_; - std::string textColor_; - std::string textBackground_; - - bool playSound_; - std::string soundFile_; - }; - - bool operator ==(HighlightAction const& a, HighlightAction const& b); - bool operator !=(HighlightAction const& a, HighlightAction const& b); - - template<class Archive> - void HighlightAction::serialize(Archive& ar, const unsigned int /*version*/) - { - ar & highlightWholeMessage_; - ar & textColor_; - ar & textBackground_; - ar & playSound_; - ar & soundFile_; - } + class HighlightRule; + + class HighlightAction { + public: + HighlightAction() : highlightWholeMessage_(false), playSound_(false) {} + + /** + * Gets the flag that indicates the entire message should be highlighted. + */ + bool highlightWholeMessage() const { return highlightWholeMessage_; } + void setHighlightWholeMessage(bool highlightText); + + /** + * Gets the foreground highlight color. + */ + const std::string& getTextColor() const { return textColor_; } + void setTextColor(const std::string& textColor) { textColor_ = textColor; } + + /** + * Gets the background highlight color. + */ + const std::string& getTextBackground() const { return textBackground_; } + void setTextBackground(const std::string& textBackground) { textBackground_ = textBackground; } + + bool playSound() const { return playSound_; } + void setPlaySound(bool playSound); + + /** + * Gets the sound filename. If the string is empty, assume a default sound file. + */ + const std::string& getSoundFile() const { return soundFile_; } + void setSoundFile(const std::string& soundFile) { soundFile_ = soundFile; } + + bool isEmpty() const { return !highlightWholeMessage_ && !playSound_; } + + private: + friend class boost::serialization::access; + template<class Archive> void serialize(Archive & ar, const unsigned int version); + + bool highlightWholeMessage_; + std::string textColor_; + std::string textBackground_; + + bool playSound_; + std::string soundFile_; + }; + + bool operator ==(HighlightAction const& a, HighlightAction const& b); + bool operator !=(HighlightAction const& a, HighlightAction const& b); + + template<class Archive> + void HighlightAction::serialize(Archive& ar, const unsigned int /*version*/) + { + ar & highlightWholeMessage_; + ar & textColor_; + ar & textBackground_; + ar & playSound_; + ar & soundFile_; + } } diff --git a/Swift/Controllers/HighlightEditorController.cpp b/Swift/Controllers/HighlightEditorController.cpp index ebda81c..bf5dbc4 100644 --- a/Swift/Controllers/HighlightEditorController.cpp +++ b/Swift/Controllers/HighlightEditorController.cpp @@ -25,33 +25,33 @@ namespace Swift { HighlightEditorController::HighlightEditorController(UIEventStream* uiEventStream, HighlightEditorWindowFactory* highlightEditorWindowFactory, HighlightManager* highlightManager) : highlightEditorWindowFactory_(highlightEditorWindowFactory), highlightEditorWindow_(NULL), highlightManager_(highlightManager), contactSuggester_(0) { - uiEventStream->onUIEvent.connect(boost::bind(&HighlightEditorController::handleUIEvent, this, _1)); + uiEventStream->onUIEvent.connect(boost::bind(&HighlightEditorController::handleUIEvent, this, _1)); } HighlightEditorController::~HighlightEditorController() { - delete highlightEditorWindow_; - highlightEditorWindow_ = NULL; + delete highlightEditorWindow_; + highlightEditorWindow_ = NULL; } void HighlightEditorController::handleUIEvent(boost::shared_ptr<UIEvent> rawEvent) { - boost::shared_ptr<RequestHighlightEditorUIEvent> event = boost::dynamic_pointer_cast<RequestHighlightEditorUIEvent>(rawEvent); - if (event) { - if (!highlightEditorWindow_) { - highlightEditorWindow_ = highlightEditorWindowFactory_->createHighlightEditorWindow(); - highlightEditorWindow_->setHighlightManager(highlightManager_); - highlightEditorWindow_->onContactSuggestionsRequested.connect(boost::bind(&HighlightEditorController::handleContactSuggestionsRequested, this, _1)); - } - highlightEditorWindow_->show(); - } + boost::shared_ptr<RequestHighlightEditorUIEvent> event = boost::dynamic_pointer_cast<RequestHighlightEditorUIEvent>(rawEvent); + if (event) { + if (!highlightEditorWindow_) { + highlightEditorWindow_ = highlightEditorWindowFactory_->createHighlightEditorWindow(); + highlightEditorWindow_->setHighlightManager(highlightManager_); + highlightEditorWindow_->onContactSuggestionsRequested.connect(boost::bind(&HighlightEditorController::handleContactSuggestionsRequested, this, _1)); + } + highlightEditorWindow_->show(); + } } void HighlightEditorController::handleContactSuggestionsRequested(const std::string& text) { - if (contactSuggester_) { - highlightEditorWindow_->setContactSuggestions(contactSuggester_->getSuggestions(text, true)); - } + if (contactSuggester_) { + highlightEditorWindow_->setContactSuggestions(contactSuggester_->getSuggestions(text, true)); + } } } diff --git a/Swift/Controllers/HighlightEditorController.h b/Swift/Controllers/HighlightEditorController.h index 52587c2..24ad9c2 100644 --- a/Swift/Controllers/HighlightEditorController.h +++ b/Swift/Controllers/HighlightEditorController.h @@ -18,31 +18,31 @@ namespace Swift { - class UIEventStream; + class UIEventStream; - class HighlightEditorWindowFactory; - class HighlightEditorWindow; + class HighlightEditorWindowFactory; + class HighlightEditorWindow; - class HighlightManager; - class ContactSuggester; + class HighlightManager; + class ContactSuggester; - class HighlightEditorController { - public: - HighlightEditorController(UIEventStream* uiEventStream, HighlightEditorWindowFactory* highlightEditorWindowFactory, HighlightManager* highlightManager); - ~HighlightEditorController(); + class HighlightEditorController { + public: + HighlightEditorController(UIEventStream* uiEventStream, HighlightEditorWindowFactory* highlightEditorWindowFactory, HighlightManager* highlightManager); + ~HighlightEditorController(); - HighlightManager* getHighlightManager() const { return highlightManager_; } - void setContactSuggester(ContactSuggester *suggester) { contactSuggester_ = suggester; } + HighlightManager* getHighlightManager() const { return highlightManager_; } + void setContactSuggester(ContactSuggester *suggester) { contactSuggester_ = suggester; } - private: - void handleUIEvent(boost::shared_ptr<UIEvent> event); - void handleContactSuggestionsRequested(const std::string& text); + private: + void handleUIEvent(boost::shared_ptr<UIEvent> event); + void handleContactSuggestionsRequested(const std::string& text); - private: - HighlightEditorWindowFactory* highlightEditorWindowFactory_; - HighlightEditorWindow* highlightEditorWindow_; - HighlightManager* highlightManager_; - ContactSuggester* contactSuggester_; - }; + private: + HighlightEditorWindowFactory* highlightEditorWindowFactory_; + HighlightEditorWindow* highlightEditorWindow_; + HighlightManager* highlightManager_; + ContactSuggester* contactSuggester_; + }; } diff --git a/Swift/Controllers/HighlightManager.cpp b/Swift/Controllers/HighlightManager.cpp index 07f8e54..45b800a 100644 --- a/Swift/Controllers/HighlightManager.cpp +++ b/Swift/Controllers/HighlightManager.cpp @@ -48,102 +48,102 @@ namespace Swift { HighlightManager::HighlightManager(SettingsProvider* settings) - : settings_(settings) - , storingSettings_(false) { - rules_ = boost::make_shared<HighlightRulesList>(); - loadSettings(); - handleSettingChangedConnection_ = settings_->onSettingChanged.connect(boost::bind(&HighlightManager::handleSettingChanged, this, _1)); + : settings_(settings) + , storingSettings_(false) { + rules_ = boost::make_shared<HighlightRulesList>(); + loadSettings(); + handleSettingChangedConnection_ = settings_->onSettingChanged.connect(boost::bind(&HighlightManager::handleSettingChanged, this, _1)); } void HighlightManager::handleSettingChanged(const std::string& settingPath) { - if (!storingSettings_ && SettingConstants::HIGHLIGHT_RULES.getKey() == settingPath) { - loadSettings(); - } + if (!storingSettings_ && SettingConstants::HIGHLIGHT_RULES.getKey() == settingPath) { + loadSettings(); + } } std::string HighlightManager::rulesToString() const { - std::stringstream stream; - boost::archive::text_oarchive archive(stream); - archive << rules_->list_; - return stream.str(); + std::stringstream stream; + boost::archive::text_oarchive archive(stream); + archive << rules_->list_; + return stream.str(); } std::vector<HighlightRule> HighlightManager::getDefaultRules() { - std::vector<HighlightRule> rules; - - HighlightRule chatNotificationRule; - chatNotificationRule.setMatchChat(true); - chatNotificationRule.getAction().setPlaySound(true); - chatNotificationRule.setMatchWholeWords(true); - rules.push_back(chatNotificationRule); - - HighlightRule selfMentionMUCRule; - selfMentionMUCRule.setMatchMUC(true); - selfMentionMUCRule.getAction().setPlaySound(true); - selfMentionMUCRule.setNickIsKeyword(true); - selfMentionMUCRule.setMatchCase(true); - selfMentionMUCRule.setMatchWholeWords(true); - rules.push_back(selfMentionMUCRule); - - return rules; + std::vector<HighlightRule> rules; + + HighlightRule chatNotificationRule; + chatNotificationRule.setMatchChat(true); + chatNotificationRule.getAction().setPlaySound(true); + chatNotificationRule.setMatchWholeWords(true); + rules.push_back(chatNotificationRule); + + HighlightRule selfMentionMUCRule; + selfMentionMUCRule.setMatchMUC(true); + selfMentionMUCRule.getAction().setPlaySound(true); + selfMentionMUCRule.setNickIsKeyword(true); + selfMentionMUCRule.setMatchCase(true); + selfMentionMUCRule.setMatchWholeWords(true); + rules.push_back(selfMentionMUCRule); + + return rules; } HighlightRule HighlightManager::getRule(int index) const { - assert(index >= 0 && static_cast<size_t>(index) < rules_->getSize()); - return rules_->getRule(static_cast<size_t>(index)); + assert(index >= 0 && static_cast<size_t>(index) < rules_->getSize()); + return rules_->getRule(static_cast<size_t>(index)); } void HighlightManager::setRule(int index, const HighlightRule& rule) { - assert(index >= 0 && static_cast<size_t>(index) < rules_->getSize()); - rules_->list_[static_cast<size_t>(index)] = rule; + assert(index >= 0 && static_cast<size_t>(index) < rules_->getSize()); + rules_->list_[static_cast<size_t>(index)] = rule; } void HighlightManager::insertRule(int index, const HighlightRule& rule) { - assert(index >= 0 && boost::numeric_cast<std::vector<std::string>::size_type>(index) <= rules_->getSize()); - rules_->list_.insert(rules_->list_.begin() + index, rule); + assert(index >= 0 && boost::numeric_cast<std::vector<std::string>::size_type>(index) <= rules_->getSize()); + rules_->list_.insert(rules_->list_.begin() + index, rule); } void HighlightManager::removeRule(int index) { - assert(index >= 0 && boost::numeric_cast<std::vector<std::string>::size_type>(index) < rules_->getSize()); - rules_->list_.erase(rules_->list_.begin() + index); + assert(index >= 0 && boost::numeric_cast<std::vector<std::string>::size_type>(index) < rules_->getSize()); + rules_->list_.erase(rules_->list_.begin() + index); } void HighlightManager::swapRules(const size_t first, const size_t second) { - assert(first < rules_->getSize()); - assert(second < rules_->getSize()); - const HighlightRule swap = rules_->getRule(first); - rules_->setRule(first, rules_->getRule(second)); - rules_->setRule(second, swap); + assert(first < rules_->getSize()); + assert(second < rules_->getSize()); + const HighlightRule swap = rules_->getRule(first); + rules_->setRule(first, rules_->getRule(second)); + rules_->setRule(second, swap); } void HighlightManager::storeSettings() { - storingSettings_ = true; // don't reload settings while saving - settings_->storeSetting(SettingConstants::HIGHLIGHT_RULES, rulesToString()); - storingSettings_ = false; + storingSettings_ = true; // don't reload settings while saving + settings_->storeSetting(SettingConstants::HIGHLIGHT_RULES, rulesToString()); + storingSettings_ = false; } void HighlightManager::loadSettings() { - std::string rulesString = settings_->getSetting(SettingConstants::HIGHLIGHT_RULES); - std::stringstream stream; - stream << rulesString; - try { - boost::archive::text_iarchive archive(stream); - archive >> rules_->list_; - } catch (boost::archive::archive_exception&) { - rules_->list_ = getDefaultRules(); - } + std::string rulesString = settings_->getSetting(SettingConstants::HIGHLIGHT_RULES); + std::stringstream stream; + stream << rulesString; + try { + boost::archive::text_iarchive archive(stream); + archive >> rules_->list_; + } catch (boost::archive::archive_exception&) { + rules_->list_ = getDefaultRules(); + } } Highlighter* HighlightManager::createHighlighter() { - return new Highlighter(this); + return new Highlighter(this); } bool HighlightManager::isDefaultRulesList() const { - return getDefaultRules() == rules_->list_; + return getDefaultRules() == rules_->list_; } void HighlightManager::resetToDefaultRulesList() { - rules_->list_ = getDefaultRules(); + rules_->list_ = getDefaultRules(); } } diff --git a/Swift/Controllers/HighlightManager.h b/Swift/Controllers/HighlightManager.h index 180f7a3..1d2eb8a 100644 --- a/Swift/Controllers/HighlightManager.h +++ b/Swift/Controllers/HighlightManager.h @@ -21,61 +21,61 @@ namespace Swift { - class SettingsProvider; - class Highlighter; - - class HighlightManager { - public: - - class HighlightRulesList { - public: - friend class HighlightManager; - size_t getSize() const { return list_.size(); } - const HighlightRule& getRule(const size_t index) const { return list_[index]; } - void addRule(const HighlightRule& rule) { list_.push_back(rule); } - void combineRules(const HighlightRulesList& rhs) { - list_.insert(list_.end(), rhs.list_.begin(), rhs.list_.end()); - } - void setRule(const size_t index, const HighlightRule& rule) { - list_[index] = rule; - } - private: - std::vector<HighlightRule> list_; - }; - - HighlightManager(SettingsProvider* settings); - - Highlighter* createHighlighter(); - - boost::shared_ptr<const HighlightManager::HighlightRulesList> getRules() const { return rules_; } - - bool isDefaultRulesList() const; - void resetToDefaultRulesList(); - - HighlightRule getRule(int index) const; - void setRule(int index, const HighlightRule& rule); - void insertRule(int index, const HighlightRule& rule); - void removeRule(int index); - void swapRules(const size_t first, const size_t second); - void storeSettings(); - void loadSettings(); - - boost::signal<void (const HighlightAction&)> onHighlight; - - private: - void handleSettingChanged(const std::string& settingPath); - - std::string rulesToString() const; - static std::vector<HighlightRule> getDefaultRules(); - - private: - SettingsProvider* settings_; - bool storingSettings_; - - boost::shared_ptr<HighlightManager::HighlightRulesList> rules_; - boost::bsignals::scoped_connection handleSettingChangedConnection_; - }; - - typedef boost::shared_ptr<const HighlightManager::HighlightRulesList> HighlightRulesListPtr; + class SettingsProvider; + class Highlighter; + + class HighlightManager { + public: + + class HighlightRulesList { + public: + friend class HighlightManager; + size_t getSize() const { return list_.size(); } + const HighlightRule& getRule(const size_t index) const { return list_[index]; } + void addRule(const HighlightRule& rule) { list_.push_back(rule); } + void combineRules(const HighlightRulesList& rhs) { + list_.insert(list_.end(), rhs.list_.begin(), rhs.list_.end()); + } + void setRule(const size_t index, const HighlightRule& rule) { + list_[index] = rule; + } + private: + std::vector<HighlightRule> list_; + }; + + HighlightManager(SettingsProvider* settings); + + Highlighter* createHighlighter(); + + boost::shared_ptr<const HighlightManager::HighlightRulesList> getRules() const { return rules_; } + + bool isDefaultRulesList() const; + void resetToDefaultRulesList(); + + HighlightRule getRule(int index) const; + void setRule(int index, const HighlightRule& rule); + void insertRule(int index, const HighlightRule& rule); + void removeRule(int index); + void swapRules(const size_t first, const size_t second); + void storeSettings(); + void loadSettings(); + + boost::signal<void (const HighlightAction&)> onHighlight; + + private: + void handleSettingChanged(const std::string& settingPath); + + std::string rulesToString() const; + static std::vector<HighlightRule> getDefaultRules(); + + private: + SettingsProvider* settings_; + bool storingSettings_; + + boost::shared_ptr<HighlightManager::HighlightRulesList> rules_; + boost::bsignals::scoped_connection handleSettingChangedConnection_; + }; + + typedef boost::shared_ptr<const HighlightManager::HighlightRulesList> HighlightRulesListPtr; } diff --git a/Swift/Controllers/HighlightRule.cpp b/Swift/Controllers/HighlightRule.cpp index 021e15d..86ac5f7 100644 --- a/Swift/Controllers/HighlightRule.cpp +++ b/Swift/Controllers/HighlightRule.cpp @@ -23,179 +23,179 @@ namespace Swift { HighlightRule::HighlightRule() - : nickIsKeyword_(false) - , matchCase_(false) - , matchWholeWords_(false) - , matchChat_(false) - , matchMUC_(false) + : nickIsKeyword_(false) + , matchCase_(false) + , matchWholeWords_(false) + , matchChat_(false) + , matchMUC_(false) { } boost::regex HighlightRule::regexFromString(const std::string & s) const { - std::string escaped = Regex::escape(s); - 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); + std::string escaped = Regex::escape(s); + 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)); - } + 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"; + return b ? "1" : "0"; } bool HighlightRule::boolFromString(const std::string& s) { - return s == "1"; + return s == "1"; } 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(); - - if (!matchesKeyword) { - // check if the nickname matches - if (nickIsKeyword_ && !nick.empty() && boost::regex_search(body, regexFromString(nick))) { - matchesKeyword = true; - } - - // check if a keyword matches - if (!matchesKeyword && !keywords_.empty()) { - foreach (const boost::regex &keyword, keywordRegex_) { - if (boost::regex_search(body, keyword)) { - matchesKeyword = true; - break; - } - } - } - } - - foreach (const boost::regex & rx, senderRegex_) { - if (boost::regex_search(sender, rx)) { - matchesSender = true; - break; - } - } - - if (matchesKeyword && matchesSender) { - return true; - } - } - - return false; + if ((messageType == HighlightRule::ChatMessage && matchChat_) || (messageType == HighlightRule::MUCMessage && matchMUC_)) { + + bool matchesKeyword = keywords_.empty() && (nick.empty() || !nickIsKeyword_); + bool matchesSender = senders_.empty(); + + if (!matchesKeyword) { + // check if the nickname matches + if (nickIsKeyword_ && !nick.empty() && boost::regex_search(body, regexFromString(nick))) { + matchesKeyword = true; + } + + // check if a keyword matches + if (!matchesKeyword && !keywords_.empty()) { + foreach (const boost::regex &keyword, keywordRegex_) { + if (boost::regex_search(body, keyword)) { + matchesKeyword = true; + break; + } + } + } + } + + 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(); + senders_ = senders; + updateRegex(); } void HighlightRule::setKeywords(const std::vector<std::string>& keywords) { - keywords_ = keywords; - updateRegex(); + keywords_ = keywords; + updateRegex(); } std::vector<boost::regex> HighlightRule::getKeywordRegex(const std::string& nick) const { - if (nickIsKeyword_) { - std::vector<boost::regex> regex; - if (!nick.empty()) { - regex.push_back(regexFromString(nick)); - } - return regex; - } else { - return keywordRegex_; - } + if (nickIsKeyword_) { + std::vector<boost::regex> regex; + if (!nick.empty()) { + regex.push_back(regexFromString(nick)); + } + return regex; + } else { + return keywordRegex_; + } } void HighlightRule::setNickIsKeyword(bool nickIsKeyword) { - nickIsKeyword_ = nickIsKeyword; - updateRegex(); + nickIsKeyword_ = nickIsKeyword; + updateRegex(); } void HighlightRule::setMatchCase(bool matchCase) { - matchCase_ = matchCase; - updateRegex(); + matchCase_ = matchCase; + updateRegex(); } void HighlightRule::setMatchWholeWords(bool matchWholeWords) { - matchWholeWords_ = matchWholeWords; - updateRegex(); + matchWholeWords_ = matchWholeWords; + updateRegex(); } void HighlightRule::setMatchChat(bool matchChat) { - matchChat_ = matchChat; - updateRegex(); + matchChat_ = matchChat; + updateRegex(); } void HighlightRule::setMatchMUC(bool matchMUC) { - matchMUC_ = matchMUC; - updateRegex(); + matchMUC_ = matchMUC; + updateRegex(); } bool HighlightRule::isEmpty() const { - return senders_.empty() && keywords_.empty() && !nickIsKeyword_ && !matchChat_ && !matchMUC_ && action_.isEmpty(); + return senders_.empty() && keywords_.empty() && !nickIsKeyword_ && !matchChat_ && !matchMUC_ && action_.isEmpty(); } bool operator ==(HighlightRule const& a, HighlightRule const& b) { - if (a.getSenders() != b.getSenders()) { - return false; - } + if (a.getSenders() != b.getSenders()) { + return false; + } - if (a.getKeywords() != b.getKeywords()) { - return false; - } + if (a.getKeywords() != b.getKeywords()) { + return false; + } - if (a.getNickIsKeyword() != b.getNickIsKeyword()) { - return false; - } + if (a.getNickIsKeyword() != b.getNickIsKeyword()) { + return false; + } - if (a.getMatchChat() != b.getMatchChat()) { - return false; - } + if (a.getMatchChat() != b.getMatchChat()) { + return false; + } - if (a.getMatchMUC() != b.getMatchMUC()) { - return false; - } + if (a.getMatchMUC() != b.getMatchMUC()) { + return false; + } - if (a.getMatchCase() != b.getMatchCase()) { - return false; - } + if (a.getMatchCase() != b.getMatchCase()) { + return false; + } - if (a.getMatchWholeWords() != b.getMatchWholeWords()) { - return false; - } + if (a.getMatchWholeWords() != b.getMatchWholeWords()) { + return false; + } - if (a.getAction() != b.getAction()) { - return false; - } + if (a.getAction() != b.getAction()) { + return false; + } - return true; + return true; } } diff --git a/Swift/Controllers/HighlightRule.h b/Swift/Controllers/HighlightRule.h index caacaee..bffdc41 100644 --- a/Swift/Controllers/HighlightRule.h +++ b/Swift/Controllers/HighlightRule.h @@ -23,81 +23,81 @@ namespace Swift { - class HighlightRule { - public: - HighlightRule(); + class HighlightRule { + public: + HighlightRule(); - enum MessageType { ChatMessage, MUCMessage }; + enum MessageType { ChatMessage, MUCMessage }; - bool isMatch(const std::string& body, const std::string& sender, const std::string& nick, MessageType) const; + 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_; } + const HighlightAction& getAction() const { return action_; } + HighlightAction& getAction() { return action_; } - const std::vector<std::string>& getSenders() const { return senders_; } - void setSenders(const std::vector<std::string>&); - const std::vector<boost::regex>& getSenderRegex() const { return senderRegex_; } + const std::vector<std::string>& getSenders() const { return senders_; } + void setSenders(const std::vector<std::string>&); + const std::vector<boost::regex>& getSenderRegex() const { return senderRegex_; } - const std::vector<std::string>& getKeywords() const { return keywords_; } - void setKeywords(const std::vector<std::string>&); - std::vector<boost::regex> getKeywordRegex(const std::string& nick) const; + const std::vector<std::string>& getKeywords() const { return keywords_; } + void setKeywords(const std::vector<std::string>&); + std::vector<boost::regex> getKeywordRegex(const std::string& nick) const; - bool getNickIsKeyword() const { return nickIsKeyword_; } - void setNickIsKeyword(bool); + bool getNickIsKeyword() const { return nickIsKeyword_; } + void setNickIsKeyword(bool); - bool getMatchCase() const { return matchCase_; } - void setMatchCase(bool); + bool getMatchCase() const { return matchCase_; } + void setMatchCase(bool); - bool getMatchWholeWords() const { return matchWholeWords_; } - void setMatchWholeWords(bool); + bool getMatchWholeWords() const { return matchWholeWords_; } + void setMatchWholeWords(bool); - bool getMatchChat() const { return matchChat_; } - void setMatchChat(bool); + bool getMatchChat() const { return matchChat_; } + void setMatchChat(bool); - bool getMatchMUC() const { return matchMUC_; } - void setMatchMUC(bool); + bool getMatchMUC() const { return matchMUC_; } + void setMatchMUC(bool); - bool isEmpty() const; + bool isEmpty() const; - private: - friend class boost::serialization::access; - template<class Archive> void serialize(Archive & ar, const unsigned int version); + private: + friend class boost::serialization::access; + template<class Archive> void serialize(Archive & ar, const unsigned int version); - static std::string boolToString(bool); - static bool boolFromString(const std::string&); + static std::string boolToString(bool); + static bool boolFromString(const std::string&); - std::vector<std::string> senders_; - std::vector<std::string> keywords_; - bool nickIsKeyword_; + 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; + 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 matchCase_; + bool matchWholeWords_; - bool matchChat_; - bool matchMUC_; + bool matchChat_; + bool matchMUC_; - HighlightAction action_; - }; + HighlightAction action_; + }; - bool operator ==(HighlightRule const& a, HighlightRule const& b); + bool operator ==(HighlightRule const& a, HighlightRule const& b); - template<class Archive> - void HighlightRule::serialize(Archive& ar, const unsigned int /*version*/) - { - ar & senders_; - ar & keywords_; - ar & nickIsKeyword_; - ar & matchChat_; - ar & matchMUC_; - ar & matchCase_; - ar & matchWholeWords_; - ar & action_; - updateRegex(); - } + template<class Archive> + void HighlightRule::serialize(Archive& ar, const unsigned int /*version*/) + { + ar & senders_; + ar & keywords_; + ar & nickIsKeyword_; + ar & matchChat_; + ar & matchMUC_; + ar & matchCase_; + ar & matchWholeWords_; + ar & action_; + updateRegex(); + } } diff --git a/Swift/Controllers/Highlighter.cpp b/Swift/Controllers/Highlighter.cpp index 40f92ba..3499217 100644 --- a/Swift/Controllers/Highlighter.cpp +++ b/Swift/Controllers/Highlighter.cpp @@ -19,35 +19,35 @@ namespace Swift { Highlighter::Highlighter(HighlightManager* manager) - : manager_(manager) + : manager_(manager) { - setMode(ChatMode); + setMode(ChatMode); } void Highlighter::setMode(Mode mode) { - mode_ = mode; - messageType_ = mode_ == ChatMode ? HighlightRule::ChatMessage : HighlightRule::MUCMessage; + mode_ = mode; + messageType_ = mode_ == ChatMode ? HighlightRule::ChatMessage : HighlightRule::MUCMessage; } HighlightAction Highlighter::findFirstFullMessageMatchAction(const std::string& body, const std::string& sender) const { - HighlightAction match; - HighlightRulesListPtr rules = manager_->getRules(); - for (size_t i = 0; i < rules->getSize(); ++i) { - const HighlightRule& rule = rules->getRule(i); - if (rule.isMatch(body, sender, nick_, messageType_) && rule.getAction().highlightWholeMessage()) { - match = rule.getAction(); - break; - } - } - - return match; + HighlightAction match; + HighlightRulesListPtr rules = manager_->getRules(); + for (size_t i = 0; i < rules->getSize(); ++i) { + const HighlightRule& rule = rules->getRule(i); + if (rule.isMatch(body, sender, nick_, messageType_) && rule.getAction().highlightWholeMessage()) { + match = rule.getAction(); + break; + } + } + + return match; } void Highlighter::handleHighlightAction(const HighlightAction& action) { - manager_->onHighlight(action); + manager_->onHighlight(action); } } diff --git a/Swift/Controllers/Highlighter.h b/Swift/Controllers/Highlighter.h index 5d5f531..9ad3339 100644 --- a/Swift/Controllers/Highlighter.h +++ b/Swift/Controllers/Highlighter.h @@ -19,27 +19,27 @@ namespace Swift { - class HighlightManager; + class HighlightManager; - class Highlighter { - public: - Highlighter(HighlightManager* manager); + class Highlighter { + public: + Highlighter(HighlightManager* manager); - enum Mode { ChatMode, MUCMode }; - void setMode(Mode mode); + enum Mode { ChatMode, MUCMode }; + void setMode(Mode mode); - void setNick(const std::string& nick) { nick_ = nick; } - std::string getNick() const { return nick_; } + void setNick(const std::string& nick) { nick_ = nick; } + std::string getNick() const { return nick_; } - HighlightAction findFirstFullMessageMatchAction(const std::string& body, const std::string& sender) const; + HighlightAction findFirstFullMessageMatchAction(const std::string& body, const std::string& sender) const; - void handleHighlightAction(const HighlightAction& action); + void handleHighlightAction(const HighlightAction& action); - private: - HighlightManager* manager_; - Mode mode_; - HighlightRule::MessageType messageType_; - std::string nick_; - }; + private: + HighlightManager* manager_; + Mode mode_; + HighlightRule::MessageType messageType_; + std::string nick_; + }; } diff --git a/Swift/Controllers/HistoryController.cpp b/Swift/Controllers/HistoryController.cpp index f439429..1e5830c 100644 --- a/Swift/Controllers/HistoryController.cpp +++ b/Swift/Controllers/HistoryController.cpp @@ -28,39 +28,39 @@ HistoryController::~HistoryController() { } void HistoryController::addMessage(const std::string& message, const JID& fromJID, const JID& toJID, HistoryMessage::Type type, const boost::posix_time::ptime& timeStamp) { - // note: using localtime timestamps - boost::posix_time::ptime localTime = boost::date_time::c_local_adjustor<boost::posix_time::ptime>::utc_to_local(timeStamp); - int offset = (localTime - timeStamp).hours(); + // note: using localtime timestamps + boost::posix_time::ptime localTime = boost::date_time::c_local_adjustor<boost::posix_time::ptime>::utc_to_local(timeStamp); + int offset = (localTime - timeStamp).hours(); - HistoryMessage historyMessage(message, fromJID, toJID, type, localTime, offset); + HistoryMessage historyMessage(message, fromJID, toJID, type, localTime, offset); - localHistory_->addMessage(historyMessage); - onNewMessage(historyMessage); + localHistory_->addMessage(historyMessage); + onNewMessage(historyMessage); } std::vector<HistoryMessage> HistoryController::getMessagesFromDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const { - return localHistory_->getMessagesFromDate(selfJID, contactJID, type, date); + return localHistory_->getMessagesFromDate(selfJID, contactJID, type, date); } std::vector<HistoryMessage> HistoryController::getMUCContext(const JID& selfJID, const JID& mucJID, const boost::posix_time::ptime& timeStamp) const { - boost::posix_time::ptime localTime = boost::date_time::c_local_adjustor<boost::posix_time::ptime>::utc_to_local(timeStamp); - return getMessagesFromDate(selfJID, mucJID, HistoryMessage::Groupchat, localTime.date()); + boost::posix_time::ptime localTime = boost::date_time::c_local_adjustor<boost::posix_time::ptime>::utc_to_local(timeStamp); + return getMessagesFromDate(selfJID, mucJID, HistoryMessage::Groupchat, localTime.date()); } std::vector<HistoryMessage> HistoryController::getMessagesFromPreviousDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const { - return localHistory_->getMessagesFromPreviousDate(selfJID, contactJID, type, date); + return localHistory_->getMessagesFromPreviousDate(selfJID, contactJID, type, date); } std::vector<HistoryMessage> HistoryController::getMessagesFromNextDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const { - return localHistory_->getMessagesFromNextDate(selfJID, contactJID, type, date); + return localHistory_->getMessagesFromNextDate(selfJID, contactJID, type, date); } ContactsMap HistoryController::getContacts(const JID& selfJID, HistoryMessage::Type type, const std::string& keyword) const { - return localHistory_->getContacts(selfJID, type, keyword); + return localHistory_->getContacts(selfJID, type, keyword); } boost::posix_time::ptime HistoryController::getLastTimeStampFromMUC(const JID& selfJID, const JID& mucJID) { - return localHistory_->getLastTimeStampFromMUC(selfJID, mucJID); + return localHistory_->getLastTimeStampFromMUC(selfJID, mucJID); } } diff --git a/Swift/Controllers/HistoryController.h b/Swift/Controllers/HistoryController.h index 0bdbb35..f1f613f 100644 --- a/Swift/Controllers/HistoryController.h +++ b/Swift/Controllers/HistoryController.h @@ -21,25 +21,25 @@ #include <Swiften/History/HistoryStorage.h> namespace Swift { - class JID; + class JID; - class HistoryController { - public: - HistoryController(HistoryStorage* localHistoryStorage); - ~HistoryController(); + class HistoryController { + public: + HistoryController(HistoryStorage* localHistoryStorage); + ~HistoryController(); - void addMessage(const std::string& message, const JID& fromJID, const JID& toJID, HistoryMessage::Type type, const boost::posix_time::ptime& timeStamp); - std::vector<HistoryMessage> getMessagesFromDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const; - std::vector<HistoryMessage> getMessagesFromPreviousDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const; - std::vector<HistoryMessage> getMessagesFromNextDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const; - ContactsMap getContacts(const JID& selfJID, HistoryMessage::Type type, const std::string& keyword = std::string()) const; - std::vector<HistoryMessage> getMUCContext(const JID& selfJID, const JID& mucJID, const boost::posix_time::ptime& timeStamp) const; + void addMessage(const std::string& message, const JID& fromJID, const JID& toJID, HistoryMessage::Type type, const boost::posix_time::ptime& timeStamp); + std::vector<HistoryMessage> getMessagesFromDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const; + std::vector<HistoryMessage> getMessagesFromPreviousDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const; + std::vector<HistoryMessage> getMessagesFromNextDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const; + ContactsMap getContacts(const JID& selfJID, HistoryMessage::Type type, const std::string& keyword = std::string()) const; + std::vector<HistoryMessage> getMUCContext(const JID& selfJID, const JID& mucJID, const boost::posix_time::ptime& timeStamp) const; - boost::posix_time::ptime getLastTimeStampFromMUC(const JID& selfJID, const JID& mucJID); + boost::posix_time::ptime getLastTimeStampFromMUC(const JID& selfJID, const JID& mucJID); - boost::signal<void (const HistoryMessage&)> onNewMessage; + boost::signal<void (const HistoryMessage&)> onNewMessage; - private: - HistoryStorage* localHistory_; - }; + private: + HistoryStorage* localHistory_; + }; } diff --git a/Swift/Controllers/HistoryViewController.cpp b/Swift/Controllers/HistoryViewController.cpp index 2d56b9e..d0ccc66 100644 --- a/Swift/Controllers/HistoryViewController.cpp +++ b/Swift/Controllers/HistoryViewController.cpp @@ -25,335 +25,335 @@ #include <Swift/Controllers/UIInterfaces/HistoryWindowFactory.h> namespace Swift { - static const std::string category[] = { "Contacts", "MUC", "Contacts" }; + static const std::string category[] = { "Contacts", "MUC", "Contacts" }; HistoryViewController::HistoryViewController( - const JID& selfJID, - UIEventStream* uiEventStream, - HistoryController* historyController, - NickResolver* nickResolver, - AvatarManager* avatarManager, - PresenceOracle* presenceOracle, - HistoryWindowFactory* historyWindowFactory) : - selfJID_(selfJID), - uiEventStream_(uiEventStream), - historyController_(historyController), - nickResolver_(nickResolver), - avatarManager_(avatarManager), - presenceOracle_(presenceOracle), - historyWindowFactory_(historyWindowFactory), - historyWindow_(NULL), - selectedItem_(NULL), - currentResultDate_(boost::gregorian::not_a_date_time) { - uiEventStream_->onUIEvent.connect(boost::bind(&HistoryViewController::handleUIEvent, this, _1)); - - roster_ = new Roster(false, true); + const JID& selfJID, + UIEventStream* uiEventStream, + HistoryController* historyController, + NickResolver* nickResolver, + AvatarManager* avatarManager, + PresenceOracle* presenceOracle, + HistoryWindowFactory* historyWindowFactory) : + selfJID_(selfJID), + uiEventStream_(uiEventStream), + historyController_(historyController), + nickResolver_(nickResolver), + avatarManager_(avatarManager), + presenceOracle_(presenceOracle), + historyWindowFactory_(historyWindowFactory), + historyWindow_(NULL), + selectedItem_(NULL), + currentResultDate_(boost::gregorian::not_a_date_time) { + uiEventStream_->onUIEvent.connect(boost::bind(&HistoryViewController::handleUIEvent, this, _1)); + + roster_ = new Roster(false, true); } HistoryViewController::~HistoryViewController() { - uiEventStream_->onUIEvent.disconnect(boost::bind(&HistoryViewController::handleUIEvent, this, _1)); - if (historyWindow_) { - historyWindow_->onSelectedContactChanged.disconnect(boost::bind(&HistoryViewController::handleSelectedContactChanged, this, _1)); - historyWindow_->onReturnPressed.disconnect(boost::bind(&HistoryViewController::handleReturnPressed, this, _1)); - historyWindow_->onScrollReachedTop.disconnect(boost::bind(&HistoryViewController::handleScrollReachedTop, this, _1)); - historyWindow_->onScrollReachedBottom.disconnect(boost::bind(&HistoryViewController::handleScrollReachedBottom, this, _1)); - historyWindow_->onPreviousButtonClicked.disconnect(boost::bind(&HistoryViewController::handlePreviousButtonClicked, this)); - historyWindow_->onNextButtonClicked.disconnect(boost::bind(&HistoryViewController::handleNextButtonClicked, this)); - historyWindow_->onCalendarClicked.disconnect(boost::bind(&HistoryViewController::handleCalendarClicked, this, _1)); - historyController_->onNewMessage.disconnect(boost::bind(&HistoryViewController::handleNewMessage, this, _1)); - - presenceOracle_->onPresenceChange.disconnect(boost::bind(&HistoryViewController::handlePresenceChanged, this, _1)); - avatarManager_->onAvatarChanged.disconnect(boost::bind(&HistoryViewController::handleAvatarChanged, this, _1)); - - delete historyWindow_; - } - delete roster_; + uiEventStream_->onUIEvent.disconnect(boost::bind(&HistoryViewController::handleUIEvent, this, _1)); + if (historyWindow_) { + historyWindow_->onSelectedContactChanged.disconnect(boost::bind(&HistoryViewController::handleSelectedContactChanged, this, _1)); + historyWindow_->onReturnPressed.disconnect(boost::bind(&HistoryViewController::handleReturnPressed, this, _1)); + historyWindow_->onScrollReachedTop.disconnect(boost::bind(&HistoryViewController::handleScrollReachedTop, this, _1)); + historyWindow_->onScrollReachedBottom.disconnect(boost::bind(&HistoryViewController::handleScrollReachedBottom, this, _1)); + historyWindow_->onPreviousButtonClicked.disconnect(boost::bind(&HistoryViewController::handlePreviousButtonClicked, this)); + historyWindow_->onNextButtonClicked.disconnect(boost::bind(&HistoryViewController::handleNextButtonClicked, this)); + historyWindow_->onCalendarClicked.disconnect(boost::bind(&HistoryViewController::handleCalendarClicked, this, _1)); + historyController_->onNewMessage.disconnect(boost::bind(&HistoryViewController::handleNewMessage, this, _1)); + + presenceOracle_->onPresenceChange.disconnect(boost::bind(&HistoryViewController::handlePresenceChanged, this, _1)); + avatarManager_->onAvatarChanged.disconnect(boost::bind(&HistoryViewController::handleAvatarChanged, this, _1)); + + delete historyWindow_; + } + delete roster_; } void HistoryViewController::handleUIEvent(boost::shared_ptr<UIEvent> rawEvent) { - boost::shared_ptr<RequestHistoryUIEvent> event = boost::dynamic_pointer_cast<RequestHistoryUIEvent>(rawEvent); - if (event != NULL) { - if (historyWindow_ == NULL) { - historyWindow_ = historyWindowFactory_->createHistoryWindow(uiEventStream_); - historyWindow_->onSelectedContactChanged.connect(boost::bind(&HistoryViewController::handleSelectedContactChanged, this, _1)); - historyWindow_->onReturnPressed.connect(boost::bind(&HistoryViewController::handleReturnPressed, this, _1)); - historyWindow_->onScrollReachedTop.connect(boost::bind(&HistoryViewController::handleScrollReachedTop, this, _1)); - historyWindow_->onScrollReachedBottom.connect(boost::bind(&HistoryViewController::handleScrollReachedBottom, this, _1)); - historyWindow_->onPreviousButtonClicked.connect(boost::bind(&HistoryViewController::handlePreviousButtonClicked, this)); - historyWindow_->onNextButtonClicked.connect(boost::bind(&HistoryViewController::handleNextButtonClicked, this)); - historyWindow_->onCalendarClicked.connect(boost::bind(&HistoryViewController::handleCalendarClicked, this, _1)); - historyController_->onNewMessage.connect(boost::bind(&HistoryViewController::handleNewMessage, this, _1)); - - presenceOracle_->onPresenceChange.connect(boost::bind(&HistoryViewController::handlePresenceChanged, this, _1)); - avatarManager_->onAvatarChanged.connect(boost::bind(&HistoryViewController::handleAvatarChanged, this, _1)); - - historyWindow_->setRosterModel(roster_); - } - - // populate roster by doing an empty search - handleReturnPressed(std::string()); - - historyWindow_->activate(); - } + boost::shared_ptr<RequestHistoryUIEvent> event = boost::dynamic_pointer_cast<RequestHistoryUIEvent>(rawEvent); + if (event != NULL) { + if (historyWindow_ == NULL) { + historyWindow_ = historyWindowFactory_->createHistoryWindow(uiEventStream_); + historyWindow_->onSelectedContactChanged.connect(boost::bind(&HistoryViewController::handleSelectedContactChanged, this, _1)); + historyWindow_->onReturnPressed.connect(boost::bind(&HistoryViewController::handleReturnPressed, this, _1)); + historyWindow_->onScrollReachedTop.connect(boost::bind(&HistoryViewController::handleScrollReachedTop, this, _1)); + historyWindow_->onScrollReachedBottom.connect(boost::bind(&HistoryViewController::handleScrollReachedBottom, this, _1)); + historyWindow_->onPreviousButtonClicked.connect(boost::bind(&HistoryViewController::handlePreviousButtonClicked, this)); + historyWindow_->onNextButtonClicked.connect(boost::bind(&HistoryViewController::handleNextButtonClicked, this)); + historyWindow_->onCalendarClicked.connect(boost::bind(&HistoryViewController::handleCalendarClicked, this, _1)); + historyController_->onNewMessage.connect(boost::bind(&HistoryViewController::handleNewMessage, this, _1)); + + presenceOracle_->onPresenceChange.connect(boost::bind(&HistoryViewController::handlePresenceChanged, this, _1)); + avatarManager_->onAvatarChanged.connect(boost::bind(&HistoryViewController::handleAvatarChanged, this, _1)); + + historyWindow_->setRosterModel(roster_); + } + + // populate roster by doing an empty search + handleReturnPressed(std::string()); + + historyWindow_->activate(); + } } void HistoryViewController::handleSelectedContactChanged(RosterItem* newContact) { - // FIXME: signal is triggerd twice. - ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(newContact); - - if (contact && selectedItem_ != contact) { - selectedItem_ = contact; - historyWindow_->resetConversationView(); - } - else { - return; - } - - JID contactJID = contact->getJID(); - - std::vector<HistoryMessage> messages; - for (int it = HistoryMessage::Chat; it <= HistoryMessage::PrivateMessage; it++) { - HistoryMessage::Type type = static_cast<HistoryMessage::Type>(it); - - if (contacts_[type].count(contactJID)) { - currentResultDate_ = *contacts_[type][contactJID].rbegin(); - selectedItemType_ = type; - messages = historyController_->getMessagesFromDate(selfJID_, contactJID, type, currentResultDate_); - } - } - - historyWindow_->setDate(currentResultDate_); - - foreach (const HistoryMessage& message, messages) { - addNewMessage(message, false); - } + // FIXME: signal is triggerd twice. + ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(newContact); + + if (contact && selectedItem_ != contact) { + selectedItem_ = contact; + historyWindow_->resetConversationView(); + } + else { + return; + } + + JID contactJID = contact->getJID(); + + std::vector<HistoryMessage> messages; + for (int it = HistoryMessage::Chat; it <= HistoryMessage::PrivateMessage; it++) { + HistoryMessage::Type type = static_cast<HistoryMessage::Type>(it); + + if (contacts_[type].count(contactJID)) { + currentResultDate_ = *contacts_[type][contactJID].rbegin(); + selectedItemType_ = type; + messages = historyController_->getMessagesFromDate(selfJID_, contactJID, type, currentResultDate_); + } + } + + historyWindow_->setDate(currentResultDate_); + + foreach (const HistoryMessage& message, messages) { + addNewMessage(message, false); + } } void HistoryViewController::handleNewMessage(const HistoryMessage& message) { - JID contactJID = message.getFromJID().toBare() == selfJID_ ? message.getToJID() : message.getFromJID(); - - JID displayJID; - if (message.getType() == HistoryMessage::PrivateMessage) { - displayJID = contactJID; - } - else { - displayJID = contactJID.toBare(); - } - - // check current conversation - if (selectedItem_ && selectedItem_->getJID() == displayJID) { - if (historyWindow_->getLastVisibleDate() == message.getTime().date()) { - addNewMessage(message, false); - } - } - - // check if the new message matches the query - if (message.getMessage().find(historyWindow_->getSearchBoxText()) == std::string::npos) { - return; - } - - // update contacts - if (!contacts_[message.getType()].count(displayJID)) { - roster_->addContact(displayJID, displayJID, nickResolver_->jidToNick(displayJID), category[message.getType()], avatarManager_->getAvatarPath(displayJID)); - } - - contacts_[message.getType()][displayJID].insert(message.getTime().date()); + JID contactJID = message.getFromJID().toBare() == selfJID_ ? message.getToJID() : message.getFromJID(); + + JID displayJID; + if (message.getType() == HistoryMessage::PrivateMessage) { + displayJID = contactJID; + } + else { + displayJID = contactJID.toBare(); + } + + // check current conversation + if (selectedItem_ && selectedItem_->getJID() == displayJID) { + if (historyWindow_->getLastVisibleDate() == message.getTime().date()) { + addNewMessage(message, false); + } + } + + // check if the new message matches the query + if (message.getMessage().find(historyWindow_->getSearchBoxText()) == std::string::npos) { + return; + } + + // update contacts + if (!contacts_[message.getType()].count(displayJID)) { + roster_->addContact(displayJID, displayJID, nickResolver_->jidToNick(displayJID), category[message.getType()], avatarManager_->getAvatarPath(displayJID)); + } + + contacts_[message.getType()][displayJID].insert(message.getTime().date()); } void HistoryViewController::addNewMessage(const HistoryMessage& message, bool addAtTheTop) { - bool senderIsSelf = message.getFromJID().toBare() == selfJID_; - std::string avatarPath = pathToString(avatarManager_->getAvatarPath(message.getFromJID())); + bool senderIsSelf = message.getFromJID().toBare() == selfJID_; + std::string avatarPath = pathToString(avatarManager_->getAvatarPath(message.getFromJID())); - std::string nick = message.getType() != HistoryMessage::Groupchat ? nickResolver_->jidToNick(message.getFromJID()) : message.getFromJID().getResource(); - historyWindow_->addMessage(message.getMessage(), nick, senderIsSelf, avatarPath, message.getTime(), addAtTheTop); + std::string nick = message.getType() != HistoryMessage::Groupchat ? nickResolver_->jidToNick(message.getFromJID()) : message.getFromJID().getResource(); + historyWindow_->addMessage(message.getMessage(), nick, senderIsSelf, avatarPath, message.getTime(), addAtTheTop); } void HistoryViewController::handleReturnPressed(const std::string& keyword) { - reset(); - - for (int it = HistoryMessage::Chat; it <= HistoryMessage::PrivateMessage; it++) { - HistoryMessage::Type type = static_cast<HistoryMessage::Type>(it); - - contacts_[type] = historyController_->getContacts(selfJID_, type, keyword); - - for (ContactsMap::const_iterator contact = contacts_[type].begin(); contact != contacts_[type].end(); contact++) { - const JID& jid = contact->first; - std::string nick; - if (type == HistoryMessage::PrivateMessage) { - nick = jid.toString(); - } - else { - nick = nickResolver_->jidToNick(jid); - } - roster_->addContact(jid, jid, nick, category[type], avatarManager_->getAvatarPath(jid)); - - Presence::ref presence = getPresence(jid, type == HistoryMessage::Groupchat); - - if (presence.get()) { - roster_->applyOnItem(SetPresence(presence, JID::WithoutResource), jid); - } - } - } + reset(); + + for (int it = HistoryMessage::Chat; it <= HistoryMessage::PrivateMessage; it++) { + HistoryMessage::Type type = static_cast<HistoryMessage::Type>(it); + + contacts_[type] = historyController_->getContacts(selfJID_, type, keyword); + + for (ContactsMap::const_iterator contact = contacts_[type].begin(); contact != contacts_[type].end(); contact++) { + const JID& jid = contact->first; + std::string nick; + if (type == HistoryMessage::PrivateMessage) { + nick = jid.toString(); + } + else { + nick = nickResolver_->jidToNick(jid); + } + roster_->addContact(jid, jid, nick, category[type], avatarManager_->getAvatarPath(jid)); + + Presence::ref presence = getPresence(jid, type == HistoryMessage::Groupchat); + + if (presence.get()) { + roster_->applyOnItem(SetPresence(presence, JID::WithoutResource), jid); + } + } + } } void HistoryViewController::handleScrollReachedTop(const boost::gregorian::date& date) { - if (!selectedItem_) { - return; - } + if (!selectedItem_) { + return; + } - std::vector<HistoryMessage> messages = historyController_->getMessagesFromPreviousDate(selfJID_, selectedItem_->getJID(), selectedItemType_, date); + std::vector<HistoryMessage> messages = historyController_->getMessagesFromPreviousDate(selfJID_, selectedItem_->getJID(), selectedItemType_, date); - foreach (const HistoryMessage& message, messages) { - addNewMessage(message, true); - } - historyWindow_->resetConversationViewTopInsertPoint(); + foreach (const HistoryMessage& message, messages) { + addNewMessage(message, true); + } + historyWindow_->resetConversationViewTopInsertPoint(); } void HistoryViewController::handleScrollReachedBottom(const boost::gregorian::date& date) { - if (!selectedItem_) { - return; - } + if (!selectedItem_) { + return; + } - std::vector<HistoryMessage> messages = historyController_->getMessagesFromNextDate(selfJID_, selectedItem_->getJID(), selectedItemType_, date); + std::vector<HistoryMessage> messages = historyController_->getMessagesFromNextDate(selfJID_, selectedItem_->getJID(), selectedItemType_, date); - foreach (const HistoryMessage& message, messages) { - addNewMessage(message, false); - } + foreach (const HistoryMessage& message, messages) { + addNewMessage(message, false); + } } void HistoryViewController::handleNextButtonClicked() { - if (!selectedItem_) { - return; - } + if (!selectedItem_) { + return; + } - std::set<boost::gregorian::date>::iterator date = contacts_[selectedItemType_][selectedItem_->getJID()].find(currentResultDate_); + std::set<boost::gregorian::date>::iterator date = contacts_[selectedItemType_][selectedItem_->getJID()].find(currentResultDate_); - if (*date == *contacts_[selectedItemType_][selectedItem_->getJID()].rbegin()) { - return; - } + if (*date == *contacts_[selectedItemType_][selectedItem_->getJID()].rbegin()) { + return; + } - historyWindow_->resetConversationView(); - currentResultDate_ = *(++date); - std::vector<HistoryMessage> messages = historyController_->getMessagesFromDate(selfJID_, selectedItem_->getJID(), selectedItemType_, currentResultDate_); - historyWindow_->setDate(currentResultDate_); + historyWindow_->resetConversationView(); + currentResultDate_ = *(++date); + std::vector<HistoryMessage> messages = historyController_->getMessagesFromDate(selfJID_, selectedItem_->getJID(), selectedItemType_, currentResultDate_); + historyWindow_->setDate(currentResultDate_); - foreach (const HistoryMessage& message, messages) { - addNewMessage(message, false); - } + foreach (const HistoryMessage& message, messages) { + addNewMessage(message, false); + } } void HistoryViewController::handlePreviousButtonClicked() { - if (!selectedItem_) { - return; - } + if (!selectedItem_) { + return; + } - std::set<boost::gregorian::date>::iterator date = contacts_[selectedItemType_][selectedItem_->getJID()].find(currentResultDate_); + std::set<boost::gregorian::date>::iterator date = contacts_[selectedItemType_][selectedItem_->getJID()].find(currentResultDate_); - if (date == contacts_[selectedItemType_][selectedItem_->getJID()].begin()) { - return; - } + if (date == contacts_[selectedItemType_][selectedItem_->getJID()].begin()) { + return; + } - historyWindow_->resetConversationView(); - currentResultDate_ = *(--date); - std::vector<HistoryMessage> messages = historyController_->getMessagesFromDate(selfJID_, selectedItem_->getJID(), selectedItemType_, currentResultDate_); - historyWindow_->setDate(currentResultDate_); + historyWindow_->resetConversationView(); + currentResultDate_ = *(--date); + std::vector<HistoryMessage> messages = historyController_->getMessagesFromDate(selfJID_, selectedItem_->getJID(), selectedItemType_, currentResultDate_); + historyWindow_->setDate(currentResultDate_); - foreach (const HistoryMessage& message, messages) { - addNewMessage(message, false); - } + foreach (const HistoryMessage& message, messages) { + addNewMessage(message, false); + } } void HistoryViewController::reset() { - roster_->removeAll(); - contacts_.clear(); - selectedItem_ = NULL; - historyWindow_->resetConversationView(); + roster_->removeAll(); + contacts_.clear(); + selectedItem_ = NULL; + historyWindow_->resetConversationView(); } void HistoryViewController::handleCalendarClicked(const boost::gregorian::date& date) { - if (!selectedItem_) { - return; - } - - boost::gregorian::date newDate; - if (contacts_[selectedItemType_][selectedItem_->getJID()].count(date)) { - newDate = date; - } - else if (date < currentResultDate_) { - foreach(const boost::gregorian::date& current, contacts_[selectedItemType_][selectedItem_->getJID()]) { - if (current > date) { - newDate = current; - break; - } - } - } - else { - reverse_foreach(const boost::gregorian::date& current, contacts_[selectedItemType_][selectedItem_->getJID()]) { - if (current < date) { - newDate = current; - break; - } - } - } - - historyWindow_->setDate(newDate); - if (newDate == currentResultDate_) { - return; - } - currentResultDate_ = newDate; - historyWindow_->resetConversationView(); - - std::vector<HistoryMessage> messages = historyController_->getMessagesFromDate(selfJID_, selectedItem_->getJID(), selectedItemType_, currentResultDate_); - historyWindow_->setDate(currentResultDate_); - - foreach (const HistoryMessage& message, messages) { - addNewMessage(message, false); - } + if (!selectedItem_) { + return; + } + + boost::gregorian::date newDate; + if (contacts_[selectedItemType_][selectedItem_->getJID()].count(date)) { + newDate = date; + } + else if (date < currentResultDate_) { + foreach(const boost::gregorian::date& current, contacts_[selectedItemType_][selectedItem_->getJID()]) { + if (current > date) { + newDate = current; + break; + } + } + } + else { + reverse_foreach(const boost::gregorian::date& current, contacts_[selectedItemType_][selectedItem_->getJID()]) { + if (current < date) { + newDate = current; + break; + } + } + } + + historyWindow_->setDate(newDate); + if (newDate == currentResultDate_) { + return; + } + currentResultDate_ = newDate; + historyWindow_->resetConversationView(); + + std::vector<HistoryMessage> messages = historyController_->getMessagesFromDate(selfJID_, selectedItem_->getJID(), selectedItemType_, currentResultDate_); + historyWindow_->setDate(currentResultDate_); + + foreach (const HistoryMessage& message, messages) { + addNewMessage(message, false); + } } void HistoryViewController::handlePresenceChanged(Presence::ref presence) { - JID jid = presence->getFrom(); - - if (contacts_[HistoryMessage::Chat].count(jid.toBare())) { - roster_->applyOnItems(SetPresence(presence, JID::WithoutResource)); - return; - } - - if (contacts_[HistoryMessage::Groupchat].count(jid.toBare())) { - Presence::ref availablePresence = boost::make_shared<Presence>(Presence()); - availablePresence->setFrom(jid.toBare()); - roster_->applyOnItems(SetPresence(availablePresence, JID::WithResource)); - } - - if (contacts_[HistoryMessage::PrivateMessage].count(jid)) { - roster_->applyOnItems(SetPresence(presence, JID::WithResource)); - } + JID jid = presence->getFrom(); + + if (contacts_[HistoryMessage::Chat].count(jid.toBare())) { + roster_->applyOnItems(SetPresence(presence, JID::WithoutResource)); + return; + } + + if (contacts_[HistoryMessage::Groupchat].count(jid.toBare())) { + Presence::ref availablePresence = boost::make_shared<Presence>(Presence()); + availablePresence->setFrom(jid.toBare()); + roster_->applyOnItems(SetPresence(availablePresence, JID::WithResource)); + } + + if (contacts_[HistoryMessage::PrivateMessage].count(jid)) { + roster_->applyOnItems(SetPresence(presence, JID::WithResource)); + } } void HistoryViewController::handleAvatarChanged(const JID& jid) { - roster_->applyOnItems(SetAvatar(jid, avatarManager_->getAvatarPath(jid))); + roster_->applyOnItems(SetAvatar(jid, avatarManager_->getAvatarPath(jid))); } Presence::ref HistoryViewController::getPresence(const JID& jid, bool isMUC) { - if (jid.isBare() && !isMUC) { - return presenceOracle_->getHighestPriorityPresence(jid); - } + if (jid.isBare() && !isMUC) { + return presenceOracle_->getHighestPriorityPresence(jid); + } - std::vector<Presence::ref> mucPresence = presenceOracle_->getAllPresence(jid.toBare()); + std::vector<Presence::ref> mucPresence = presenceOracle_->getAllPresence(jid.toBare()); - if (isMUC && !mucPresence.empty()) { - Presence::ref presence = boost::make_shared<Presence>(Presence()); - presence->setFrom(jid); - return presence; - } + if (isMUC && !mucPresence.empty()) { + Presence::ref presence = boost::make_shared<Presence>(Presence()); + presence->setFrom(jid); + return presence; + } - foreach (Presence::ref presence, mucPresence) { - if (presence.get() && presence->getFrom() == jid) { - return presence; - } - } + foreach (Presence::ref presence, mucPresence) { + if (presence.get() && presence->getFrom() == jid) { + return presence; + } + } - return Presence::create(); + return Presence::create(); } } diff --git a/Swift/Controllers/HistoryViewController.h b/Swift/Controllers/HistoryViewController.h index b388160..463ee06 100644 --- a/Swift/Controllers/HistoryViewController.h +++ b/Swift/Controllers/HistoryViewController.h @@ -25,51 +25,51 @@ #include <Swift/Controllers/UIEvents/UIEventStream.h> namespace Swift { - class HistoryWindowFactory; - class HistoryWindow; - class Roster; - class RosterItem; - class ContactRosterItem; - class HistoryController; - class NickResolver; - class AvatarManager; + class HistoryWindowFactory; + class HistoryWindow; + class Roster; + class RosterItem; + class ContactRosterItem; + class HistoryController; + class NickResolver; + class AvatarManager; - class HistoryViewController { - public: - HistoryViewController(const JID& selfJID, UIEventStream* uiEventStream, HistoryController* historyController, NickResolver* nickResolver, AvatarManager* avatarManager, PresenceOracle* presenceOracle, HistoryWindowFactory* historyWindowFactory); - ~HistoryViewController(); + class HistoryViewController { + public: + HistoryViewController(const JID& selfJID, UIEventStream* uiEventStream, HistoryController* historyController, NickResolver* nickResolver, AvatarManager* avatarManager, PresenceOracle* presenceOracle, HistoryWindowFactory* historyWindowFactory); + ~HistoryViewController(); - private: - void handleUIEvent(boost::shared_ptr<UIEvent> event); - void handleSelectedContactChanged(RosterItem* item); - void handleNewMessage(const HistoryMessage& message); - void handleReturnPressed(const std::string& keyword); - void handleScrollReachedTop(const boost::gregorian::date& date); - void handleScrollReachedBottom(const boost::gregorian::date& date); - void handlePreviousButtonClicked(); - void handleNextButtonClicked(); - void handleCalendarClicked(const boost::gregorian::date& date); - void handlePresenceChanged(Presence::ref presence); - void handleAvatarChanged(const JID& jid); + private: + void handleUIEvent(boost::shared_ptr<UIEvent> event); + void handleSelectedContactChanged(RosterItem* item); + void handleNewMessage(const HistoryMessage& message); + void handleReturnPressed(const std::string& keyword); + void handleScrollReachedTop(const boost::gregorian::date& date); + void handleScrollReachedBottom(const boost::gregorian::date& date); + void handlePreviousButtonClicked(); + void handleNextButtonClicked(); + void handleCalendarClicked(const boost::gregorian::date& date); + void handlePresenceChanged(Presence::ref presence); + void handleAvatarChanged(const JID& jid); - void addNewMessage(const HistoryMessage& message, bool addAtTheTop); - void reset(); - Presence::ref getPresence(const JID& jid, bool isMUC); + void addNewMessage(const HistoryMessage& message, bool addAtTheTop); + void reset(); + Presence::ref getPresence(const JID& jid, bool isMUC); - private: - JID selfJID_; - UIEventStream* uiEventStream_; - HistoryController* historyController_; - NickResolver* nickResolver_; - AvatarManager* avatarManager_; - PresenceOracle* presenceOracle_; - HistoryWindowFactory* historyWindowFactory_; - HistoryWindow* historyWindow_; - Roster* roster_; + private: + JID selfJID_; + UIEventStream* uiEventStream_; + HistoryController* historyController_; + NickResolver* nickResolver_; + AvatarManager* avatarManager_; + PresenceOracle* presenceOracle_; + HistoryWindowFactory* historyWindowFactory_; + HistoryWindow* historyWindow_; + Roster* roster_; - std::map<HistoryMessage::Type, ContactsMap> contacts_; - ContactRosterItem* selectedItem_; - HistoryMessage::Type selectedItemType_; - boost::gregorian::date currentResultDate_; - }; + std::map<HistoryMessage::Type, ContactsMap> contacts_; + ContactRosterItem* selectedItem_; + HistoryMessage::Type selectedItemType_; + boost::gregorian::date currentResultDate_; + }; } diff --git a/Swift/Controllers/Intl.h b/Swift/Controllers/Intl.h index 386696a..c599493 100644 --- a/Swift/Controllers/Intl.h +++ b/Swift/Controllers/Intl.h @@ -8,4 +8,4 @@ #include <Swift/Controllers/Translator.h> #define QT_TRANSLATE_NOOP(context, text) \ - Swift::Translator::getInstance()->translate(text, context) + Swift::Translator::getInstance()->translate(text, context) diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp index 9f61b2b..b48059c 100644 --- a/Swift/Controllers/MainController.cpp +++ b/Swift/Controllers/MainController.cpp @@ -99,749 +99,749 @@ static const std::string CLIENT_NODE = "http://swift.im"; MainController::MainController( - EventLoop* eventLoop, - NetworkFactories* networkFactories, - UIFactory* uiFactories, - SettingsProvider* settings, - SystemTray* systemTray, - SoundPlayer* soundPlayer, - StoragesFactory* storagesFactory, - CertificateStorageFactory* certificateStorageFactory, - Dock* dock, - Notifier* notifier, - URIHandler* uriHandler, - IdleDetector* idleDetector, - const std::map<std::string, std::string>& emoticons, - bool useDelayForLatency) : - eventLoop_(eventLoop), - networkFactories_(networkFactories), - uiFactory_(uiFactories), - storagesFactory_(storagesFactory), - certificateStorageFactory_(certificateStorageFactory), - settings_(settings), - uriHandler_(uriHandler), - idleDetector_(idleDetector), - loginWindow_(NULL) , - useDelayForLatency_(useDelayForLatency), - ftOverview_(NULL), - emoticons_(emoticons) { - storages_ = NULL; - certificateStorage_ = NULL; - certificateTrustChecker_ = NULL; - statusTracker_ = NULL; - presenceNotifier_ = NULL; - eventNotifier_ = NULL; - rosterController_ = NULL; - chatsManager_ = NULL; - historyController_ = NULL; - historyViewController_ = NULL; - eventWindowController_ = NULL; - profileController_ = NULL; - blockListController_ = NULL; - showProfileController_ = NULL; - contactEditController_ = NULL; - userSearchControllerChat_ = NULL; - userSearchControllerAdd_ = NULL; - userSearchControllerInvite_ = NULL; - contactsFromRosterProvider_ = NULL; - contactSuggesterWithoutRoster_ = NULL; - contactSuggesterWithRoster_ = NULL; - whiteboardManager_ = NULL; - adHocManager_ = NULL; - quitRequested_ = false; - clientInitialized_ = false; - offlineRequested_ = false; - - timeBeforeNextReconnect_ = -1; - dock_ = dock; - uiEventStream_ = new UIEventStream(); - - notifier_ = new TogglableNotifier(notifier); - notifier_->setPersistentEnabled(settings_->getSetting(SettingConstants::SHOW_NOTIFICATIONS)); - eventController_ = new EventController(); - eventController_->onEventQueueLengthChange.connect(boost::bind(&MainController::handleEventQueueLengthChange, this, _1)); - - systemTrayController_ = new SystemTrayController(eventController_, systemTray); - loginWindow_ = uiFactory_->createLoginWindow(uiEventStream_); - loginWindow_->setShowNotificationToggle(!notifier->isExternallyConfigured()); - - highlightManager_ = new HighlightManager(settings_); - highlightEditorController_ = new HighlightEditorController(uiEventStream_, uiFactory_, highlightManager_); - - soundEventController_ = new SoundEventController(eventController_, soundPlayer, settings, highlightManager_); - - xmppURIController_ = new XMPPURIController(uriHandler_, uiEventStream_); - - std::string selectedLoginJID = settings_->getSetting(SettingConstants::LAST_LOGIN_JID); - bool loginAutomatically = settings_->getSetting(SettingConstants::LOGIN_AUTOMATICALLY); - std::string cachedPassword; - std::string cachedCertificate; - ClientOptions cachedOptions; - bool eagle = settings_->getSetting(SettingConstants::FORGET_PASSWORDS); - if (!eagle) { - foreach (std::string profile, settings->getAvailableProfiles()) { - ProfileSettingsProvider profileSettings(profile, settings); - std::string password = profileSettings.getStringSetting("pass"); - std::string certificate = profileSettings.getStringSetting("certificate"); - std::string jid = profileSettings.getStringSetting("jid"); - ClientOptions clientOptions = parseClientOptions(profileSettings.getStringSetting("options")); + EventLoop* eventLoop, + NetworkFactories* networkFactories, + UIFactory* uiFactories, + SettingsProvider* settings, + SystemTray* systemTray, + SoundPlayer* soundPlayer, + StoragesFactory* storagesFactory, + CertificateStorageFactory* certificateStorageFactory, + Dock* dock, + Notifier* notifier, + URIHandler* uriHandler, + IdleDetector* idleDetector, + const std::map<std::string, std::string>& emoticons, + bool useDelayForLatency) : + eventLoop_(eventLoop), + networkFactories_(networkFactories), + uiFactory_(uiFactories), + storagesFactory_(storagesFactory), + certificateStorageFactory_(certificateStorageFactory), + settings_(settings), + uriHandler_(uriHandler), + idleDetector_(idleDetector), + loginWindow_(NULL) , + useDelayForLatency_(useDelayForLatency), + ftOverview_(NULL), + emoticons_(emoticons) { + storages_ = NULL; + certificateStorage_ = NULL; + certificateTrustChecker_ = NULL; + statusTracker_ = NULL; + presenceNotifier_ = NULL; + eventNotifier_ = NULL; + rosterController_ = NULL; + chatsManager_ = NULL; + historyController_ = NULL; + historyViewController_ = NULL; + eventWindowController_ = NULL; + profileController_ = NULL; + blockListController_ = NULL; + showProfileController_ = NULL; + contactEditController_ = NULL; + userSearchControllerChat_ = NULL; + userSearchControllerAdd_ = NULL; + userSearchControllerInvite_ = NULL; + contactsFromRosterProvider_ = NULL; + contactSuggesterWithoutRoster_ = NULL; + contactSuggesterWithRoster_ = NULL; + whiteboardManager_ = NULL; + adHocManager_ = NULL; + quitRequested_ = false; + clientInitialized_ = false; + offlineRequested_ = false; + + timeBeforeNextReconnect_ = -1; + dock_ = dock; + uiEventStream_ = new UIEventStream(); + + notifier_ = new TogglableNotifier(notifier); + notifier_->setPersistentEnabled(settings_->getSetting(SettingConstants::SHOW_NOTIFICATIONS)); + eventController_ = new EventController(); + eventController_->onEventQueueLengthChange.connect(boost::bind(&MainController::handleEventQueueLengthChange, this, _1)); + + systemTrayController_ = new SystemTrayController(eventController_, systemTray); + loginWindow_ = uiFactory_->createLoginWindow(uiEventStream_); + loginWindow_->setShowNotificationToggle(!notifier->isExternallyConfigured()); + + highlightManager_ = new HighlightManager(settings_); + highlightEditorController_ = new HighlightEditorController(uiEventStream_, uiFactory_, highlightManager_); + + soundEventController_ = new SoundEventController(eventController_, soundPlayer, settings, highlightManager_); + + xmppURIController_ = new XMPPURIController(uriHandler_, uiEventStream_); + + std::string selectedLoginJID = settings_->getSetting(SettingConstants::LAST_LOGIN_JID); + bool loginAutomatically = settings_->getSetting(SettingConstants::LOGIN_AUTOMATICALLY); + std::string cachedPassword; + std::string cachedCertificate; + ClientOptions cachedOptions; + bool eagle = settings_->getSetting(SettingConstants::FORGET_PASSWORDS); + if (!eagle) { + foreach (std::string profile, settings->getAvailableProfiles()) { + ProfileSettingsProvider profileSettings(profile, settings); + std::string password = profileSettings.getStringSetting("pass"); + std::string certificate = profileSettings.getStringSetting("certificate"); + std::string jid = profileSettings.getStringSetting("jid"); + ClientOptions clientOptions = parseClientOptions(profileSettings.getStringSetting("options")); #ifdef SWIFTEN_PLATFORM_WIN32 - clientOptions.singleSignOn = settings_->getSetting(SettingConstants::SINGLE_SIGN_ON); + clientOptions.singleSignOn = settings_->getSetting(SettingConstants::SINGLE_SIGN_ON); #endif - loginWindow_->addAvailableAccount(jid, password, certificate, clientOptions); - if (jid == selectedLoginJID) { - cachedPassword = password; - cachedCertificate = certificate; - cachedOptions = clientOptions; - } - } - loginWindow_->selectUser(selectedLoginJID); - loginWindow_->setLoginAutomatically(loginAutomatically); - } + loginWindow_->addAvailableAccount(jid, password, certificate, clientOptions); + if (jid == selectedLoginJID) { + cachedPassword = password; + cachedCertificate = certificate; + cachedOptions = clientOptions; + } + } + loginWindow_->selectUser(selectedLoginJID); + loginWindow_->setLoginAutomatically(loginAutomatically); + } - loginWindow_->onLoginRequest.connect(boost::bind(&MainController::handleLoginRequest, this, _1, _2, _3, _4, _5, _6, _7)); - loginWindow_->onPurgeSavedLoginRequest.connect(boost::bind(&MainController::handlePurgeSavedLoginRequest, this, _1)); - loginWindow_->onCancelLoginRequest.connect(boost::bind(&MainController::handleCancelLoginRequest, this)); - loginWindow_->onQuitRequest.connect(boost::bind(&MainController::handleQuitRequest, this)); + loginWindow_->onLoginRequest.connect(boost::bind(&MainController::handleLoginRequest, this, _1, _2, _3, _4, _5, _6, _7)); + loginWindow_->onPurgeSavedLoginRequest.connect(boost::bind(&MainController::handlePurgeSavedLoginRequest, this, _1)); + loginWindow_->onCancelLoginRequest.connect(boost::bind(&MainController::handleCancelLoginRequest, this)); + loginWindow_->onQuitRequest.connect(boost::bind(&MainController::handleQuitRequest, this)); - idleDetector_->setIdleTimeSeconds(settings->getSetting(SettingConstants::IDLE_TIMEOUT)); - idleDetector_->onIdleChanged.connect(boost::bind(&MainController::handleInputIdleChanged, this, _1)); + idleDetector_->setIdleTimeSeconds(settings->getSetting(SettingConstants::IDLE_TIMEOUT)); + idleDetector_->onIdleChanged.connect(boost::bind(&MainController::handleInputIdleChanged, this, _1)); - xmlConsoleController_ = new XMLConsoleController(uiEventStream_, uiFactory_); + xmlConsoleController_ = new XMLConsoleController(uiEventStream_, uiFactory_); - fileTransferListController_ = new FileTransferListController(uiEventStream_, uiFactory_); + fileTransferListController_ = new FileTransferListController(uiEventStream_, uiFactory_); - settings_->onSettingChanged.connect(boost::bind(&MainController::handleSettingChanged, this, _1)); + settings_->onSettingChanged.connect(boost::bind(&MainController::handleSettingChanged, this, _1)); - if (loginAutomatically) { - profileSettings_ = new ProfileSettingsProvider(selectedLoginJID, settings_); - /* FIXME: deal with autologin with a cert*/ - handleLoginRequest(selectedLoginJID, cachedPassword, cachedCertificate, CertificateWithKey::ref(), cachedOptions, true, true); - } else { - profileSettings_ = NULL; - } + if (loginAutomatically) { + profileSettings_ = new ProfileSettingsProvider(selectedLoginJID, settings_); + /* FIXME: deal with autologin with a cert*/ + handleLoginRequest(selectedLoginJID, cachedPassword, cachedCertificate, CertificateWithKey::ref(), cachedOptions, true, true); + } else { + profileSettings_ = NULL; + } } MainController::~MainController() { - idleDetector_->onIdleChanged.disconnect(boost::bind(&MainController::handleInputIdleChanged, this, _1)); - - purgeCachedCredentials(); - //setManagersOffline(); - eventController_->disconnectAll(); - - resetClient(); - delete highlightEditorController_; - delete highlightManager_; - delete fileTransferListController_; - delete xmlConsoleController_; - delete xmppURIController_; - delete soundEventController_; - delete systemTrayController_; - delete eventController_; - delete notifier_; - delete uiEventStream_; + idleDetector_->onIdleChanged.disconnect(boost::bind(&MainController::handleInputIdleChanged, this, _1)); + + purgeCachedCredentials(); + //setManagersOffline(); + eventController_->disconnectAll(); + + resetClient(); + delete highlightEditorController_; + delete highlightManager_; + delete fileTransferListController_; + delete xmlConsoleController_; + delete xmppURIController_; + delete soundEventController_; + delete systemTrayController_; + delete eventController_; + delete notifier_; + delete uiEventStream_; } void MainController::purgeCachedCredentials() { - safeClear(password_); + safeClear(password_); } void MainController::resetClient() { - purgeCachedCredentials(); - resetCurrentError(); - resetPendingReconnects(); - vCardPhotoHash_.clear(); - delete contactEditController_; - contactEditController_ = NULL; - delete profileController_; - profileController_ = NULL; - delete showProfileController_; - showProfileController_ = NULL; - delete eventWindowController_; - eventWindowController_ = NULL; - delete chatsManager_; - chatsManager_ = NULL; + purgeCachedCredentials(); + resetCurrentError(); + resetPendingReconnects(); + vCardPhotoHash_.clear(); + delete contactEditController_; + contactEditController_ = NULL; + delete profileController_; + profileController_ = NULL; + delete showProfileController_; + showProfileController_ = NULL; + delete eventWindowController_; + eventWindowController_ = NULL; + delete chatsManager_; + chatsManager_ = NULL; #ifdef SWIFT_EXPERIMENTAL_HISTORY - delete historyViewController_; - historyViewController_ = NULL; - delete historyController_; - historyController_ = NULL; + delete historyViewController_; + historyViewController_ = NULL; + delete historyController_; + historyController_ = NULL; #endif - fileTransferListController_->setFileTransferOverview(NULL); - delete ftOverview_; - ftOverview_ = NULL; - delete blockListController_; - blockListController_ = NULL; - delete rosterController_; - rosterController_ = NULL; - delete eventNotifier_; - eventNotifier_ = NULL; - delete presenceNotifier_; - presenceNotifier_ = NULL; - delete certificateTrustChecker_; - certificateTrustChecker_ = NULL; - delete certificateStorage_; - certificateStorage_ = NULL; - delete storages_; - storages_ = NULL; - delete statusTracker_; - statusTracker_ = NULL; - delete profileSettings_; - profileSettings_ = NULL; - delete userSearchControllerChat_; - userSearchControllerChat_ = NULL; - delete userSearchControllerAdd_; - userSearchControllerAdd_ = NULL; - delete userSearchControllerInvite_; - userSearchControllerInvite_ = NULL; - delete contactSuggesterWithoutRoster_; - contactSuggesterWithoutRoster_ = NULL; - delete contactSuggesterWithRoster_; - contactSuggesterWithRoster_ = NULL; - delete contactsFromRosterProvider_; - contactsFromRosterProvider_ = NULL; - delete adHocManager_; - adHocManager_ = NULL; - delete whiteboardManager_; - whiteboardManager_ = NULL; - clientInitialized_ = false; + fileTransferListController_->setFileTransferOverview(NULL); + delete ftOverview_; + ftOverview_ = NULL; + delete blockListController_; + blockListController_ = NULL; + delete rosterController_; + rosterController_ = NULL; + delete eventNotifier_; + eventNotifier_ = NULL; + delete presenceNotifier_; + presenceNotifier_ = NULL; + delete certificateTrustChecker_; + certificateTrustChecker_ = NULL; + delete certificateStorage_; + certificateStorage_ = NULL; + delete storages_; + storages_ = NULL; + delete statusTracker_; + statusTracker_ = NULL; + delete profileSettings_; + profileSettings_ = NULL; + delete userSearchControllerChat_; + userSearchControllerChat_ = NULL; + delete userSearchControllerAdd_; + userSearchControllerAdd_ = NULL; + delete userSearchControllerInvite_; + userSearchControllerInvite_ = NULL; + delete contactSuggesterWithoutRoster_; + contactSuggesterWithoutRoster_ = NULL; + delete contactSuggesterWithRoster_; + contactSuggesterWithRoster_ = NULL; + delete contactsFromRosterProvider_; + contactsFromRosterProvider_ = NULL; + delete adHocManager_; + adHocManager_ = NULL; + delete whiteboardManager_; + whiteboardManager_ = NULL; + clientInitialized_ = false; } void MainController::handleSettingChanged(const std::string& settingPath) { - if (settingPath == SettingConstants::SHOW_NOTIFICATIONS.getKey()) { - notifier_->setPersistentEnabled(settings_->getSetting(SettingConstants::SHOW_NOTIFICATIONS)); - } + if (settingPath == SettingConstants::SHOW_NOTIFICATIONS.getKey()) { + notifier_->setPersistentEnabled(settings_->getSetting(SettingConstants::SHOW_NOTIFICATIONS)); + } } void MainController::resetPendingReconnects() { - timeBeforeNextReconnect_ = -1; - if (reconnectTimer_) { - reconnectTimer_->stop(); - reconnectTimer_.reset(); - } - resetCurrentError(); + timeBeforeNextReconnect_ = -1; + if (reconnectTimer_) { + reconnectTimer_->stop(); + reconnectTimer_.reset(); + } + resetCurrentError(); } void MainController::resetCurrentError() { - if (lastDisconnectError_) { - lastDisconnectError_->conclude(); - lastDisconnectError_ = boost::shared_ptr<ErrorEvent>(); - } + if (lastDisconnectError_) { + lastDisconnectError_->conclude(); + lastDisconnectError_ = boost::shared_ptr<ErrorEvent>(); + } } void MainController::handleConnected() { - boundJID_ = client_->getJID(); - resetCurrentError(); - resetPendingReconnects(); - - if (settings_->getSetting(SettingConstants::FORGET_PASSWORDS)) { - purgeCachedCredentials(); - } - - bool freshLogin = rosterController_ == NULL; - myStatusLooksOnline_ = true; - if (freshLogin) { - profileController_ = new ProfileController(client_->getVCardManager(), uiFactory_, uiEventStream_); - showProfileController_ = new ShowProfileController(client_->getVCardManager(), uiFactory_, uiEventStream_); - ftOverview_ = new FileTransferOverview(client_->getFileTransferManager()); - fileTransferListController_->setFileTransferOverview(ftOverview_); - rosterController_ = new RosterController(boundJID_, client_->getRoster(), client_->getAvatarManager(), uiFactory_, client_->getNickManager(), client_->getNickResolver(), client_->getPresenceOracle(), client_->getSubscriptionManager(), eventController_, uiEventStream_, client_->getIQRouter(), settings_, client_->getEntityCapsProvider(), ftOverview_, client_->getClientBlockListManager(), client_->getVCardManager()); - rosterController_->onChangeStatusRequest.connect(boost::bind(&MainController::handleChangeStatusRequest, this, _1, _2)); - rosterController_->onSignOutRequest.connect(boost::bind(&MainController::signOut, this)); - rosterController_->getWindow()->onShowCertificateRequest.connect(boost::bind(&MainController::handleShowCertificateRequest, this)); - - blockListController_ = new BlockListController(client_->getClientBlockListManager(), uiEventStream_, uiFactory_, eventController_); - - contactEditController_ = new ContactEditController(rosterController_, client_->getVCardManager(), uiFactory_, uiEventStream_); - whiteboardManager_ = new WhiteboardManager(uiFactory_, uiEventStream_, client_->getNickResolver(), client_->getWhiteboardSessionManager()); - - /* Doing this early as an ordering fix. Various things later will - * want to have the user's nick available and this means it will - * be before they receive stanzas that need it (e.g. bookmarks).*/ - client_->getVCardManager()->requestOwnVCard(); - - contactSuggesterWithoutRoster_ = new ContactSuggester(); - contactSuggesterWithRoster_ = new ContactSuggester(); - - userSearchControllerInvite_ = new UserSearchController(UserSearchController::InviteToChat, jid_, uiEventStream_, client_->getVCardManager(), uiFactory_, client_->getIQRouter(), rosterController_, contactSuggesterWithRoster_, client_->getAvatarManager(), client_->getPresenceOracle(), profileSettings_); + boundJID_ = client_->getJID(); + resetCurrentError(); + resetPendingReconnects(); + + if (settings_->getSetting(SettingConstants::FORGET_PASSWORDS)) { + purgeCachedCredentials(); + } + + bool freshLogin = rosterController_ == NULL; + myStatusLooksOnline_ = true; + if (freshLogin) { + profileController_ = new ProfileController(client_->getVCardManager(), uiFactory_, uiEventStream_); + showProfileController_ = new ShowProfileController(client_->getVCardManager(), uiFactory_, uiEventStream_); + ftOverview_ = new FileTransferOverview(client_->getFileTransferManager()); + fileTransferListController_->setFileTransferOverview(ftOverview_); + rosterController_ = new RosterController(boundJID_, client_->getRoster(), client_->getAvatarManager(), uiFactory_, client_->getNickManager(), client_->getNickResolver(), client_->getPresenceOracle(), client_->getSubscriptionManager(), eventController_, uiEventStream_, client_->getIQRouter(), settings_, client_->getEntityCapsProvider(), ftOverview_, client_->getClientBlockListManager(), client_->getVCardManager()); + rosterController_->onChangeStatusRequest.connect(boost::bind(&MainController::handleChangeStatusRequest, this, _1, _2)); + rosterController_->onSignOutRequest.connect(boost::bind(&MainController::signOut, this)); + rosterController_->getWindow()->onShowCertificateRequest.connect(boost::bind(&MainController::handleShowCertificateRequest, this)); + + blockListController_ = new BlockListController(client_->getClientBlockListManager(), uiEventStream_, uiFactory_, eventController_); + + contactEditController_ = new ContactEditController(rosterController_, client_->getVCardManager(), uiFactory_, uiEventStream_); + whiteboardManager_ = new WhiteboardManager(uiFactory_, uiEventStream_, client_->getNickResolver(), client_->getWhiteboardSessionManager()); + + /* Doing this early as an ordering fix. Various things later will + * want to have the user's nick available and this means it will + * be before they receive stanzas that need it (e.g. bookmarks).*/ + client_->getVCardManager()->requestOwnVCard(); + + contactSuggesterWithoutRoster_ = new ContactSuggester(); + contactSuggesterWithRoster_ = new ContactSuggester(); + + userSearchControllerInvite_ = new UserSearchController(UserSearchController::InviteToChat, jid_, uiEventStream_, client_->getVCardManager(), uiFactory_, client_->getIQRouter(), rosterController_, contactSuggesterWithRoster_, client_->getAvatarManager(), client_->getPresenceOracle(), profileSettings_); #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_, highlightManager_, client_->getClientBlockListManager(), emoticons_, client_->getVCardManager()); + 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_, highlightManager_, client_->getClientBlockListManager(), emoticons_, client_->getVCardManager()); #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_, highlightManager_, client_->getClientBlockListManager(), emoticons_, client_->getVCardManager()); + 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_, client_->getClientBlockListManager(), emoticons_, client_->getVCardManager()); #endif - contactsFromRosterProvider_ = new ContactsFromXMPPRoster(client_->getRoster(), client_->getAvatarManager(), client_->getPresenceOracle()); - contactSuggesterWithoutRoster_->addContactProvider(chatsManager_); - contactSuggesterWithRoster_->addContactProvider(chatsManager_); - contactSuggesterWithRoster_->addContactProvider(contactsFromRosterProvider_); - highlightEditorController_->setContactSuggester(contactSuggesterWithoutRoster_); + contactsFromRosterProvider_ = new ContactsFromXMPPRoster(client_->getRoster(), client_->getAvatarManager(), client_->getPresenceOracle()); + contactSuggesterWithoutRoster_->addContactProvider(chatsManager_); + contactSuggesterWithRoster_->addContactProvider(chatsManager_); + contactSuggesterWithRoster_->addContactProvider(contactsFromRosterProvider_); + highlightEditorController_->setContactSuggester(contactSuggesterWithoutRoster_); - client_->onMessageReceived.connect(boost::bind(&ChatsManager::handleIncomingMessage, chatsManager_, _1)); - chatsManager_->setAvatarManager(client_->getAvatarManager()); + client_->onMessageReceived.connect(boost::bind(&ChatsManager::handleIncomingMessage, chatsManager_, _1)); + chatsManager_->setAvatarManager(client_->getAvatarManager()); - eventWindowController_ = new EventWindowController(eventController_, uiFactory_); + eventWindowController_ = new EventWindowController(eventController_, uiFactory_); - loginWindow_->morphInto(rosterController_->getWindow()); + loginWindow_->morphInto(rosterController_->getWindow()); - DiscoInfo discoInfo; - discoInfo.addIdentity(DiscoInfo::Identity(CLIENT_NAME, "client", "pc")); - discoInfo.addFeature(DiscoInfo::ChatStatesFeature); - discoInfo.addFeature(DiscoInfo::SecurityLabelsFeature); - discoInfo.addFeature(DiscoInfo::MessageCorrectionFeature); + DiscoInfo discoInfo; + discoInfo.addIdentity(DiscoInfo::Identity(CLIENT_NAME, "client", "pc")); + discoInfo.addFeature(DiscoInfo::ChatStatesFeature); + discoInfo.addFeature(DiscoInfo::SecurityLabelsFeature); + discoInfo.addFeature(DiscoInfo::MessageCorrectionFeature); #ifdef SWIFT_EXPERIMENTAL_FT - discoInfo.addFeature(DiscoInfo::JingleFeature); - discoInfo.addFeature(DiscoInfo::JingleFTFeature); - discoInfo.addFeature(DiscoInfo::JingleTransportsIBBFeature); - discoInfo.addFeature(DiscoInfo::JingleTransportsS5BFeature); + discoInfo.addFeature(DiscoInfo::JingleFeature); + discoInfo.addFeature(DiscoInfo::JingleFTFeature); + discoInfo.addFeature(DiscoInfo::JingleTransportsIBBFeature); + discoInfo.addFeature(DiscoInfo::JingleTransportsS5BFeature); #endif #ifdef SWIFT_EXPERIMENTAL_WB - discoInfo.addFeature(DiscoInfo::WhiteboardFeature); + discoInfo.addFeature(DiscoInfo::WhiteboardFeature); #endif - discoInfo.addFeature(DiscoInfo::MessageDeliveryReceiptsFeature); - client_->getDiscoManager()->setCapsNode(CLIENT_NODE); - client_->getDiscoManager()->setDiscoInfo(discoInfo); - - userSearchControllerChat_ = new UserSearchController(UserSearchController::StartChat, jid_, uiEventStream_, client_->getVCardManager(), uiFactory_, client_->getIQRouter(), rosterController_, contactSuggesterWithRoster_, client_->getAvatarManager(), client_->getPresenceOracle(), profileSettings_); - userSearchControllerAdd_ = new UserSearchController(UserSearchController::AddContact, jid_, uiEventStream_, client_->getVCardManager(), uiFactory_, client_->getIQRouter(), rosterController_, contactSuggesterWithoutRoster_, client_->getAvatarManager(), client_->getPresenceOracle(), profileSettings_); - adHocManager_ = new AdHocManager(JID(boundJID_.getDomain()), uiFactory_, client_->getIQRouter(), uiEventStream_, rosterController_->getWindow()); - - chatsManager_->onImpromptuMUCServiceDiscovered.connect(boost::bind(&UserSearchController::setCanInitiateImpromptuMUC, userSearchControllerChat_, _1)); - } - loginWindow_->setIsLoggingIn(false); - - client_->requestRoster(); - - GetDiscoInfoRequest::ref discoInfoRequest = GetDiscoInfoRequest::create(JID(boundJID_.getDomain()), client_->getIQRouter()); - discoInfoRequest->onResponse.connect(boost::bind(&MainController::handleServerDiscoInfoResponse, this, _1, _2)); - discoInfoRequest->send(); - - client_->getVCardManager()->requestOwnVCard(); - - rosterController_->setJID(boundJID_); - rosterController_->setEnabled(true); - rosterController_->getWindow()->setStreamEncryptionStatus(client_->isStreamEncrypted()); - profileController_->setAvailable(true); - 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); - adHocManager_->setOnline(true); + discoInfo.addFeature(DiscoInfo::MessageDeliveryReceiptsFeature); + client_->getDiscoManager()->setCapsNode(CLIENT_NODE); + client_->getDiscoManager()->setDiscoInfo(discoInfo); + + userSearchControllerChat_ = new UserSearchController(UserSearchController::StartChat, jid_, uiEventStream_, client_->getVCardManager(), uiFactory_, client_->getIQRouter(), rosterController_, contactSuggesterWithRoster_, client_->getAvatarManager(), client_->getPresenceOracle(), profileSettings_); + userSearchControllerAdd_ = new UserSearchController(UserSearchController::AddContact, jid_, uiEventStream_, client_->getVCardManager(), uiFactory_, client_->getIQRouter(), rosterController_, contactSuggesterWithoutRoster_, client_->getAvatarManager(), client_->getPresenceOracle(), profileSettings_); + adHocManager_ = new AdHocManager(JID(boundJID_.getDomain()), uiFactory_, client_->getIQRouter(), uiEventStream_, rosterController_->getWindow()); + + chatsManager_->onImpromptuMUCServiceDiscovered.connect(boost::bind(&UserSearchController::setCanInitiateImpromptuMUC, userSearchControllerChat_, _1)); + } + loginWindow_->setIsLoggingIn(false); + + client_->requestRoster(); + + GetDiscoInfoRequest::ref discoInfoRequest = GetDiscoInfoRequest::create(JID(boundJID_.getDomain()), client_->getIQRouter()); + discoInfoRequest->onResponse.connect(boost::bind(&MainController::handleServerDiscoInfoResponse, this, _1, _2)); + discoInfoRequest->send(); + + client_->getVCardManager()->requestOwnVCard(); + + rosterController_->setJID(boundJID_); + rosterController_->setEnabled(true); + rosterController_->getWindow()->setStreamEncryptionStatus(client_->isStreamEncrypted()); + profileController_->setAvailable(true); + 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); + adHocManager_->setOnline(true); } void MainController::handleEventQueueLengthChange(int count) { - dock_->setNumberOfPendingMessages(count); + dock_->setNumberOfPendingMessages(count); } void MainController::reconnectAfterError() { - if (reconnectTimer_) { - reconnectTimer_->stop(); - } - performLoginFromCachedCredentials(); + if (reconnectTimer_) { + reconnectTimer_->stop(); + } + performLoginFromCachedCredentials(); } void MainController::handleChangeStatusRequest(StatusShow::Type show, const std::string &statusText) { - boost::shared_ptr<Presence> presence(new Presence()); - if (show == StatusShow::None) { - // Note: this is misleading, None doesn't mean unavailable on the wire. - presence->setType(Presence::Unavailable); - resetPendingReconnects(); - myStatusLooksOnline_ = false; - offlineRequested_ = true; - } - else { - offlineRequested_ = false; - presence->setShow(show); - } - presence->setStatus(statusText); - statusTracker_->setRequestedPresence(presence); - if (presence->getType() != Presence::Unavailable) { - profileSettings_->storeInt("lastShow", presence->getShow()); - profileSettings_->storeString("lastStatus", presence->getStatus()); - } - if (presence->getType() != Presence::Unavailable && !client_->isAvailable()) { - performLoginFromCachedCredentials(); - } else { - sendPresence(presence); - } + boost::shared_ptr<Presence> presence(new Presence()); + if (show == StatusShow::None) { + // Note: this is misleading, None doesn't mean unavailable on the wire. + presence->setType(Presence::Unavailable); + resetPendingReconnects(); + myStatusLooksOnline_ = false; + offlineRequested_ = true; + } + else { + offlineRequested_ = false; + presence->setShow(show); + } + presence->setStatus(statusText); + statusTracker_->setRequestedPresence(presence); + if (presence->getType() != Presence::Unavailable) { + profileSettings_->storeInt("lastShow", presence->getShow()); + profileSettings_->storeString("lastStatus", presence->getStatus()); + } + if (presence->getType() != Presence::Unavailable && !client_->isAvailable()) { + performLoginFromCachedCredentials(); + } else { + sendPresence(presence); + } } void MainController::sendPresence(boost::shared_ptr<Presence> presence) { - rosterController_->getWindow()->setMyStatusType(presence->getShow()); - rosterController_->getWindow()->setMyStatusText(presence->getStatus()); - systemTrayController_->setMyStatusType(presence->getShow()); - notifier_->setTemporarilyDisabled(presence->getShow() == StatusShow::DND); - - // Add information and send - presence->updatePayload(boost::make_shared<VCardUpdate>(vCardPhotoHash_)); - client_->getPresenceSender()->sendPresence(presence); - if (presence->getType() == Presence::Unavailable) { - logout(); - } + rosterController_->getWindow()->setMyStatusType(presence->getShow()); + rosterController_->getWindow()->setMyStatusText(presence->getStatus()); + systemTrayController_->setMyStatusType(presence->getShow()); + notifier_->setTemporarilyDisabled(presence->getShow() == StatusShow::DND); + + // Add information and send + presence->updatePayload(boost::make_shared<VCardUpdate>(vCardPhotoHash_)); + client_->getPresenceSender()->sendPresence(presence); + if (presence->getType() == Presence::Unavailable) { + logout(); + } } void MainController::handleInputIdleChanged(bool idle) { - if (!statusTracker_) { - //Haven't logged in yet. - return; - } - - if (settings_->getSetting(SettingConstants::IDLE_GOES_OFFLINE)) { - if (idle) { - logout(); - } - } - else { - if (idle) { - if (statusTracker_->goAutoAway(idleDetector_->getIdleTimeSeconds())) { - if (client_ && client_->isAvailable()) { - sendPresence(statusTracker_->getNextPresence()); - } - } - } else { - if (statusTracker_->goAutoUnAway()) { - if (client_ && client_->isAvailable()) { - sendPresence(statusTracker_->getNextPresence()); - } - } - } - } + if (!statusTracker_) { + //Haven't logged in yet. + return; + } + + if (settings_->getSetting(SettingConstants::IDLE_GOES_OFFLINE)) { + if (idle) { + logout(); + } + } + else { + if (idle) { + if (statusTracker_->goAutoAway(idleDetector_->getIdleTimeSeconds())) { + if (client_ && client_->isAvailable()) { + sendPresence(statusTracker_->getNextPresence()); + } + } + } else { + if (statusTracker_->goAutoUnAway()) { + if (client_ && client_->isAvailable()) { + sendPresence(statusTracker_->getNextPresence()); + } + } + } + } } void MainController::handleShowCertificateRequest() { - std::vector<Certificate::ref> chain = client_->getStanzaChannel()->getPeerCertificateChain(); - rosterController_->getWindow()->openCertificateDialog(chain); + std::vector<Certificate::ref> chain = client_->getStanzaChannel()->getPeerCertificateChain(); + rosterController_->getWindow()->openCertificateDialog(chain); } void MainController::handleLoginRequest(const std::string &username, const std::string &password, const std::string& certificatePath, CertificateWithKey::ref certificate, const ClientOptions& options, bool remember, bool loginAutomatically) { - jid_ = JID(username); - if (options.singleSignOn && (!jid_.isValid() || !jid_.getNode().empty())) { - loginWindow_->setMessage(QT_TRANSLATE_NOOP("", "User address invalid. User address should be of the form 'wonderland.lit'")); - loginWindow_->setIsLoggingIn(false); - } else if (!options.singleSignOn && (!jid_.isValid() || jid_.getNode().empty())) { - loginWindow_->setMessage(QT_TRANSLATE_NOOP("", "User address invalid. User address should be of the form 'alice@wonderland.lit'")); - loginWindow_->setIsLoggingIn(false); - } else { + jid_ = JID(username); + if (options.singleSignOn && (!jid_.isValid() || !jid_.getNode().empty())) { + loginWindow_->setMessage(QT_TRANSLATE_NOOP("", "User address invalid. User address should be of the form 'wonderland.lit'")); + loginWindow_->setIsLoggingIn(false); + } else if (!options.singleSignOn && (!jid_.isValid() || jid_.getNode().empty())) { + loginWindow_->setMessage(QT_TRANSLATE_NOOP("", "User address invalid. User address should be of the form 'alice@wonderland.lit'")); + loginWindow_->setIsLoggingIn(false); + } else { #ifdef SWIFTEN_PLATFORM_WIN32 - if (options.singleSignOn) { - std::string userName; - std::string clientName; - std::string serverName; - boost::shared_ptr<boost::system::error_code> errorCode = getUserNameEx(userName, clientName, serverName); - - if (!errorCode) { - /* Create JID using the Windows logon name and user provided domain name */ - jid_ = JID(clientName, username); - } - else { - loginWindow_->setMessage(str(format(QT_TRANSLATE_NOOP("", "Error obtaining Windows user name (%1%)")) % errorCode->message())); - loginWindow_->setIsLoggingIn(false); - return; - } - } + if (options.singleSignOn) { + std::string userName; + std::string clientName; + std::string serverName; + boost::shared_ptr<boost::system::error_code> errorCode = getUserNameEx(userName, clientName, serverName); + + if (!errorCode) { + /* Create JID using the Windows logon name and user provided domain name */ + jid_ = JID(clientName, username); + } + else { + loginWindow_->setMessage(str(format(QT_TRANSLATE_NOOP("", "Error obtaining Windows user name (%1%)")) % errorCode->message())); + loginWindow_->setIsLoggingIn(false); + return; + } + } #endif - loginWindow_->setMessage(""); - loginWindow_->setIsLoggingIn(true); - profileSettings_ = new ProfileSettingsProvider(username, settings_); - if (!settings_->getSetting(SettingConstants::FORGET_PASSWORDS)) { - profileSettings_->storeString("jid", username); - profileSettings_->storeString("certificate", certificatePath); - profileSettings_->storeString("pass", (remember || loginAutomatically) ? password : ""); - std::string optionString = serializeClientOptions(options); - profileSettings_->storeString("options", optionString); - settings_->storeSetting(SettingConstants::LAST_LOGIN_JID, username); - settings_->storeSetting(SettingConstants::LOGIN_AUTOMATICALLY, loginAutomatically); - loginWindow_->addAvailableAccount(profileSettings_->getStringSetting("jid"), profileSettings_->getStringSetting("pass"), profileSettings_->getStringSetting("certificate"), options); - } - - password_ = password; - certificate_ = certificate; - clientOptions_ = options; - performLoginFromCachedCredentials(); - } + loginWindow_->setMessage(""); + loginWindow_->setIsLoggingIn(true); + profileSettings_ = new ProfileSettingsProvider(username, settings_); + if (!settings_->getSetting(SettingConstants::FORGET_PASSWORDS)) { + profileSettings_->storeString("jid", username); + profileSettings_->storeString("certificate", certificatePath); + profileSettings_->storeString("pass", (remember || loginAutomatically) ? password : ""); + std::string optionString = serializeClientOptions(options); + profileSettings_->storeString("options", optionString); + settings_->storeSetting(SettingConstants::LAST_LOGIN_JID, username); + settings_->storeSetting(SettingConstants::LOGIN_AUTOMATICALLY, loginAutomatically); + loginWindow_->addAvailableAccount(profileSettings_->getStringSetting("jid"), profileSettings_->getStringSetting("pass"), profileSettings_->getStringSetting("certificate"), options); + } + + password_ = password; + certificate_ = certificate; + clientOptions_ = options; + performLoginFromCachedCredentials(); + } } void MainController::handlePurgeSavedLoginRequest(const std::string& username) { - settings_->removeProfile(username); - loginWindow_->removeAvailableAccount(username); + settings_->removeProfile(username); + loginWindow_->removeAvailableAccount(username); } void MainController::performLoginFromCachedCredentials() { - if (settings_->getSetting(SettingConstants::FORGET_PASSWORDS) && password_.empty()) { - /* Then we can't try to login again. */ - return; - } - /* If we logged in with a bare JID, and we have a full bound JID, re-login with the - * bound JID to try and keep dynamically assigned resources */ - JID clientJID = jid_; - if (boundJID_.isValid() && jid_.isBare() && boundJID_.toBare() == jid_) { - clientJID = boundJID_; - } - - if (!statusTracker_) { - statusTracker_ = new StatusTracker(); - } - if (!clientInitialized_) { - storages_ = storagesFactory_->createStorages(jid_.toBare()); - certificateStorage_ = certificateStorageFactory_->createCertificateStorage(jid_.toBare()); - certificateTrustChecker_ = new CertificateStorageTrustChecker(certificateStorage_); - - client_ = boost::make_shared<Swift::Client>(clientJID, createSafeByteArray(password_.c_str()), networkFactories_, storages_); - clientInitialized_ = true; - client_->setCertificateTrustChecker(certificateTrustChecker_); - client_->onDataRead.connect(boost::bind(&XMLConsoleController::handleDataRead, xmlConsoleController_, _1)); - client_->onDataWritten.connect(boost::bind(&XMLConsoleController::handleDataWritten, xmlConsoleController_, _1)); - client_->onDisconnected.connect(boost::bind(&MainController::handleDisconnected, this, _1)); - client_->onConnected.connect(boost::bind(&MainController::handleConnected, this)); - - client_->setSoftwareVersion(CLIENT_NAME, buildVersion); - - client_->getVCardManager()->onVCardChanged.connect(boost::bind(&MainController::handleVCardReceived, this, _1, _2)); - presenceNotifier_ = new PresenceNotifier(client_->getStanzaChannel(), notifier_, client_->getMUCRegistry(), client_->getAvatarManager(), client_->getNickResolver(), client_->getPresenceOracle(), networkFactories_->getTimerFactory()); - presenceNotifier_->onNotificationActivated.connect(boost::bind(&MainController::handleNotificationClicked, this, _1)); - eventNotifier_ = new EventNotifier(eventController_, notifier_, client_->getAvatarManager(), client_->getNickResolver()); - eventNotifier_->onNotificationActivated.connect(boost::bind(&MainController::handleNotificationClicked, this, _1)); - if (certificate_) { - client_->setCertificate(certificate_); - } - boost::shared_ptr<Presence> presence(new Presence()); - presence->setShow(static_cast<StatusShow::Type>(profileSettings_->getIntSetting("lastShow", StatusShow::Online))); - presence->setStatus(profileSettings_->getStringSetting("lastStatus")); - statusTracker_->setRequestedPresence(presence); - } else { - /* In case we're in the middle of another login, make sure they don't overlap */ - client_->disconnect(); - } - systemTrayController_->setConnecting(); - if (rosterController_) { - rosterController_->getWindow()->setConnecting(); - } - ClientOptions clientOptions = clientOptions_; - bool eagle = settings_->getSetting(SettingConstants::FORGET_PASSWORDS); - clientOptions.forgetPassword = eagle; - clientOptions.useTLS = eagle ? ClientOptions::RequireTLS : clientOptions_.useTLS; - client_->connect(clientOptions); + if (settings_->getSetting(SettingConstants::FORGET_PASSWORDS) && password_.empty()) { + /* Then we can't try to login again. */ + return; + } + /* If we logged in with a bare JID, and we have a full bound JID, re-login with the + * bound JID to try and keep dynamically assigned resources */ + JID clientJID = jid_; + if (boundJID_.isValid() && jid_.isBare() && boundJID_.toBare() == jid_) { + clientJID = boundJID_; + } + + if (!statusTracker_) { + statusTracker_ = new StatusTracker(); + } + if (!clientInitialized_) { + storages_ = storagesFactory_->createStorages(jid_.toBare()); + certificateStorage_ = certificateStorageFactory_->createCertificateStorage(jid_.toBare()); + certificateTrustChecker_ = new CertificateStorageTrustChecker(certificateStorage_); + + client_ = boost::make_shared<Swift::Client>(clientJID, createSafeByteArray(password_.c_str()), networkFactories_, storages_); + clientInitialized_ = true; + client_->setCertificateTrustChecker(certificateTrustChecker_); + client_->onDataRead.connect(boost::bind(&XMLConsoleController::handleDataRead, xmlConsoleController_, _1)); + client_->onDataWritten.connect(boost::bind(&XMLConsoleController::handleDataWritten, xmlConsoleController_, _1)); + client_->onDisconnected.connect(boost::bind(&MainController::handleDisconnected, this, _1)); + client_->onConnected.connect(boost::bind(&MainController::handleConnected, this)); + + client_->setSoftwareVersion(CLIENT_NAME, buildVersion); + + client_->getVCardManager()->onVCardChanged.connect(boost::bind(&MainController::handleVCardReceived, this, _1, _2)); + presenceNotifier_ = new PresenceNotifier(client_->getStanzaChannel(), notifier_, client_->getMUCRegistry(), client_->getAvatarManager(), client_->getNickResolver(), client_->getPresenceOracle(), networkFactories_->getTimerFactory()); + presenceNotifier_->onNotificationActivated.connect(boost::bind(&MainController::handleNotificationClicked, this, _1)); + eventNotifier_ = new EventNotifier(eventController_, notifier_, client_->getAvatarManager(), client_->getNickResolver()); + eventNotifier_->onNotificationActivated.connect(boost::bind(&MainController::handleNotificationClicked, this, _1)); + if (certificate_) { + client_->setCertificate(certificate_); + } + boost::shared_ptr<Presence> presence(new Presence()); + presence->setShow(static_cast<StatusShow::Type>(profileSettings_->getIntSetting("lastShow", StatusShow::Online))); + presence->setStatus(profileSettings_->getStringSetting("lastStatus")); + statusTracker_->setRequestedPresence(presence); + } else { + /* In case we're in the middle of another login, make sure they don't overlap */ + client_->disconnect(); + } + systemTrayController_->setConnecting(); + if (rosterController_) { + rosterController_->getWindow()->setConnecting(); + } + ClientOptions clientOptions = clientOptions_; + bool eagle = settings_->getSetting(SettingConstants::FORGET_PASSWORDS); + clientOptions.forgetPassword = eagle; + clientOptions.useTLS = eagle ? ClientOptions::RequireTLS : clientOptions_.useTLS; + client_->connect(clientOptions); } void MainController::handleDisconnected(const boost::optional<ClientError>& error) { - if (rosterController_) { - rosterController_->getWindow()->setStreamEncryptionStatus(false); - } - if (adHocManager_) { - adHocManager_->setOnline(false); - } - if (settings_->getSetting(SettingConstants::FORGET_PASSWORDS)) { - purgeCachedCredentials(); - } - if (quitRequested_) { - resetClient(); - loginWindow_->quit(); - } - else if (error) { - std::string message; - std::string certificateErrorMessage; - bool forceSignout = false; - switch(error->getType()) { - case ClientError::UnknownError: message = QT_TRANSLATE_NOOP("", "Unknown Error"); break; - case ClientError::DomainNameResolveError: message = QT_TRANSLATE_NOOP("", "Unable to find server"); break; - case ClientError::ConnectionError: message = QT_TRANSLATE_NOOP("", "Error connecting to server"); break; - case ClientError::ConnectionReadError: message = QT_TRANSLATE_NOOP("", "Error while receiving server data"); break; - case ClientError::ConnectionWriteError: message = QT_TRANSLATE_NOOP("", "Error while sending data to the server"); break; - case ClientError::XMLError: message = QT_TRANSLATE_NOOP("", "Error parsing server data"); break; - case ClientError::AuthenticationFailedError: message = QT_TRANSLATE_NOOP("", "Login/password invalid"); break; - case ClientError::CompressionFailedError: message = QT_TRANSLATE_NOOP("", "Error while compressing stream"); break; - case ClientError::ServerVerificationFailedError: message = QT_TRANSLATE_NOOP("", "Server verification failed"); break; - case ClientError::NoSupportedAuthMechanismsError: message = QT_TRANSLATE_NOOP("", "Authentication mechanisms not supported"); break; - case ClientError::UnexpectedElementError: message = QT_TRANSLATE_NOOP("", "Unexpected response"); break; - case ClientError::ResourceBindError: message = QT_TRANSLATE_NOOP("", "Error binding resource"); break; - case ClientError::SessionStartError: message = QT_TRANSLATE_NOOP("", "Error starting session"); break; - case ClientError::StreamError: message = QT_TRANSLATE_NOOP("", "Stream error"); break; - case ClientError::TLSError: message = QT_TRANSLATE_NOOP("", "Encryption error"); break; - case ClientError::ClientCertificateLoadError: message = QT_TRANSLATE_NOOP("", "Error loading certificate (Invalid file or password?)"); break; - case ClientError::ClientCertificateError: message = QT_TRANSLATE_NOOP("", "Certificate not authorized"); break; - case ClientError::CertificateCardRemoved: message = QT_TRANSLATE_NOOP("", "Certificate card removed"); forceSignout = true; break; - - case ClientError::UnknownCertificateError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Unknown certificate"); break; - case ClientError::CertificateExpiredError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate has expired"); break; - case ClientError::CertificateNotYetValidError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate is not yet valid"); break; - case ClientError::CertificateSelfSignedError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate is self-signed"); break; - case ClientError::CertificateRejectedError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate has been rejected"); break; - case ClientError::CertificateUntrustedError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate is not trusted"); break; - case ClientError::InvalidCertificatePurposeError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate cannot be used for encrypting your connection"); break; - case ClientError::CertificatePathLengthExceededError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate path length constraint exceeded"); break; - case ClientError::InvalidCertificateSignatureError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Invalid certificate signature"); break; - case ClientError::InvalidCAError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Invalid Certificate Authority"); break; - case ClientError::InvalidServerIdentityError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate does not match the host identity"); break; - case ClientError::RevokedError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate has been revoked"); break; - case ClientError::RevocationCheckFailedError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Unable to determine certificate revocation state"); break; - } - bool forceReconnectAfterCertificateTrust = false; - if (!certificateErrorMessage.empty()) { - std::vector<Certificate::ref> certificates = certificateTrustChecker_->getLastCertificateChain(); - if (!certificates.empty() && loginWindow_->askUserToTrustCertificatePermanently(certificateErrorMessage, certificates)) { - certificateStorage_->addCertificate(certificates[0]); - forceReconnectAfterCertificateTrust = true; - } - else { - message = QT_TRANSLATE_NOOP("", "Certificate error"); - } - } - - if (!message.empty() && error->getErrorCode()) { - message = str(format(QT_TRANSLATE_NOOP("", "%1% (%2%)")) % message % error->getErrorCode()->message()); - } - - if (forceReconnectAfterCertificateTrust && settings_->getSetting(SettingConstants::FORGET_PASSWORDS)) { - forceReconnectAfterCertificateTrust = false; - forceSignout = true; - message = QT_TRANSLATE_NOOP("", "Re-enter credentials and retry"); - } - - if (forceReconnectAfterCertificateTrust) { - performLoginFromCachedCredentials(); - } - else if (forceSignout || !rosterController_) { //hasn't been logged in yet or permanent error - signOut(); - loginWindow_->setMessage(message); - loginWindow_->setIsLoggingIn(false); - } else { - logout(); - if (settings_->getSetting(SettingConstants::FORGET_PASSWORDS)) { - message = str(format(QT_TRANSLATE_NOOP("", "Disconnected from %1%: %2%. To reconnect, Sign Out and provide your password again.")) % jid_.getDomain() % message); - } else { - if (!offlineRequested_) { - setReconnectTimer(); - } - if (lastDisconnectError_) { - message = str(format(QT_TRANSLATE_NOOP("", "Reconnect to %1% failed: %2%. Will retry in %3% seconds.")) % jid_.getDomain() % message % boost::lexical_cast<std::string>(timeBeforeNextReconnect_)); - lastDisconnectError_->conclude(); - } else { - message = str(format(QT_TRANSLATE_NOOP("", "Disconnected from %1%: %2%.")) % jid_.getDomain() % message); - } - lastDisconnectError_ = boost::make_shared<ErrorEvent>(JID(jid_.getDomain()), message); - eventController_->handleIncomingEvent(lastDisconnectError_); - } - } - } - else if (!rosterController_) { //hasn't been logged in yet - loginWindow_->setIsLoggingIn(false); - } + if (rosterController_) { + rosterController_->getWindow()->setStreamEncryptionStatus(false); + } + if (adHocManager_) { + adHocManager_->setOnline(false); + } + if (settings_->getSetting(SettingConstants::FORGET_PASSWORDS)) { + purgeCachedCredentials(); + } + if (quitRequested_) { + resetClient(); + loginWindow_->quit(); + } + else if (error) { + std::string message; + std::string certificateErrorMessage; + bool forceSignout = false; + switch(error->getType()) { + case ClientError::UnknownError: message = QT_TRANSLATE_NOOP("", "Unknown Error"); break; + case ClientError::DomainNameResolveError: message = QT_TRANSLATE_NOOP("", "Unable to find server"); break; + case ClientError::ConnectionError: message = QT_TRANSLATE_NOOP("", "Error connecting to server"); break; + case ClientError::ConnectionReadError: message = QT_TRANSLATE_NOOP("", "Error while receiving server data"); break; + case ClientError::ConnectionWriteError: message = QT_TRANSLATE_NOOP("", "Error while sending data to the server"); break; + case ClientError::XMLError: message = QT_TRANSLATE_NOOP("", "Error parsing server data"); break; + case ClientError::AuthenticationFailedError: message = QT_TRANSLATE_NOOP("", "Login/password invalid"); break; + case ClientError::CompressionFailedError: message = QT_TRANSLATE_NOOP("", "Error while compressing stream"); break; + case ClientError::ServerVerificationFailedError: message = QT_TRANSLATE_NOOP("", "Server verification failed"); break; + case ClientError::NoSupportedAuthMechanismsError: message = QT_TRANSLATE_NOOP("", "Authentication mechanisms not supported"); break; + case ClientError::UnexpectedElementError: message = QT_TRANSLATE_NOOP("", "Unexpected response"); break; + case ClientError::ResourceBindError: message = QT_TRANSLATE_NOOP("", "Error binding resource"); break; + case ClientError::SessionStartError: message = QT_TRANSLATE_NOOP("", "Error starting session"); break; + case ClientError::StreamError: message = QT_TRANSLATE_NOOP("", "Stream error"); break; + case ClientError::TLSError: message = QT_TRANSLATE_NOOP("", "Encryption error"); break; + case ClientError::ClientCertificateLoadError: message = QT_TRANSLATE_NOOP("", "Error loading certificate (Invalid file or password?)"); break; + case ClientError::ClientCertificateError: message = QT_TRANSLATE_NOOP("", "Certificate not authorized"); break; + case ClientError::CertificateCardRemoved: message = QT_TRANSLATE_NOOP("", "Certificate card removed"); forceSignout = true; break; + + case ClientError::UnknownCertificateError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Unknown certificate"); break; + case ClientError::CertificateExpiredError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate has expired"); break; + case ClientError::CertificateNotYetValidError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate is not yet valid"); break; + case ClientError::CertificateSelfSignedError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate is self-signed"); break; + case ClientError::CertificateRejectedError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate has been rejected"); break; + case ClientError::CertificateUntrustedError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate is not trusted"); break; + case ClientError::InvalidCertificatePurposeError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate cannot be used for encrypting your connection"); break; + case ClientError::CertificatePathLengthExceededError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate path length constraint exceeded"); break; + case ClientError::InvalidCertificateSignatureError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Invalid certificate signature"); break; + case ClientError::InvalidCAError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Invalid Certificate Authority"); break; + case ClientError::InvalidServerIdentityError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate does not match the host identity"); break; + case ClientError::RevokedError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate has been revoked"); break; + case ClientError::RevocationCheckFailedError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Unable to determine certificate revocation state"); break; + } + bool forceReconnectAfterCertificateTrust = false; + if (!certificateErrorMessage.empty()) { + std::vector<Certificate::ref> certificates = certificateTrustChecker_->getLastCertificateChain(); + if (!certificates.empty() && loginWindow_->askUserToTrustCertificatePermanently(certificateErrorMessage, certificates)) { + certificateStorage_->addCertificate(certificates[0]); + forceReconnectAfterCertificateTrust = true; + } + else { + message = QT_TRANSLATE_NOOP("", "Certificate error"); + } + } + + if (!message.empty() && error->getErrorCode()) { + message = str(format(QT_TRANSLATE_NOOP("", "%1% (%2%)")) % message % error->getErrorCode()->message()); + } + + if (forceReconnectAfterCertificateTrust && settings_->getSetting(SettingConstants::FORGET_PASSWORDS)) { + forceReconnectAfterCertificateTrust = false; + forceSignout = true; + message = QT_TRANSLATE_NOOP("", "Re-enter credentials and retry"); + } + + if (forceReconnectAfterCertificateTrust) { + performLoginFromCachedCredentials(); + } + else if (forceSignout || !rosterController_) { //hasn't been logged in yet or permanent error + signOut(); + loginWindow_->setMessage(message); + loginWindow_->setIsLoggingIn(false); + } else { + logout(); + if (settings_->getSetting(SettingConstants::FORGET_PASSWORDS)) { + message = str(format(QT_TRANSLATE_NOOP("", "Disconnected from %1%: %2%. To reconnect, Sign Out and provide your password again.")) % jid_.getDomain() % message); + } else { + if (!offlineRequested_) { + setReconnectTimer(); + } + if (lastDisconnectError_) { + message = str(format(QT_TRANSLATE_NOOP("", "Reconnect to %1% failed: %2%. Will retry in %3% seconds.")) % jid_.getDomain() % message % boost::lexical_cast<std::string>(timeBeforeNextReconnect_)); + lastDisconnectError_->conclude(); + } else { + message = str(format(QT_TRANSLATE_NOOP("", "Disconnected from %1%: %2%.")) % jid_.getDomain() % message); + } + lastDisconnectError_ = boost::make_shared<ErrorEvent>(JID(jid_.getDomain()), message); + eventController_->handleIncomingEvent(lastDisconnectError_); + } + } + } + else if (!rosterController_) { //hasn't been logged in yet + loginWindow_->setIsLoggingIn(false); + } } void MainController::setReconnectTimer() { - if (timeBeforeNextReconnect_ < 0) { - timeBeforeNextReconnect_ = 1; - } else { - timeBeforeNextReconnect_ = timeBeforeNextReconnect_ >= 150 ? 300 : timeBeforeNextReconnect_ * 2; // Randomly selected by roll of a die, as required by 3920bis - } - if (reconnectTimer_) { - reconnectTimer_->stop(); - } - reconnectTimer_ = networkFactories_->getTimerFactory()->createTimer(timeBeforeNextReconnect_ * 1000); - reconnectTimer_->onTick.connect(boost::bind(&MainController::reconnectAfterError, this)); - reconnectTimer_->start(); + if (timeBeforeNextReconnect_ < 0) { + timeBeforeNextReconnect_ = 1; + } else { + timeBeforeNextReconnect_ = timeBeforeNextReconnect_ >= 150 ? 300 : timeBeforeNextReconnect_ * 2; // Randomly selected by roll of a die, as required by 3920bis + } + if (reconnectTimer_) { + reconnectTimer_->stop(); + } + reconnectTimer_ = networkFactories_->getTimerFactory()->createTimer(timeBeforeNextReconnect_ * 1000); + reconnectTimer_->onTick.connect(boost::bind(&MainController::reconnectAfterError, this)); + reconnectTimer_->start(); } void MainController::handleCancelLoginRequest() { - signOut(); + signOut(); } void MainController::signOut() { - if (settings_->getSetting(SettingConstants::FORGET_PASSWORDS)) { - purgeCachedCredentials(); - } - eventController_->clear(); - logout(); - loginWindow_->loggedOut(); - resetClient(); + if (settings_->getSetting(SettingConstants::FORGET_PASSWORDS)) { + purgeCachedCredentials(); + } + eventController_->clear(); + logout(); + loginWindow_->loggedOut(); + resetClient(); } void MainController::logout() { - if (settings_->getSetting(SettingConstants::FORGET_PASSWORDS)) { - purgeCachedCredentials(); - } - systemTrayController_->setMyStatusType(StatusShow::None); - if (clientInitialized_ /*&& client_->isAvailable()*/) { - client_->disconnect(); - } - if (rosterController_ && myStatusLooksOnline_) { - rosterController_->getWindow()->setMyStatusType(StatusShow::None); - rosterController_->getWindow()->setMyStatusText(""); - myStatusLooksOnline_ = false; - } - setManagersOffline(); + if (settings_->getSetting(SettingConstants::FORGET_PASSWORDS)) { + purgeCachedCredentials(); + } + systemTrayController_->setMyStatusType(StatusShow::None); + if (clientInitialized_ /*&& client_->isAvailable()*/) { + client_->disconnect(); + } + if (rosterController_ && myStatusLooksOnline_) { + rosterController_->getWindow()->setMyStatusType(StatusShow::None); + rosterController_->getWindow()->setMyStatusText(""); + myStatusLooksOnline_ = false; + } + setManagersOffline(); } void MainController::setManagersOffline() { - if (chatsManager_) { - chatsManager_->setOnline(false); - } - if (rosterController_) { - rosterController_->setEnabled(false); - } - if (profileController_) { - profileController_->setAvailable(false); - } - if (contactEditController_) { - contactEditController_->setAvailable(false); - } + if (chatsManager_) { + chatsManager_->setOnline(false); + } + if (rosterController_) { + rosterController_->setEnabled(false); + } + if (profileController_) { + profileController_->setAvailable(false); + } + if (contactEditController_) { + contactEditController_->setAvailable(false); + } } void MainController::handleServerDiscoInfoResponse(boost::shared_ptr<DiscoInfo> info, ErrorPayload::ref error) { - if (!error) { - chatsManager_->setServerDiscoInfo(info); - adHocManager_->setServerDiscoInfo(info); - if (info->hasFeature(DiscoInfo::BlockingCommandFeature)) { - rosterController_->getWindow()->setBlockingCommandAvailable(true); - rosterController_->initBlockingCommand(); - } - } + if (!error) { + chatsManager_->setServerDiscoInfo(info); + adHocManager_->setServerDiscoInfo(info); + if (info->hasFeature(DiscoInfo::BlockingCommandFeature)) { + rosterController_->getWindow()->setBlockingCommandAvailable(true); + rosterController_->initBlockingCommand(); + } + } } void MainController::handleVCardReceived(const JID& jid, VCard::ref vCard) { - if (!jid.equals(jid_, JID::WithoutResource) || !vCard) { - return; - } - std::string hash; - if (!vCard->getPhoto().empty()) { - hash = Hexify::hexify(networkFactories_->getCryptoProvider()->getSHA1Hash(vCard->getPhoto())); - } - if (hash != vCardPhotoHash_) { - vCardPhotoHash_ = hash; - if (client_ && client_->isAvailable()) { - sendPresence(statusTracker_->getNextPresence()); - } - } + if (!jid.equals(jid_, JID::WithoutResource) || !vCard) { + return; + } + std::string hash; + if (!vCard->getPhoto().empty()) { + hash = Hexify::hexify(networkFactories_->getCryptoProvider()->getSHA1Hash(vCard->getPhoto())); + } + if (hash != vCardPhotoHash_) { + vCardPhotoHash_ = hash; + if (client_ && client_->isAvailable()) { + sendPresence(statusTracker_->getNextPresence()); + } + } } void MainController::handleNotificationClicked(const JID& jid) { - assert(chatsManager_); - if (clientInitialized_) { - if (client_->getMUCRegistry()->isMUC(jid)) { - uiEventStream_->send(boost::make_shared<JoinMUCUIEvent>(jid)); - } - else { - uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(jid))); - } - } + assert(chatsManager_); + if (clientInitialized_) { + if (client_->getMUCRegistry()->isMUC(jid)) { + uiEventStream_->send(boost::make_shared<JoinMUCUIEvent>(jid)); + } + else { + uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(jid))); + } + } } void MainController::handleQuitRequest() { - if (client_ && client_->isActive()) { - quitRequested_ = true; - client_->disconnect(); - } - else { - resetClient(); - loginWindow_->quit(); - } + if (client_ && client_->isActive()) { + quitRequested_ = true; + client_->disconnect(); + } + else { + resetClient(); + loginWindow_->quit(); + } } #define SERIALIZE_BOOL(option) result += options.option ? "1" : "0"; result += ","; @@ -851,34 +851,34 @@ void MainController::handleQuitRequest() { #define SERIALIZE_URL(option) SERIALIZE_STRING(option.toString()) std::string MainController::serializeClientOptions(const ClientOptions& options) { - std::string result; - SERIALIZE_BOOL(useStreamCompression); - switch (options.useTLS) { - case ClientOptions::NeverUseTLS: result += "1";break; - case ClientOptions::UseTLSWhenAvailable: result += "2";break; - case ClientOptions::RequireTLS: result += "3";break; - } - result += ","; - SERIALIZE_BOOL(allowPLAINWithoutTLS); - SERIALIZE_BOOL(useStreamResumption); - SERIALIZE_BOOL(useAcks); - SERIALIZE_STRING(manualHostname); - SERIALIZE_INT(manualPort); - switch (options.proxyType) { - case ClientOptions::NoProxy: result += "1";break; - case ClientOptions::SystemConfiguredProxy: result += "2";break; - case ClientOptions::SOCKS5Proxy: result += "3";break; - case ClientOptions::HTTPConnectProxy: result += "4";break; - } - result += ","; - SERIALIZE_STRING(manualProxyHostname); - SERIALIZE_INT(manualProxyPort); - SERIALIZE_URL(boshURL); - SERIALIZE_URL(boshHTTPConnectProxyURL); - SERIALIZE_SAFE_STRING(boshHTTPConnectProxyAuthID); - SERIALIZE_SAFE_STRING(boshHTTPConnectProxyAuthPassword); - SERIALIZE_BOOL(tlsOptions.schannelTLS1_0Workaround); - return result; + std::string result; + SERIALIZE_BOOL(useStreamCompression); + switch (options.useTLS) { + case ClientOptions::NeverUseTLS: result += "1";break; + case ClientOptions::UseTLSWhenAvailable: result += "2";break; + case ClientOptions::RequireTLS: result += "3";break; + } + result += ","; + SERIALIZE_BOOL(allowPLAINWithoutTLS); + SERIALIZE_BOOL(useStreamResumption); + SERIALIZE_BOOL(useAcks); + SERIALIZE_STRING(manualHostname); + SERIALIZE_INT(manualPort); + switch (options.proxyType) { + case ClientOptions::NoProxy: result += "1";break; + case ClientOptions::SystemConfiguredProxy: result += "2";break; + case ClientOptions::SOCKS5Proxy: result += "3";break; + case ClientOptions::HTTPConnectProxy: result += "4";break; + } + result += ","; + SERIALIZE_STRING(manualProxyHostname); + SERIALIZE_INT(manualProxyPort); + SERIALIZE_URL(boshURL); + SERIALIZE_URL(boshHTTPConnectProxyURL); + SERIALIZE_SAFE_STRING(boshHTTPConnectProxyAuthID); + SERIALIZE_SAFE_STRING(boshHTTPConnectProxyAuthPassword); + SERIALIZE_BOOL(tlsOptions.schannelTLS1_0Workaround); + return result; } #define CHECK_PARSE_LENGTH if (i >= segments.size()) {return result;} @@ -893,41 +893,41 @@ std::string MainController::serializeClientOptions(const ClientOptions& options) ClientOptions MainController::parseClientOptions(const std::string& optionString) { - ClientOptions result; - size_t i = 0; - int intVal = 0; - std::string stringVal; - std::vector<std::string> segments = String::split(optionString, ','); - - PARSE_BOOL(useStreamCompression, 1); - PARSE_INT_RAW(-1); - switch (intVal) { - case 1: result.useTLS = ClientOptions::NeverUseTLS;break; - case 2: result.useTLS = ClientOptions::UseTLSWhenAvailable;break; - case 3: result.useTLS = ClientOptions::RequireTLS;break; - default:; - } - PARSE_BOOL(allowPLAINWithoutTLS, 0); - PARSE_BOOL(useStreamResumption, 0); - PARSE_BOOL(useAcks, 1); - PARSE_STRING(manualHostname); - PARSE_INT(manualPort, -1); - PARSE_INT_RAW(-1); - switch (intVal) { - case 1: result.proxyType = ClientOptions::NoProxy;break; - case 2: result.proxyType = ClientOptions::SystemConfiguredProxy;break; - case 3: result.proxyType = ClientOptions::SOCKS5Proxy;break; - case 4: result.proxyType = ClientOptions::HTTPConnectProxy;break; - } - PARSE_STRING(manualProxyHostname); - PARSE_INT(manualProxyPort, -1); - PARSE_URL(boshURL); - PARSE_URL(boshHTTPConnectProxyURL); - PARSE_SAFE_STRING(boshHTTPConnectProxyAuthID); - PARSE_SAFE_STRING(boshHTTPConnectProxyAuthPassword); - PARSE_BOOL(tlsOptions.schannelTLS1_0Workaround, false); - - return result; + ClientOptions result; + size_t i = 0; + int intVal = 0; + std::string stringVal; + std::vector<std::string> segments = String::split(optionString, ','); + + PARSE_BOOL(useStreamCompression, 1); + PARSE_INT_RAW(-1); + switch (intVal) { + case 1: result.useTLS = ClientOptions::NeverUseTLS;break; + case 2: result.useTLS = ClientOptions::UseTLSWhenAvailable;break; + case 3: result.useTLS = ClientOptions::RequireTLS;break; + default:; + } + PARSE_BOOL(allowPLAINWithoutTLS, 0); + PARSE_BOOL(useStreamResumption, 0); + PARSE_BOOL(useAcks, 1); + PARSE_STRING(manualHostname); + PARSE_INT(manualPort, -1); + PARSE_INT_RAW(-1); + switch (intVal) { + case 1: result.proxyType = ClientOptions::NoProxy;break; + case 2: result.proxyType = ClientOptions::SystemConfiguredProxy;break; + case 3: result.proxyType = ClientOptions::SOCKS5Proxy;break; + case 4: result.proxyType = ClientOptions::HTTPConnectProxy;break; + } + PARSE_STRING(manualProxyHostname); + PARSE_INT(manualProxyPort, -1); + PARSE_URL(boshURL); + PARSE_URL(boshHTTPConnectProxyURL); + PARSE_SAFE_STRING(boshHTTPConnectProxyAuthID); + PARSE_SAFE_STRING(boshHTTPConnectProxyAuthPassword); + PARSE_BOOL(tlsOptions.schannelTLS1_0Workaround, false); + + return result; } } diff --git a/Swift/Controllers/MainController.h b/Swift/Controllers/MainController.h index e8a915e..ed7765a 100644 --- a/Swift/Controllers/MainController.h +++ b/Swift/Controllers/MainController.h @@ -29,171 +29,171 @@ #include <Swift/Controllers/XMPPEvents/ErrorEvent.h> namespace Swift { - class IdleDetector; - class UIFactory; - class EventLoop; - class Client; - class ChatController; - class ChatsManager; - class CertificateStorageFactory; - class CertificateStorage; - class CertificateStorageTrustChecker; - class EventController; - class MainWindow; - class RosterController; - class LoginWindow; - class EventLoop; - class MUCController; - class Notifier; - class ProfileController; - class ShowProfileController; - class ContactEditController; - class TogglableNotifier; - class PresenceNotifier; - class EventNotifier; - class SystemTray; - class SystemTrayController; - class SoundEventController; - class SoundPlayer; - class XMLConsoleController; - class HistoryViewController; - class HistoryController; - class FileTransferListController; - class UIEventStream; - class EventWindowFactory; - class EventWindowController; - class MUCSearchController; - class UserSearchController; - class StatusTracker; - class Dock; - class Storages; - class StoragesFactory; - class NetworkFactories; - class URIHandler; - class XMPPURIController; - class AdHocManager; - class AdHocCommandWindowFactory; - class FileTransferOverview; - class WhiteboardManager; - class HighlightManager; - class HighlightEditorController; - class BlockListController; - class ContactSuggester; - class ContactsFromXMPPRoster; + class IdleDetector; + class UIFactory; + class EventLoop; + class Client; + class ChatController; + class ChatsManager; + class CertificateStorageFactory; + class CertificateStorage; + class CertificateStorageTrustChecker; + class EventController; + class MainWindow; + class RosterController; + class LoginWindow; + class EventLoop; + class MUCController; + class Notifier; + class ProfileController; + class ShowProfileController; + class ContactEditController; + class TogglableNotifier; + class PresenceNotifier; + class EventNotifier; + class SystemTray; + class SystemTrayController; + class SoundEventController; + class SoundPlayer; + class XMLConsoleController; + class HistoryViewController; + class HistoryController; + class FileTransferListController; + class UIEventStream; + class EventWindowFactory; + class EventWindowController; + class MUCSearchController; + class UserSearchController; + class StatusTracker; + class Dock; + class Storages; + class StoragesFactory; + class NetworkFactories; + class URIHandler; + class XMPPURIController; + class AdHocManager; + class AdHocCommandWindowFactory; + class FileTransferOverview; + class WhiteboardManager; + class HighlightManager; + class HighlightEditorController; + class BlockListController; + class ContactSuggester; + class ContactsFromXMPPRoster; - class MainController { - public: - MainController( - EventLoop* eventLoop, - NetworkFactories* networkFactories, - UIFactory* uiFactories, - SettingsProvider *settings, - SystemTray* systemTray, - SoundPlayer* soundPlayer, - StoragesFactory* storagesFactory, - CertificateStorageFactory* certificateStorageFactory, - Dock* dock, - Notifier* notifier, - URIHandler* uriHandler, - IdleDetector* idleDetector, - const std::map<std::string, std::string>& emoticons, - bool useDelayForLatency); - ~MainController(); + class MainController { + public: + MainController( + EventLoop* eventLoop, + NetworkFactories* networkFactories, + UIFactory* uiFactories, + SettingsProvider *settings, + SystemTray* systemTray, + SoundPlayer* soundPlayer, + StoragesFactory* storagesFactory, + CertificateStorageFactory* certificateStorageFactory, + Dock* dock, + Notifier* notifier, + URIHandler* uriHandler, + IdleDetector* idleDetector, + const std::map<std::string, std::string>& emoticons, + bool useDelayForLatency); + ~MainController(); - private: - void resetClient(); - void handleConnected(); - void handleLoginRequest(const std::string& username, const std::string& password, const std::string& certificatePath, CertificateWithKey::ref certificate, const ClientOptions& options, bool remember, bool loginAutomatically); - void handleCancelLoginRequest(); - void handleQuitRequest(); - void handleChangeStatusRequest(StatusShow::Type show, const std::string &statusText); - void handleDisconnected(const boost::optional<ClientError>& error); - void handleServerDiscoInfoResponse(boost::shared_ptr<DiscoInfo>, ErrorPayload::ref); - void handleEventQueueLengthChange(int count); - void handleVCardReceived(const JID& j, VCard::ref vCard); - void handleSettingChanged(const std::string& settingPath); - void handlePurgeSavedLoginRequest(const std::string& username); - void sendPresence(boost::shared_ptr<Presence> presence); - void handleInputIdleChanged(bool); - void handleShowCertificateRequest(); - void logout(); - void signOut(); - void setReconnectTimer(); - void resetPendingReconnects(); - void resetCurrentError(); - - void performLoginFromCachedCredentials(); - void reconnectAfterError(); - void setManagersOffline(); - void handleNotificationClicked(const JID& jid); - void handleForceQuit(); - void purgeCachedCredentials(); - std::string serializeClientOptions(const ClientOptions& options); - ClientOptions parseClientOptions(const std::string& optionString); + private: + void resetClient(); + void handleConnected(); + void handleLoginRequest(const std::string& username, const std::string& password, const std::string& certificatePath, CertificateWithKey::ref certificate, const ClientOptions& options, bool remember, bool loginAutomatically); + void handleCancelLoginRequest(); + void handleQuitRequest(); + void handleChangeStatusRequest(StatusShow::Type show, const std::string &statusText); + void handleDisconnected(const boost::optional<ClientError>& error); + void handleServerDiscoInfoResponse(boost::shared_ptr<DiscoInfo>, ErrorPayload::ref); + void handleEventQueueLengthChange(int count); + void handleVCardReceived(const JID& j, VCard::ref vCard); + void handleSettingChanged(const std::string& settingPath); + void handlePurgeSavedLoginRequest(const std::string& username); + void sendPresence(boost::shared_ptr<Presence> presence); + void handleInputIdleChanged(bool); + void handleShowCertificateRequest(); + void logout(); + void signOut(); + void setReconnectTimer(); + void resetPendingReconnects(); + void resetCurrentError(); - private: - EventLoop* eventLoop_; - NetworkFactories* networkFactories_; - UIFactory* uiFactory_; - StoragesFactory* storagesFactory_; - Storages* storages_; - CertificateStorageFactory* certificateStorageFactory_; - CertificateStorage* certificateStorage_; - CertificateStorageTrustChecker* certificateTrustChecker_; - bool clientInitialized_; - boost::shared_ptr<Client> client_; - SettingsProvider *settings_; - ProfileSettingsProvider* profileSettings_; - Dock* dock_; - URIHandler* uriHandler_; - IdleDetector* idleDetector_; - TogglableNotifier* notifier_; - PresenceNotifier* presenceNotifier_; - EventNotifier* eventNotifier_; - RosterController* rosterController_; - EventController* eventController_; - EventWindowController* eventWindowController_; - AdHocManager* adHocManager_; - LoginWindow* loginWindow_; - UIEventStream* uiEventStream_; - XMLConsoleController* xmlConsoleController_; - HistoryViewController* historyViewController_; - HistoryController* historyController_; - FileTransferListController* fileTransferListController_; - BlockListController* blockListController_; - ChatsManager* chatsManager_; - ProfileController* profileController_; - ShowProfileController* showProfileController_; - ContactEditController* contactEditController_; - ContactsFromXMPPRoster* contactsFromRosterProvider_; - ContactSuggester* contactSuggesterWithoutRoster_; - ContactSuggester* contactSuggesterWithRoster_; - JID jid_; - JID boundJID_; - SystemTrayController* systemTrayController_; - SoundEventController* soundEventController_; - XMPPURIController* xmppURIController_; - std::string vCardPhotoHash_; - std::string password_; - CertificateWithKey::ref certificate_; - ClientOptions clientOptions_; - boost::shared_ptr<ErrorEvent> lastDisconnectError_; - bool useDelayForLatency_; - UserSearchController* userSearchControllerChat_; - UserSearchController* userSearchControllerAdd_; - UserSearchController* userSearchControllerInvite_; - int timeBeforeNextReconnect_; - Timer::ref reconnectTimer_; - StatusTracker* statusTracker_; - bool myStatusLooksOnline_; - bool quitRequested_; - bool offlineRequested_; - static const int SecondsToWaitBeforeForceQuitting; - FileTransferOverview* ftOverview_; - WhiteboardManager* whiteboardManager_; - HighlightManager* highlightManager_; - HighlightEditorController* highlightEditorController_; - std::map<std::string, std::string> emoticons_; - }; + void performLoginFromCachedCredentials(); + void reconnectAfterError(); + void setManagersOffline(); + void handleNotificationClicked(const JID& jid); + void handleForceQuit(); + void purgeCachedCredentials(); + std::string serializeClientOptions(const ClientOptions& options); + ClientOptions parseClientOptions(const std::string& optionString); + + private: + EventLoop* eventLoop_; + NetworkFactories* networkFactories_; + UIFactory* uiFactory_; + StoragesFactory* storagesFactory_; + Storages* storages_; + CertificateStorageFactory* certificateStorageFactory_; + CertificateStorage* certificateStorage_; + CertificateStorageTrustChecker* certificateTrustChecker_; + bool clientInitialized_; + boost::shared_ptr<Client> client_; + SettingsProvider *settings_; + ProfileSettingsProvider* profileSettings_; + Dock* dock_; + URIHandler* uriHandler_; + IdleDetector* idleDetector_; + TogglableNotifier* notifier_; + PresenceNotifier* presenceNotifier_; + EventNotifier* eventNotifier_; + RosterController* rosterController_; + EventController* eventController_; + EventWindowController* eventWindowController_; + AdHocManager* adHocManager_; + LoginWindow* loginWindow_; + UIEventStream* uiEventStream_; + XMLConsoleController* xmlConsoleController_; + HistoryViewController* historyViewController_; + HistoryController* historyController_; + FileTransferListController* fileTransferListController_; + BlockListController* blockListController_; + ChatsManager* chatsManager_; + ProfileController* profileController_; + ShowProfileController* showProfileController_; + ContactEditController* contactEditController_; + ContactsFromXMPPRoster* contactsFromRosterProvider_; + ContactSuggester* contactSuggesterWithoutRoster_; + ContactSuggester* contactSuggesterWithRoster_; + JID jid_; + JID boundJID_; + SystemTrayController* systemTrayController_; + SoundEventController* soundEventController_; + XMPPURIController* xmppURIController_; + std::string vCardPhotoHash_; + std::string password_; + CertificateWithKey::ref certificate_; + ClientOptions clientOptions_; + boost::shared_ptr<ErrorEvent> lastDisconnectError_; + bool useDelayForLatency_; + UserSearchController* userSearchControllerChat_; + UserSearchController* userSearchControllerAdd_; + UserSearchController* userSearchControllerInvite_; + int timeBeforeNextReconnect_; + Timer::ref reconnectTimer_; + StatusTracker* statusTracker_; + bool myStatusLooksOnline_; + bool quitRequested_; + bool offlineRequested_; + static const int SecondsToWaitBeforeForceQuitting; + FileTransferOverview* ftOverview_; + WhiteboardManager* whiteboardManager_; + HighlightManager* highlightManager_; + HighlightEditorController* highlightEditorController_; + std::map<std::string, std::string> emoticons_; + }; } diff --git a/Swift/Controllers/PresenceNotifier.cpp b/Swift/Controllers/PresenceNotifier.cpp index b579187..c000107 100644 --- a/Swift/Controllers/PresenceNotifier.cpp +++ b/Swift/Controllers/PresenceNotifier.cpp @@ -21,117 +21,117 @@ namespace Swift { PresenceNotifier::PresenceNotifier(StanzaChannel* stanzaChannel, Notifier* notifier, const MUCRegistry* mucRegistry, AvatarManager* avatarManager, NickResolver* nickResolver, const PresenceOracle* presenceOracle, TimerFactory* timerFactory) : stanzaChannel(stanzaChannel), notifier(notifier), mucRegistry(mucRegistry), avatarManager(avatarManager), nickResolver(nickResolver), presenceOracle(presenceOracle), timerFactory(timerFactory) { - justInitialized = true; - inQuietPeriod = false; - stanzaChannel->onPresenceReceived.connect(boost::bind(&PresenceNotifier::handlePresenceReceived, this, _1)); - stanzaChannel->onAvailableChanged.connect(boost::bind(&PresenceNotifier::handleStanzaChannelAvailableChanged, this, _1)); - setInitialQuietPeriodMS(3000); + justInitialized = true; + inQuietPeriod = false; + stanzaChannel->onPresenceReceived.connect(boost::bind(&PresenceNotifier::handlePresenceReceived, this, _1)); + stanzaChannel->onAvailableChanged.connect(boost::bind(&PresenceNotifier::handleStanzaChannelAvailableChanged, this, _1)); + setInitialQuietPeriodMS(3000); } PresenceNotifier::~PresenceNotifier() { - if (timer) { - timer->stop(); - timer->onTick.disconnect(boost::bind(&PresenceNotifier::handleTimerTick, this)); - timer.reset(); - } - stanzaChannel->onAvailableChanged.disconnect(boost::bind(&PresenceNotifier::handleStanzaChannelAvailableChanged, this, _1)); - stanzaChannel->onPresenceReceived.disconnect(boost::bind(&PresenceNotifier::handlePresenceReceived, this, _1)); + if (timer) { + timer->stop(); + timer->onTick.disconnect(boost::bind(&PresenceNotifier::handleTimerTick, this)); + timer.reset(); + } + stanzaChannel->onAvailableChanged.disconnect(boost::bind(&PresenceNotifier::handleStanzaChannelAvailableChanged, this, _1)); + stanzaChannel->onPresenceReceived.disconnect(boost::bind(&PresenceNotifier::handlePresenceReceived, this, _1)); } void PresenceNotifier::handlePresenceReceived(boost::shared_ptr<Presence> presence) { - JID from = presence->getFrom(); - - if (mucRegistry->isMUC(from.toBare())) { - return; - } - - if (justInitialized) { - justInitialized = false; - if (timer) { - inQuietPeriod = true; - } - } - - if (inQuietPeriod) { - timer->stop(); - timer->start(); - return; - } - - std::set<JID>::iterator i = availableUsers.find(from); - if (presence->isAvailable()) { - if (i != availableUsers.end()) { - showNotification(from, Notifier::ContactStatusChange); - } - else { - showNotification(from, Notifier::ContactAvailable); - availableUsers.insert(from); - } - } - else { - if (i != availableUsers.end()) { - showNotification(from, Notifier::ContactUnavailable); - availableUsers.erase(i); - } - } + JID from = presence->getFrom(); + + if (mucRegistry->isMUC(from.toBare())) { + return; + } + + if (justInitialized) { + justInitialized = false; + if (timer) { + inQuietPeriod = true; + } + } + + if (inQuietPeriod) { + timer->stop(); + timer->start(); + return; + } + + std::set<JID>::iterator i = availableUsers.find(from); + if (presence->isAvailable()) { + if (i != availableUsers.end()) { + showNotification(from, Notifier::ContactStatusChange); + } + else { + showNotification(from, Notifier::ContactAvailable); + availableUsers.insert(from); + } + } + else { + if (i != availableUsers.end()) { + showNotification(from, Notifier::ContactUnavailable); + availableUsers.erase(i); + } + } } void PresenceNotifier::handleStanzaChannelAvailableChanged(bool available) { - if (available) { - availableUsers.clear(); - justInitialized = true; - if (timer) { - timer->stop(); - } - } + if (available) { + availableUsers.clear(); + justInitialized = true; + if (timer) { + timer->stop(); + } + } } void PresenceNotifier::showNotification(const JID& jid, Notifier::Type type) { - std::string name = nickResolver->jidToNick(jid); - std::string title = name + " (" + getStatusType(jid) + ")"; - std::string message = getStatusMessage(jid); - notifier->showMessage(type, title, message, avatarManager->getAvatarPath(jid), boost::bind(&PresenceNotifier::handleNotificationActivated, this, jid)); + std::string name = nickResolver->jidToNick(jid); + std::string title = name + " (" + getStatusType(jid) + ")"; + std::string message = getStatusMessage(jid); + notifier->showMessage(type, title, message, avatarManager->getAvatarPath(jid), boost::bind(&PresenceNotifier::handleNotificationActivated, this, jid)); } void PresenceNotifier::handleNotificationActivated(JID jid) { - onNotificationActivated(jid); + onNotificationActivated(jid); } std::string PresenceNotifier::getStatusType(const JID& jid) const { - Presence::ref presence = presenceOracle->getLastPresence(jid); - if (presence) { - return statusShowTypeToFriendlyName(presence->getShow()); - } - else { - return "Unavailable"; - } + Presence::ref presence = presenceOracle->getLastPresence(jid); + if (presence) { + return statusShowTypeToFriendlyName(presence->getShow()); + } + else { + return "Unavailable"; + } } std::string PresenceNotifier::getStatusMessage(const JID& jid) const { - Presence::ref presence = presenceOracle->getLastPresence(jid); - if (presence) { - return presence->getStatus(); - } - else { - return std::string(); - } + Presence::ref presence = presenceOracle->getLastPresence(jid); + if (presence) { + return presence->getStatus(); + } + else { + return std::string(); + } } void PresenceNotifier::setInitialQuietPeriodMS(int ms) { - if (timer) { - timer->stop(); - timer->onTick.disconnect(boost::bind(&PresenceNotifier::handleTimerTick, this)); - timer.reset(); - } - if (ms > 0) { - timer = timerFactory->createTimer(ms); - timer->onTick.connect(boost::bind(&PresenceNotifier::handleTimerTick, this)); - } + if (timer) { + timer->stop(); + timer->onTick.disconnect(boost::bind(&PresenceNotifier::handleTimerTick, this)); + timer.reset(); + } + if (ms > 0) { + timer = timerFactory->createTimer(ms); + timer->onTick.connect(boost::bind(&PresenceNotifier::handleTimerTick, this)); + } } void PresenceNotifier::handleTimerTick() { - inQuietPeriod = false; - timer->stop(); + inQuietPeriod = false; + timer->stop(); } diff --git a/Swift/Controllers/PresenceNotifier.h b/Swift/Controllers/PresenceNotifier.h index b02f8a2..3d498bd 100644 --- a/Swift/Controllers/PresenceNotifier.h +++ b/Swift/Controllers/PresenceNotifier.h @@ -19,44 +19,44 @@ #include <SwifTools/Notifier/Notifier.h> namespace Swift { - class TimerFactory; - class StanzaChannel; - class MUCRegistry; - class NickResolver; - class PresenceOracle; - - class PresenceNotifier { - public: - PresenceNotifier(StanzaChannel* stanzaChannel, Notifier* notifier, const MUCRegistry* mucRegistry, AvatarManager* avatarManager, NickResolver* nickResolver, const PresenceOracle* presenceOracle, TimerFactory* timerFactory); - ~PresenceNotifier(); - - void setInitialQuietPeriodMS(int ms); - - boost::signal<void (const JID&)> onNotificationActivated; - - private: - void handlePresenceReceived(boost::shared_ptr<Presence>); - void handleStanzaChannelAvailableChanged(bool); - void handleNotificationActivated(JID jid); - void handleTimerTick(); - std::string getStatusType(const JID&) const; - std::string getStatusMessage(const JID&) const; - - private: - void showNotification(const JID& jid, Notifier::Type type); - - private: - StanzaChannel* stanzaChannel; - Notifier* notifier; - const MUCRegistry* mucRegistry; - AvatarManager* avatarManager; - NickResolver* nickResolver; - const PresenceOracle* presenceOracle; - TimerFactory* timerFactory; - boost::shared_ptr<Timer> timer; - bool justInitialized; - bool inQuietPeriod; - std::set<JID> availableUsers; - }; + class TimerFactory; + class StanzaChannel; + class MUCRegistry; + class NickResolver; + class PresenceOracle; + + class PresenceNotifier { + public: + PresenceNotifier(StanzaChannel* stanzaChannel, Notifier* notifier, const MUCRegistry* mucRegistry, AvatarManager* avatarManager, NickResolver* nickResolver, const PresenceOracle* presenceOracle, TimerFactory* timerFactory); + ~PresenceNotifier(); + + void setInitialQuietPeriodMS(int ms); + + boost::signal<void (const JID&)> onNotificationActivated; + + private: + void handlePresenceReceived(boost::shared_ptr<Presence>); + void handleStanzaChannelAvailableChanged(bool); + void handleNotificationActivated(JID jid); + void handleTimerTick(); + std::string getStatusType(const JID&) const; + std::string getStatusMessage(const JID&) const; + + private: + void showNotification(const JID& jid, Notifier::Type type); + + private: + StanzaChannel* stanzaChannel; + Notifier* notifier; + const MUCRegistry* mucRegistry; + AvatarManager* avatarManager; + NickResolver* nickResolver; + const PresenceOracle* presenceOracle; + TimerFactory* timerFactory; + boost::shared_ptr<Timer> timer; + bool justInitialized; + bool inQuietPeriod; + std::set<JID> availableUsers; + }; } diff --git a/Swift/Controllers/PreviousStatusStore.cpp b/Swift/Controllers/PreviousStatusStore.cpp index 6564ab5..4806f9c 100644 --- a/Swift/Controllers/PreviousStatusStore.cpp +++ b/Swift/Controllers/PreviousStatusStore.cpp @@ -19,35 +19,35 @@ PreviousStatusStore::~PreviousStatusStore() { } void PreviousStatusStore::addStatus(StatusShow::Type status, const std::string& message) { - //FIXME: remove old entries - store_.push_back(TypeStringPair(status, message)); + //FIXME: remove old entries + store_.push_back(TypeStringPair(status, message)); } std::vector<TypeStringPair> PreviousStatusStore::exactMatchSuggestions(StatusShow::Type status, const std::string& message) { - std::vector<TypeStringPair> suggestions; - suggestions.push_back(TypeStringPair(status, message)); - return suggestions; + std::vector<TypeStringPair> suggestions; + suggestions.push_back(TypeStringPair(status, message)); + return suggestions; } std::vector<TypeStringPair> PreviousStatusStore::getSuggestions(const std::string& message) { - std::vector<TypeStringPair> suggestions; - foreach (TypeStringPair status, store_) { - if (status.second == message) { - suggestions.clear(); - suggestions.push_back(status); - break; - } else if (status.second.find(message) != std::string::npos) { - suggestions.push_back(status); - } - } - if (suggestions.empty()) { - TypeStringPair suggestion(StatusShow::Online, message); - suggestions.push_back(suggestion); - } - if (suggestions.size() == 1) { - suggestions = exactMatchSuggestions(suggestions[0].first, suggestions[0].second); - } - return suggestions; + std::vector<TypeStringPair> suggestions; + foreach (TypeStringPair status, store_) { + if (status.second == message) { + suggestions.clear(); + suggestions.push_back(status); + break; + } else if (status.second.find(message) != std::string::npos) { + suggestions.push_back(status); + } + } + if (suggestions.empty()) { + TypeStringPair suggestion(StatusShow::Online, message); + suggestions.push_back(suggestion); + } + if (suggestions.size() == 1) { + suggestions = exactMatchSuggestions(suggestions[0].first, suggestions[0].second); + } + return suggestions; } } diff --git a/Swift/Controllers/PreviousStatusStore.h b/Swift/Controllers/PreviousStatusStore.h index 51c2dd9..eb1fb59 100644 --- a/Swift/Controllers/PreviousStatusStore.h +++ b/Swift/Controllers/PreviousStatusStore.h @@ -13,16 +13,16 @@ #include <Swiften/Elements/StatusShow.h> namespace Swift { - typedef std::pair<StatusShow::Type, std::string> TypeStringPair; - class PreviousStatusStore { - public: - PreviousStatusStore(); - ~PreviousStatusStore(); - void addStatus(StatusShow::Type status, const std::string& message); - std::vector<TypeStringPair> getSuggestions(const std::string& message); + typedef std::pair<StatusShow::Type, std::string> TypeStringPair; + class PreviousStatusStore { + public: + PreviousStatusStore(); + ~PreviousStatusStore(); + void addStatus(StatusShow::Type status, const std::string& message); + std::vector<TypeStringPair> getSuggestions(const std::string& message); - private: - std::vector<TypeStringPair> exactMatchSuggestions(StatusShow::Type status, const std::string& message); - std::vector<TypeStringPair> store_; - }; + private: + std::vector<TypeStringPair> exactMatchSuggestions(StatusShow::Type status, const std::string& message); + std::vector<TypeStringPair> store_; + }; } diff --git a/Swift/Controllers/ProfileController.cpp b/Swift/Controllers/ProfileController.cpp index a1aa5f9..756aaff 100644 --- a/Swift/Controllers/ProfileController.cpp +++ b/Swift/Controllers/ProfileController.cpp @@ -18,97 +18,97 @@ namespace Swift { ProfileController::ProfileController(VCardManager* vcardManager, ProfileWindowFactory* profileWindowFactory, UIEventStream* uiEventStream) : vcardManager(vcardManager), profileWindowFactory(profileWindowFactory), uiEventStream(uiEventStream), available(true), profileWindow(NULL), gettingVCard(false) { - uiEventStream->onUIEvent.connect(boost::bind(&ProfileController::handleUIEvent, this, _1)); + uiEventStream->onUIEvent.connect(boost::bind(&ProfileController::handleUIEvent, this, _1)); } ProfileController::~ProfileController() { - if (profileWindow) { - vcardManager->onOwnVCardChanged.disconnect(boost::bind(&ProfileController::handleOwnVCardChanged, this, _1)); - vcardManager->onVCardRetrievalError.disconnect(boost::bind(&ProfileController::handleVCardRetrievalError, this, _1, _2)); - profileWindow->onVCardChangeRequest.disconnect(boost::bind(&ProfileController::handleVCardChangeRequest, this, _1)); - profileWindow->onWindowAboutToBeClosed.disconnect(boost::bind(&ProfileController::handleProfileWindowAboutToBeClosed, this, _1)); - } - uiEventStream->onUIEvent.disconnect(boost::bind(&ProfileController::handleUIEvent, this, _1)); - delete profileWindow; + if (profileWindow) { + vcardManager->onOwnVCardChanged.disconnect(boost::bind(&ProfileController::handleOwnVCardChanged, this, _1)); + vcardManager->onVCardRetrievalError.disconnect(boost::bind(&ProfileController::handleVCardRetrievalError, this, _1, _2)); + profileWindow->onVCardChangeRequest.disconnect(boost::bind(&ProfileController::handleVCardChangeRequest, this, _1)); + profileWindow->onWindowAboutToBeClosed.disconnect(boost::bind(&ProfileController::handleProfileWindowAboutToBeClosed, this, _1)); + } + uiEventStream->onUIEvent.disconnect(boost::bind(&ProfileController::handleUIEvent, this, _1)); + delete profileWindow; } void ProfileController::handleUIEvent(UIEvent::ref event) { - if (!boost::dynamic_pointer_cast<RequestProfileEditorUIEvent>(event)) { - return; - } - - if (!profileWindow) { - profileWindow = profileWindowFactory->createProfileWindow(); - profileWindow->setEditable(true); - profileWindow->onVCardChangeRequest.connect(boost::bind(&ProfileController::handleVCardChangeRequest, this, _1)); - profileWindow->onWindowAboutToBeClosed.connect(boost::bind(&ProfileController::handleProfileWindowAboutToBeClosed, this, _1)); - vcardManager->onOwnVCardChanged.connect(boost::bind(&ProfileController::handleOwnVCardChanged, this, _1)); - vcardManager->onVCardRetrievalError.connect(boost::bind(&ProfileController::handleVCardRetrievalError, this, _1, _2)); - } - gettingVCard = true; - updateDialogStatus(); - vcardManager->requestOwnVCard(); - profileWindow->show(); + if (!boost::dynamic_pointer_cast<RequestProfileEditorUIEvent>(event)) { + return; + } + + if (!profileWindow) { + profileWindow = profileWindowFactory->createProfileWindow(); + profileWindow->setEditable(true); + profileWindow->onVCardChangeRequest.connect(boost::bind(&ProfileController::handleVCardChangeRequest, this, _1)); + profileWindow->onWindowAboutToBeClosed.connect(boost::bind(&ProfileController::handleProfileWindowAboutToBeClosed, this, _1)); + vcardManager->onOwnVCardChanged.connect(boost::bind(&ProfileController::handleOwnVCardChanged, this, _1)); + vcardManager->onVCardRetrievalError.connect(boost::bind(&ProfileController::handleVCardRetrievalError, this, _1, _2)); + } + gettingVCard = true; + updateDialogStatus(); + vcardManager->requestOwnVCard(); + profileWindow->show(); } void ProfileController::handleVCardChangeRequest(VCard::ref vcard) { - assert(!pendingSetVCardRequest); - profileWindow->setError(""); - pendingSetVCardRequest = vcardManager->createSetVCardRequest(vcard); - pendingSetVCardRequest->onResponse.connect(boost::bind(&ProfileController::handleSetVCardResponse, this, _2)); - pendingSetVCardRequest->send(); - updateDialogStatus(); + assert(!pendingSetVCardRequest); + profileWindow->setError(""); + pendingSetVCardRequest = vcardManager->createSetVCardRequest(vcard); + pendingSetVCardRequest->onResponse.connect(boost::bind(&ProfileController::handleSetVCardResponse, this, _2)); + pendingSetVCardRequest->send(); + updateDialogStatus(); } void ProfileController::handleSetVCardResponse(ErrorPayload::ref error) { - pendingSetVCardRequest.reset(); - updateDialogStatus(); - if (error) { - profileWindow->setVCard(vcardBeforeEdit); - profileWindow->setError(QT_TRANSLATE_NOOP("", "There was an error publishing your profile data")); - } - else { - profileWindow->setError(""); - profileWindow->hide(); - } + pendingSetVCardRequest.reset(); + updateDialogStatus(); + if (error) { + profileWindow->setVCard(vcardBeforeEdit); + profileWindow->setError(QT_TRANSLATE_NOOP("", "There was an error publishing your profile data")); + } + else { + profileWindow->setError(""); + profileWindow->hide(); + } } void ProfileController::handleVCardRetrievalError(const JID& jid, ErrorPayload::ref /* error */) { - if ((jid == JID()) && profileWindow) { - profileWindow->setProcessing(false); - profileWindow->setEnabled(false); - profileWindow->setVCard(boost::make_shared<VCard>()); - profileWindow->setError(QT_TRANSLATE_NOOP("", "There was an error fetching your current profile data")); - } + if ((jid == JID()) && profileWindow) { + profileWindow->setProcessing(false); + profileWindow->setEnabled(false); + profileWindow->setVCard(boost::make_shared<VCard>()); + profileWindow->setError(QT_TRANSLATE_NOOP("", "There was an error fetching your current profile data")); + } } void ProfileController::handleOwnVCardChanged(VCard::ref vcard) { - if (profileWindow) { - profileWindow->setVCard(vcard); - vcardBeforeEdit = vcard; - gettingVCard = false; - updateDialogStatus(); - } + if (profileWindow) { + profileWindow->setVCard(vcard); + vcardBeforeEdit = vcard; + gettingVCard = false; + updateDialogStatus(); + } } void ProfileController::handleProfileWindowAboutToBeClosed(const JID&) { - profileWindow = NULL; + profileWindow = NULL; } void ProfileController::setAvailable(bool b) { - available = b; - if (!available) { - pendingSetVCardRequest.reset(); - } - updateDialogStatus(); + available = b; + if (!available) { + pendingSetVCardRequest.reset(); + } + updateDialogStatus(); } void ProfileController::updateDialogStatus() { - if (profileWindow) { - profileWindow->setEnabled(available && !gettingVCard && !pendingSetVCardRequest); - profileWindow->setProcessing(gettingVCard || pendingSetVCardRequest); - } + if (profileWindow) { + profileWindow->setEnabled(available && !gettingVCard && !pendingSetVCardRequest); + profileWindow->setProcessing(gettingVCard || pendingSetVCardRequest); + } } } diff --git a/Swift/Controllers/ProfileController.h b/Swift/Controllers/ProfileController.h index ebb569d..3bb1fce 100644 --- a/Swift/Controllers/ProfileController.h +++ b/Swift/Controllers/ProfileController.h @@ -13,36 +13,36 @@ #include <Swift/Controllers/UIEvents/UIEvent.h> namespace Swift { - class ProfileWindow; - class ProfileWindowFactory; - class UIEventStream; - class VCardManager; - - class ProfileController { - public: - ProfileController(VCardManager* vcardManager, ProfileWindowFactory* profileWindowFactory, UIEventStream* uiEventStream); - ~ProfileController(); - - void setAvailable(bool b); - - private: - void handleUIEvent(UIEvent::ref event); - void handleVCardChangeRequest(VCard::ref vcard); - void handleSetVCardResponse(ErrorPayload::ref); - void handleOwnVCardChanged(VCard::ref vcard); - void handleVCardRetrievalError(const JID& jid, ErrorPayload::ref error); - void handleProfileWindowAboutToBeClosed(const JID&); - void updateDialogStatus(); - - private: - VCardManager* vcardManager; - ProfileWindowFactory* profileWindowFactory; - UIEventStream* uiEventStream; - bool available; - SetVCardRequest::ref pendingSetVCardRequest; - ProfileWindow* profileWindow; - bool gettingVCard; - VCard::ref vcardBeforeEdit; - }; + class ProfileWindow; + class ProfileWindowFactory; + class UIEventStream; + class VCardManager; + + class ProfileController { + public: + ProfileController(VCardManager* vcardManager, ProfileWindowFactory* profileWindowFactory, UIEventStream* uiEventStream); + ~ProfileController(); + + void setAvailable(bool b); + + private: + void handleUIEvent(UIEvent::ref event); + void handleVCardChangeRequest(VCard::ref vcard); + void handleSetVCardResponse(ErrorPayload::ref); + void handleOwnVCardChanged(VCard::ref vcard); + void handleVCardRetrievalError(const JID& jid, ErrorPayload::ref error); + void handleProfileWindowAboutToBeClosed(const JID&); + void updateDialogStatus(); + + private: + VCardManager* vcardManager; + ProfileWindowFactory* profileWindowFactory; + UIEventStream* uiEventStream; + bool available; + SetVCardRequest::ref pendingSetVCardRequest; + ProfileWindow* profileWindow; + bool gettingVCard; + VCard::ref vcardBeforeEdit; + }; } diff --git a/Swift/Controllers/ProfileSettingsProvider.cpp b/Swift/Controllers/ProfileSettingsProvider.cpp index 86f4c99..bb186fc 100644 --- a/Swift/Controllers/ProfileSettingsProvider.cpp +++ b/Swift/Controllers/ProfileSettingsProvider.cpp @@ -9,58 +9,58 @@ namespace Swift { ProfileSettingsProvider::ProfileSettingsProvider(const std::string& profile, SettingsProvider* provider) : - profile_(profile) { - provider_ = provider; - bool found = false; - foreach (std::string existingProfile, provider->getAvailableProfiles()) { - if (existingProfile == profile) { - found = true; - } - } - if (!found) { - provider_->createProfile(profile); - } + profile_(profile) { + provider_ = provider; + bool found = false; + foreach (std::string existingProfile, provider->getAvailableProfiles()) { + if (existingProfile == profile) { + found = true; + } + } + if (!found) { + provider_->createProfile(profile); + } } ProfileSettingsProvider::~ProfileSettingsProvider() { } std::string ProfileSettingsProvider::getStringSetting(const std::string &settingPath) { - //FIXME: Remove shim - SettingsProvider::Setting<std::string> setting(profileSettingPath(settingPath), ""); - return provider_->getSetting(setting); + //FIXME: Remove shim + SettingsProvider::Setting<std::string> setting(profileSettingPath(settingPath), ""); + return provider_->getSetting(setting); } void ProfileSettingsProvider::storeString(const std::string &settingPath, const std::string &settingValue) { - //FIXME: Remove shim - if (!getIsSettingFinal(settingPath)) { - SettingsProvider::Setting<std::string> setting(profileSettingPath(settingPath), ""); - provider_->storeSetting(setting, settingValue); - } + //FIXME: Remove shim + if (!getIsSettingFinal(settingPath)) { + SettingsProvider::Setting<std::string> setting(profileSettingPath(settingPath), ""); + provider_->storeSetting(setting, settingValue); + } } int ProfileSettingsProvider::getIntSetting(const std::string& settingPath, int defaultValue) { - //FIXME: Remove shim - SettingsProvider::Setting<int> setting(profileSettingPath(settingPath), defaultValue); - return provider_->getSetting(setting); + //FIXME: Remove shim + SettingsProvider::Setting<int> setting(profileSettingPath(settingPath), defaultValue); + return provider_->getSetting(setting); } void ProfileSettingsProvider::storeInt(const std::string& settingPath, int settingValue) { - //FIXME: Remove shim - if (!getIsSettingFinal(settingPath)) { - SettingsProvider::Setting<int> setting(profileSettingPath(settingPath), 0); - provider_->storeSetting(setting, settingValue); - } + //FIXME: Remove shim + if (!getIsSettingFinal(settingPath)) { + SettingsProvider::Setting<int> setting(profileSettingPath(settingPath), 0); + provider_->storeSetting(setting, settingValue); + } } bool ProfileSettingsProvider::getIsSettingFinal(const std::string& settingPath) { - //FIXME: Remove shim - SettingsProvider::Setting<int> setting(settingPath, 0); - return provider_->getIsSettingFinal(setting); + //FIXME: Remove shim + SettingsProvider::Setting<int> setting(settingPath, 0); + return provider_->getIsSettingFinal(setting); } std::string ProfileSettingsProvider::profileSettingPath(const std::string &settingPath) { - return profile_ + ":" + settingPath; + return profile_ + ":" + settingPath; } diff --git a/Swift/Controllers/ProfileSettingsProvider.h b/Swift/Controllers/ProfileSettingsProvider.h index 02e1e81..f3c3156 100644 --- a/Swift/Controllers/ProfileSettingsProvider.h +++ b/Swift/Controllers/ProfileSettingsProvider.h @@ -13,20 +13,20 @@ namespace Swift { class ProfileSettingsProvider { - public: - ProfileSettingsProvider(const std::string& profile, SettingsProvider* provider); - virtual ~ProfileSettingsProvider(); - virtual std::string getStringSetting(const std::string &settingPath); - virtual void storeString(const std::string &settingPath, const std::string &settingValue); - virtual int getIntSetting(const std::string& settingPath, int defaultValue); - virtual void storeInt(const std::string& settingPath, int settingValue); - /** See \ref SettingsProvider::getIsSettingFinal for discussion of what this means.*/ - virtual bool getIsSettingFinal(const std::string& settingPath); - - private: - std::string profileSettingPath(const std::string &settingPath); - SettingsProvider* provider_; - std::string profile_; + public: + ProfileSettingsProvider(const std::string& profile, SettingsProvider* provider); + virtual ~ProfileSettingsProvider(); + virtual std::string getStringSetting(const std::string &settingPath); + virtual void storeString(const std::string &settingPath, const std::string &settingValue); + virtual int getIntSetting(const std::string& settingPath, int defaultValue); + virtual void storeInt(const std::string& settingPath, int settingValue); + /** See \ref SettingsProvider::getIsSettingFinal for discussion of what this means.*/ + virtual bool getIsSettingFinal(const std::string& settingPath); + + private: + std::string profileSettingPath(const std::string &settingPath); + SettingsProvider* provider_; + std::string profile_; }; } diff --git a/Swift/Controllers/Roster/ContactRosterItem.cpp b/Swift/Controllers/Roster/ContactRosterItem.cpp index 3258fb5..89053e6 100644 --- a/Swift/Controllers/Roster/ContactRosterItem.cpp +++ b/Swift/Controllers/Roster/ContactRosterItem.cpp @@ -27,149 +27,149 @@ ContactRosterItem::~ContactRosterItem() { } StatusShow::Type ContactRosterItem::getStatusShow() const { - return presence_ ? presence_->getShow() : StatusShow::None; + return presence_ ? presence_->getShow() : StatusShow::None; } StatusShow::Type ContactRosterItem::getSimplifiedStatusShow() const { - switch (presence_ ? presence_->getShow() : StatusShow::None) { - 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; + switch (presence_ ? presence_->getShow() : StatusShow::None) { + 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; } std::string ContactRosterItem::getStatusText() const { - return presence_ ? presence_->getStatus() : ""; + return presence_ ? presence_->getStatus() : ""; } std::string ContactRosterItem::getIdleText() const { - Idle::ref idle = presence_ ? presence_->getPayload<Idle>() : Idle::ref(); - if (!idle || idle->getSince().is_not_a_date_time()) { - return ""; - } else { - return dateTimeToLocalString(idle->getSince()); - } + Idle::ref idle = presence_ ? presence_->getPayload<Idle>() : Idle::ref(); + if (!idle || idle->getSince().is_not_a_date_time()) { + return ""; + } else { + return dateTimeToLocalString(idle->getSince()); + } } std::string ContactRosterItem::getOfflineSinceText() const { - if (presence_ && presence_->getType() == Presence::Unavailable) { - boost::optional<boost::posix_time::ptime> delay = presence_->getTimestamp(); - if (delay) { - return dateTimeToLocalString(*delay); - } - } - return ""; + if (presence_ && presence_->getType() == Presence::Unavailable) { + boost::optional<boost::posix_time::ptime> delay = presence_->getTimestamp(); + if (delay) { + return dateTimeToLocalString(*delay); + } + } + return ""; } void ContactRosterItem::setAvatarPath(const boost::filesystem::path& path) { - avatarPath_ = path; - onDataChanged(); + avatarPath_ = path; + onDataChanged(); } const boost::filesystem::path& ContactRosterItem::getAvatarPath() const { - return avatarPath_; + return avatarPath_; } const JID& ContactRosterItem::getJID() const { - return jid_; + return jid_; } void ContactRosterItem::setDisplayJID(const JID& jid) { - displayJID_ = jid; + displayJID_ = jid; } const JID& ContactRosterItem::getDisplayJID() const { - return displayJID_; + return displayJID_; } typedef std::pair<std::string, boost::shared_ptr<Presence> > StringPresencePair; void ContactRosterItem::clearPresence() { - presence_.reset(); - onDataChanged(); + presence_.reset(); + onDataChanged(); } void ContactRosterItem::applyPresence(boost::shared_ptr<Presence> presence) { - presence_ = presence; - onDataChanged(); + presence_ = presence; + onDataChanged(); } const std::vector<std::string>& ContactRosterItem::getGroups() const { - return groups_; + return groups_; } /** Only used so a contact can know about the groups it's in*/ void ContactRosterItem::addGroup(const std::string& group) { - groups_.push_back(group); + groups_.push_back(group); } void ContactRosterItem::removeGroup(const std::string& group) { - groups_.erase(std::remove(groups_.begin(), groups_.end(), group), groups_.end()); + groups_.erase(std::remove(groups_.begin(), groups_.end(), group), groups_.end()); } MUCOccupant::Role ContactRosterItem::getMUCRole() const { - return mucRole_; + return mucRole_; } void ContactRosterItem::setMUCRole(const MUCOccupant::Role& role) { - mucRole_ = role; + mucRole_ = role; } MUCOccupant::Affiliation ContactRosterItem::getMUCAffiliation() const { - return mucAffiliation_; + return mucAffiliation_; } void ContactRosterItem::setMUCAffiliation(const MUCOccupant::Affiliation& affiliation) { - mucAffiliation_ = affiliation; + mucAffiliation_ = affiliation; } std::string ContactRosterItem::getMUCAffiliationText() const { - std::string affiliationString; - switch (mucAffiliation_) { - case MUCOccupant::Owner: affiliationString = QT_TRANSLATE_NOOP("", "Owner"); break; - case MUCOccupant::Admin: affiliationString = QT_TRANSLATE_NOOP("", "Admin"); break; - case MUCOccupant::Member: affiliationString = QT_TRANSLATE_NOOP("", "Member"); break; - case MUCOccupant::Outcast: affiliationString = QT_TRANSLATE_NOOP("", "Outcast"); break; - case MUCOccupant::NoAffiliation: affiliationString = ""; break; - } + std::string affiliationString; + switch (mucAffiliation_) { + case MUCOccupant::Owner: affiliationString = QT_TRANSLATE_NOOP("", "Owner"); break; + case MUCOccupant::Admin: affiliationString = QT_TRANSLATE_NOOP("", "Admin"); break; + case MUCOccupant::Member: affiliationString = QT_TRANSLATE_NOOP("", "Member"); break; + case MUCOccupant::Outcast: affiliationString = QT_TRANSLATE_NOOP("", "Outcast"); break; + case MUCOccupant::NoAffiliation: affiliationString = ""; break; + } - return affiliationString; + return affiliationString; } void ContactRosterItem::setSupportedFeatures(const std::set<Feature>& features) { - features_ = features; - onDataChanged(); + features_ = features; + onDataChanged(); } bool ContactRosterItem::supportsFeature(const Feature feature) const { - return features_.find(feature) != features_.end(); + return features_.find(feature) != features_.end(); } void ContactRosterItem::setBlockState(BlockState state) { - blockState_ = state; - onDataChanged(); + blockState_ = state; + onDataChanged(); } ContactRosterItem::BlockState ContactRosterItem::blockState() const { - return blockState_; + return blockState_; } VCard::ref ContactRosterItem::getVCard() const { - return vcard_; + return vcard_; } void ContactRosterItem::setVCard(VCard::ref vcard) { - vcard_ = vcard; - onDataChanged(); + vcard_ = vcard; + onDataChanged(); } } diff --git a/Swift/Controllers/Roster/ContactRosterItem.h b/Swift/Controllers/Roster/ContactRosterItem.h index d21935c..d77ba2d 100644 --- a/Swift/Controllers/Roster/ContactRosterItem.h +++ b/Swift/Controllers/Roster/ContactRosterItem.h @@ -28,69 +28,69 @@ namespace Swift { class GroupRosterItem; class ContactRosterItem : public RosterItem { - public: - enum Feature { - FileTransferFeature, - WhiteboardFeature - }; - - enum BlockState { - BlockingNotSupported, - IsBlocked, - IsUnblocked, - IsDomainBlocked - }; - - public: - ContactRosterItem(const JID& jid, const JID& displayJID, const std::string& name, GroupRosterItem* parent); - virtual ~ContactRosterItem(); - - StatusShow::Type getStatusShow() const; - StatusShow::Type getSimplifiedStatusShow() const; - std::string getStatusText() const; - std::string getIdleText() const; - std::string getOfflineSinceText() const; - void setAvatarPath(const boost::filesystem::path& path); - const boost::filesystem::path& getAvatarPath() const; - const JID& getJID() const; - void setDisplayJID(const JID& jid); - const JID& getDisplayJID() const; - void applyPresence(boost::shared_ptr<Presence> presence); - const std::vector<std::string>& getGroups() const; - /** Only used so a contact can know about the groups it's in*/ - void addGroup(const std::string& group); - void removeGroup(const std::string& group); - void clearPresence(); - - MUCOccupant::Role getMUCRole() const; - void setMUCRole(const MUCOccupant::Role& role); - MUCOccupant::Affiliation getMUCAffiliation() const; - void setMUCAffiliation(const MUCOccupant::Affiliation& affiliation); - std::string getMUCAffiliationText() const; - - void setSupportedFeatures(const std::set<Feature>& features); - bool supportsFeature(Feature feature) const; - - void setBlockState(BlockState state); - BlockState blockState() const; - - VCard::ref getVCard() const; - void setVCard(VCard::ref vcard); - - boost::signal<void ()> onVCardRequested; - - private: - JID jid_; - JID displayJID_; - boost::posix_time::ptime lastAvailableTime_; - boost::filesystem::path avatarPath_; - boost::shared_ptr<Presence> presence_; - std::vector<std::string> groups_; - MUCOccupant::Role mucRole_; - MUCOccupant::Affiliation mucAffiliation_; - std::set<Feature> features_; - BlockState blockState_; - VCard::ref vcard_; + public: + enum Feature { + FileTransferFeature, + WhiteboardFeature + }; + + enum BlockState { + BlockingNotSupported, + IsBlocked, + IsUnblocked, + IsDomainBlocked + }; + + public: + ContactRosterItem(const JID& jid, const JID& displayJID, const std::string& name, GroupRosterItem* parent); + virtual ~ContactRosterItem(); + + StatusShow::Type getStatusShow() const; + StatusShow::Type getSimplifiedStatusShow() const; + std::string getStatusText() const; + std::string getIdleText() const; + std::string getOfflineSinceText() const; + void setAvatarPath(const boost::filesystem::path& path); + const boost::filesystem::path& getAvatarPath() const; + const JID& getJID() const; + void setDisplayJID(const JID& jid); + const JID& getDisplayJID() const; + void applyPresence(boost::shared_ptr<Presence> presence); + const std::vector<std::string>& getGroups() const; + /** Only used so a contact can know about the groups it's in*/ + void addGroup(const std::string& group); + void removeGroup(const std::string& group); + void clearPresence(); + + MUCOccupant::Role getMUCRole() const; + void setMUCRole(const MUCOccupant::Role& role); + MUCOccupant::Affiliation getMUCAffiliation() const; + void setMUCAffiliation(const MUCOccupant::Affiliation& affiliation); + std::string getMUCAffiliationText() const; + + void setSupportedFeatures(const std::set<Feature>& features); + bool supportsFeature(Feature feature) const; + + void setBlockState(BlockState state); + BlockState blockState() const; + + VCard::ref getVCard() const; + void setVCard(VCard::ref vcard); + + boost::signal<void ()> onVCardRequested; + + private: + JID jid_; + JID displayJID_; + boost::posix_time::ptime lastAvailableTime_; + boost::filesystem::path avatarPath_; + boost::shared_ptr<Presence> presence_; + std::vector<std::string> groups_; + MUCOccupant::Role mucRole_; + MUCOccupant::Affiliation mucAffiliation_; + std::set<Feature> features_; + BlockState blockState_; + VCard::ref vcard_; }; } diff --git a/Swift/Controllers/Roster/FuzzyRosterFilter.h b/Swift/Controllers/Roster/FuzzyRosterFilter.h index 14e0f62..8c45935 100644 --- a/Swift/Controllers/Roster/FuzzyRosterFilter.h +++ b/Swift/Controllers/Roster/FuzzyRosterFilter.h @@ -22,21 +22,21 @@ namespace Swift { class FuzzyRosterFilter : public RosterFilter { - public: - FuzzyRosterFilter(const std::string& query) : query_(query) { } - virtual ~FuzzyRosterFilter() {} - virtual bool operator() (RosterItem* item) const { - ContactRosterItem *contactItem = dynamic_cast<ContactRosterItem*>(item); - if (contactItem) { - const bool itemMatched = ContactSuggester::fuzzyMatch(contactItem->getDisplayName(), query_) || ContactSuggester::fuzzyMatch(contactItem->getDisplayJID(), query_); - return !itemMatched; - } else { - return false; - } - } - - private: - std::string query_; + public: + FuzzyRosterFilter(const std::string& query) : query_(query) { } + virtual ~FuzzyRosterFilter() {} + virtual bool operator() (RosterItem* item) const { + ContactRosterItem *contactItem = dynamic_cast<ContactRosterItem*>(item); + if (contactItem) { + const bool itemMatched = ContactSuggester::fuzzyMatch(contactItem->getDisplayName(), query_) || ContactSuggester::fuzzyMatch(contactItem->getDisplayJID(), query_); + return !itemMatched; + } else { + return false; + } + } + + private: + std::string query_; }; } diff --git a/Swift/Controllers/Roster/GroupRosterItem.cpp b/Swift/Controllers/Roster/GroupRosterItem.cpp index 6c68851..82e43df 100644 --- a/Swift/Controllers/Roster/GroupRosterItem.cpp +++ b/Swift/Controllers/Roster/GroupRosterItem.cpp @@ -12,7 +12,7 @@ namespace Swift { GroupRosterItem::GroupRosterItem(const std::string& name, GroupRosterItem* parent, bool sortByStatus) : RosterItem(name, parent), sortByStatus_(sortByStatus), manualSort_(false) { - expanded_ = true; + expanded_ = true; } GroupRosterItem::~GroupRosterItem() { @@ -20,77 +20,77 @@ GroupRosterItem::~GroupRosterItem() { } void GroupRosterItem::setManualSort(const std::string& manualSortValue) { - manualSort_ = true; - bool changed = manualSortValue_ != manualSortValue; - manualSortValue_ = manualSortValue; - if (changed) { - onChildrenChanged(); - onDataChanged(); - } + manualSort_ = true; + bool changed = manualSortValue_ != manualSortValue; + manualSortValue_ = manualSortValue; + if (changed) { + onChildrenChanged(); + onDataChanged(); + } } const std::string& GroupRosterItem::getSortableDisplayName() const { - return manualSort_ ? manualSortValue_ : RosterItem::getSortableDisplayName(); + return manualSort_ ? manualSortValue_ : RosterItem::getSortableDisplayName(); } bool GroupRosterItem::isExpanded() const { - return expanded_; + return expanded_; } /** - This has no effect, and is only used by the UI. - If reTransmit is specified, dataChanged will be emitted on a change - - This may be undesireable if called from the UI, so you can use reTransmit=false - to avoid a loop in this case. + This has no effect, and is only used by the UI. + If reTransmit is specified, dataChanged will be emitted on a change - + This may be undesireable if called from the UI, so you can use reTransmit=false + to avoid a loop in this case. */ void GroupRosterItem::setExpanded(bool expanded) { - bool old = expanded_; - expanded_ = expanded; - if (expanded != old) { - onExpandedChanged(expanded); - } + bool old = expanded_; + expanded_ = expanded; + if (expanded != old) { + onExpandedChanged(expanded); + } } const std::vector<RosterItem*>& GroupRosterItem::getChildren() const { - return children_; + return children_; } const std::vector<RosterItem*>& GroupRosterItem::getDisplayedChildren() const { - return displayedChildren_; + return displayedChildren_; } void GroupRosterItem::addChild(RosterItem* item) { - children_.push_back(item); - GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(item); - if (group) { - group->onChildrenChanged.connect(boost::bind(&GroupRosterItem::handleChildrenChanged, this, group)); - } else { - item->onDataChanged.connect(boost::bind(&GroupRosterItem::handleDataChanged, this, item)); - } - onChildrenChanged(); - onDataChanged(); + children_.push_back(item); + GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(item); + if (group) { + group->onChildrenChanged.connect(boost::bind(&GroupRosterItem::handleChildrenChanged, this, group)); + } else { + item->onDataChanged.connect(boost::bind(&GroupRosterItem::handleDataChanged, this, item)); + } + onChildrenChanged(); + onDataChanged(); } /** * Does not emit a changed signal. */ void GroupRosterItem::removeAll() { - std::vector<RosterItem*>::iterator it = children_.begin(); - displayedChildren_.clear(); - while (it != children_.end()) { - ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(*it); - if (contact) { - delete contact; - } else { - GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(*it); - if (group) { - group->removeAll(); - delete group; - } - } - ++it; - } - children_.clear(); + std::vector<RosterItem*>::iterator it = children_.begin(); + displayedChildren_.clear(); + while (it != children_.end()) { + ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(*it); + if (contact) { + delete contact; + } else { + GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(*it); + if (group) { + group->removeAll(); + delete group; + } + } + ++it; + } + children_.clear(); } /** @@ -98,136 +98,136 @@ void GroupRosterItem::removeAll() { * the return result is undefined. */ ContactRosterItem* GroupRosterItem::removeChild(const JID& jid) { - std::vector<RosterItem*>::iterator it = children_.begin(); - ContactRosterItem* removed = NULL; - while (it != children_.end()) { - ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(*it); - if (contact && contact->getJID() == jid) { - displayedChildren_.erase(std::remove(displayedChildren_.begin(), displayedChildren_.end(), contact), displayedChildren_.end()); - removed = contact; - delete contact; - it = children_.erase(it); - continue; - } - GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(*it); - if (group) { - ContactRosterItem* groupRemoved = group->removeChild(jid); - if (groupRemoved) { - removed = groupRemoved; - } - } - ++it; - } - onChildrenChanged(); - onDataChanged(); - return removed; + std::vector<RosterItem*>::iterator it = children_.begin(); + ContactRosterItem* removed = NULL; + while (it != children_.end()) { + ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(*it); + if (contact && contact->getJID() == jid) { + displayedChildren_.erase(std::remove(displayedChildren_.begin(), displayedChildren_.end(), contact), displayedChildren_.end()); + removed = contact; + delete contact; + it = children_.erase(it); + continue; + } + GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(*it); + if (group) { + ContactRosterItem* groupRemoved = group->removeChild(jid); + if (groupRemoved) { + removed = groupRemoved; + } + } + ++it; + } + onChildrenChanged(); + onDataChanged(); + return removed; } GroupRosterItem* GroupRosterItem::removeGroupChild(const std::string& groupName) { - std::vector<RosterItem*>::iterator it = children_.begin(); - GroupRosterItem* removed = NULL; - while (it != children_.end()) { - GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(*it); - if (group && group->getDisplayName() == groupName) { - displayedChildren_.erase(std::remove(displayedChildren_.begin(), displayedChildren_.end(), group), displayedChildren_.end()); - removed = group; - delete group; - it = children_.erase(it); - continue; - } - ++it; - } - onChildrenChanged(); - onDataChanged(); - return removed; + std::vector<RosterItem*>::iterator it = children_.begin(); + GroupRosterItem* removed = NULL; + while (it != children_.end()) { + GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(*it); + if (group && group->getDisplayName() == groupName) { + displayedChildren_.erase(std::remove(displayedChildren_.begin(), displayedChildren_.end(), group), displayedChildren_.end()); + removed = group; + delete group; + it = children_.erase(it); + continue; + } + ++it; + } + onChildrenChanged(); + onDataChanged(); + return removed; } /** * Returns false if the list didn't need a resort */ bool GroupRosterItem::sortDisplayed() { - /* Not doing this until we import boost::algorithm*/ -// if (boost::is_sorted(displayedChildren_begin(), displayedChildren_.end(), itemLessThan)) { -// return false; -// } - //Sholudn't need stable_sort here - std::sort(displayedChildren_.begin(), displayedChildren_.end(), sortByStatus_? itemLessThanWithStatus : itemLessThanWithoutStatus); - return true; + /* Not doing this until we import boost::algorithm*/ +// if (boost::is_sorted(displayedChildren_begin(), displayedChildren_.end(), itemLessThan)) { +// return false; +// } + //Sholudn't need stable_sort here + std::sort(displayedChildren_.begin(), displayedChildren_.end(), sortByStatus_? itemLessThanWithStatus : itemLessThanWithoutStatus); + return true; } bool GroupRosterItem::itemLessThanWithoutStatus(const RosterItem* left, const RosterItem* right) { - return left->getSortableDisplayName() < right->getSortableDisplayName(); + return left->getSortableDisplayName() < right->getSortableDisplayName(); } bool GroupRosterItem::itemLessThanWithStatus(const RosterItem* left, const RosterItem* right) { - const ContactRosterItem* leftContact = dynamic_cast<const ContactRosterItem*>(left); - const ContactRosterItem* rightContact = dynamic_cast<const ContactRosterItem*>(right); - if (leftContact) { - if (!rightContact) { - return false; - } - StatusShow::Type leftType = leftContact->getSimplifiedStatusShow(); - StatusShow::Type rightType = rightContact->getSimplifiedStatusShow(); - if (leftType == rightType) { - return left->getSortableDisplayName() < right->getSortableDisplayName(); - } else { - return leftType < rightType; - } - } else { - if (rightContact) { - return true; - } - return left->getSortableDisplayName() < right->getSortableDisplayName(); - } + const ContactRosterItem* leftContact = dynamic_cast<const ContactRosterItem*>(left); + const ContactRosterItem* rightContact = dynamic_cast<const ContactRosterItem*>(right); + if (leftContact) { + if (!rightContact) { + return false; + } + StatusShow::Type leftType = leftContact->getSimplifiedStatusShow(); + StatusShow::Type rightType = rightContact->getSimplifiedStatusShow(); + if (leftType == rightType) { + return left->getSortableDisplayName() < right->getSortableDisplayName(); + } else { + return leftType < rightType; + } + } else { + if (rightContact) { + return true; + } + return left->getSortableDisplayName() < right->getSortableDisplayName(); + } } void GroupRosterItem::setDisplayed(RosterItem* item, bool displayed) { - bool found = false; - for (size_t i = 0; i < displayedChildren_.size(); i++) { - if (displayedChildren_[i] == item) { - found = true; - } - } - if (found == displayed) { - return; - } - if (displayed) { - displayedChildren_.push_back(item); - sortDisplayed(); - } else { - displayedChildren_.erase(std::remove(displayedChildren_.begin(), displayedChildren_.end(), item), displayedChildren_.end()); - } - onChildrenChanged(); - onDataChanged(); + bool found = false; + for (size_t i = 0; i < displayedChildren_.size(); i++) { + if (displayedChildren_[i] == item) { + found = true; + } + } + if (found == displayed) { + return; + } + if (displayed) { + displayedChildren_.push_back(item); + sortDisplayed(); + } else { + displayedChildren_.erase(std::remove(displayedChildren_.begin(), displayedChildren_.end(), item), displayedChildren_.end()); + } + onChildrenChanged(); + onDataChanged(); } void GroupRosterItem::handleDataChanged(RosterItem* /*item*/) { - if (sortDisplayed()) { - onChildrenChanged(); - } + if (sortDisplayed()) { + onChildrenChanged(); + } } void GroupRosterItem::handleChildrenChanged(GroupRosterItem* group) { - size_t oldSize = getDisplayedChildren().size(); - if (group->getDisplayedChildren().size() > 0) { - bool found = false; - for (size_t i = 0; i < displayedChildren_.size(); i++) { - if (displayedChildren_[i] == group) { - found = true; - } - } - if (!found) { - displayedChildren_.push_back(group); - sortDisplayed(); - } - } else { - displayedChildren_.erase(std::remove(displayedChildren_.begin(), displayedChildren_.end(), group), displayedChildren_.end()); - } - - if (oldSize != getDisplayedChildren().size() || sortDisplayed()) { - onChildrenChanged(); - onDataChanged(); - } + size_t oldSize = getDisplayedChildren().size(); + if (group->getDisplayedChildren().size() > 0) { + bool found = false; + for (size_t i = 0; i < displayedChildren_.size(); i++) { + if (displayedChildren_[i] == group) { + found = true; + } + } + if (!found) { + displayedChildren_.push_back(group); + sortDisplayed(); + } + } else { + displayedChildren_.erase(std::remove(displayedChildren_.begin(), displayedChildren_.end(), group), displayedChildren_.end()); + } + + if (oldSize != getDisplayedChildren().size() || sortDisplayed()) { + onChildrenChanged(); + onDataChanged(); + } } diff --git a/Swift/Controllers/Roster/GroupRosterItem.h b/Swift/Controllers/Roster/GroupRosterItem.h index 9b4024f..760b008 100644 --- a/Swift/Controllers/Roster/GroupRosterItem.h +++ b/Swift/Controllers/Roster/GroupRosterItem.h @@ -15,35 +15,35 @@ namespace Swift { class GroupRosterItem : public RosterItem { - public: - GroupRosterItem(const std::string& name, GroupRosterItem* parent, bool sortByStatus); - virtual ~GroupRosterItem(); - const std::vector<RosterItem*>& getChildren() const; - const std::vector<RosterItem*>& getDisplayedChildren() const; - void addChild(RosterItem* item); - ContactRosterItem* removeChild(const JID& jid); - GroupRosterItem* removeGroupChild(const std::string& group); - void removeAll(); - void setDisplayed(RosterItem* item, bool displayed); - boost::signal<void ()> onChildrenChanged; - static bool itemLessThanWithStatus(const RosterItem* left, const RosterItem* right); - static bool itemLessThanWithoutStatus(const RosterItem* left, const RosterItem* right); - void setExpanded(bool expanded); - bool isExpanded() const; - boost::signal<void (bool)> onExpandedChanged; - void setManualSort(const std::string& manualSortValue); - virtual const std::string& getSortableDisplayName() const; - private: - void handleChildrenChanged(GroupRosterItem* group); - void handleDataChanged(RosterItem* item); - bool sortDisplayed(); - std::string name_; - bool expanded_; - std::vector<RosterItem*> children_; - std::vector<RosterItem*> displayedChildren_; - bool sortByStatus_; - bool manualSort_; - std::string manualSortValue_; + public: + GroupRosterItem(const std::string& name, GroupRosterItem* parent, bool sortByStatus); + virtual ~GroupRosterItem(); + const std::vector<RosterItem*>& getChildren() const; + const std::vector<RosterItem*>& getDisplayedChildren() const; + void addChild(RosterItem* item); + ContactRosterItem* removeChild(const JID& jid); + GroupRosterItem* removeGroupChild(const std::string& group); + void removeAll(); + void setDisplayed(RosterItem* item, bool displayed); + boost::signal<void ()> onChildrenChanged; + static bool itemLessThanWithStatus(const RosterItem* left, const RosterItem* right); + static bool itemLessThanWithoutStatus(const RosterItem* left, const RosterItem* right); + void setExpanded(bool expanded); + bool isExpanded() const; + boost::signal<void (bool)> onExpandedChanged; + void setManualSort(const std::string& manualSortValue); + virtual const std::string& getSortableDisplayName() const; + private: + void handleChildrenChanged(GroupRosterItem* group); + void handleDataChanged(RosterItem* item); + bool sortDisplayed(); + std::string name_; + bool expanded_; + std::vector<RosterItem*> children_; + std::vector<RosterItem*> displayedChildren_; + bool sortByStatus_; + bool manualSort_; + std::string manualSortValue_; }; } diff --git a/Swift/Controllers/Roster/ItemOperations/AppearOffline.h b/Swift/Controllers/Roster/ItemOperations/AppearOffline.h index e59e01b..c57974b 100644 --- a/Swift/Controllers/Roster/ItemOperations/AppearOffline.h +++ b/Swift/Controllers/Roster/ItemOperations/AppearOffline.h @@ -14,16 +14,16 @@ namespace Swift { class RosterItem; class AppearOffline : public RosterItemOperation { - public: - AppearOffline() { - } - - virtual void operator() (RosterItem* item) const { - ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item); - if (contact) { - contact->clearPresence(); - } - } + public: + AppearOffline() { + } + + virtual void operator() (RosterItem* item) const { + ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item); + if (contact) { + contact->clearPresence(); + } + } }; diff --git a/Swift/Controllers/Roster/ItemOperations/RosterItemOperation.h b/Swift/Controllers/Roster/ItemOperations/RosterItemOperation.h index 833c863..76227c0 100644 --- a/Swift/Controllers/Roster/ItemOperations/RosterItemOperation.h +++ b/Swift/Controllers/Roster/ItemOperations/RosterItemOperation.h @@ -11,20 +11,20 @@ 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_;} - /** - * 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 - * with the same bare JID but different full JID may be passed. - */ - virtual void operator() (RosterItem*) const = 0; - private: - bool requiresLookup_; - JID lookupJID_; + 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_;} + /** + * 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 + * with the same bare JID but different full JID may be passed. + */ + virtual void operator() (RosterItem*) const = 0; + private: + bool requiresLookup_; + JID lookupJID_; }; } diff --git a/Swift/Controllers/Roster/ItemOperations/SetAvailableFeatures.h b/Swift/Controllers/Roster/ItemOperations/SetAvailableFeatures.h index b19b95a..29f9722 100644 --- a/Swift/Controllers/Roster/ItemOperations/SetAvailableFeatures.h +++ b/Swift/Controllers/Roster/ItemOperations/SetAvailableFeatures.h @@ -22,21 +22,21 @@ namespace Swift { class RosterItem; class SetAvailableFeatures : public RosterItemOperation { - public: - SetAvailableFeatures(const JID& jid, const std::set<ContactRosterItem::Feature>& availableFeatures, JID::CompareType compareType = JID::WithoutResource) : RosterItemOperation(true, jid), jid_(jid), availableFeatures_(availableFeatures), compareType_(compareType) { - } - - virtual void operator() (RosterItem* item) const { - ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item); - if (contact && contact->getJID().equals(jid_, compareType_)) { - contact->setSupportedFeatures(availableFeatures_); - } - } - - private: - JID jid_; - std::set<ContactRosterItem::Feature> availableFeatures_; - JID::CompareType compareType_; + public: + SetAvailableFeatures(const JID& jid, const std::set<ContactRosterItem::Feature>& availableFeatures, JID::CompareType compareType = JID::WithoutResource) : RosterItemOperation(true, jid), jid_(jid), availableFeatures_(availableFeatures), compareType_(compareType) { + } + + virtual void operator() (RosterItem* item) const { + ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item); + if (contact && contact->getJID().equals(jid_, compareType_)) { + contact->setSupportedFeatures(availableFeatures_); + } + } + + private: + JID jid_; + std::set<ContactRosterItem::Feature> availableFeatures_; + JID::CompareType compareType_; }; } diff --git a/Swift/Controllers/Roster/ItemOperations/SetAvatar.h b/Swift/Controllers/Roster/ItemOperations/SetAvatar.h index 211321e..d47c921 100644 --- a/Swift/Controllers/Roster/ItemOperations/SetAvatar.h +++ b/Swift/Controllers/Roster/ItemOperations/SetAvatar.h @@ -19,21 +19,21 @@ namespace Swift { class RosterItem; class SetAvatar : public RosterItemOperation { - public: - SetAvatar(const JID& jid, const boost::filesystem::path& path, JID::CompareType compareType = JID::WithoutResource) : RosterItemOperation(true, jid), jid_(jid), path_(path), compareType_(compareType) { - } - - virtual void operator() (RosterItem* item) const { - ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item); - if (contact && contact->getJID().equals(jid_, compareType_)) { - contact->setAvatarPath(path_); - } - } - - private: - JID jid_; - boost::filesystem::path path_; - JID::CompareType compareType_; + public: + SetAvatar(const JID& jid, const boost::filesystem::path& path, JID::CompareType compareType = JID::WithoutResource) : RosterItemOperation(true, jid), jid_(jid), path_(path), compareType_(compareType) { + } + + virtual void operator() (RosterItem* item) const { + ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item); + if (contact && contact->getJID().equals(jid_, compareType_)) { + contact->setAvatarPath(path_); + } + } + + private: + JID jid_; + boost::filesystem::path path_; + JID::CompareType compareType_; }; } diff --git a/Swift/Controllers/Roster/ItemOperations/SetBlockingState.h b/Swift/Controllers/Roster/ItemOperations/SetBlockingState.h index 098eeb5..818d9b4 100644 --- a/Swift/Controllers/Roster/ItemOperations/SetBlockingState.h +++ b/Swift/Controllers/Roster/ItemOperations/SetBlockingState.h @@ -22,30 +22,30 @@ namespace Swift { class RosterItem; class SetBlockingState : public RosterItemOperation { - public: - SetBlockingState(const JID& jid, ContactRosterItem::BlockState state, JID::CompareType compareType = JID::WithoutResource) : RosterItemOperation(!jid.getNode().empty(), jid), jid_(jid), state_(state), compareType_(compareType) { - if (state_ == ContactRosterItem::IsBlocked && jid.getNode().empty()) { - state_ = ContactRosterItem::IsDomainBlocked; - } - } - - virtual void operator() (RosterItem* item) const { - ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item); - if (jid_.getNode().empty()) { - if (contact && contact->getJID().getDomain() == jid_.getDomain()) { - contact->setBlockState(state_); - } - } else { - if (contact && contact->getJID().equals(jid_, compareType_)) { - contact->setBlockState(state_); - } - } - } - - private: - JID jid_; - ContactRosterItem::BlockState state_; - JID::CompareType compareType_; + public: + SetBlockingState(const JID& jid, ContactRosterItem::BlockState state, JID::CompareType compareType = JID::WithoutResource) : RosterItemOperation(!jid.getNode().empty(), jid), jid_(jid), state_(state), compareType_(compareType) { + if (state_ == ContactRosterItem::IsBlocked && jid.getNode().empty()) { + state_ = ContactRosterItem::IsDomainBlocked; + } + } + + virtual void operator() (RosterItem* item) const { + ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item); + if (jid_.getNode().empty()) { + if (contact && contact->getJID().getDomain() == jid_.getDomain()) { + contact->setBlockState(state_); + } + } else { + if (contact && contact->getJID().equals(jid_, compareType_)) { + contact->setBlockState(state_); + } + } + } + + private: + JID jid_; + ContactRosterItem::BlockState state_; + JID::CompareType compareType_; }; } diff --git a/Swift/Controllers/Roster/ItemOperations/SetMUC.h b/Swift/Controllers/Roster/ItemOperations/SetMUC.h index 8a4a0c6..7640c24 100644 --- a/Swift/Controllers/Roster/ItemOperations/SetMUC.h +++ b/Swift/Controllers/Roster/ItemOperations/SetMUC.h @@ -16,23 +16,23 @@ namespace Swift { class RosterItem; class SetMUC : public RosterItemOperation { - public: - SetMUC(const JID& jid, const MUCOccupant::Role& role, const MUCOccupant::Affiliation& affiliation) - : RosterItemOperation(true, jid), jid_(jid), mucRole_(role), mucAffiliation_(affiliation) { - } - - virtual void operator() (RosterItem* item) const { - ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item); - if (contact && contact->getJID().equals(jid_, JID::WithResource)) { - contact->setMUCRole(mucRole_); - contact->setMUCAffiliation(mucAffiliation_); - } - } - - private: - JID jid_; - MUCOccupant::Role mucRole_; - MUCOccupant::Affiliation mucAffiliation_; + public: + SetMUC(const JID& jid, const MUCOccupant::Role& role, const MUCOccupant::Affiliation& affiliation) + : RosterItemOperation(true, jid), jid_(jid), mucRole_(role), mucAffiliation_(affiliation) { + } + + virtual void operator() (RosterItem* item) const { + ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item); + if (contact && contact->getJID().equals(jid_, JID::WithResource)) { + contact->setMUCRole(mucRole_); + contact->setMUCAffiliation(mucAffiliation_); + } + } + + private: + JID jid_; + MUCOccupant::Role mucRole_; + MUCOccupant::Affiliation mucAffiliation_; }; } diff --git a/Swift/Controllers/Roster/ItemOperations/SetName.h b/Swift/Controllers/Roster/ItemOperations/SetName.h index 9f8a0b9..fa0694d 100644 --- a/Swift/Controllers/Roster/ItemOperations/SetName.h +++ b/Swift/Controllers/Roster/ItemOperations/SetName.h @@ -16,21 +16,21 @@ namespace Swift { class RosterItem; class SetName : public RosterItemOperation { - public: - SetName(const std::string& name, const JID& jid, JID::CompareType compareType = JID::WithoutResource) : RosterItemOperation(true, jid), name_(name), jid_(jid), compareType_(compareType) { - } - - virtual void operator() (RosterItem* item) const { - ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item); - if (contact && contact->getJID().equals(jid_, compareType_)) { - contact->setDisplayName(name_); - } - } - - private: - std::string name_; - JID jid_; - JID::CompareType compareType_; + public: + SetName(const std::string& name, const JID& jid, JID::CompareType compareType = JID::WithoutResource) : RosterItemOperation(true, jid), name_(name), jid_(jid), compareType_(compareType) { + } + + virtual void operator() (RosterItem* item) const { + ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item); + if (contact && contact->getJID().equals(jid_, compareType_)) { + contact->setDisplayName(name_); + } + } + + private: + std::string name_; + JID jid_; + JID::CompareType compareType_; }; } diff --git a/Swift/Controllers/Roster/ItemOperations/SetPresence.h b/Swift/Controllers/Roster/ItemOperations/SetPresence.h index 2b5bbbe..fc39e5c 100644 --- a/Swift/Controllers/Roster/ItemOperations/SetPresence.h +++ b/Swift/Controllers/Roster/ItemOperations/SetPresence.h @@ -17,20 +17,20 @@ namespace Swift { class RosterItem; class SetPresence : public RosterItemOperation { - public: - SetPresence(Presence::ref presence, JID::CompareType compareType = JID::WithoutResource) : RosterItemOperation(true, compareType == JID::WithoutResource ? presence->getFrom().toBare() : presence->getFrom()), presence_(presence), compareType_(compareType) { - } - - virtual void operator() (RosterItem* item) const { - ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item); - if (contact && contact->getJID().equals(presence_->getFrom(), compareType_)) { - contact->applyPresence(presence_); - } - } - - private: - Presence::ref presence_; - JID::CompareType compareType_; + public: + SetPresence(Presence::ref presence, JID::CompareType compareType = JID::WithoutResource) : RosterItemOperation(true, compareType == JID::WithoutResource ? presence->getFrom().toBare() : presence->getFrom()), presence_(presence), compareType_(compareType) { + } + + virtual void operator() (RosterItem* item) const { + ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item); + if (contact && contact->getJID().equals(presence_->getFrom(), compareType_)) { + contact->applyPresence(presence_); + } + } + + private: + Presence::ref presence_; + JID::CompareType compareType_; }; } diff --git a/Swift/Controllers/Roster/ItemOperations/SetVCard.h b/Swift/Controllers/Roster/ItemOperations/SetVCard.h index e1744b9..278ae56 100644 --- a/Swift/Controllers/Roster/ItemOperations/SetVCard.h +++ b/Swift/Controllers/Roster/ItemOperations/SetVCard.h @@ -23,21 +23,21 @@ namespace Swift { class RosterItem; class SetVCard : public RosterItemOperation { - public: - SetVCard(const JID& jid, VCard::ref vcard, JID::CompareType compareType = JID::WithoutResource) : RosterItemOperation(true, jid), jid_(jid), vcard_(vcard), compareType_(compareType) { - } - - virtual void operator() (RosterItem* item) const { - ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item); - if (contact && contact->getJID().equals(jid_, compareType_)) { - contact->setVCard(vcard_); - } - } - - private: - JID jid_; - VCard::ref vcard_; - JID::CompareType compareType_; + public: + SetVCard(const JID& jid, VCard::ref vcard, JID::CompareType compareType = JID::WithoutResource) : RosterItemOperation(true, jid), jid_(jid), vcard_(vcard), compareType_(compareType) { + } + + virtual void operator() (RosterItem* item) const { + ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item); + if (contact && contact->getJID().equals(jid_, compareType_)) { + contact->setVCard(vcard_); + } + } + + private: + JID jid_; + VCard::ref vcard_; + JID::CompareType compareType_; }; } diff --git a/Swift/Controllers/Roster/LeastCommonSubsequence.h b/Swift/Controllers/Roster/LeastCommonSubsequence.h index e7b9370..8daa20c 100644 --- a/Swift/Controllers/Roster/LeastCommonSubsequence.h +++ b/Swift/Controllers/Roster/LeastCommonSubsequence.h @@ -11,98 +11,98 @@ #include <boost/numeric/conversion/cast.hpp> namespace Swift { - using std::equal_to; + using std::equal_to; - 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 = 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); + 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 = 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 - for (size_t i = 0; i < width; ++i) { - result[i] = 0; - } - for (size_t j = 0; j < height; ++j) { - result[j*width] = 0; - } + // Initialize first row & column + for (size_t i = 0; i < width; ++i) { + result[i] = 0; + } + for (size_t j = 0; j < height; ++j) { + result[j*width] = 0; + } - // Compute the LCS lengths for subsets - Predicate predicate; - for (size_t i = 1; i < width; ++i) { - for (size_t j = 1; j < height; ++j) { - 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)]); - } - } - } - } + // Compute the LCS lengths for subsets + Predicate predicate; + for (size_t i = 1; i < width; ++i) { + for (size_t j = 1; j < height; ++j) { + 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)]); + } + } + } + } - template<typename X, typename InsertRemovePredicate, typename UpdatePredicate> - void computeIndexDiff(const std::vector<X>& x, const std::vector<X>& y, std::vector<size_t>& updates, std::vector<size_t>& postUpdates, std::vector<size_t>& removes, std::vector<size_t>& inserts) { - InsertRemovePredicate insertRemovePredicate; - UpdatePredicate updatePredicate; + template<typename X, typename InsertRemovePredicate, typename UpdatePredicate> + void computeIndexDiff(const std::vector<X>& x, const std::vector<X>& y, std::vector<size_t>& updates, std::vector<size_t>& postUpdates, std::vector<size_t>& removes, std::vector<size_t>& inserts) { + InsertRemovePredicate insertRemovePredicate; + UpdatePredicate updatePredicate; - // Find & handle common prefix (Optimization to reduce LCS matrix size) - typename std::vector<X>::const_iterator xBegin = x.begin(); - 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(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 = static_cast<size_t>(std::distance(x.begin(), xBegin)); + // Find & handle common prefix (Optimization to reduce LCS matrix size) + typename std::vector<X>::const_iterator xBegin = x.begin(); + 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(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 = 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(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; - } + // 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(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 = static_cast<size_t>(std::distance(xBegin, xEnd.base())); - size_t yLength = static_cast<size_t>(std::distance(yBegin, yEnd.base())); + // Compute lengths + 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; - Detail::computeLeastCommonSubsequenceMatrix<typename std::vector<X>::const_iterator, typename std::vector<X>::const_iterator, unsigned int, InsertRemovePredicate>(xBegin, xEnd.base(), yBegin, yEnd.base(), lcs); + // Compute LCS matrix + std::vector<unsigned int> lcs; + Detail::computeLeastCommonSubsequenceMatrix<typename std::vector<X>::const_iterator, typename std::vector<X>::const_iterator, unsigned int, InsertRemovePredicate>(xBegin, xEnd.base(), yBegin, yEnd.base(), lcs); - // Process LCS matrix - size_t i = xLength; - size_t j = yLength; - 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 - if (updatePredicate(x[prefixLength + i - 1], y[prefixLength + j - 1])) { - updates.push_back(prefixLength + i-1); - postUpdates.push_back(prefixLength + j-1); - } - i -= 1; - j -= 1; - } - else if (j > 0 && (i == 0 || lcs[i + (j-1)*width] >= lcs[i-1 + j*width])) { - // y[j-1] added - inserts.push_back(prefixLength + j-1); - j -= 1; - } - else if (i > 0 && (j == 0 || lcs[i + (j-1)*width] < lcs[i-1 + j*width])) { - // x[i-1] removed - removes.push_back(prefixLength + i-1); - i -= 1; - } - else { - break; - } - } - } + // Process LCS matrix + size_t i = xLength; + size_t j = yLength; + 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 + if (updatePredicate(x[prefixLength + i - 1], y[prefixLength + j - 1])) { + updates.push_back(prefixLength + i-1); + postUpdates.push_back(prefixLength + j-1); + } + i -= 1; + j -= 1; + } + else if (j > 0 && (i == 0 || lcs[i + (j-1)*width] >= lcs[i-1 + j*width])) { + // y[j-1] added + inserts.push_back(prefixLength + j-1); + j -= 1; + } + else if (i > 0 && (j == 0 || lcs[i + (j-1)*width] < lcs[i-1 + j*width])) { + // x[i-1] removed + removes.push_back(prefixLength + i-1); + i -= 1; + } + else { + break; + } + } + } } diff --git a/Swift/Controllers/Roster/OfflineRosterFilter.h b/Swift/Controllers/Roster/OfflineRosterFilter.h index d25d073..033eecb 100644 --- a/Swift/Controllers/Roster/OfflineRosterFilter.h +++ b/Swift/Controllers/Roster/OfflineRosterFilter.h @@ -15,12 +15,12 @@ namespace Swift { class OfflineRosterFilter : public RosterFilter { - public: - virtual ~OfflineRosterFilter() {} - virtual bool operator() (RosterItem *item) const { - ContactRosterItem *contactItem = dynamic_cast<ContactRosterItem*>(item); - return contactItem && contactItem->getStatusShow() == StatusShow::None; - } + public: + virtual ~OfflineRosterFilter() {} + virtual bool operator() (RosterItem *item) const { + ContactRosterItem *contactItem = dynamic_cast<ContactRosterItem*>(item); + return contactItem && contactItem->getStatusShow() == StatusShow::None; + } }; } diff --git a/Swift/Controllers/Roster/Roster.cpp b/Swift/Controllers/Roster/Roster.cpp index 77d6b78..2e68fd4 100644 --- a/Swift/Controllers/Roster/Roster.cpp +++ b/Swift/Controllers/Roster/Roster.cpp @@ -23,252 +23,252 @@ namespace Swift { Roster::Roster(bool sortByStatus, bool fullJIDMapping) : blockingSupported_(false) { - sortByStatus_ = sortByStatus; - fullJIDMapping_ = fullJIDMapping; - root_ = new GroupRosterItem("Dummy-Root", NULL, sortByStatus_); - root_->onChildrenChanged.connect(boost::bind(&Roster::handleChildrenChanged, this, root_)); + sortByStatus_ = sortByStatus; + fullJIDMapping_ = fullJIDMapping; + root_ = new GroupRosterItem("Dummy-Root", NULL, sortByStatus_); + root_->onChildrenChanged.connect(boost::bind(&Roster::handleChildrenChanged, this, root_)); } Roster::~Roster() { - std::deque<RosterItem*> queue; - queue.push_back(root_); - while (!queue.empty()) { - RosterItem* item = *queue.begin(); - queue.pop_front(); - GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(item); - if (group) { - queue.insert(queue.begin(), group->getChildren().begin(), group->getChildren().end()); - } - ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item); - if (contact) { - contact->onVCardRequested.disconnect(boost::bind(boost::ref(onVCardUpdateRequested), contact->getJID())); - } - delete item; - } + std::deque<RosterItem*> queue; + queue.push_back(root_); + while (!queue.empty()) { + RosterItem* item = *queue.begin(); + queue.pop_front(); + GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(item); + if (group) { + queue.insert(queue.begin(), group->getChildren().begin(), group->getChildren().end()); + } + ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item); + if (contact) { + contact->onVCardRequested.disconnect(boost::bind(boost::ref(onVCardUpdateRequested), contact->getJID())); + } + delete item; + } } GroupRosterItem* Roster::getRoot() const { - return root_; + return root_; } std::set<JID> Roster::getJIDs() const { - std::set<JID> jids; - - std::deque<RosterItem*> queue; - queue.push_back(root_); - while (!queue.empty()) { - RosterItem* item = *queue.begin(); - queue.pop_front(); - GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(item); - ContactRosterItem *contact = dynamic_cast<ContactRosterItem*>(item); - if (contact) { - jids.insert(contact->getJID()); - jids.insert(contact->getDisplayJID()); - } - else if (group) { - queue.insert(queue.begin(), group->getChildren().begin(), group->getChildren().end()); - } - } - - return jids; + std::set<JID> jids; + + std::deque<RosterItem*> queue; + queue.push_back(root_); + while (!queue.empty()) { + RosterItem* item = *queue.begin(); + queue.pop_front(); + GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(item); + ContactRosterItem *contact = dynamic_cast<ContactRosterItem*>(item); + if (contact) { + jids.insert(contact->getJID()); + jids.insert(contact->getDisplayJID()); + } + else if (group) { + queue.insert(queue.begin(), group->getChildren().begin(), group->getChildren().end()); + } + } + + return jids; } GroupRosterItem* Roster::getGroup(const std::string& groupName) { - foreach (RosterItem *item, root_->getChildren()) { - GroupRosterItem *group = dynamic_cast<GroupRosterItem*>(item); - if (group && group->getDisplayName() == groupName) { - return group; - } - } - GroupRosterItem* group = new GroupRosterItem(groupName, root_, sortByStatus_); - root_->addChild(group); - group->onChildrenChanged.connect(boost::bind(&Roster::handleChildrenChanged, this, group)); - group->onDataChanged.connect(boost::bind(&Roster::handleDataChanged, this, group)); - return group; + foreach (RosterItem *item, root_->getChildren()) { + GroupRosterItem *group = dynamic_cast<GroupRosterItem*>(item); + if (group && group->getDisplayName() == groupName) { + return group; + } + } + GroupRosterItem* group = new GroupRosterItem(groupName, root_, sortByStatus_); + root_->addChild(group); + group->onChildrenChanged.connect(boost::bind(&Roster::handleChildrenChanged, this, group)); + group->onDataChanged.connect(boost::bind(&Roster::handleDataChanged, this, group)); + return group; } void Roster::setBlockingSupported(bool isSupported) { - if (!blockingSupported_) { - foreach(ItemMap::value_type i, itemMap_) { - foreach(ContactRosterItem* item, i.second) { - item->setBlockState(ContactRosterItem::IsUnblocked); - } - } - } - blockingSupported_ = isSupported; + if (!blockingSupported_) { + foreach(ItemMap::value_type i, itemMap_) { + foreach(ContactRosterItem* item, i.second) { + item->setBlockState(ContactRosterItem::IsUnblocked); + } + } + } + blockingSupported_ = isSupported; } void Roster::removeGroup(const std::string& group) { - root_->removeGroupChild(group); + root_->removeGroupChild(group); } void Roster::handleDataChanged(RosterItem* item) { - onDataChanged(item); + onDataChanged(item); } void Roster::handleChildrenChanged(GroupRosterItem* item) { - onChildrenChanged(item); + onChildrenChanged(item); } void Roster::addContact(const JID& jid, const JID& displayJID, const std::string& name, const std::string& groupName, const boost::filesystem::path& avatarPath) { - GroupRosterItem* group(getGroup(groupName)); - ContactRosterItem *item = new ContactRosterItem(jid, displayJID, name, group); - item->onVCardRequested.connect(boost::bind(boost::ref(onVCardUpdateRequested), jid)); - item->setAvatarPath(avatarPath); - if (blockingSupported_) { - item->setBlockState(ContactRosterItem::IsUnblocked); - } - group->addChild(item); - ItemMap::iterator i = itemMap_.insert(std::make_pair(fullJIDMapping_ ? jid : jid.toBare(), std::vector<ContactRosterItem*>())).first; - if (!i->second.empty()) { - foreach (const std::string& existingGroup, i->second[0]->getGroups()) { - item->addGroup(existingGroup); - } - } - i->second.push_back(item); - item->onDataChanged.connect(boost::bind(&Roster::handleDataChanged, this, item)); - filterContact(item, group); - - foreach (ContactRosterItem* item, i->second) { - item->addGroup(groupName); - } + GroupRosterItem* group(getGroup(groupName)); + ContactRosterItem *item = new ContactRosterItem(jid, displayJID, name, group); + item->onVCardRequested.connect(boost::bind(boost::ref(onVCardUpdateRequested), jid)); + item->setAvatarPath(avatarPath); + if (blockingSupported_) { + item->setBlockState(ContactRosterItem::IsUnblocked); + } + group->addChild(item); + ItemMap::iterator i = itemMap_.insert(std::make_pair(fullJIDMapping_ ? jid : jid.toBare(), std::vector<ContactRosterItem*>())).first; + if (!i->second.empty()) { + foreach (const std::string& existingGroup, i->second[0]->getGroups()) { + item->addGroup(existingGroup); + } + } + i->second.push_back(item); + item->onDataChanged.connect(boost::bind(&Roster::handleDataChanged, this, item)); + filterContact(item, group); + + foreach (ContactRosterItem* item, i->second) { + item->addGroup(groupName); + } } struct JIDEqualsTo { - JIDEqualsTo(const JID& jid) : jid(jid) {} - bool operator()(ContactRosterItem* i) const { return jid == i->getJID(); } - JID jid; + JIDEqualsTo(const JID& jid) : jid(jid) {} + bool operator()(ContactRosterItem* i) const { return jid == i->getJID(); } + JID jid; }; void Roster::removeAll() { - root_->removeAll(); - itemMap_.clear(); - onChildrenChanged(root_); - onDataChanged(root_); + root_->removeAll(); + itemMap_.clear(); + onChildrenChanged(root_); + onDataChanged(root_); } void Roster::removeContact(const JID& jid) { - ItemMap::iterator item = itemMap_.find(fullJIDMapping_ ? jid : jid.toBare()); - if (item != itemMap_.end()) { - std::vector<ContactRosterItem*>& items = item->second; - items.erase(std::remove_if(items.begin(), items.end(), JIDEqualsTo(jid)), items.end()); - if (items.empty()) { - itemMap_.erase(item); - } - } - //Causes the delete - root_->removeChild(jid); + ItemMap::iterator item = itemMap_.find(fullJIDMapping_ ? jid : jid.toBare()); + if (item != itemMap_.end()) { + std::vector<ContactRosterItem*>& items = item->second; + items.erase(std::remove_if(items.begin(), items.end(), JIDEqualsTo(jid)), items.end()); + if (items.empty()) { + itemMap_.erase(item); + } + } + //Causes the delete + root_->removeChild(jid); } void Roster::removeContactFromGroup(const JID& jid, const std::string& groupName) { - std::vector<RosterItem*> children = root_->getChildren(); - std::vector<RosterItem*>::iterator it = children.begin(); - ItemMap::iterator itemIt = itemMap_.find(fullJIDMapping_ ? jid : jid.toBare()); - while (it != children.end()) { - GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(*it); - if (group && group->getDisplayName() == groupName) { - ContactRosterItem* deleted = group->removeChild(jid); - if (itemIt != itemMap_.end()) { - std::vector<ContactRosterItem*>& items = itemIt->second; - items.erase(std::remove(items.begin(), items.end(), deleted), items.end()); - } - } - ++it; - } - - if (itemIt != itemMap_.end()) { - foreach (ContactRosterItem* item, itemIt->second) { - item->removeGroup(groupName); - } - } + std::vector<RosterItem*> children = root_->getChildren(); + std::vector<RosterItem*>::iterator it = children.begin(); + ItemMap::iterator itemIt = itemMap_.find(fullJIDMapping_ ? jid : jid.toBare()); + while (it != children.end()) { + GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(*it); + if (group && group->getDisplayName() == groupName) { + ContactRosterItem* deleted = group->removeChild(jid); + if (itemIt != itemMap_.end()) { + std::vector<ContactRosterItem*>& items = itemIt->second; + items.erase(std::remove(items.begin(), items.end(), deleted), items.end()); + } + } + ++it; + } + + if (itemIt != itemMap_.end()) { + foreach (ContactRosterItem* item, itemIt->second) { + item->removeGroup(groupName); + } + } } void Roster::applyOnItems(const RosterItemOperation& operation) { - if (operation.requiresLookup()) { - applyOnItem(operation, operation.lookupJID()); - } else { - applyOnAllItems(operation); - } + if (operation.requiresLookup()) { + applyOnItem(operation, operation.lookupJID()); + } else { + applyOnAllItems(operation); + } } void Roster::applyOnItem(const RosterItemOperation& operation, const JID& jid) { - ItemMap::iterator i = itemMap_.find(fullJIDMapping_ ? jid : jid.toBare()); - if (i == itemMap_.end()) { - return; - } - foreach (ContactRosterItem* item, i->second) { - operation(item); - filterContact(item, item->getParent()); - } + ItemMap::iterator i = itemMap_.find(fullJIDMapping_ ? jid : jid.toBare()); + if (i == itemMap_.end()) { + return; + } + foreach (ContactRosterItem* item, i->second) { + operation(item); + filterContact(item, item->getParent()); + } } void Roster::applyOnAllItems(const RosterItemOperation& operation) { - std::deque<RosterItem*> queue; - queue.push_back(root_); - while (!queue.empty()) { - RosterItem* item = *queue.begin(); - queue.pop_front(); - operation(item); - GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(item); - if (group) { - queue.insert(queue.begin(), group->getChildren().begin(), group->getChildren().end()); - } - } - filterAll(); + std::deque<RosterItem*> queue; + queue.push_back(root_); + while (!queue.empty()) { + RosterItem* item = *queue.begin(); + queue.pop_front(); + operation(item); + GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(item); + if (group) { + queue.insert(queue.begin(), group->getChildren().begin(), group->getChildren().end()); + } + } + filterAll(); } void Roster::addFilter(RosterFilter* filter) { - filters_.push_back(filter); - filterAll(); - onFilterAdded(filter); + filters_.push_back(filter); + filterAll(); + onFilterAdded(filter); } void Roster::removeFilter(RosterFilter* filter) { - for (unsigned int i = 0; i < filters_.size(); i++) { - if (filters_[i] == filter) { - filters_.erase(filters_.begin() + i); - break; - } - } - filterAll(); - onFilterRemoved(filter); + for (unsigned int i = 0; i < filters_.size(); i++) { + if (filters_[i] == filter) { + filters_.erase(filters_.begin() + i); + break; + } + } + filterAll(); + onFilterRemoved(filter); } void Roster::filterContact(ContactRosterItem* contact, GroupRosterItem* group) { - size_t oldDisplayedSize = group->getDisplayedChildren().size(); - bool hide = true; - foreach (RosterFilter *filter, filters_) { - hide &= (*filter)(contact); - } - group->setDisplayed(contact, filters_.empty() || !hide); - size_t newDisplayedSize = group->getDisplayedChildren().size(); - if (oldDisplayedSize == 0 && newDisplayedSize > 0) { - onGroupAdded(group); - } + size_t oldDisplayedSize = group->getDisplayedChildren().size(); + bool hide = true; + foreach (RosterFilter *filter, filters_) { + hide &= (*filter)(contact); + } + group->setDisplayed(contact, filters_.empty() || !hide); + size_t newDisplayedSize = group->getDisplayedChildren().size(); + if (oldDisplayedSize == 0 && newDisplayedSize > 0) { + onGroupAdded(group); + } } void Roster::filterGroup(GroupRosterItem* group) { - foreach (RosterItem* child, group->getChildren()) { - ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(child); - if (contact) { - filterContact(contact, group); - } - } + foreach (RosterItem* child, group->getChildren()) { + ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(child); + if (contact) { + filterContact(contact, group); + } + } } void Roster::filterAll() { - std::deque<RosterItem*> queue; - queue.push_back(root_); - while (!queue.empty()) { - RosterItem *item = *queue.begin(); - queue.pop_front(); - GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(item); - if (group) { - queue.insert(queue.begin(), group->getChildren().begin(), group->getChildren().end()); - filterGroup(group); - } - } + std::deque<RosterItem*> queue; + queue.push_back(root_); + while (!queue.empty()) { + RosterItem *item = *queue.begin(); + queue.pop_front(); + GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(item); + if (group) { + queue.insert(queue.begin(), group->getChildren().begin(), group->getChildren().end()); + filterGroup(group); + } + } } } diff --git a/Swift/Controllers/Roster/Roster.h b/Swift/Controllers/Roster/Roster.h index 269ec4d..70e5bab 100644 --- a/Swift/Controllers/Roster/Roster.h +++ b/Swift/Controllers/Roster/Roster.h @@ -27,46 +27,46 @@ class GroupRosterItem; class ContactRosterItem; class Roster { - public: - Roster(bool sortByStatus = true, bool fullJIDMapping = false); - ~Roster(); + public: + Roster(bool sortByStatus = true, bool fullJIDMapping = false); + ~Roster(); - void addContact(const JID& jid, const JID& displayJID, const std::string& name, const std::string& group, const boost::filesystem::path& avatarPath); - void removeContact(const JID& jid); - void removeContactFromGroup(const JID& jid, const std::string& group); - void removeGroup(const std::string& group); - void removeAll(); - void applyOnItems(const RosterItemOperation& operation); - void applyOnAllItems(const RosterItemOperation& operation); - void applyOnItem(const RosterItemOperation& operation, const JID& jid); - void addFilter(RosterFilter* filter); - void removeFilter(RosterFilter* filter); - GroupRosterItem* getRoot() const; - std::set<JID> getJIDs() const; + void addContact(const JID& jid, const JID& displayJID, const std::string& name, const std::string& group, const boost::filesystem::path& avatarPath); + void removeContact(const JID& jid); + void removeContactFromGroup(const JID& jid, const std::string& group); + void removeGroup(const std::string& group); + void removeAll(); + void applyOnItems(const RosterItemOperation& operation); + void applyOnAllItems(const RosterItemOperation& operation); + void applyOnItem(const RosterItemOperation& operation, const JID& jid); + void addFilter(RosterFilter* filter); + void removeFilter(RosterFilter* filter); + GroupRosterItem* getRoot() const; + std::set<JID> getJIDs() const; - std::vector<RosterFilter*> getFilters() {return filters_;} - boost::signal<void (GroupRosterItem*)> onChildrenChanged; - boost::signal<void (GroupRosterItem*)> onGroupAdded; - boost::signal<void (RosterItem*)> onDataChanged; - boost::signal<void (JID&)> onVCardUpdateRequested; - boost::signal<void (RosterFilter* filter)> onFilterAdded; - boost::signal<void (RosterFilter* filter)> onFilterRemoved; - GroupRosterItem* getGroup(const std::string& groupName); - void setBlockingSupported(bool isSupported); + std::vector<RosterFilter*> getFilters() {return filters_;} + boost::signal<void (GroupRosterItem*)> onChildrenChanged; + boost::signal<void (GroupRosterItem*)> onGroupAdded; + boost::signal<void (RosterItem*)> onDataChanged; + boost::signal<void (JID&)> onVCardUpdateRequested; + boost::signal<void (RosterFilter* filter)> onFilterAdded; + boost::signal<void (RosterFilter* filter)> onFilterRemoved; + GroupRosterItem* getGroup(const std::string& groupName); + void setBlockingSupported(bool isSupported); - private: - void handleDataChanged(RosterItem* item); - void handleChildrenChanged(GroupRosterItem* item); - void filterGroup(GroupRosterItem* item); - void filterContact(ContactRosterItem* contact, GroupRosterItem* group); - void filterAll(); - GroupRosterItem* root_; - std::vector<RosterFilter*> filters_; - typedef std::map<JID, std::vector<ContactRosterItem*> > ItemMap; - ItemMap itemMap_; - bool fullJIDMapping_; - bool sortByStatus_; - bool blockingSupported_; + private: + void handleDataChanged(RosterItem* item); + void handleChildrenChanged(GroupRosterItem* item); + void filterGroup(GroupRosterItem* item); + void filterContact(ContactRosterItem* contact, GroupRosterItem* group); + void filterAll(); + GroupRosterItem* root_; + std::vector<RosterFilter*> filters_; + typedef std::map<JID, std::vector<ContactRosterItem*> > ItemMap; + ItemMap itemMap_; + bool fullJIDMapping_; + bool sortByStatus_; + bool blockingSupported_; }; } diff --git a/Swift/Controllers/Roster/RosterController.cpp b/Swift/Controllers/Roster/RosterController.cpp index 4fbdea4..e391f41 100644 --- a/Swift/Controllers/Roster/RosterController.cpp +++ b/Swift/Controllers/Roster/RosterController.cpp @@ -62,354 +62,354 @@ namespace Swift { * The controller does not gain ownership of these parameters. */ RosterController::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* entityCapsManager, FileTransferOverview* fileTransferOverview, ClientBlockListManager* clientBlockListManager, VCardManager* vcardManager) - : myJID_(jid), xmppRoster_(xmppRoster), mainWindowFactory_(mainWindowFactory), mainWindow_(mainWindowFactory_->createMainWindow(uiEventStream)), roster_(new Roster()), offlineFilter_(new OfflineRosterFilter()), vcardManager_(vcardManager), avatarManager_(avatarManager), nickManager_(nickManager), nickResolver_(nickResolver), presenceOracle_(presenceOracle), uiEventStream_(uiEventStream), entityCapsManager_(entityCapsManager), ftOverview_(fileTransferOverview), clientBlockListManager_(clientBlockListManager) { - assert(fileTransferOverview); - iqRouter_ = iqRouter; - subscriptionManager_ = subscriptionManager; - eventController_ = eventController; - settings_ = settings; - expandiness_ = new RosterGroupExpandinessPersister(roster_, settings); - mainWindow_->setRosterModel(roster_); - rosterVCardProvider_ = new RosterVCardProvider(roster_, vcardManager, JID::WithoutResource); - - changeStatusConnection_ = mainWindow_->onChangeStatusRequest.connect(boost::bind(&RosterController::handleChangeStatusRequest, this, _1, _2)); - signOutConnection_ = mainWindow_->onSignOutRequest.connect(boost::bind(boost::ref(onSignOutRequest))); - xmppRoster_->onJIDAdded.connect(boost::bind(&RosterController::handleOnJIDAdded, this, _1)); - xmppRoster_->onJIDUpdated.connect(boost::bind(&RosterController::handleOnJIDUpdated, this, _1, _2, _3)); - xmppRoster_->onJIDRemoved.connect(boost::bind(&RosterController::handleOnJIDRemoved, this, _1)); - xmppRoster_->onRosterCleared.connect(boost::bind(&RosterController::handleRosterCleared, this)); - subscriptionManager_->onPresenceSubscriptionRequest.connect(boost::bind(&RosterController::handleSubscriptionRequest, this, _1, _2)); - uiEventConnection_ = uiEventStream->onUIEvent.connect(boost::bind(&RosterController::handleUIEvent, this, _1)); - - vcardManager_->onOwnVCardChanged.connect(boost::bind(&RosterController::handleOwnVCardChanged, this, _1)); - avatarManager_->onAvatarChanged.connect(boost::bind(&RosterController::handleAvatarChanged, this, _1)); - presenceOracle_->onPresenceChange.connect(boost::bind(&RosterController::handlePresenceChanged, this, _1)); - mainWindow_->setMyAvatarPath(pathToString(avatarManager_->getAvatarPath(myJID_.toBare()))); - - nickManager_->onOwnNickChanged.connect(boost::bind(&MainWindow::setMyNick, mainWindow_, _1)); - mainWindow_->setMyJID(jid); - mainWindow_->setMyNick(nickManager_->getOwnNick()); - - entityCapsManager_->onCapsChanged.connect(boost::bind(&RosterController::handleOnCapsChanged, this, _1)); - - settings_->onSettingChanged.connect(boost::bind(&RosterController::handleSettingChanged, this, _1)); - - handleShowOfflineToggled(settings_->getSetting(SettingConstants::SHOW_OFFLINE)); - - ownContact_ = boost::make_shared<ContactRosterItem>(myJID_.toBare(), myJID_.toBare(), nickManager_->getOwnNick(), static_cast<GroupRosterItem*>(0)); - ownContact_->setVCard(vcardManager_->getVCard(myJID_.toBare())); - ownContact_->setAvatarPath(pathToString(avatarManager_->getAvatarPath(myJID_.toBare()))); - mainWindow_->setMyContactRosterItem(ownContact_); + : myJID_(jid), xmppRoster_(xmppRoster), mainWindowFactory_(mainWindowFactory), mainWindow_(mainWindowFactory_->createMainWindow(uiEventStream)), roster_(new Roster()), offlineFilter_(new OfflineRosterFilter()), vcardManager_(vcardManager), avatarManager_(avatarManager), nickManager_(nickManager), nickResolver_(nickResolver), presenceOracle_(presenceOracle), uiEventStream_(uiEventStream), entityCapsManager_(entityCapsManager), ftOverview_(fileTransferOverview), clientBlockListManager_(clientBlockListManager) { + assert(fileTransferOverview); + iqRouter_ = iqRouter; + subscriptionManager_ = subscriptionManager; + eventController_ = eventController; + settings_ = settings; + expandiness_ = new RosterGroupExpandinessPersister(roster_, settings); + mainWindow_->setRosterModel(roster_); + rosterVCardProvider_ = new RosterVCardProvider(roster_, vcardManager, JID::WithoutResource); + + changeStatusConnection_ = mainWindow_->onChangeStatusRequest.connect(boost::bind(&RosterController::handleChangeStatusRequest, this, _1, _2)); + signOutConnection_ = mainWindow_->onSignOutRequest.connect(boost::bind(boost::ref(onSignOutRequest))); + xmppRoster_->onJIDAdded.connect(boost::bind(&RosterController::handleOnJIDAdded, this, _1)); + xmppRoster_->onJIDUpdated.connect(boost::bind(&RosterController::handleOnJIDUpdated, this, _1, _2, _3)); + xmppRoster_->onJIDRemoved.connect(boost::bind(&RosterController::handleOnJIDRemoved, this, _1)); + xmppRoster_->onRosterCleared.connect(boost::bind(&RosterController::handleRosterCleared, this)); + subscriptionManager_->onPresenceSubscriptionRequest.connect(boost::bind(&RosterController::handleSubscriptionRequest, this, _1, _2)); + uiEventConnection_ = uiEventStream->onUIEvent.connect(boost::bind(&RosterController::handleUIEvent, this, _1)); + + vcardManager_->onOwnVCardChanged.connect(boost::bind(&RosterController::handleOwnVCardChanged, this, _1)); + avatarManager_->onAvatarChanged.connect(boost::bind(&RosterController::handleAvatarChanged, this, _1)); + presenceOracle_->onPresenceChange.connect(boost::bind(&RosterController::handlePresenceChanged, this, _1)); + mainWindow_->setMyAvatarPath(pathToString(avatarManager_->getAvatarPath(myJID_.toBare()))); + + nickManager_->onOwnNickChanged.connect(boost::bind(&MainWindow::setMyNick, mainWindow_, _1)); + mainWindow_->setMyJID(jid); + mainWindow_->setMyNick(nickManager_->getOwnNick()); + + entityCapsManager_->onCapsChanged.connect(boost::bind(&RosterController::handleOnCapsChanged, this, _1)); + + settings_->onSettingChanged.connect(boost::bind(&RosterController::handleSettingChanged, this, _1)); + + handleShowOfflineToggled(settings_->getSetting(SettingConstants::SHOW_OFFLINE)); + + ownContact_ = boost::make_shared<ContactRosterItem>(myJID_.toBare(), myJID_.toBare(), nickManager_->getOwnNick(), static_cast<GroupRosterItem*>(0)); + ownContact_->setVCard(vcardManager_->getVCard(myJID_.toBare())); + ownContact_->setAvatarPath(pathToString(avatarManager_->getAvatarPath(myJID_.toBare()))); + mainWindow_->setMyContactRosterItem(ownContact_); } -RosterController::~RosterController() { - settings_->onSettingChanged.disconnect(boost::bind(&RosterController::handleSettingChanged, this, _1)); - nickManager_->onOwnNickChanged.disconnect(boost::bind(&MainWindow::setMyNick, mainWindow_, _1)); - - delete offlineFilter_; - delete expandiness_; +RosterController::~RosterController() { + settings_->onSettingChanged.disconnect(boost::bind(&RosterController::handleSettingChanged, this, _1)); + nickManager_->onOwnNickChanged.disconnect(boost::bind(&MainWindow::setMyNick, mainWindow_, _1)); - mainWindow_->setRosterModel(NULL); - if (mainWindow_->canDelete()) { - delete mainWindow_; - } - delete rosterVCardProvider_; - delete roster_; + delete offlineFilter_; + delete expandiness_; + + mainWindow_->setRosterModel(NULL); + if (mainWindow_->canDelete()) { + delete mainWindow_; + } + delete rosterVCardProvider_; + delete roster_; } void RosterController::setEnabled(bool enabled) { - if (!enabled) { - roster_->applyOnItems(AppearOffline()); - } + if (!enabled) { + roster_->applyOnItems(AppearOffline()); + } } void RosterController::handleShowOfflineToggled(bool state) { - if (state) { - roster_->removeFilter(offlineFilter_); - } else { - roster_->addFilter(offlineFilter_); - } + if (state) { + roster_->removeFilter(offlineFilter_); + } else { + roster_->addFilter(offlineFilter_); + } } void RosterController::handleChangeStatusRequest(StatusShow::Type show, const std::string &statusText) { - onChangeStatusRequest(show, statusText); + onChangeStatusRequest(show, statusText); } void RosterController::handleOnJIDAdded(const JID& jid) { - std::vector<std::string> groups = xmppRoster_->getGroupsForJID(jid); - std::string name = nickResolver_->jidToNick(jid); - if (!groups.empty()) { - foreach(const std::string& group, groups) { - roster_->addContact(jid, jid, name, group, avatarManager_->getAvatarPath(jid)); - } - } - else { - roster_->addContact(jid, jid, name, QT_TRANSLATE_NOOP("", "Contacts"), avatarManager_->getAvatarPath(jid)); - } - applyAllPresenceTo(jid); + std::vector<std::string> groups = xmppRoster_->getGroupsForJID(jid); + std::string name = nickResolver_->jidToNick(jid); + if (!groups.empty()) { + foreach(const std::string& group, groups) { + roster_->addContact(jid, jid, name, group, avatarManager_->getAvatarPath(jid)); + } + } + else { + roster_->addContact(jid, jid, name, QT_TRANSLATE_NOOP("", "Contacts"), avatarManager_->getAvatarPath(jid)); + } + applyAllPresenceTo(jid); } void RosterController::applyAllPresenceTo(const JID& jid) { - foreach (Presence::ref presence, presenceOracle_->getAllPresence(jid)) { - roster_->applyOnItems(SetPresence(presence)); - } + foreach (Presence::ref presence, presenceOracle_->getAllPresence(jid)) { + roster_->applyOnItems(SetPresence(presence)); + } } void RosterController::handleRosterCleared() { - roster_->removeAll(); + roster_->removeAll(); } void RosterController::handleOnJIDRemoved(const JID& jid) { - roster_->removeContact(jid); + roster_->removeContact(jid); } void RosterController::handleOnJIDUpdated(const JID& jid, const std::string& oldName, const std::vector<std::string>& passedOldGroups) { - if (oldName != xmppRoster_->getNameForJID(jid)) { - roster_->applyOnItems(SetName(nickResolver_->jidToNick(jid), jid)); - } - std::vector<std::string> groups = xmppRoster_->getGroupsForJID(jid); - std::vector<std::string> oldGroups = passedOldGroups; - std::string name = nickResolver_->jidToNick(jid); - std::string contactsGroup = QT_TRANSLATE_NOOP("", "Contacts"); - if (oldGroups.empty()) { - oldGroups.push_back(contactsGroup); - } - if (groups.empty()) { - groups.push_back(contactsGroup); - } - foreach(const std::string& group, groups) { - if (std::find(oldGroups.begin(), oldGroups.end(), group) == oldGroups.end()) { - roster_->addContact(jid, jid, name, group, avatarManager_->getAvatarPath(jid)); - } - } - foreach(const std::string& group, oldGroups) { - if (std::find(groups.begin(), groups.end(), group) == groups.end()) { - roster_->removeContactFromGroup(jid, group); - if (roster_->getGroup(group)->getChildren().size() == 0) { - roster_->removeGroup(group); - } - } - } - applyAllPresenceTo(jid); + if (oldName != xmppRoster_->getNameForJID(jid)) { + roster_->applyOnItems(SetName(nickResolver_->jidToNick(jid), jid)); + } + std::vector<std::string> groups = xmppRoster_->getGroupsForJID(jid); + std::vector<std::string> oldGroups = passedOldGroups; + std::string name = nickResolver_->jidToNick(jid); + std::string contactsGroup = QT_TRANSLATE_NOOP("", "Contacts"); + if (oldGroups.empty()) { + oldGroups.push_back(contactsGroup); + } + if (groups.empty()) { + groups.push_back(contactsGroup); + } + foreach(const std::string& group, groups) { + if (std::find(oldGroups.begin(), oldGroups.end(), group) == oldGroups.end()) { + roster_->addContact(jid, jid, name, group, avatarManager_->getAvatarPath(jid)); + } + } + foreach(const std::string& group, oldGroups) { + if (std::find(groups.begin(), groups.end(), group) == groups.end()) { + roster_->removeContactFromGroup(jid, group); + if (roster_->getGroup(group)->getChildren().size() == 0) { + roster_->removeGroup(group); + } + } + } + applyAllPresenceTo(jid); } void RosterController::handleSettingChanged(const std::string& settingPath) { - if (settingPath == SettingConstants::SHOW_OFFLINE.getKey()) { - handleShowOfflineToggled(settings_->getSetting(SettingConstants::SHOW_OFFLINE)); - } + if (settingPath == SettingConstants::SHOW_OFFLINE.getKey()) { + handleShowOfflineToggled(settings_->getSetting(SettingConstants::SHOW_OFFLINE)); + } } void RosterController::handleBlockingStateChanged() { - if (clientBlockListManager_->getBlockList()->getState() == BlockList::Available) { - foreach(const JID& jid, clientBlockListManager_->getBlockList()->getItems()) { - roster_->applyOnItems(SetBlockingState(jid, ContactRosterItem::IsBlocked)); - } - } + if (clientBlockListManager_->getBlockList()->getState() == BlockList::Available) { + foreach(const JID& jid, clientBlockListManager_->getBlockList()->getItems()) { + roster_->applyOnItems(SetBlockingState(jid, ContactRosterItem::IsBlocked)); + } + } } void RosterController::handleBlockingItemAdded(const JID& jid) { - roster_->applyOnItems(SetBlockingState(jid, ContactRosterItem::IsBlocked)); + roster_->applyOnItems(SetBlockingState(jid, ContactRosterItem::IsBlocked)); } void RosterController::handleBlockingItemRemoved(const JID& jid) { - roster_->applyOnItems(SetBlockingState(jid, ContactRosterItem::IsUnblocked)); + roster_->applyOnItems(SetBlockingState(jid, ContactRosterItem::IsUnblocked)); } void RosterController::handleUIEvent(boost::shared_ptr<UIEvent> event) { - if (boost::shared_ptr<AddContactUIEvent> addContactEvent = boost::dynamic_pointer_cast<AddContactUIEvent>(event)) { - RosterItemPayload item; - item.setName(addContactEvent->getName()); - item.setJID(addContactEvent->getJID()); - item.setGroups(std::vector<std::string>(addContactEvent->getGroups().begin(), addContactEvent->getGroups().end())); - boost::shared_ptr<RosterPayload> roster(new RosterPayload()); - roster->addItem(item); - SetRosterRequest::ref request = SetRosterRequest::create(roster, iqRouter_); - request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster)); - request->send(); - subscriptionManager_->requestSubscription(addContactEvent->getJID()); - } - else if (boost::shared_ptr<RemoveRosterItemUIEvent> removeEvent = boost::dynamic_pointer_cast<RemoveRosterItemUIEvent>(event)) { - RosterItemPayload item(removeEvent->getJID(), "", RosterItemPayload::Remove); - boost::shared_ptr<RosterPayload> roster(new RosterPayload()); - roster->addItem(item); - SetRosterRequest::ref request = SetRosterRequest::create(roster, iqRouter_); - request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster)); - request->send(); - - } - else if (boost::shared_ptr<RenameRosterItemUIEvent> renameEvent = boost::dynamic_pointer_cast<RenameRosterItemUIEvent>(event)) { - JID contact(renameEvent->getJID()); - RosterItemPayload item(contact, renameEvent->getNewName(), xmppRoster_->getSubscriptionStateForJID(contact)); - item.setGroups(xmppRoster_->getGroupsForJID(contact)); - boost::shared_ptr<RosterPayload> roster(new RosterPayload()); - roster->addItem(item); - SetRosterRequest::ref request = SetRosterRequest::create(roster, iqRouter_); - request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster)); - request->send(); - } - else if (boost::shared_ptr<RenameGroupUIEvent> renameGroupEvent = boost::dynamic_pointer_cast<RenameGroupUIEvent>(event)) { - std::vector<XMPPRosterItem> items = xmppRoster_->getItems(); - std::string group = renameGroupEvent->getGroup(); - // FIXME: We should handle contacts groups specially to avoid clashes - if (group == QT_TRANSLATE_NOOP("", "Contacts")) { - group = ""; - } - foreach(XMPPRosterItem& item, items) { - std::vector<std::string> groups = item.getGroups(); - if ( (group.empty() && groups.empty()) || std::find(groups.begin(), groups.end(), group) != groups.end()) { - groups.erase(std::remove(groups.begin(), groups.end(), group), groups.end()); - if (std::find(groups.begin(), groups.end(), renameGroupEvent->getNewName()) == groups.end()) { - groups.push_back(renameGroupEvent->getNewName()); - } - item.setGroups(groups); - updateItem(item); - } - } - } - else if (boost::shared_ptr<SendFileUIEvent> sendFileEvent = boost::dynamic_pointer_cast<SendFileUIEvent>(event)) { - //TODO add send file dialog to ChatView of receipient jid - ftOverview_->sendFile(sendFileEvent->getJID(), sendFileEvent->getFilename()); - } + if (boost::shared_ptr<AddContactUIEvent> addContactEvent = boost::dynamic_pointer_cast<AddContactUIEvent>(event)) { + RosterItemPayload item; + item.setName(addContactEvent->getName()); + item.setJID(addContactEvent->getJID()); + item.setGroups(std::vector<std::string>(addContactEvent->getGroups().begin(), addContactEvent->getGroups().end())); + boost::shared_ptr<RosterPayload> roster(new RosterPayload()); + roster->addItem(item); + SetRosterRequest::ref request = SetRosterRequest::create(roster, iqRouter_); + request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster)); + request->send(); + subscriptionManager_->requestSubscription(addContactEvent->getJID()); + } + else if (boost::shared_ptr<RemoveRosterItemUIEvent> removeEvent = boost::dynamic_pointer_cast<RemoveRosterItemUIEvent>(event)) { + RosterItemPayload item(removeEvent->getJID(), "", RosterItemPayload::Remove); + boost::shared_ptr<RosterPayload> roster(new RosterPayload()); + roster->addItem(item); + SetRosterRequest::ref request = SetRosterRequest::create(roster, iqRouter_); + request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster)); + request->send(); + + } + else if (boost::shared_ptr<RenameRosterItemUIEvent> renameEvent = boost::dynamic_pointer_cast<RenameRosterItemUIEvent>(event)) { + JID contact(renameEvent->getJID()); + RosterItemPayload item(contact, renameEvent->getNewName(), xmppRoster_->getSubscriptionStateForJID(contact)); + item.setGroups(xmppRoster_->getGroupsForJID(contact)); + boost::shared_ptr<RosterPayload> roster(new RosterPayload()); + roster->addItem(item); + SetRosterRequest::ref request = SetRosterRequest::create(roster, iqRouter_); + request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster)); + request->send(); + } + else if (boost::shared_ptr<RenameGroupUIEvent> renameGroupEvent = boost::dynamic_pointer_cast<RenameGroupUIEvent>(event)) { + std::vector<XMPPRosterItem> items = xmppRoster_->getItems(); + std::string group = renameGroupEvent->getGroup(); + // FIXME: We should handle contacts groups specially to avoid clashes + if (group == QT_TRANSLATE_NOOP("", "Contacts")) { + group = ""; + } + foreach(XMPPRosterItem& item, items) { + std::vector<std::string> groups = item.getGroups(); + if ( (group.empty() && groups.empty()) || std::find(groups.begin(), groups.end(), group) != groups.end()) { + groups.erase(std::remove(groups.begin(), groups.end(), group), groups.end()); + if (std::find(groups.begin(), groups.end(), renameGroupEvent->getNewName()) == groups.end()) { + groups.push_back(renameGroupEvent->getNewName()); + } + item.setGroups(groups); + updateItem(item); + } + } + } + else if (boost::shared_ptr<SendFileUIEvent> sendFileEvent = boost::dynamic_pointer_cast<SendFileUIEvent>(event)) { + //TODO add send file dialog to ChatView of receipient jid + ftOverview_->sendFile(sendFileEvent->getJID(), sendFileEvent->getFilename()); + } } void RosterController::setContactGroups(const JID& jid, const std::vector<std::string>& groups) { - updateItem(XMPPRosterItem(jid, xmppRoster_->getNameForJID(jid), groups, xmppRoster_->getSubscriptionStateForJID(jid))); + updateItem(XMPPRosterItem(jid, xmppRoster_->getNameForJID(jid), groups, xmppRoster_->getSubscriptionStateForJID(jid))); } void RosterController::updateItem(const XMPPRosterItem& item) { - RosterItemPayload itemPayload(item.getJID(), item.getName(), item.getSubscription()); - itemPayload.setGroups(item.getGroups()); + RosterItemPayload itemPayload(item.getJID(), item.getName(), item.getSubscription()); + itemPayload.setGroups(item.getGroups()); - RosterPayload::ref roster = boost::make_shared<RosterPayload>(); - roster->addItem(itemPayload); + RosterPayload::ref roster = boost::make_shared<RosterPayload>(); + roster->addItem(itemPayload); - SetRosterRequest::ref request = SetRosterRequest::create(roster, iqRouter_); - request->onResponse.connect(boost::bind(&RosterController::handleRosterItemUpdated, this, _1, roster)); - request->send(); + SetRosterRequest::ref request = SetRosterRequest::create(roster, iqRouter_); + request->onResponse.connect(boost::bind(&RosterController::handleRosterItemUpdated, this, _1, roster)); + request->send(); } void RosterController::initBlockingCommand() { - boost::shared_ptr<BlockList> blockList = clientBlockListManager_->requestBlockList(); - - blockingOnStateChangedConnection_ = blockList->onStateChanged.connect(boost::bind(&RosterController::handleBlockingStateChanged, this)); - blockingOnItemAddedConnection_ = blockList->onItemAdded.connect(boost::bind(&RosterController::handleBlockingItemAdded, this, _1)); - blockingOnItemRemovedConnection_ = blockList->onItemRemoved.connect(boost::bind(&RosterController::handleBlockingItemRemoved, this, _1)); - roster_->setBlockingSupported(true); - if (blockList->getState() == BlockList::Available) { - foreach(const JID& jid, blockList->getItems()) { - roster_->applyOnItems(SetBlockingState(jid, ContactRosterItem::IsBlocked)); - } - } + boost::shared_ptr<BlockList> blockList = clientBlockListManager_->requestBlockList(); + + blockingOnStateChangedConnection_ = blockList->onStateChanged.connect(boost::bind(&RosterController::handleBlockingStateChanged, this)); + blockingOnItemAddedConnection_ = blockList->onItemAdded.connect(boost::bind(&RosterController::handleBlockingItemAdded, this, _1)); + blockingOnItemRemovedConnection_ = blockList->onItemRemoved.connect(boost::bind(&RosterController::handleBlockingItemRemoved, this, _1)); + roster_->setBlockingSupported(true); + if (blockList->getState() == BlockList::Available) { + foreach(const JID& jid, blockList->getItems()) { + roster_->applyOnItems(SetBlockingState(jid, ContactRosterItem::IsBlocked)); + } + } } void RosterController::handleRosterItemUpdated(ErrorPayload::ref error, boost::shared_ptr<RosterPayload> rosterPayload) { - if (!!error) { - handleRosterSetError(error, rosterPayload); - } - boost::shared_ptr<BlockList> blockList = clientBlockListManager_->getBlockList(); - std::vector<RosterItemPayload> items = rosterPayload->getItems(); - if (blockList->getState() == BlockList::Available && items.size() > 0) { - std::vector<JID> jids = blockList->getItems(); - if (std::find(jids.begin(), jids.end(), items[0].getJID()) != jids.end()) { - roster_->applyOnItems(SetBlockingState(items[0].getJID(), ContactRosterItem::IsBlocked)); - } - } + if (!!error) { + handleRosterSetError(error, rosterPayload); + } + boost::shared_ptr<BlockList> blockList = clientBlockListManager_->getBlockList(); + std::vector<RosterItemPayload> items = rosterPayload->getItems(); + if (blockList->getState() == BlockList::Available && items.size() > 0) { + std::vector<JID> jids = blockList->getItems(); + if (std::find(jids.begin(), jids.end(), items[0].getJID()) != jids.end()) { + roster_->applyOnItems(SetBlockingState(items[0].getJID(), ContactRosterItem::IsBlocked)); + } + } } void RosterController::handleRosterSetError(ErrorPayload::ref error, boost::shared_ptr<RosterPayload> rosterPayload) { - if (!error) { - return; - } - std::string text = str(format(QT_TRANSLATE_NOOP("", "Server %1% rejected contact list change to item '%2%'")) % myJID_.getDomain() % rosterPayload->getItems()[0].getJID().toString()); - if (!error->getText().empty()) { - text += ": " + error->getText(); - } - boost::shared_ptr<ErrorEvent> errorEvent(new ErrorEvent(JID(myJID_.getDomain()), text)); - eventController_->handleIncomingEvent(errorEvent); + if (!error) { + return; + } + std::string text = str(format(QT_TRANSLATE_NOOP("", "Server %1% rejected contact list change to item '%2%'")) % myJID_.getDomain() % rosterPayload->getItems()[0].getJID().toString()); + if (!error->getText().empty()) { + text += ": " + error->getText(); + } + boost::shared_ptr<ErrorEvent> errorEvent(new ErrorEvent(JID(myJID_.getDomain()), text)); + eventController_->handleIncomingEvent(errorEvent); } void RosterController::handleIncomingPresence(Presence::ref newPresence) { - if (newPresence->getType() == Presence::Error) { - return; - } - Presence::ref accountPresence = presenceOracle_->getAccountPresence(newPresence->getFrom().toBare()); - if (!accountPresence) { - accountPresence = Presence::create(); - accountPresence->setFrom(newPresence->getFrom()); - accountPresence->setType(Presence::Unavailable); - } - roster_->applyOnItems(SetPresence(accountPresence)); + if (newPresence->getType() == Presence::Error) { + return; + } + Presence::ref accountPresence = presenceOracle_->getAccountPresence(newPresence->getFrom().toBare()); + if (!accountPresence) { + accountPresence = Presence::create(); + accountPresence->setFrom(newPresence->getFrom()); + accountPresence->setType(Presence::Unavailable); + } + roster_->applyOnItems(SetPresence(accountPresence)); } void RosterController::handleSubscriptionRequest(const JID& jid, const std::string& message) { - if (xmppRoster_->containsJID(jid) && (xmppRoster_->getSubscriptionStateForJID(jid) == RosterItemPayload::To || xmppRoster_->getSubscriptionStateForJID(jid) == RosterItemPayload::Both)) { - subscriptionManager_->confirmSubscription(jid); - return; - } - SubscriptionRequestEvent* eventPointer = new SubscriptionRequestEvent(jid, message); - eventPointer->onAccept.connect(boost::bind(&RosterController::handleSubscriptionRequestAccepted, this, eventPointer)); - eventPointer->onDecline.connect(boost::bind(&RosterController::handleSubscriptionRequestDeclined, this, eventPointer)); - boost::shared_ptr<StanzaEvent> event(eventPointer); - eventController_->handleIncomingEvent(event); + if (xmppRoster_->containsJID(jid) && (xmppRoster_->getSubscriptionStateForJID(jid) == RosterItemPayload::To || xmppRoster_->getSubscriptionStateForJID(jid) == RosterItemPayload::Both)) { + subscriptionManager_->confirmSubscription(jid); + return; + } + SubscriptionRequestEvent* eventPointer = new SubscriptionRequestEvent(jid, message); + eventPointer->onAccept.connect(boost::bind(&RosterController::handleSubscriptionRequestAccepted, this, eventPointer)); + eventPointer->onDecline.connect(boost::bind(&RosterController::handleSubscriptionRequestDeclined, this, eventPointer)); + boost::shared_ptr<StanzaEvent> event(eventPointer); + eventController_->handleIncomingEvent(event); } void RosterController::handleSubscriptionRequestAccepted(SubscriptionRequestEvent* event) { - subscriptionManager_->confirmSubscription(event->getJID()); - if (!xmppRoster_->containsJID(event->getJID()) || xmppRoster_->getSubscriptionStateForJID(event->getJID()) == RosterItemPayload::None || xmppRoster_->getSubscriptionStateForJID(event->getJID()) == RosterItemPayload::From) { - subscriptionManager_->requestSubscription(event->getJID()); - } + subscriptionManager_->confirmSubscription(event->getJID()); + if (!xmppRoster_->containsJID(event->getJID()) || xmppRoster_->getSubscriptionStateForJID(event->getJID()) == RosterItemPayload::None || xmppRoster_->getSubscriptionStateForJID(event->getJID()) == RosterItemPayload::From) { + subscriptionManager_->requestSubscription(event->getJID()); + } } void RosterController::handleSubscriptionRequestDeclined(SubscriptionRequestEvent* event) { - subscriptionManager_->cancelSubscription(event->getJID()); + subscriptionManager_->cancelSubscription(event->getJID()); } void RosterController::handleOwnVCardChanged(VCard::ref vcard) { - ownContact_->setVCard(vcard); - mainWindow_->setMyContactRosterItem(ownContact_); + ownContact_->setVCard(vcard); + mainWindow_->setMyContactRosterItem(ownContact_); } void RosterController::handleAvatarChanged(const JID& jid) { - boost::filesystem::path path = avatarManager_->getAvatarPath(jid); - roster_->applyOnItems(SetAvatar(jid, path)); - if (jid.equals(myJID_, JID::WithoutResource)) { - mainWindow_->setMyAvatarPath(pathToString(path)); - ownContact_->setAvatarPath(pathToString(path)); - mainWindow_->setMyContactRosterItem(ownContact_); - } + boost::filesystem::path path = avatarManager_->getAvatarPath(jid); + roster_->applyOnItems(SetAvatar(jid, path)); + if (jid.equals(myJID_, JID::WithoutResource)) { + mainWindow_->setMyAvatarPath(pathToString(path)); + ownContact_->setAvatarPath(pathToString(path)); + mainWindow_->setMyContactRosterItem(ownContact_); + } } void RosterController::handlePresenceChanged(Presence::ref presence) { - if (presence->getFrom().equals(myJID_, JID::WithResource)) { - ownContact_->applyPresence(presence); - mainWindow_->setMyContactRosterItem(ownContact_); - } - else { - handleIncomingPresence(presence); - } + if (presence->getFrom().equals(myJID_, JID::WithResource)) { + ownContact_->applyPresence(presence); + mainWindow_->setMyContactRosterItem(ownContact_); + } + else { + handleIncomingPresence(presence); + } } boost::optional<XMPPRosterItem> RosterController::getItem(const JID& jid) const { - return xmppRoster_->getItem(jid); + return xmppRoster_->getItem(jid); } std::set<std::string> RosterController::getGroups() const { - return xmppRoster_->getGroups(); + return xmppRoster_->getGroups(); } void RosterController::handleOnCapsChanged(const JID& jid) { - DiscoInfo::ref info = entityCapsManager_->getCaps(jid); - if (info) { - std::set<ContactRosterItem::Feature> features; - if (FileTransferManager::isSupportedBy(info)) { - features.insert(ContactRosterItem::FileTransferFeature); - } - if (info->hasFeature(DiscoInfo::WhiteboardFeature)) { - features.insert(ContactRosterItem::WhiteboardFeature); - } - roster_->applyOnItems(SetAvailableFeatures(jid, features)); - } + DiscoInfo::ref info = entityCapsManager_->getCaps(jid); + if (info) { + std::set<ContactRosterItem::Feature> features; + if (FileTransferManager::isSupportedBy(info)) { + features.insert(ContactRosterItem::FileTransferFeature); + } + if (info->hasFeature(DiscoInfo::WhiteboardFeature)) { + features.insert(ContactRosterItem::WhiteboardFeature); + } + roster_->applyOnItems(SetAvailableFeatures(jid, features)); + } } } diff --git a/Swift/Controllers/Roster/RosterController.h b/Swift/Controllers/Roster/RosterController.h index 545abfc..f1660a8 100644 --- a/Swift/Controllers/Roster/RosterController.h +++ b/Swift/Controllers/Roster/RosterController.h @@ -23,104 +23,104 @@ #include <Swift/Controllers/UIEvents/UIEvent.h> namespace Swift { - class AvatarManager; - class ClientBlockListManager; - class EntityCapsProvider; - class EventController; - class FileTransferManager; - class FileTransferOverview; - class IQRouter; - class MainWindow; - class MainWindowFactory; - class NickManager; - class NickResolver; - class OfflineRosterFilter; - class PresenceOracle; - class Roster; - class RosterGroupExpandinessPersister; - class RosterVCardProvider; - class SettingsProvider; - class SubscriptionManager; - class SubscriptionRequestEvent; - class UIEventStream; - class VCardManager; - class XMPPRoster; - class XMPPRosterItem; + class AvatarManager; + class ClientBlockListManager; + class EntityCapsProvider; + class EventController; + class FileTransferManager; + class FileTransferOverview; + class IQRouter; + class MainWindow; + class MainWindowFactory; + class NickManager; + class NickResolver; + class OfflineRosterFilter; + class PresenceOracle; + class Roster; + class RosterGroupExpandinessPersister; + class RosterVCardProvider; + class SettingsProvider; + class SubscriptionManager; + class SubscriptionRequestEvent; + class UIEventStream; + class VCardManager; + class XMPPRoster; + class XMPPRosterItem; - class RosterController { - public: - 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, ClientBlockListManager* clientBlockListManager, VCardManager* vcardManager); - ~RosterController(); - void showRosterWindow(); - void setJID(const JID& jid) { myJID_ = jid; } - MainWindow* getWindow() {return mainWindow_;} - boost::signal<void (StatusShow::Type, const std::string&)> onChangeStatusRequest; - boost::signal<void ()> onSignOutRequest; - void handleOwnVCardChanged(VCard::ref vcard); - void handleAvatarChanged(const JID& jid); - void handlePresenceChanged(Presence::ref presence); - void setEnabled(bool enabled); + class RosterController { + public: + 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, ClientBlockListManager* clientBlockListManager, VCardManager* vcardManager); + ~RosterController(); + void showRosterWindow(); + void setJID(const JID& jid) { myJID_ = jid; } + MainWindow* getWindow() {return mainWindow_;} + boost::signal<void (StatusShow::Type, const std::string&)> onChangeStatusRequest; + boost::signal<void ()> onSignOutRequest; + void handleOwnVCardChanged(VCard::ref vcard); + void handleAvatarChanged(const JID& jid); + void handlePresenceChanged(Presence::ref presence); + void setEnabled(bool enabled); - boost::optional<XMPPRosterItem> getItem(const JID&) const; - std::set<std::string> getGroups() const; + boost::optional<XMPPRosterItem> getItem(const JID&) const; + std::set<std::string> getGroups() const; - void setContactGroups(const JID& jid, const std::vector<std::string>& groups); - void updateItem(const XMPPRosterItem&); + void setContactGroups(const JID& jid, const std::vector<std::string>& groups); + void updateItem(const XMPPRosterItem&); - void initBlockingCommand(); + void initBlockingCommand(); - private: - void handleOnJIDAdded(const JID &jid); - void handleRosterCleared(); - void handleOnJIDRemoved(const JID &jid); - void handleOnJIDUpdated(const JID &jid, const std::string& oldName, const std::vector<std::string>& oldGroups); - void handleStartChatRequest(const JID& contact); - void handleChangeStatusRequest(StatusShow::Type show, const std::string &statusText); - void handleShowOfflineToggled(bool state); - void handleIncomingPresence(boost::shared_ptr<Presence> newPresence); - void handleSubscriptionRequest(const JID& jid, const std::string& message); - void handleSubscriptionRequestAccepted(SubscriptionRequestEvent* event); - void handleSubscriptionRequestDeclined(SubscriptionRequestEvent* event); - void handleUIEvent(boost::shared_ptr<UIEvent> event); - void handleRosterItemUpdated(ErrorPayload::ref error, boost::shared_ptr<RosterPayload> rosterPayload); - void handleRosterSetError(ErrorPayload::ref error, boost::shared_ptr<RosterPayload> rosterPayload); - void applyAllPresenceTo(const JID& jid); - void handleEditProfileRequest(); - void handleOnCapsChanged(const JID& jid); - void handleSettingChanged(const std::string& settingPath); + private: + void handleOnJIDAdded(const JID &jid); + void handleRosterCleared(); + void handleOnJIDRemoved(const JID &jid); + void handleOnJIDUpdated(const JID &jid, const std::string& oldName, const std::vector<std::string>& oldGroups); + void handleStartChatRequest(const JID& contact); + void handleChangeStatusRequest(StatusShow::Type show, const std::string &statusText); + void handleShowOfflineToggled(bool state); + void handleIncomingPresence(boost::shared_ptr<Presence> newPresence); + void handleSubscriptionRequest(const JID& jid, const std::string& message); + void handleSubscriptionRequestAccepted(SubscriptionRequestEvent* event); + void handleSubscriptionRequestDeclined(SubscriptionRequestEvent* event); + void handleUIEvent(boost::shared_ptr<UIEvent> event); + void handleRosterItemUpdated(ErrorPayload::ref error, boost::shared_ptr<RosterPayload> rosterPayload); + void handleRosterSetError(ErrorPayload::ref error, boost::shared_ptr<RosterPayload> rosterPayload); + void applyAllPresenceTo(const JID& jid); + void handleEditProfileRequest(); + void handleOnCapsChanged(const JID& jid); + void handleSettingChanged(const std::string& settingPath); - void handleBlockingStateChanged(); - void handleBlockingItemAdded(const JID& jid); - void handleBlockingItemRemoved(const JID& jid); + void handleBlockingStateChanged(); + void handleBlockingItemAdded(const JID& jid); + void handleBlockingItemRemoved(const JID& jid); - JID myJID_; - XMPPRoster* xmppRoster_; - MainWindowFactory* mainWindowFactory_; - MainWindow* mainWindow_; - Roster* roster_; - OfflineRosterFilter* offlineFilter_; - VCardManager* vcardManager_; - AvatarManager* avatarManager_; - NickManager* nickManager_; - NickResolver* nickResolver_; - PresenceOracle* presenceOracle_; - SubscriptionManager* subscriptionManager_; - EventController* eventController_; - RosterGroupExpandinessPersister* expandiness_; - IQRouter* iqRouter_; - SettingsProvider* settings_; - UIEventStream* uiEventStream_; - EntityCapsProvider* entityCapsManager_; - FileTransferOverview* ftOverview_; - ClientBlockListManager* clientBlockListManager_; - RosterVCardProvider* rosterVCardProvider_; - boost::shared_ptr<ContactRosterItem> ownContact_; - - boost::bsignals::scoped_connection blockingOnStateChangedConnection_; - boost::bsignals::scoped_connection blockingOnItemAddedConnection_; - boost::bsignals::scoped_connection blockingOnItemRemovedConnection_; - boost::bsignals::scoped_connection changeStatusConnection_; - boost::bsignals::scoped_connection signOutConnection_; - boost::bsignals::scoped_connection uiEventConnection_; - }; + JID myJID_; + XMPPRoster* xmppRoster_; + MainWindowFactory* mainWindowFactory_; + MainWindow* mainWindow_; + Roster* roster_; + OfflineRosterFilter* offlineFilter_; + VCardManager* vcardManager_; + AvatarManager* avatarManager_; + NickManager* nickManager_; + NickResolver* nickResolver_; + PresenceOracle* presenceOracle_; + SubscriptionManager* subscriptionManager_; + EventController* eventController_; + RosterGroupExpandinessPersister* expandiness_; + IQRouter* iqRouter_; + SettingsProvider* settings_; + UIEventStream* uiEventStream_; + EntityCapsProvider* entityCapsManager_; + FileTransferOverview* ftOverview_; + ClientBlockListManager* clientBlockListManager_; + RosterVCardProvider* rosterVCardProvider_; + boost::shared_ptr<ContactRosterItem> ownContact_; + + boost::bsignals::scoped_connection blockingOnStateChangedConnection_; + boost::bsignals::scoped_connection blockingOnItemAddedConnection_; + boost::bsignals::scoped_connection blockingOnItemRemovedConnection_; + boost::bsignals::scoped_connection changeStatusConnection_; + boost::bsignals::scoped_connection signOutConnection_; + boost::bsignals::scoped_connection uiEventConnection_; + }; } diff --git a/Swift/Controllers/Roster/RosterFilter.h b/Swift/Controllers/Roster/RosterFilter.h index e68ab57..6075c66 100644 --- a/Swift/Controllers/Roster/RosterFilter.h +++ b/Swift/Controllers/Roster/RosterFilter.h @@ -11,9 +11,9 @@ namespace Swift { class RosterFilter { - public: - virtual ~RosterFilter() {} - virtual bool operator() (RosterItem* item) const = 0; + public: + virtual ~RosterFilter() {} + virtual bool operator() (RosterItem* item) const = 0; }; } diff --git a/Swift/Controllers/Roster/RosterGroupExpandinessPersister.cpp b/Swift/Controllers/Roster/RosterGroupExpandinessPersister.cpp index a39667c..af89b54 100644 --- a/Swift/Controllers/Roster/RosterGroupExpandinessPersister.cpp +++ b/Swift/Controllers/Roster/RosterGroupExpandinessPersister.cpp @@ -19,45 +19,45 @@ namespace Swift { RosterGroupExpandinessPersister::RosterGroupExpandinessPersister(Roster* roster, SettingsProvider* settings) : roster_(roster), settings_(settings) { - load(); - roster_->onGroupAdded.connect(boost::bind(&RosterGroupExpandinessPersister::handleGroupAdded, this, _1)); + load(); + roster_->onGroupAdded.connect(boost::bind(&RosterGroupExpandinessPersister::handleGroupAdded, this, _1)); } void RosterGroupExpandinessPersister::handleGroupAdded(GroupRosterItem* group) { - if (collapsed_.find(group->getDisplayName()) != collapsed_.end()) { - group->setExpanded(false); - } else { - group->setExpanded(true); - } - group->onExpandedChanged.connect(boost::bind(&RosterGroupExpandinessPersister::handleExpandedChanged, this, group, _1)); + if (collapsed_.find(group->getDisplayName()) != collapsed_.end()) { + group->setExpanded(false); + } else { + group->setExpanded(true); + } + group->onExpandedChanged.connect(boost::bind(&RosterGroupExpandinessPersister::handleExpandedChanged, this, group, _1)); } void RosterGroupExpandinessPersister::handleExpandedChanged(GroupRosterItem* group, bool expanded) { - if (expanded) { - std::string displayName = group->getDisplayName(); - //collapsed_.erase(std::remove(collapsed_.begin(), collapsed_.end(), displayName), collapsed_.end()); - collapsed_.erase(displayName); - } else { - collapsed_.insert(group->getDisplayName()); - } - save(); + if (expanded) { + std::string displayName = group->getDisplayName(); + //collapsed_.erase(std::remove(collapsed_.begin(), collapsed_.end(), displayName), collapsed_.end()); + collapsed_.erase(displayName); + } else { + collapsed_.insert(group->getDisplayName()); + } + save(); } void RosterGroupExpandinessPersister::save() { - std::string setting; - foreach (const std::string& group, collapsed_) { - if (!setting.empty()) { - setting += "\n"; - } - setting += group; - } - settings_->storeSetting(SettingConstants::EXPANDED_ROSTER_GROUPS, setting); + std::string setting; + foreach (const std::string& group, collapsed_) { + if (!setting.empty()) { + setting += "\n"; + } + setting += group; + } + settings_->storeSetting(SettingConstants::EXPANDED_ROSTER_GROUPS, setting); } void RosterGroupExpandinessPersister::load() { - std::string saved = settings_->getSetting(SettingConstants::EXPANDED_ROSTER_GROUPS); - std::vector<std::string> collapsed = String::split(saved, '\n'); - collapsed_.insert(collapsed.begin(), collapsed.end()); + std::string saved = settings_->getSetting(SettingConstants::EXPANDED_ROSTER_GROUPS); + std::vector<std::string> collapsed = String::split(saved, '\n'); + collapsed_.insert(collapsed.begin(), collapsed.end()); } diff --git a/Swift/Controllers/Roster/RosterGroupExpandinessPersister.h b/Swift/Controllers/Roster/RosterGroupExpandinessPersister.h index c3d5c12..4cc08a7 100644 --- a/Swift/Controllers/Roster/RosterGroupExpandinessPersister.h +++ b/Swift/Controllers/Roster/RosterGroupExpandinessPersister.h @@ -12,16 +12,16 @@ #include <Swift/Controllers/Settings/SettingsProvider.h> namespace Swift { - class RosterGroupExpandinessPersister { - public: - RosterGroupExpandinessPersister(Roster* roster, SettingsProvider* settings); - private: - void handleExpandedChanged(GroupRosterItem* group, bool expanded); - void handleGroupAdded(GroupRosterItem* group); - void load(); - void save(); - std::set<std::string> collapsed_; - Roster* roster_; - SettingsProvider* settings_; - }; + class RosterGroupExpandinessPersister { + public: + RosterGroupExpandinessPersister(Roster* roster, SettingsProvider* settings); + private: + void handleExpandedChanged(GroupRosterItem* group, bool expanded); + void handleGroupAdded(GroupRosterItem* group); + void load(); + void save(); + std::set<std::string> collapsed_; + Roster* roster_; + SettingsProvider* settings_; + }; } diff --git a/Swift/Controllers/Roster/RosterItem.cpp b/Swift/Controllers/Roster/RosterItem.cpp index 51478c3..685613f 100644 --- a/Swift/Controllers/Roster/RosterItem.cpp +++ b/Swift/Controllers/Roster/RosterItem.cpp @@ -13,10 +13,10 @@ namespace Swift { RosterItem::RosterItem(const std::string& name, GroupRosterItem* parent) : name_(name), sortableDisplayName_(boost::to_lower_copy(name_)), parent_(parent) { - /* The following would be good, but because of C++'s inheritance not working in constructors, it's not going to work. */ - //if (parent) { - // parent_->addChild(this); - //} + /* The following would be good, but because of C++'s inheritance not working in constructors, it's not going to work. */ + //if (parent) { + // parent_->addChild(this); + //} } RosterItem::~RosterItem() { @@ -24,21 +24,21 @@ RosterItem::~RosterItem() { } GroupRosterItem* RosterItem::getParent() const { - return parent_; + return parent_; } void RosterItem::setDisplayName(const std::string& name) { - name_ = name; - sortableDisplayName_ = boost::to_lower_copy(name_); - onDataChanged(); + name_ = name; + sortableDisplayName_ = boost::to_lower_copy(name_); + onDataChanged(); } const std::string& RosterItem::getDisplayName() const { - return name_; + return name_; } const std::string& RosterItem::getSortableDisplayName() const { - return sortableDisplayName_; + return sortableDisplayName_; } diff --git a/Swift/Controllers/Roster/RosterItem.h b/Swift/Controllers/Roster/RosterItem.h index 736c6af..e7a3e20 100644 --- a/Swift/Controllers/Roster/RosterItem.h +++ b/Swift/Controllers/Roster/RosterItem.h @@ -15,18 +15,18 @@ namespace Swift { class GroupRosterItem; class RosterItem { - public: - RosterItem(const std::string& name, GroupRosterItem* parent); - virtual ~RosterItem(); - boost::signal<void ()> onDataChanged; - GroupRosterItem* getParent() const; - void setDisplayName(const std::string& name); - const std::string& getDisplayName() const; - virtual const std::string& getSortableDisplayName() const; - private: - std::string name_; - std::string sortableDisplayName_; - GroupRosterItem* parent_; + public: + RosterItem(const std::string& name, GroupRosterItem* parent); + virtual ~RosterItem(); + boost::signal<void ()> onDataChanged; + GroupRosterItem* getParent() const; + void setDisplayName(const std::string& name); + const std::string& getDisplayName() const; + virtual const std::string& getSortableDisplayName() const; + private: + std::string name_; + std::string sortableDisplayName_; + GroupRosterItem* parent_; }; } diff --git a/Swift/Controllers/Roster/RosterVCardProvider.cpp b/Swift/Controllers/Roster/RosterVCardProvider.cpp index d00d318..2aa82a9 100644 --- a/Swift/Controllers/Roster/RosterVCardProvider.cpp +++ b/Swift/Controllers/Roster/RosterVCardProvider.cpp @@ -20,22 +20,22 @@ namespace Swift { RosterVCardProvider::RosterVCardProvider(Roster* roster, VCardManager* vcardManager, JID::CompareType compareType) : roster_(roster), vcardManager_(vcardManager), compareType_(compareType) { - vcardUpdateRequestedConnection = roster_->onVCardUpdateRequested.connect(boost::bind(&RosterVCardProvider::handleVCardUpdateRequested, this, _1)); - vcardChangedConnection = vcardManager_->onVCardChanged.connect(boost::bind(&RosterVCardProvider::handleVCardChanged, this, _1, _2)); + vcardUpdateRequestedConnection = roster_->onVCardUpdateRequested.connect(boost::bind(&RosterVCardProvider::handleVCardUpdateRequested, this, _1)); + vcardChangedConnection = vcardManager_->onVCardChanged.connect(boost::bind(&RosterVCardProvider::handleVCardChanged, this, _1, _2)); } RosterVCardProvider::~RosterVCardProvider() { } void RosterVCardProvider::handleVCardUpdateRequested(const JID& jid) { - VCard::ref vcard = vcardManager_->getVCardAndRequestWhenNeeded(jid); - if (vcard) { - handleVCardChanged(jid, vcard); - } + VCard::ref vcard = vcardManager_->getVCardAndRequestWhenNeeded(jid); + if (vcard) { + handleVCardChanged(jid, vcard); + } } void RosterVCardProvider::handleVCardChanged(const JID& jid, VCard::ref vcard) { - roster_->applyOnItem(SetVCard(jid, vcard, compareType_), jid); + roster_->applyOnItem(SetVCard(jid, vcard, compareType_), jid); } diff --git a/Swift/Controllers/Roster/RosterVCardProvider.h b/Swift/Controllers/Roster/RosterVCardProvider.h index da41298..a697dae 100644 --- a/Swift/Controllers/Roster/RosterVCardProvider.h +++ b/Swift/Controllers/Roster/RosterVCardProvider.h @@ -18,20 +18,20 @@ class Roster; class VCardManager; class RosterVCardProvider { - public: - RosterVCardProvider(Roster* roster, VCardManager* vcardManager, JID::CompareType compareType); - ~RosterVCardProvider(); - - private: - void handleVCardUpdateRequested(const JID& jid); - void handleVCardChanged(const JID& jid, VCard::ref vcard); - - private: - Roster* roster_; - VCardManager* vcardManager_; - JID::CompareType compareType_; - boost::bsignals::scoped_connection vcardUpdateRequestedConnection; - boost::bsignals::scoped_connection vcardChangedConnection; + public: + RosterVCardProvider(Roster* roster, VCardManager* vcardManager, JID::CompareType compareType); + ~RosterVCardProvider(); + + private: + void handleVCardUpdateRequested(const JID& jid); + void handleVCardChanged(const JID& jid, VCard::ref vcard); + + private: + Roster* roster_; + VCardManager* vcardManager_; + JID::CompareType compareType_; + boost::bsignals::scoped_connection vcardUpdateRequestedConnection; + boost::bsignals::scoped_connection vcardChangedConnection; }; } diff --git a/Swift/Controllers/Roster/TableRoster.cpp b/Swift/Controllers/Roster/TableRoster.cpp index fde3304..f164a4d 100644 --- a/Swift/Controllers/Roster/TableRoster.cpp +++ b/Swift/Controllers/Roster/TableRoster.cpp @@ -21,167 +21,167 @@ #include <Swift/Controllers/Roster/Roster.h> namespace Swift { - struct SectionNameEquals { - bool operator()(const TableRoster::Section& s1, const TableRoster::Section& s2) const { - return s1.name == s2.name; - } - }; - - template<typename T> - struct True { - bool operator()(const T&, const T&) const { - return true; - } - }; - - struct ItemEquals { - bool operator()(const TableRoster::Item& i1, const TableRoster::Item& i2) const { - return i1.jid == i2.jid; - } - }; - - - struct ItemNeedsUpdate { - bool operator()(const TableRoster::Item& i1, const TableRoster::Item& i2) const { - return i1.status != i2.status || i1.description != i2.description || i1.name != i2.name || i1.avatarPath.empty() != i2.avatarPath.empty(); - } - }; - - struct CreateIndexForSection { - CreateIndexForSection(size_t section) : section(section) { - } - - TableRoster::Index operator()(size_t row) const { - return TableRoster::Index(section, row); - } - - size_t section; - }; + struct SectionNameEquals { + bool operator()(const TableRoster::Section& s1, const TableRoster::Section& s2) const { + return s1.name == s2.name; + } + }; + + template<typename T> + struct True { + bool operator()(const T&, const T&) const { + return true; + } + }; + + struct ItemEquals { + bool operator()(const TableRoster::Item& i1, const TableRoster::Item& i2) const { + return i1.jid == i2.jid; + } + }; + + + struct ItemNeedsUpdate { + bool operator()(const TableRoster::Item& i1, const TableRoster::Item& i2) const { + return i1.status != i2.status || i1.description != i2.description || i1.name != i2.name || i1.avatarPath.empty() != i2.avatarPath.empty(); + } + }; + + struct CreateIndexForSection { + CreateIndexForSection(size_t section) : section(section) { + } + + TableRoster::Index operator()(size_t row) const { + return TableRoster::Index(section, row); + } + + size_t section; + }; } using namespace Swift; TableRoster::TableRoster(Roster* model, TimerFactory* timerFactory, int updateDelay) : model(model), updatePending(false) { - updateTimer = timerFactory->createTimer(updateDelay); - updateTimer->onTick.connect(boost::bind(&TableRoster::handleUpdateTimerTick, this)); - if (model) { - model->onChildrenChanged.connect(boost::bind(&TableRoster::scheduleUpdate, this)); - model->onGroupAdded.connect(boost::bind(&TableRoster::scheduleUpdate, this)); - model->onDataChanged.connect(boost::bind(&TableRoster::scheduleUpdate, this)); - } + updateTimer = timerFactory->createTimer(updateDelay); + updateTimer->onTick.connect(boost::bind(&TableRoster::handleUpdateTimerTick, this)); + if (model) { + model->onChildrenChanged.connect(boost::bind(&TableRoster::scheduleUpdate, this)); + model->onGroupAdded.connect(boost::bind(&TableRoster::scheduleUpdate, this)); + model->onDataChanged.connect(boost::bind(&TableRoster::scheduleUpdate, this)); + } } TableRoster::~TableRoster() { - updateTimer->stop(); - updateTimer->onTick.disconnect(boost::bind(&TableRoster::handleUpdateTimerTick, this)); - if (model) { - model->onDataChanged.disconnect(boost::bind(&TableRoster::scheduleUpdate, this)); - model->onGroupAdded.disconnect(boost::bind(&TableRoster::scheduleUpdate, this)); - model->onChildrenChanged.disconnect(boost::bind(&TableRoster::scheduleUpdate, this)); - } + updateTimer->stop(); + updateTimer->onTick.disconnect(boost::bind(&TableRoster::handleUpdateTimerTick, this)); + if (model) { + model->onDataChanged.disconnect(boost::bind(&TableRoster::scheduleUpdate, this)); + model->onGroupAdded.disconnect(boost::bind(&TableRoster::scheduleUpdate, this)); + model->onChildrenChanged.disconnect(boost::bind(&TableRoster::scheduleUpdate, this)); + } } - + size_t TableRoster::getNumberOfSections() const { - return sections.size(); + return sections.size(); } const std::string& TableRoster::getSectionTitle(size_t section) { - return sections[section].name; + return sections[section].name; } size_t TableRoster::getNumberOfRowsInSection(size_t section) const { - return sections[section].items.size(); + return sections[section].items.size(); } const TableRoster::Item& TableRoster::getItem(const Index& index) const { - return sections[index.section].items[index.row]; + return sections[index.section].items[index.row]; } - + void TableRoster::handleUpdateTimerTick() { - updateTimer->stop(); - updatePending = false; - - // Get a model for the new roster - std::vector<Section> newSections; - if (model) { - foreach(RosterItem* item, model->getRoot()->getDisplayedChildren()) { - if (GroupRosterItem* groupItem = boost::polymorphic_downcast<GroupRosterItem*>(item)) { - //std::cerr << "* " << groupItem->getDisplayName() << std::endl; - Section section(groupItem->getDisplayName()); - foreach(RosterItem* groupChildItem, groupItem->getDisplayedChildren()) { - if (ContactRosterItem* contact = boost::polymorphic_downcast<ContactRosterItem*>(groupChildItem)) { - //std::cerr << " - " << contact->getDisplayJID() << std::endl; - section.items.push_back(Item(contact->getDisplayName(), contact->getStatusText(), contact->getDisplayJID(), contact->getStatusShow(), contact->getAvatarPath())); - } - } - newSections.push_back(section); - } - } - } - - // Do a diff with the previous roster - Update update; - std::vector<size_t> sectionUpdates; - std::vector<size_t> sectionPostUpdates; - computeIndexDiff<Section,SectionNameEquals,True<Section> >(sections, newSections, sectionUpdates, sectionPostUpdates, update.deletedSections, update.insertedSections); - assert(sectionUpdates.size() == sectionPostUpdates.size()); - for (size_t i = 0; i < sectionUpdates.size(); ++i) { - assert(sectionUpdates[i] < sections.size()); - assert(sectionPostUpdates[i] < newSections.size()); - std::vector<size_t> itemUpdates; - std::vector<size_t> itemPostUpdates; - std::vector<size_t> itemRemoves; - std::vector<size_t> itemInserts; - 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() + 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() + 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() + boost::numeric_cast<long long>(end), CreateIndexForSection(sectionPostUpdates[i])); - } - - // Switch the old model with the new - sections.swap(newSections); - - /* - std::cerr << "-S: "; - for (size_t i = 0; i < update.deletedSections.size(); ++i) { - std::cerr << update.deletedSections[i] << " "; - } - std::cerr << std::endl; - std::cerr << "+S: "; - for (size_t i = 0; i < update.insertedSections.size(); ++i) { - std::cerr << update.insertedSections[i] << " "; - } - std::cerr << std::endl; - std::cerr << "-R: "; - for (size_t i = 0; i < update.deletedRows.size(); ++i) { - std::cerr << update.deletedRows[i].section << "," << update.deletedRows[i].row << " "; - } - std::cerr << std::endl; - std::cerr << "*R: "; - for (size_t i = 0; i < update.updatedRows.size(); ++i) { - std::cerr << update.updatedRows[i].section << "," << update.updatedRows[i].row << " "; - } - std::cerr << std::endl; - std::cerr << "+R: "; - for (size_t i = 0; i < update.insertedRows.size(); ++i) { - std::cerr << update.insertedRows[i].section << "," << update.insertedRows[i].row << " "; - } - std::cerr << std::endl; - */ - - // Emit the update - onUpdate(update); + updateTimer->stop(); + updatePending = false; + + // Get a model for the new roster + std::vector<Section> newSections; + if (model) { + foreach(RosterItem* item, model->getRoot()->getDisplayedChildren()) { + if (GroupRosterItem* groupItem = boost::polymorphic_downcast<GroupRosterItem*>(item)) { + //std::cerr << "* " << groupItem->getDisplayName() << std::endl; + Section section(groupItem->getDisplayName()); + foreach(RosterItem* groupChildItem, groupItem->getDisplayedChildren()) { + if (ContactRosterItem* contact = boost::polymorphic_downcast<ContactRosterItem*>(groupChildItem)) { + //std::cerr << " - " << contact->getDisplayJID() << std::endl; + section.items.push_back(Item(contact->getDisplayName(), contact->getStatusText(), contact->getDisplayJID(), contact->getStatusShow(), contact->getAvatarPath())); + } + } + newSections.push_back(section); + } + } + } + + // Do a diff with the previous roster + Update update; + std::vector<size_t> sectionUpdates; + std::vector<size_t> sectionPostUpdates; + computeIndexDiff<Section,SectionNameEquals,True<Section> >(sections, newSections, sectionUpdates, sectionPostUpdates, update.deletedSections, update.insertedSections); + assert(sectionUpdates.size() == sectionPostUpdates.size()); + for (size_t i = 0; i < sectionUpdates.size(); ++i) { + assert(sectionUpdates[i] < sections.size()); + assert(sectionPostUpdates[i] < newSections.size()); + std::vector<size_t> itemUpdates; + std::vector<size_t> itemPostUpdates; + std::vector<size_t> itemRemoves; + std::vector<size_t> itemInserts; + 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() + 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() + 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() + boost::numeric_cast<long long>(end), CreateIndexForSection(sectionPostUpdates[i])); + } + + // Switch the old model with the new + sections.swap(newSections); + + /* + std::cerr << "-S: "; + for (size_t i = 0; i < update.deletedSections.size(); ++i) { + std::cerr << update.deletedSections[i] << " "; + } + std::cerr << std::endl; + std::cerr << "+S: "; + for (size_t i = 0; i < update.insertedSections.size(); ++i) { + std::cerr << update.insertedSections[i] << " "; + } + std::cerr << std::endl; + std::cerr << "-R: "; + for (size_t i = 0; i < update.deletedRows.size(); ++i) { + std::cerr << update.deletedRows[i].section << "," << update.deletedRows[i].row << " "; + } + std::cerr << std::endl; + std::cerr << "*R: "; + for (size_t i = 0; i < update.updatedRows.size(); ++i) { + std::cerr << update.updatedRows[i].section << "," << update.updatedRows[i].row << " "; + } + std::cerr << std::endl; + std::cerr << "+R: "; + for (size_t i = 0; i < update.insertedRows.size(); ++i) { + std::cerr << update.insertedRows[i].section << "," << update.insertedRows[i].row << " "; + } + std::cerr << std::endl; + */ + + // Emit the update + onUpdate(update); } void TableRoster::scheduleUpdate() { - if (!updatePending) { - updatePending = true; - updateTimer->start(); - } + if (!updatePending) { + updatePending = true; + updateTimer->start(); + } } diff --git a/Swift/Controllers/Roster/TableRoster.h b/Swift/Controllers/Roster/TableRoster.h index 87f9e75..3d336ef 100644 --- a/Swift/Controllers/Roster/TableRoster.h +++ b/Swift/Controllers/Roster/TableRoster.h @@ -16,70 +16,70 @@ #include <Swiften/JID/JID.h> namespace Swift { - class Roster; - class TimerFactory; - class Timer; - - class TableRoster { - public: - struct Item { - Item(const std::string& name, const std::string& description, const JID& jid, StatusShow::Type status, const boost::filesystem::path& avatarPath) : name(name), description(description), jid(jid), status(status), avatarPath(avatarPath) { - } - std::string name; - std::string description; - JID jid; - StatusShow::Type status; - boost::filesystem::path avatarPath; - }; - - struct Index { - Index(size_t section = 0, size_t row = 0) : section(section), row(row) { - } - size_t section; - size_t row; - - bool operator==(const Index& o) const { - return o.section == section && o.row == row; - } - }; - - struct Update { - std::vector<Index> updatedRows; - std::vector<Index> insertedRows; - std::vector<Index> deletedRows; - std::vector<size_t> insertedSections; - std::vector<size_t> deletedSections; - }; - - TableRoster(Roster* model, TimerFactory* timerFactory, int updateDelay); - ~TableRoster(); - - size_t getNumberOfSections() const; - size_t getNumberOfRowsInSection(size_t section) const; - - const std::string& getSectionTitle(size_t); - - const Item& getItem(const Index&) const; - - boost::signal<void (const Update&)> onUpdate; - - private: - void handleUpdateTimerTick(); - void scheduleUpdate(); - - private: - friend struct SectionNameEquals; - struct Section { - Section(const std::string& name) : name(name) { - } - - std::string name; - std::vector<Item> items; - }; - - Roster* model; - std::vector<Section> sections; - bool updatePending; - boost::shared_ptr<Timer> updateTimer; - }; + class Roster; + class TimerFactory; + class Timer; + + class TableRoster { + public: + struct Item { + Item(const std::string& name, const std::string& description, const JID& jid, StatusShow::Type status, const boost::filesystem::path& avatarPath) : name(name), description(description), jid(jid), status(status), avatarPath(avatarPath) { + } + std::string name; + std::string description; + JID jid; + StatusShow::Type status; + boost::filesystem::path avatarPath; + }; + + struct Index { + Index(size_t section = 0, size_t row = 0) : section(section), row(row) { + } + size_t section; + size_t row; + + bool operator==(const Index& o) const { + return o.section == section && o.row == row; + } + }; + + struct Update { + std::vector<Index> updatedRows; + std::vector<Index> insertedRows; + std::vector<Index> deletedRows; + std::vector<size_t> insertedSections; + std::vector<size_t> deletedSections; + }; + + TableRoster(Roster* model, TimerFactory* timerFactory, int updateDelay); + ~TableRoster(); + + size_t getNumberOfSections() const; + size_t getNumberOfRowsInSection(size_t section) const; + + const std::string& getSectionTitle(size_t); + + const Item& getItem(const Index&) const; + + boost::signal<void (const Update&)> onUpdate; + + private: + void handleUpdateTimerTick(); + void scheduleUpdate(); + + private: + friend struct SectionNameEquals; + struct Section { + Section(const std::string& name) : name(name) { + } + + std::string name; + std::vector<Item> items; + }; + + Roster* model; + std::vector<Section> sections; + bool updatePending; + boost::shared_ptr<Timer> updateTimer; + }; } diff --git a/Swift/Controllers/Roster/UnitTest/LeastCommonSubsequenceTest.cpp b/Swift/Controllers/Roster/UnitTest/LeastCommonSubsequenceTest.cpp index 144de77..5844ebe 100644 --- a/Swift/Controllers/Roster/UnitTest/LeastCommonSubsequenceTest.cpp +++ b/Swift/Controllers/Roster/UnitTest/LeastCommonSubsequenceTest.cpp @@ -18,294 +18,294 @@ using namespace Swift; struct IsBOrC { - bool operator()(char c, char c2) const { - CPPUNIT_ASSERT_EQUAL(c, c2); - return c == 'b' || c == 'c'; - } + bool operator()(char c, char c2) const { + CPPUNIT_ASSERT_EQUAL(c, c2); + return c == 'b' || c == 'c'; + } }; struct IsXOrY { - bool operator()(char c, char c2) const { - CPPUNIT_ASSERT_EQUAL(c, c2); - return c == 'x' || c == 'y'; - } + bool operator()(char c, char c2) const { + CPPUNIT_ASSERT_EQUAL(c, c2); + return c == 'x' || c == 'y'; + } }; struct IsArizonaOrNewJersey { - bool operator()(const std::string& s, const std::string& s2) const { - CPPUNIT_ASSERT_EQUAL(s, s2); - return s == "Arizona" || s == "New Jersey"; - } + bool operator()(const std::string& s, const std::string& s2) const { + CPPUNIT_ASSERT_EQUAL(s, s2); + return s == "Arizona" || s == "New Jersey"; + } }; class LeastCommonSubsequenceTest : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(LeastCommonSubsequenceTest); - CPPUNIT_TEST(testComputeLeastCommonSubsequenceMatrix_1); - CPPUNIT_TEST(testComputeLeastCommonSubsequenceMatrix_2); - CPPUNIT_TEST(testComputeLeastCommonSubsequenceMatrix_Sequence1Empty); - CPPUNIT_TEST(testComputeLeastCommonSubsequenceMatrix_Sequence2Empty); - CPPUNIT_TEST(testComputeLeastCommonSubsequenceMatrix_BothSequencesEmpty); - CPPUNIT_TEST(testComputeLeastCommonSubsequenceMatrix_NoCommonSequence); - CPPUNIT_TEST(testComputeLeastCommonSubsequenceMatrix_SameSequences); - CPPUNIT_TEST(testComputeIndexDiff_1); - CPPUNIT_TEST(testComputeIndexDiff_2); - CPPUNIT_TEST(testComputeIndexDiff_Sequence1Empty); - CPPUNIT_TEST(testComputeIndexDiff_Sequence2Empty); - CPPUNIT_TEST(testComputeIndexDiff_BothSequencesEmpty); - CPPUNIT_TEST(testComputeIndexDiff_NoCommonSequence); - CPPUNIT_TEST(testComputeIndexDiff_SameSequences); - CPPUNIT_TEST(testComputeIndexDiff_CommonPrefixAndSuffix); - CPPUNIT_TEST_SUITE_END(); - - public: - void testComputeLeastCommonSubsequenceMatrix_1() { - std::vector<char> x = boost::assign::list_of('x')('m')('j')('y')('a')('u')('z'); - std::vector<char> y = boost::assign::list_of('m')('z')('j')('a')('w')('x')('u'); - - std::vector<int> result; - Detail::computeLeastCommonSubsequenceMatrix<std::vector<char>::const_iterator, std::vector<char>::const_iterator, int, std::equal_to<char> >(x.begin(), x.end(), y.begin(), y.end(), result); - - std::vector<int> expected = boost::assign::list_of - (0)(0)(0)(0)(0)(0)(0)(0) - (0)(0)(1)(1)(1)(1)(1)(1) - (0)(0)(1)(1)(1)(1)(1)(2) - (0)(0)(1)(2)(2)(2)(2)(2) - (0)(0)(1)(2)(2)(3)(3)(3) - (0)(0)(1)(2)(2)(3)(3)(3) - (0)(1)(1)(2)(2)(3)(3)(3) - (0)(1)(1)(2)(2)(3)(4)(4); - CPPUNIT_ASSERT_EQUAL(expected, result); - } - - void testComputeLeastCommonSubsequenceMatrix_2() { - std::vector<char> x = boost::assign::list_of('x')('x')('x')('m')('j')('y')('a')('u')('z'); - std::vector<char> y = boost::assign::list_of('m')('z')('j')('a')('w')('x')('u'); - - std::vector<int> result; - Detail::computeLeastCommonSubsequenceMatrix<std::vector<char>::const_iterator, std::vector<char>::const_iterator, int, std::equal_to<char> >(x.begin(), x.end(), y.begin(), y.end(), result); - - std::vector<int> expected = boost::assign::list_of - (0)(0)(0)(0)(0)(0)(0)(0)(0)(0) - (0)(0)(0)(0)(1)(1)(1)(1)(1)(1) - (0)(0)(0)(0)(1)(1)(1)(1)(1)(2) - (0)(0)(0)(0)(1)(2)(2)(2)(2)(2) - (0)(0)(0)(0)(1)(2)(2)(3)(3)(3) - (0)(0)(0)(0)(1)(2)(2)(3)(3)(3) - (0)(1)(1)(1)(1)(2)(2)(3)(3)(3) - (0)(1)(1)(1)(1)(2)(2)(3)(4)(4); - CPPUNIT_ASSERT_EQUAL(expected, result); - } - - void testComputeLeastCommonSubsequenceMatrix_Sequence1Empty() { - std::vector<char> x; - std::vector<char> y = boost::assign::list_of('a')('b')('c'); - - std::vector<int> result; - Detail::computeLeastCommonSubsequenceMatrix<std::vector<char>::const_iterator, std::vector<char>::const_iterator, int, std::equal_to<char> >(x.begin(), x.end(), y.begin(), y.end(), result); - - std::vector<int> expected = boost::assign::list_of - (0) - (0) - (0) - (0); - CPPUNIT_ASSERT_EQUAL(expected, result); - } - - void testComputeLeastCommonSubsequenceMatrix_Sequence2Empty() { - std::vector<char> x = boost::assign::list_of('a')('b')('c'); - std::vector<char> y; - - std::vector<int> result; - Detail::computeLeastCommonSubsequenceMatrix<std::vector<char>::const_iterator, std::vector<char>::const_iterator, int, std::equal_to<char> >(x.begin(), x.end(), y.begin(), y.end(), result); - - std::vector<int> expected = boost::assign::list_of - (0)(0)(0)(0); - CPPUNIT_ASSERT_EQUAL(expected, result); - } - - void testComputeLeastCommonSubsequenceMatrix_BothSequencesEmpty() { - std::vector<char> x; - std::vector<char> y; - - std::vector<int> result; - Detail::computeLeastCommonSubsequenceMatrix<std::vector<char>::const_iterator, std::vector<char>::const_iterator, int, std::equal_to<char> >(x.begin(), x.end(), y.begin(), y.end(), result); - - std::vector<int> expected = boost::assign::list_of(0); - CPPUNIT_ASSERT_EQUAL(expected, result); - } - - void testComputeLeastCommonSubsequenceMatrix_NoCommonSequence() { - std::vector<char> x = boost::assign::list_of('a')('b')('c'); - std::vector<char> y = boost::assign::list_of('d')('e')('f')('g'); - - std::vector<int> result; - Detail::computeLeastCommonSubsequenceMatrix<std::vector<char>::const_iterator, std::vector<char>::const_iterator, int, std::equal_to<char> >(x.begin(), x.end(), y.begin(), y.end(), result); - - std::vector<int> expected = boost::assign::list_of - (0)(0)(0)(0) - (0)(0)(0)(0) - (0)(0)(0)(0) - (0)(0)(0)(0) - (0)(0)(0)(0); - CPPUNIT_ASSERT_EQUAL(expected, result); - } - - void testComputeLeastCommonSubsequenceMatrix_SameSequences() { - std::vector<char> x = boost::assign::list_of('a')('b')('c'); - std::vector<char> y = boost::assign::list_of('a')('b')('c'); - - std::vector<int> result; - Detail::computeLeastCommonSubsequenceMatrix<std::vector<char>::const_iterator, std::vector<char>::const_iterator, int, std::equal_to<char> >(x.begin(), x.end(), y.begin(), y.end(), result); - - std::vector<int> expected = boost::assign::list_of - (0)(0)(0)(0) - (0)(1)(1)(1) - (0)(1)(2)(2) - (0)(1)(2)(3); - CPPUNIT_ASSERT_EQUAL(expected, result); - } - - void testComputeIndexDiff_1() { - std::vector<std::string> x = boost::assign::list_of("Arizona")("California")("Delaware")("New Jersey")("Washington"); - std::vector<std::string> y = boost::assign::list_of("Alaska")("Arizona")("California")("Georgia")("New Jersey")("Virginia"); - - std::vector<size_t> updates; - std::vector<size_t> postUpdates; - std::vector<size_t> removes; - std::vector<size_t> inserts; - computeIndexDiff<std::string, std::equal_to<std::string>, IsArizonaOrNewJersey >(x, y, updates, postUpdates, removes, inserts); - - std::vector<size_t> expectedUpdates = boost::assign::list_of(3)(0); - std::vector<size_t> expectedPostUpdates = boost::assign::list_of(4)(1); - std::vector<size_t> expectedRemoves = boost::assign::list_of(4)(2); - std::vector<size_t> expectedInserts = boost::assign::list_of(5)(3)(0); - CPPUNIT_ASSERT_EQUAL(expectedUpdates, updates); - CPPUNIT_ASSERT_EQUAL(expectedPostUpdates, postUpdates); - CPPUNIT_ASSERT_EQUAL(expectedRemoves, removes); - CPPUNIT_ASSERT_EQUAL(expectedInserts, inserts); - } - - void testComputeIndexDiff_2() { - std::vector<char> x = boost::assign::list_of('x')('y'); - std::vector<char> y = boost::assign::list_of('x'); - - std::vector<size_t> updates; - std::vector<size_t> postUpdates; - std::vector<size_t> removes; - std::vector<size_t> inserts; - computeIndexDiff<char, std::equal_to<char>, IsBOrC >(x, y, updates, postUpdates, removes, inserts); - - std::vector<size_t> expectedRemoves = boost::assign::list_of(1); - CPPUNIT_ASSERT(updates.empty()); - CPPUNIT_ASSERT(postUpdates.empty()); - CPPUNIT_ASSERT(inserts.empty()); - CPPUNIT_ASSERT_EQUAL(expectedRemoves, removes); - } - - void testComputeIndexDiff_Sequence1Empty() { - std::vector<char> x; - std::vector<char> y = boost::assign::list_of('a')('b')('c'); - - std::vector<size_t> updates; - std::vector<size_t> postUpdates; - std::vector<size_t> removes; - std::vector<size_t> inserts; - computeIndexDiff<char, std::equal_to<char>, IsBOrC >(x, y, updates, postUpdates, removes, inserts); - - std::vector<size_t> expectedInserts = boost::assign::list_of(2)(1)(0); - CPPUNIT_ASSERT(updates.empty()); - CPPUNIT_ASSERT(postUpdates.empty()); - CPPUNIT_ASSERT(removes.empty()); - CPPUNIT_ASSERT_EQUAL(expectedInserts, inserts); - } - - void testComputeIndexDiff_Sequence2Empty() { - std::vector<char> x = boost::assign::list_of('a')('b')('c'); - std::vector<char> y; - - std::vector<size_t> updates; - std::vector<size_t> postUpdates; - std::vector<size_t> removes; - std::vector<size_t> inserts; - computeIndexDiff<char, std::equal_to<char>, IsBOrC >(x, y, updates, postUpdates, removes, inserts); - - std::vector<size_t> expectedRemoves = boost::assign::list_of(2)(1)(0); - CPPUNIT_ASSERT(updates.empty()); - CPPUNIT_ASSERT(postUpdates.empty()); - CPPUNIT_ASSERT_EQUAL(expectedRemoves, removes); - CPPUNIT_ASSERT(inserts.empty()); - } - - void testComputeIndexDiff_BothSequencesEmpty() { - std::vector<char> x; - std::vector<char> y; - - std::vector<size_t> updates; - std::vector<size_t> postUpdates; - std::vector<size_t> removes; - std::vector<size_t> inserts; - computeIndexDiff<char, std::equal_to<char>, IsBOrC >(x, y, updates, postUpdates, removes, inserts); - - CPPUNIT_ASSERT(updates.empty()); - CPPUNIT_ASSERT(postUpdates.empty()); - CPPUNIT_ASSERT(removes.empty()); - CPPUNIT_ASSERT(inserts.empty()); - } - - void testComputeIndexDiff_NoCommonSequence() { - std::vector<char> x = boost::assign::list_of('a')('b')('c'); - std::vector<char> y = boost::assign::list_of('d')('e')('f')('g'); - - std::vector<size_t> updates; - std::vector<size_t> postUpdates; - std::vector<size_t> removes; - std::vector<size_t> inserts; - computeIndexDiff<char, std::equal_to<char>, IsBOrC >(x, y, updates, postUpdates, removes, inserts); - - std::vector<size_t> expectedRemoves = boost::assign::list_of(2)(1)(0); - std::vector<size_t> expectedInserts = boost::assign::list_of(3)(2)(1)(0); - CPPUNIT_ASSERT(updates.empty()); - CPPUNIT_ASSERT(postUpdates.empty()); - CPPUNIT_ASSERT_EQUAL(expectedRemoves, removes); - CPPUNIT_ASSERT_EQUAL(expectedInserts, inserts); - } - - void testComputeIndexDiff_SameSequences() { - std::vector<char> x = boost::assign::list_of('a')('b')('c'); - std::vector<char> y = boost::assign::list_of('a')('b')('c'); - - std::vector<size_t> updates; - std::vector<size_t> postUpdates; - std::vector<size_t> removes; - std::vector<size_t> inserts; - computeIndexDiff<char, std::equal_to<char>, IsBOrC >(x, y, updates, postUpdates, removes, inserts); - - std::vector<size_t> expectedUpdates = boost::assign::list_of(1)(2); - CPPUNIT_ASSERT_EQUAL(expectedUpdates, updates); - CPPUNIT_ASSERT_EQUAL(expectedUpdates, postUpdates); - CPPUNIT_ASSERT(removes.empty()); - CPPUNIT_ASSERT(inserts.empty()); - } - - void testComputeIndexDiff_CommonPrefixAndSuffix() { - std::vector<char> x = boost::assign::list_of('x')('x')('x')('x')('a')('b')('c')('d')('e')('y')('y')('y'); - std::vector<char> y = boost::assign::list_of('x')('x')('x')('x')('e')('a')('b')('f')('d')('g')('y')('y')('y'); - - std::vector<size_t> updates; - std::vector<size_t> postUpdates; - std::vector<size_t> removes; - std::vector<size_t> inserts; - computeIndexDiff<char, std::equal_to<char>, IsXOrY >(x, y, updates, postUpdates, removes, inserts); - - std::vector<size_t> expectedUpdates = boost::assign::list_of(0)(1)(2)(3)(11)(10)(9); - std::vector<size_t> expectedPostUpdates = boost::assign::list_of(0)(1)(2)(3)(12)(11)(10); - std::vector<size_t> expectedRemoves = boost::assign::list_of(8)(6); - std::vector<size_t> expectedInserts = boost::assign::list_of(9)(7)(4); - CPPUNIT_ASSERT_EQUAL(expectedUpdates, updates); - CPPUNIT_ASSERT_EQUAL(expectedPostUpdates, postUpdates); - CPPUNIT_ASSERT_EQUAL(expectedRemoves, removes); - CPPUNIT_ASSERT_EQUAL(expectedInserts, inserts); - } + CPPUNIT_TEST_SUITE(LeastCommonSubsequenceTest); + CPPUNIT_TEST(testComputeLeastCommonSubsequenceMatrix_1); + CPPUNIT_TEST(testComputeLeastCommonSubsequenceMatrix_2); + CPPUNIT_TEST(testComputeLeastCommonSubsequenceMatrix_Sequence1Empty); + CPPUNIT_TEST(testComputeLeastCommonSubsequenceMatrix_Sequence2Empty); + CPPUNIT_TEST(testComputeLeastCommonSubsequenceMatrix_BothSequencesEmpty); + CPPUNIT_TEST(testComputeLeastCommonSubsequenceMatrix_NoCommonSequence); + CPPUNIT_TEST(testComputeLeastCommonSubsequenceMatrix_SameSequences); + CPPUNIT_TEST(testComputeIndexDiff_1); + CPPUNIT_TEST(testComputeIndexDiff_2); + CPPUNIT_TEST(testComputeIndexDiff_Sequence1Empty); + CPPUNIT_TEST(testComputeIndexDiff_Sequence2Empty); + CPPUNIT_TEST(testComputeIndexDiff_BothSequencesEmpty); + CPPUNIT_TEST(testComputeIndexDiff_NoCommonSequence); + CPPUNIT_TEST(testComputeIndexDiff_SameSequences); + CPPUNIT_TEST(testComputeIndexDiff_CommonPrefixAndSuffix); + CPPUNIT_TEST_SUITE_END(); + + public: + void testComputeLeastCommonSubsequenceMatrix_1() { + std::vector<char> x = boost::assign::list_of('x')('m')('j')('y')('a')('u')('z'); + std::vector<char> y = boost::assign::list_of('m')('z')('j')('a')('w')('x')('u'); + + std::vector<int> result; + Detail::computeLeastCommonSubsequenceMatrix<std::vector<char>::const_iterator, std::vector<char>::const_iterator, int, std::equal_to<char> >(x.begin(), x.end(), y.begin(), y.end(), result); + + std::vector<int> expected = boost::assign::list_of + (0)(0)(0)(0)(0)(0)(0)(0) + (0)(0)(1)(1)(1)(1)(1)(1) + (0)(0)(1)(1)(1)(1)(1)(2) + (0)(0)(1)(2)(2)(2)(2)(2) + (0)(0)(1)(2)(2)(3)(3)(3) + (0)(0)(1)(2)(2)(3)(3)(3) + (0)(1)(1)(2)(2)(3)(3)(3) + (0)(1)(1)(2)(2)(3)(4)(4); + CPPUNIT_ASSERT_EQUAL(expected, result); + } + + void testComputeLeastCommonSubsequenceMatrix_2() { + std::vector<char> x = boost::assign::list_of('x')('x')('x')('m')('j')('y')('a')('u')('z'); + std::vector<char> y = boost::assign::list_of('m')('z')('j')('a')('w')('x')('u'); + + std::vector<int> result; + Detail::computeLeastCommonSubsequenceMatrix<std::vector<char>::const_iterator, std::vector<char>::const_iterator, int, std::equal_to<char> >(x.begin(), x.end(), y.begin(), y.end(), result); + + std::vector<int> expected = boost::assign::list_of + (0)(0)(0)(0)(0)(0)(0)(0)(0)(0) + (0)(0)(0)(0)(1)(1)(1)(1)(1)(1) + (0)(0)(0)(0)(1)(1)(1)(1)(1)(2) + (0)(0)(0)(0)(1)(2)(2)(2)(2)(2) + (0)(0)(0)(0)(1)(2)(2)(3)(3)(3) + (0)(0)(0)(0)(1)(2)(2)(3)(3)(3) + (0)(1)(1)(1)(1)(2)(2)(3)(3)(3) + (0)(1)(1)(1)(1)(2)(2)(3)(4)(4); + CPPUNIT_ASSERT_EQUAL(expected, result); + } + + void testComputeLeastCommonSubsequenceMatrix_Sequence1Empty() { + std::vector<char> x; + std::vector<char> y = boost::assign::list_of('a')('b')('c'); + + std::vector<int> result; + Detail::computeLeastCommonSubsequenceMatrix<std::vector<char>::const_iterator, std::vector<char>::const_iterator, int, std::equal_to<char> >(x.begin(), x.end(), y.begin(), y.end(), result); + + std::vector<int> expected = boost::assign::list_of + (0) + (0) + (0) + (0); + CPPUNIT_ASSERT_EQUAL(expected, result); + } + + void testComputeLeastCommonSubsequenceMatrix_Sequence2Empty() { + std::vector<char> x = boost::assign::list_of('a')('b')('c'); + std::vector<char> y; + + std::vector<int> result; + Detail::computeLeastCommonSubsequenceMatrix<std::vector<char>::const_iterator, std::vector<char>::const_iterator, int, std::equal_to<char> >(x.begin(), x.end(), y.begin(), y.end(), result); + + std::vector<int> expected = boost::assign::list_of + (0)(0)(0)(0); + CPPUNIT_ASSERT_EQUAL(expected, result); + } + + void testComputeLeastCommonSubsequenceMatrix_BothSequencesEmpty() { + std::vector<char> x; + std::vector<char> y; + + std::vector<int> result; + Detail::computeLeastCommonSubsequenceMatrix<std::vector<char>::const_iterator, std::vector<char>::const_iterator, int, std::equal_to<char> >(x.begin(), x.end(), y.begin(), y.end(), result); + + std::vector<int> expected = boost::assign::list_of(0); + CPPUNIT_ASSERT_EQUAL(expected, result); + } + + void testComputeLeastCommonSubsequenceMatrix_NoCommonSequence() { + std::vector<char> x = boost::assign::list_of('a')('b')('c'); + std::vector<char> y = boost::assign::list_of('d')('e')('f')('g'); + + std::vector<int> result; + Detail::computeLeastCommonSubsequenceMatrix<std::vector<char>::const_iterator, std::vector<char>::const_iterator, int, std::equal_to<char> >(x.begin(), x.end(), y.begin(), y.end(), result); + + std::vector<int> expected = boost::assign::list_of + (0)(0)(0)(0) + (0)(0)(0)(0) + (0)(0)(0)(0) + (0)(0)(0)(0) + (0)(0)(0)(0); + CPPUNIT_ASSERT_EQUAL(expected, result); + } + + void testComputeLeastCommonSubsequenceMatrix_SameSequences() { + std::vector<char> x = boost::assign::list_of('a')('b')('c'); + std::vector<char> y = boost::assign::list_of('a')('b')('c'); + + std::vector<int> result; + Detail::computeLeastCommonSubsequenceMatrix<std::vector<char>::const_iterator, std::vector<char>::const_iterator, int, std::equal_to<char> >(x.begin(), x.end(), y.begin(), y.end(), result); + + std::vector<int> expected = boost::assign::list_of + (0)(0)(0)(0) + (0)(1)(1)(1) + (0)(1)(2)(2) + (0)(1)(2)(3); + CPPUNIT_ASSERT_EQUAL(expected, result); + } + + void testComputeIndexDiff_1() { + std::vector<std::string> x = boost::assign::list_of("Arizona")("California")("Delaware")("New Jersey")("Washington"); + std::vector<std::string> y = boost::assign::list_of("Alaska")("Arizona")("California")("Georgia")("New Jersey")("Virginia"); + + std::vector<size_t> updates; + std::vector<size_t> postUpdates; + std::vector<size_t> removes; + std::vector<size_t> inserts; + computeIndexDiff<std::string, std::equal_to<std::string>, IsArizonaOrNewJersey >(x, y, updates, postUpdates, removes, inserts); + + std::vector<size_t> expectedUpdates = boost::assign::list_of(3)(0); + std::vector<size_t> expectedPostUpdates = boost::assign::list_of(4)(1); + std::vector<size_t> expectedRemoves = boost::assign::list_of(4)(2); + std::vector<size_t> expectedInserts = boost::assign::list_of(5)(3)(0); + CPPUNIT_ASSERT_EQUAL(expectedUpdates, updates); + CPPUNIT_ASSERT_EQUAL(expectedPostUpdates, postUpdates); + CPPUNIT_ASSERT_EQUAL(expectedRemoves, removes); + CPPUNIT_ASSERT_EQUAL(expectedInserts, inserts); + } + + void testComputeIndexDiff_2() { + std::vector<char> x = boost::assign::list_of('x')('y'); + std::vector<char> y = boost::assign::list_of('x'); + + std::vector<size_t> updates; + std::vector<size_t> postUpdates; + std::vector<size_t> removes; + std::vector<size_t> inserts; + computeIndexDiff<char, std::equal_to<char>, IsBOrC >(x, y, updates, postUpdates, removes, inserts); + + std::vector<size_t> expectedRemoves = boost::assign::list_of(1); + CPPUNIT_ASSERT(updates.empty()); + CPPUNIT_ASSERT(postUpdates.empty()); + CPPUNIT_ASSERT(inserts.empty()); + CPPUNIT_ASSERT_EQUAL(expectedRemoves, removes); + } + + void testComputeIndexDiff_Sequence1Empty() { + std::vector<char> x; + std::vector<char> y = boost::assign::list_of('a')('b')('c'); + + std::vector<size_t> updates; + std::vector<size_t> postUpdates; + std::vector<size_t> removes; + std::vector<size_t> inserts; + computeIndexDiff<char, std::equal_to<char>, IsBOrC >(x, y, updates, postUpdates, removes, inserts); + + std::vector<size_t> expectedInserts = boost::assign::list_of(2)(1)(0); + CPPUNIT_ASSERT(updates.empty()); + CPPUNIT_ASSERT(postUpdates.empty()); + CPPUNIT_ASSERT(removes.empty()); + CPPUNIT_ASSERT_EQUAL(expectedInserts, inserts); + } + + void testComputeIndexDiff_Sequence2Empty() { + std::vector<char> x = boost::assign::list_of('a')('b')('c'); + std::vector<char> y; + + std::vector<size_t> updates; + std::vector<size_t> postUpdates; + std::vector<size_t> removes; + std::vector<size_t> inserts; + computeIndexDiff<char, std::equal_to<char>, IsBOrC >(x, y, updates, postUpdates, removes, inserts); + + std::vector<size_t> expectedRemoves = boost::assign::list_of(2)(1)(0); + CPPUNIT_ASSERT(updates.empty()); + CPPUNIT_ASSERT(postUpdates.empty()); + CPPUNIT_ASSERT_EQUAL(expectedRemoves, removes); + CPPUNIT_ASSERT(inserts.empty()); + } + + void testComputeIndexDiff_BothSequencesEmpty() { + std::vector<char> x; + std::vector<char> y; + + std::vector<size_t> updates; + std::vector<size_t> postUpdates; + std::vector<size_t> removes; + std::vector<size_t> inserts; + computeIndexDiff<char, std::equal_to<char>, IsBOrC >(x, y, updates, postUpdates, removes, inserts); + + CPPUNIT_ASSERT(updates.empty()); + CPPUNIT_ASSERT(postUpdates.empty()); + CPPUNIT_ASSERT(removes.empty()); + CPPUNIT_ASSERT(inserts.empty()); + } + + void testComputeIndexDiff_NoCommonSequence() { + std::vector<char> x = boost::assign::list_of('a')('b')('c'); + std::vector<char> y = boost::assign::list_of('d')('e')('f')('g'); + + std::vector<size_t> updates; + std::vector<size_t> postUpdates; + std::vector<size_t> removes; + std::vector<size_t> inserts; + computeIndexDiff<char, std::equal_to<char>, IsBOrC >(x, y, updates, postUpdates, removes, inserts); + + std::vector<size_t> expectedRemoves = boost::assign::list_of(2)(1)(0); + std::vector<size_t> expectedInserts = boost::assign::list_of(3)(2)(1)(0); + CPPUNIT_ASSERT(updates.empty()); + CPPUNIT_ASSERT(postUpdates.empty()); + CPPUNIT_ASSERT_EQUAL(expectedRemoves, removes); + CPPUNIT_ASSERT_EQUAL(expectedInserts, inserts); + } + + void testComputeIndexDiff_SameSequences() { + std::vector<char> x = boost::assign::list_of('a')('b')('c'); + std::vector<char> y = boost::assign::list_of('a')('b')('c'); + + std::vector<size_t> updates; + std::vector<size_t> postUpdates; + std::vector<size_t> removes; + std::vector<size_t> inserts; + computeIndexDiff<char, std::equal_to<char>, IsBOrC >(x, y, updates, postUpdates, removes, inserts); + + std::vector<size_t> expectedUpdates = boost::assign::list_of(1)(2); + CPPUNIT_ASSERT_EQUAL(expectedUpdates, updates); + CPPUNIT_ASSERT_EQUAL(expectedUpdates, postUpdates); + CPPUNIT_ASSERT(removes.empty()); + CPPUNIT_ASSERT(inserts.empty()); + } + + void testComputeIndexDiff_CommonPrefixAndSuffix() { + std::vector<char> x = boost::assign::list_of('x')('x')('x')('x')('a')('b')('c')('d')('e')('y')('y')('y'); + std::vector<char> y = boost::assign::list_of('x')('x')('x')('x')('e')('a')('b')('f')('d')('g')('y')('y')('y'); + + std::vector<size_t> updates; + std::vector<size_t> postUpdates; + std::vector<size_t> removes; + std::vector<size_t> inserts; + computeIndexDiff<char, std::equal_to<char>, IsXOrY >(x, y, updates, postUpdates, removes, inserts); + + std::vector<size_t> expectedUpdates = boost::assign::list_of(0)(1)(2)(3)(11)(10)(9); + std::vector<size_t> expectedPostUpdates = boost::assign::list_of(0)(1)(2)(3)(12)(11)(10); + std::vector<size_t> expectedRemoves = boost::assign::list_of(8)(6); + std::vector<size_t> expectedInserts = boost::assign::list_of(9)(7)(4); + CPPUNIT_ASSERT_EQUAL(expectedUpdates, updates); + CPPUNIT_ASSERT_EQUAL(expectedPostUpdates, postUpdates); + CPPUNIT_ASSERT_EQUAL(expectedRemoves, removes); + CPPUNIT_ASSERT_EQUAL(expectedInserts, inserts); + } }; CPPUNIT_TEST_SUITE_REGISTRATION(LeastCommonSubsequenceTest); diff --git a/Swift/Controllers/Roster/UnitTest/RosterControllerTest.cpp b/Swift/Controllers/Roster/UnitTest/RosterControllerTest.cpp index d774e6d..551bd6b 100644 --- a/Swift/Controllers/Roster/UnitTest/RosterControllerTest.cpp +++ b/Swift/Controllers/Roster/UnitTest/RosterControllerTest.cpp @@ -46,351 +46,351 @@ using namespace Swift; #define CHILDREN mainWindow_->roster->getRoot()->getChildren() class DummyCapsProvider : public CapsProvider { - DiscoInfo::ref getCaps(const std::string&) const {return DiscoInfo::ref(new DiscoInfo());} + DiscoInfo::ref getCaps(const std::string&) const {return DiscoInfo::ref(new DiscoInfo());} }; class RosterControllerTest : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(RosterControllerTest); - CPPUNIT_TEST(testAdd); - CPPUNIT_TEST(testAddSubscription); - CPPUNIT_TEST(testReceiveRename); - CPPUNIT_TEST(testReceiveRegroup); - CPPUNIT_TEST(testSendRename); - CPPUNIT_TEST(testPresence); - CPPUNIT_TEST(testHighestPresence); - CPPUNIT_TEST(testNotHighestPresence); - CPPUNIT_TEST(testUnavailablePresence); - CPPUNIT_TEST(testRemoveResultsInUnavailablePresence); - CPPUNIT_TEST_SUITE_END(); - - public: - void setUp() { - jid_ = JID("testjid@swift.im/swift"); - xmppRoster_ = new XMPPRosterImpl(); - avatarManager_ = new NullAvatarManager(); - mainWindowFactory_ = new MockMainWindowFactory(); - mucRegistry_ = new MUCRegistry(); - nickResolver_ = new NickResolver(jid_.toBare(), xmppRoster_, NULL, mucRegistry_); - channel_ = new DummyIQChannel(); - router_ = new IQRouter(channel_); - stanzaChannel_ = new DummyStanzaChannel(); - presenceOracle_ = new PresenceOracle(stanzaChannel_, xmppRoster_); - subscriptionManager_ = new SubscriptionManager(stanzaChannel_); - eventController_ = new EventController(); - uiEventStream_ = new UIEventStream(); - settings_ = new DummySettingsProvider(); - nickManager_ = new DummyNickManager(); - capsProvider_ = new DummyCapsProvider(); - entityCapsManager_ = new EntityCapsManager(capsProvider_, stanzaChannel_); - jingleSessionManager_ = new JingleSessionManager(router_); - - ftManager_ = new DummyFileTransferManager(); - ftOverview_ = new FileTransferOverview(ftManager_); - clientBlockListManager_ = new ClientBlockListManager(router_); - crypto_ = PlatformCryptoProvider::create(); - vcardStorage_ = new VCardMemoryStorage(crypto_); - vcardManager_ = new VCardManager(jid_, router_, vcardStorage_); - rosterController_ = new RosterController(jid_, xmppRoster_, avatarManager_, mainWindowFactory_, nickManager_, nickResolver_, presenceOracle_, subscriptionManager_, eventController_, uiEventStream_, router_, settings_, entityCapsManager_, ftOverview_, clientBlockListManager_, vcardManager_); - mainWindow_ = mainWindowFactory_->last; - } - - void tearDown() { - delete rosterController_; - delete vcardManager_; - delete vcardStorage_; - delete crypto_; - delete clientBlockListManager_; - delete ftOverview_; - delete ftManager_; - delete jingleSessionManager_; - delete entityCapsManager_; - delete capsProvider_; - delete nickManager_; - delete nickResolver_; - delete mucRegistry_; - delete mainWindowFactory_; - delete avatarManager_; - delete router_; - delete channel_; - delete eventController_; - delete subscriptionManager_; - delete presenceOracle_; - delete stanzaChannel_; - delete uiEventStream_; - delete settings_; - delete xmppRoster_; - } - - GroupRosterItem* groupChild(size_t i) { - return dynamic_cast<GroupRosterItem*>(CHILDREN[i]); - } - - JID withResource(const JID& jid, const std::string& resource) { - return JID(jid.toBare().toString() + "/" + resource); - } - - void testPresence() { - std::vector<std::string> groups; - groups.push_back("testGroup1"); - groups.push_back("testGroup2"); - JID from("test@testdomain.com"); - xmppRoster_->addContact(from, "name", groups, RosterItemPayload::Both); - Presence::ref presence(new Presence()); - presence->setFrom(withResource(from, "bob")); - presence->setPriority(2); - presence->setStatus("So totally here"); - stanzaChannel_->onPresenceReceived(presence); - ContactRosterItem* item = dynamic_cast<ContactRosterItem*>(dynamic_cast<GroupRosterItem*>(CHILDREN[0])->getChildren()[0]); - CPPUNIT_ASSERT(item); - CPPUNIT_ASSERT_EQUAL(presence->getStatus(), item->getStatusText()); - ContactRosterItem* item2 = dynamic_cast<ContactRosterItem*>(dynamic_cast<GroupRosterItem*>(CHILDREN[1])->getChildren()[0]); - CPPUNIT_ASSERT(item2); - CPPUNIT_ASSERT_EQUAL(presence->getStatus(), item2->getStatusText()); - - } - - void testHighestPresence() { - std::vector<std::string> groups; - groups.push_back("testGroup1"); - JID from("test@testdomain.com"); - xmppRoster_->addContact(from, "name", groups, RosterItemPayload::Both); - Presence::ref lowPresence(new Presence()); - lowPresence->setFrom(withResource(from, "bob")); - lowPresence->setPriority(2); - lowPresence->setStatus("Not here"); - Presence::ref highPresence(new Presence()); - highPresence->setFrom(withResource(from, "bert")); - highPresence->setPriority(10); - highPresence->setStatus("So totally here"); - stanzaChannel_->onPresenceReceived(lowPresence); - stanzaChannel_->onPresenceReceived(highPresence); - 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; - groups.push_back("testGroup1"); - JID from("test@testdomain.com"); - xmppRoster_->addContact(from, "name", groups, RosterItemPayload::Both); - Presence::ref lowPresence(new Presence()); - lowPresence->setFrom(withResource(from, "bob")); - lowPresence->setPriority(2); - lowPresence->setStatus("Not here"); - Presence::ref highPresence(new Presence()); - highPresence->setFrom(withResource(from, "bert")); - highPresence->setPriority(10); - highPresence->setStatus("So totally here"); - stanzaChannel_->onPresenceReceived(highPresence); - stanzaChannel_->onPresenceReceived(lowPresence); - 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; - groups.push_back("testGroup1"); - JID from("test@testdomain.com"); - xmppRoster_->addContact(from, "name", groups, RosterItemPayload::Both); - - Presence::ref lowPresence(new Presence()); - lowPresence->setFrom(withResource(from, "bob")); - lowPresence->setPriority(2); - lowPresence->setShow(StatusShow::Away); - lowPresence->setStatus("Not here"); - Presence::ref lowPresenceOffline(new Presence()); - lowPresenceOffline->setFrom(withResource(from, "bob")); - lowPresenceOffline->setStatus("Signing out"); - lowPresenceOffline->setType(Presence::Unavailable); - - Presence::ref highPresence(new Presence()); - highPresence->setFrom(withResource(from, "bert")); - highPresence->setPriority(10); - highPresence->setStatus("So totally here"); - Presence::ref highPresenceOffline(new Presence()); - highPresenceOffline->setFrom(withResource(from, "bert")); - highPresenceOffline->setType(Presence::Unavailable); - - stanzaChannel_->onPresenceReceived(lowPresence); - Presence::ref accountPresence = presenceOracle_->getAccountPresence(from); - CPPUNIT_ASSERT_EQUAL(StatusShow::Away, accountPresence->getShow()); - - stanzaChannel_->onPresenceReceived(highPresence); - accountPresence = presenceOracle_->getAccountPresence(from); - CPPUNIT_ASSERT_EQUAL(StatusShow::Online, accountPresence->getShow()); - - stanzaChannel_->onPresenceReceived(highPresenceOffline); - - // After this, the roster should show the low presence. - ContactRosterItem* item = dynamic_cast<ContactRosterItem*>(dynamic_cast<GroupRosterItem*>(CHILDREN[0])->getChildren()[0]); - CPPUNIT_ASSERT(item); - - Presence::ref low = presenceOracle_->getAccountPresence(from); - - CPPUNIT_ASSERT_EQUAL(Presence::Available, low->getType()); - CPPUNIT_ASSERT_EQUAL(lowPresence->getStatus(), low->getStatus()); - CPPUNIT_ASSERT_EQUAL(lowPresence->getShow(), item->getStatusShow()); - CPPUNIT_ASSERT_EQUAL(lowPresence->getStatus(), item->getStatusText()); - stanzaChannel_->onPresenceReceived(lowPresenceOffline); - item = dynamic_cast<ContactRosterItem*>(dynamic_cast<GroupRosterItem*>(CHILDREN[0])->getChildren()[0]); - CPPUNIT_ASSERT(item); - /* A verification that if the test fails, it's the RosterController, not the PresenceOracle. */ - low = presenceOracle_->getHighestPriorityPresence(from); - CPPUNIT_ASSERT_EQUAL(Presence::Unavailable, low->getType()); - CPPUNIT_ASSERT_EQUAL(lowPresenceOffline->getStatus(), low->getStatus()); - CPPUNIT_ASSERT_EQUAL(StatusShow::None, item->getStatusShow()); - CPPUNIT_ASSERT_EQUAL(lowPresenceOffline->getStatus(), item->getStatusText()); - } - - void testAdd() { - std::vector<std::string> groups; - groups.push_back("testGroup1"); - groups.push_back("testGroup2"); - xmppRoster_->addContact(JID("test@testdomain.com/bob"), "name", groups, RosterItemPayload::Both); - - 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; - JID jid("test@testdomain.com"); - xmppRoster_->addContact(jid, "name", groups, RosterItemPayload::None); - - CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(CHILDREN.size())); - CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(groupChild(0)->getChildren().size())); - xmppRoster_->addContact(jid, "name", groups, RosterItemPayload::To); - CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(CHILDREN.size())); - CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(groupChild(0)->getChildren().size())); - - xmppRoster_->addContact(jid, "name", groups, RosterItemPayload::Both); - 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; - JID jid("test@testdomain.com"); - xmppRoster_->addContact(jid, "name", groups, RosterItemPayload::Both); - - 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("name"), groupChild(0)->getChildren()[0]->getDisplayName()); - xmppRoster_->addContact(jid, "NewName", groups, RosterItemPayload::Both); - 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; - std::vector<std::string> newGroups; - newGroups.push_back("A Group"); - std::vector<std::string> newestGroups; - newestGroups.push_back("Best Group"); - JID jid("test@testdomain.com"); - xmppRoster_->addContact(jid, "", oldGroups, RosterItemPayload::Both); - - CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(CHILDREN.size())); - CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(groupChild(0)->getChildren().size())); - CPPUNIT_ASSERT_EQUAL(jid.toString(), groupChild(0)->getChildren()[0]->getDisplayName()); - - xmppRoster_->addContact(jid, "new name", newGroups, RosterItemPayload::Both); - 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("new name"), groupChild(0)->getChildren()[0]->getDisplayName()); - CPPUNIT_ASSERT_EQUAL(std::string("A Group"), groupChild(0)->getDisplayName()); - - xmppRoster_->addContact(jid, "new name", newestGroups, RosterItemPayload::Both); - 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("new name"), groupChild(0)->getChildren()[0]->getDisplayName()); - CPPUNIT_ASSERT_EQUAL(std::string("Best Group"), groupChild(0)->getDisplayName()); - } - - void testSendRename() { - JID jid("testling@wonderland.lit"); - std::vector<std::string> groups; - groups.push_back("Friends"); - groups.push_back("Enemies"); - xmppRoster_->addContact(jid, "Bob", groups, RosterItemPayload::From); - CPPUNIT_ASSERT_EQUAL(groups.size(), xmppRoster_->getGroupsForJID(jid).size()); - uiEventStream_->send(boost::shared_ptr<UIEvent>(new RenameRosterItemUIEvent(jid, "Robert"))); - CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), channel_->iqs_.size()); - CPPUNIT_ASSERT_EQUAL(IQ::Set, channel_->iqs_[0]->getType()); - boost::shared_ptr<RosterPayload> payload = channel_->iqs_[0]->getPayload<RosterPayload>(); - CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), payload->getItems().size()); - RosterItemPayload item = payload->getItems()[0]; - CPPUNIT_ASSERT_EQUAL(jid, item.getJID()); - CPPUNIT_ASSERT_EQUAL(std::string("Robert"), item.getName()); - - CPPUNIT_ASSERT_EQUAL(groups.size(), item.getGroups().size()); - assertVectorsEqual(groups, item.getGroups(), __LINE__); - } - - void testRemoveResultsInUnavailablePresence() { - std::vector<std::string> groups; - groups.push_back("testGroup1"); - JID from("test@testdomain.com"); - xmppRoster_->addContact(from, "name", groups, RosterItemPayload::Both); - Presence::ref lowPresence(new Presence()); - lowPresence->setFrom(withResource(from, "bob")); - lowPresence->setPriority(2); - lowPresence->setStatus("Not here"); - Presence::ref highPresence(new Presence()); - highPresence->setFrom(withResource(from, "bert")); - highPresence->setPriority(10); - highPresence->setStatus("So totally here"); - stanzaChannel_->onPresenceReceived(highPresence); - stanzaChannel_->onPresenceReceived(lowPresence); - - CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), presenceOracle_->getAllPresence("test@testdomain.com").size()); - - xmppRoster_->onJIDRemoved(JID("test@testdomain.com")); - CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), presenceOracle_->getAllPresence("test@testdomain.com").size()); - CPPUNIT_ASSERT_EQUAL(Presence::Unavailable, presenceOracle_->getAllPresence("test@testdomain.com")[0]->getType()); - } - - void assertVectorsEqual(const std::vector<std::string>& v1, const std::vector<std::string>& v2, int line) { - foreach (const std::string& entry, v1) { - if (std::find(v2.begin(), v2.end(), entry) == v2.end()) { - std::stringstream stream; - stream << "Couldn't find " << entry << " in v2 (line " << line << ")"; - CPPUNIT_FAIL(stream.str()); - } - } - } - - private: - JID jid_; - XMPPRosterImpl* xmppRoster_; - MUCRegistry* mucRegistry_; - AvatarManager* avatarManager_; - MockMainWindowFactory* mainWindowFactory_; - NickManager* nickManager_; - NickResolver* nickResolver_; - RosterController* rosterController_; - DummyIQChannel* channel_; - DummyStanzaChannel* stanzaChannel_; - IQRouter* router_; - PresenceOracle* presenceOracle_; - SubscriptionManager* subscriptionManager_; - EventController* eventController_; - UIEventStream* uiEventStream_; - MockMainWindow* mainWindow_; - DummySettingsProvider* settings_; - DummyCapsProvider* capsProvider_; - EntityCapsManager* entityCapsManager_; - JingleSessionManager* jingleSessionManager_; - FileTransferManager* ftManager_; - FileTransferOverview* ftOverview_; - ClientBlockListManager* clientBlockListManager_; - CryptoProvider* crypto_; - VCardStorage* vcardStorage_; - VCardManager* vcardManager_; + CPPUNIT_TEST_SUITE(RosterControllerTest); + CPPUNIT_TEST(testAdd); + CPPUNIT_TEST(testAddSubscription); + CPPUNIT_TEST(testReceiveRename); + CPPUNIT_TEST(testReceiveRegroup); + CPPUNIT_TEST(testSendRename); + CPPUNIT_TEST(testPresence); + CPPUNIT_TEST(testHighestPresence); + CPPUNIT_TEST(testNotHighestPresence); + CPPUNIT_TEST(testUnavailablePresence); + CPPUNIT_TEST(testRemoveResultsInUnavailablePresence); + CPPUNIT_TEST_SUITE_END(); + + public: + void setUp() { + jid_ = JID("testjid@swift.im/swift"); + xmppRoster_ = new XMPPRosterImpl(); + avatarManager_ = new NullAvatarManager(); + mainWindowFactory_ = new MockMainWindowFactory(); + mucRegistry_ = new MUCRegistry(); + nickResolver_ = new NickResolver(jid_.toBare(), xmppRoster_, NULL, mucRegistry_); + channel_ = new DummyIQChannel(); + router_ = new IQRouter(channel_); + stanzaChannel_ = new DummyStanzaChannel(); + presenceOracle_ = new PresenceOracle(stanzaChannel_, xmppRoster_); + subscriptionManager_ = new SubscriptionManager(stanzaChannel_); + eventController_ = new EventController(); + uiEventStream_ = new UIEventStream(); + settings_ = new DummySettingsProvider(); + nickManager_ = new DummyNickManager(); + capsProvider_ = new DummyCapsProvider(); + entityCapsManager_ = new EntityCapsManager(capsProvider_, stanzaChannel_); + jingleSessionManager_ = new JingleSessionManager(router_); + + ftManager_ = new DummyFileTransferManager(); + ftOverview_ = new FileTransferOverview(ftManager_); + clientBlockListManager_ = new ClientBlockListManager(router_); + crypto_ = PlatformCryptoProvider::create(); + vcardStorage_ = new VCardMemoryStorage(crypto_); + vcardManager_ = new VCardManager(jid_, router_, vcardStorage_); + rosterController_ = new RosterController(jid_, xmppRoster_, avatarManager_, mainWindowFactory_, nickManager_, nickResolver_, presenceOracle_, subscriptionManager_, eventController_, uiEventStream_, router_, settings_, entityCapsManager_, ftOverview_, clientBlockListManager_, vcardManager_); + mainWindow_ = mainWindowFactory_->last; + } + + void tearDown() { + delete rosterController_; + delete vcardManager_; + delete vcardStorage_; + delete crypto_; + delete clientBlockListManager_; + delete ftOverview_; + delete ftManager_; + delete jingleSessionManager_; + delete entityCapsManager_; + delete capsProvider_; + delete nickManager_; + delete nickResolver_; + delete mucRegistry_; + delete mainWindowFactory_; + delete avatarManager_; + delete router_; + delete channel_; + delete eventController_; + delete subscriptionManager_; + delete presenceOracle_; + delete stanzaChannel_; + delete uiEventStream_; + delete settings_; + delete xmppRoster_; + } + + GroupRosterItem* groupChild(size_t i) { + return dynamic_cast<GroupRosterItem*>(CHILDREN[i]); + } + + JID withResource(const JID& jid, const std::string& resource) { + return JID(jid.toBare().toString() + "/" + resource); + } + + void testPresence() { + std::vector<std::string> groups; + groups.push_back("testGroup1"); + groups.push_back("testGroup2"); + JID from("test@testdomain.com"); + xmppRoster_->addContact(from, "name", groups, RosterItemPayload::Both); + Presence::ref presence(new Presence()); + presence->setFrom(withResource(from, "bob")); + presence->setPriority(2); + presence->setStatus("So totally here"); + stanzaChannel_->onPresenceReceived(presence); + ContactRosterItem* item = dynamic_cast<ContactRosterItem*>(dynamic_cast<GroupRosterItem*>(CHILDREN[0])->getChildren()[0]); + CPPUNIT_ASSERT(item); + CPPUNIT_ASSERT_EQUAL(presence->getStatus(), item->getStatusText()); + ContactRosterItem* item2 = dynamic_cast<ContactRosterItem*>(dynamic_cast<GroupRosterItem*>(CHILDREN[1])->getChildren()[0]); + CPPUNIT_ASSERT(item2); + CPPUNIT_ASSERT_EQUAL(presence->getStatus(), item2->getStatusText()); + + } + + void testHighestPresence() { + std::vector<std::string> groups; + groups.push_back("testGroup1"); + JID from("test@testdomain.com"); + xmppRoster_->addContact(from, "name", groups, RosterItemPayload::Both); + Presence::ref lowPresence(new Presence()); + lowPresence->setFrom(withResource(from, "bob")); + lowPresence->setPriority(2); + lowPresence->setStatus("Not here"); + Presence::ref highPresence(new Presence()); + highPresence->setFrom(withResource(from, "bert")); + highPresence->setPriority(10); + highPresence->setStatus("So totally here"); + stanzaChannel_->onPresenceReceived(lowPresence); + stanzaChannel_->onPresenceReceived(highPresence); + 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; + groups.push_back("testGroup1"); + JID from("test@testdomain.com"); + xmppRoster_->addContact(from, "name", groups, RosterItemPayload::Both); + Presence::ref lowPresence(new Presence()); + lowPresence->setFrom(withResource(from, "bob")); + lowPresence->setPriority(2); + lowPresence->setStatus("Not here"); + Presence::ref highPresence(new Presence()); + highPresence->setFrom(withResource(from, "bert")); + highPresence->setPriority(10); + highPresence->setStatus("So totally here"); + stanzaChannel_->onPresenceReceived(highPresence); + stanzaChannel_->onPresenceReceived(lowPresence); + 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; + groups.push_back("testGroup1"); + JID from("test@testdomain.com"); + xmppRoster_->addContact(from, "name", groups, RosterItemPayload::Both); + + Presence::ref lowPresence(new Presence()); + lowPresence->setFrom(withResource(from, "bob")); + lowPresence->setPriority(2); + lowPresence->setShow(StatusShow::Away); + lowPresence->setStatus("Not here"); + Presence::ref lowPresenceOffline(new Presence()); + lowPresenceOffline->setFrom(withResource(from, "bob")); + lowPresenceOffline->setStatus("Signing out"); + lowPresenceOffline->setType(Presence::Unavailable); + + Presence::ref highPresence(new Presence()); + highPresence->setFrom(withResource(from, "bert")); + highPresence->setPriority(10); + highPresence->setStatus("So totally here"); + Presence::ref highPresenceOffline(new Presence()); + highPresenceOffline->setFrom(withResource(from, "bert")); + highPresenceOffline->setType(Presence::Unavailable); + + stanzaChannel_->onPresenceReceived(lowPresence); + Presence::ref accountPresence = presenceOracle_->getAccountPresence(from); + CPPUNIT_ASSERT_EQUAL(StatusShow::Away, accountPresence->getShow()); + + stanzaChannel_->onPresenceReceived(highPresence); + accountPresence = presenceOracle_->getAccountPresence(from); + CPPUNIT_ASSERT_EQUAL(StatusShow::Online, accountPresence->getShow()); + + stanzaChannel_->onPresenceReceived(highPresenceOffline); + + // After this, the roster should show the low presence. + ContactRosterItem* item = dynamic_cast<ContactRosterItem*>(dynamic_cast<GroupRosterItem*>(CHILDREN[0])->getChildren()[0]); + CPPUNIT_ASSERT(item); + + Presence::ref low = presenceOracle_->getAccountPresence(from); + + CPPUNIT_ASSERT_EQUAL(Presence::Available, low->getType()); + CPPUNIT_ASSERT_EQUAL(lowPresence->getStatus(), low->getStatus()); + CPPUNIT_ASSERT_EQUAL(lowPresence->getShow(), item->getStatusShow()); + CPPUNIT_ASSERT_EQUAL(lowPresence->getStatus(), item->getStatusText()); + stanzaChannel_->onPresenceReceived(lowPresenceOffline); + item = dynamic_cast<ContactRosterItem*>(dynamic_cast<GroupRosterItem*>(CHILDREN[0])->getChildren()[0]); + CPPUNIT_ASSERT(item); + /* A verification that if the test fails, it's the RosterController, not the PresenceOracle. */ + low = presenceOracle_->getHighestPriorityPresence(from); + CPPUNIT_ASSERT_EQUAL(Presence::Unavailable, low->getType()); + CPPUNIT_ASSERT_EQUAL(lowPresenceOffline->getStatus(), low->getStatus()); + CPPUNIT_ASSERT_EQUAL(StatusShow::None, item->getStatusShow()); + CPPUNIT_ASSERT_EQUAL(lowPresenceOffline->getStatus(), item->getStatusText()); + } + + void testAdd() { + std::vector<std::string> groups; + groups.push_back("testGroup1"); + groups.push_back("testGroup2"); + xmppRoster_->addContact(JID("test@testdomain.com/bob"), "name", groups, RosterItemPayload::Both); + + 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; + JID jid("test@testdomain.com"); + xmppRoster_->addContact(jid, "name", groups, RosterItemPayload::None); + + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(CHILDREN.size())); + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(groupChild(0)->getChildren().size())); + xmppRoster_->addContact(jid, "name", groups, RosterItemPayload::To); + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(CHILDREN.size())); + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(groupChild(0)->getChildren().size())); + + xmppRoster_->addContact(jid, "name", groups, RosterItemPayload::Both); + 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; + JID jid("test@testdomain.com"); + xmppRoster_->addContact(jid, "name", groups, RosterItemPayload::Both); + + 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("name"), groupChild(0)->getChildren()[0]->getDisplayName()); + xmppRoster_->addContact(jid, "NewName", groups, RosterItemPayload::Both); + 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; + std::vector<std::string> newGroups; + newGroups.push_back("A Group"); + std::vector<std::string> newestGroups; + newestGroups.push_back("Best Group"); + JID jid("test@testdomain.com"); + xmppRoster_->addContact(jid, "", oldGroups, RosterItemPayload::Both); + + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(CHILDREN.size())); + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(groupChild(0)->getChildren().size())); + CPPUNIT_ASSERT_EQUAL(jid.toString(), groupChild(0)->getChildren()[0]->getDisplayName()); + + xmppRoster_->addContact(jid, "new name", newGroups, RosterItemPayload::Both); + 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("new name"), groupChild(0)->getChildren()[0]->getDisplayName()); + CPPUNIT_ASSERT_EQUAL(std::string("A Group"), groupChild(0)->getDisplayName()); + + xmppRoster_->addContact(jid, "new name", newestGroups, RosterItemPayload::Both); + 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("new name"), groupChild(0)->getChildren()[0]->getDisplayName()); + CPPUNIT_ASSERT_EQUAL(std::string("Best Group"), groupChild(0)->getDisplayName()); + } + + void testSendRename() { + JID jid("testling@wonderland.lit"); + std::vector<std::string> groups; + groups.push_back("Friends"); + groups.push_back("Enemies"); + xmppRoster_->addContact(jid, "Bob", groups, RosterItemPayload::From); + CPPUNIT_ASSERT_EQUAL(groups.size(), xmppRoster_->getGroupsForJID(jid).size()); + uiEventStream_->send(boost::shared_ptr<UIEvent>(new RenameRosterItemUIEvent(jid, "Robert"))); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), channel_->iqs_.size()); + CPPUNIT_ASSERT_EQUAL(IQ::Set, channel_->iqs_[0]->getType()); + boost::shared_ptr<RosterPayload> payload = channel_->iqs_[0]->getPayload<RosterPayload>(); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), payload->getItems().size()); + RosterItemPayload item = payload->getItems()[0]; + CPPUNIT_ASSERT_EQUAL(jid, item.getJID()); + CPPUNIT_ASSERT_EQUAL(std::string("Robert"), item.getName()); + + CPPUNIT_ASSERT_EQUAL(groups.size(), item.getGroups().size()); + assertVectorsEqual(groups, item.getGroups(), __LINE__); + } + + void testRemoveResultsInUnavailablePresence() { + std::vector<std::string> groups; + groups.push_back("testGroup1"); + JID from("test@testdomain.com"); + xmppRoster_->addContact(from, "name", groups, RosterItemPayload::Both); + Presence::ref lowPresence(new Presence()); + lowPresence->setFrom(withResource(from, "bob")); + lowPresence->setPriority(2); + lowPresence->setStatus("Not here"); + Presence::ref highPresence(new Presence()); + highPresence->setFrom(withResource(from, "bert")); + highPresence->setPriority(10); + highPresence->setStatus("So totally here"); + stanzaChannel_->onPresenceReceived(highPresence); + stanzaChannel_->onPresenceReceived(lowPresence); + + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), presenceOracle_->getAllPresence("test@testdomain.com").size()); + + xmppRoster_->onJIDRemoved(JID("test@testdomain.com")); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), presenceOracle_->getAllPresence("test@testdomain.com").size()); + CPPUNIT_ASSERT_EQUAL(Presence::Unavailable, presenceOracle_->getAllPresence("test@testdomain.com")[0]->getType()); + } + + void assertVectorsEqual(const std::vector<std::string>& v1, const std::vector<std::string>& v2, int line) { + foreach (const std::string& entry, v1) { + if (std::find(v2.begin(), v2.end(), entry) == v2.end()) { + std::stringstream stream; + stream << "Couldn't find " << entry << " in v2 (line " << line << ")"; + CPPUNIT_FAIL(stream.str()); + } + } + } + + private: + JID jid_; + XMPPRosterImpl* xmppRoster_; + MUCRegistry* mucRegistry_; + AvatarManager* avatarManager_; + MockMainWindowFactory* mainWindowFactory_; + NickManager* nickManager_; + NickResolver* nickResolver_; + RosterController* rosterController_; + DummyIQChannel* channel_; + DummyStanzaChannel* stanzaChannel_; + IQRouter* router_; + PresenceOracle* presenceOracle_; + SubscriptionManager* subscriptionManager_; + EventController* eventController_; + UIEventStream* uiEventStream_; + MockMainWindow* mainWindow_; + DummySettingsProvider* settings_; + DummyCapsProvider* capsProvider_; + EntityCapsManager* entityCapsManager_; + JingleSessionManager* jingleSessionManager_; + FileTransferManager* ftManager_; + FileTransferOverview* ftOverview_; + ClientBlockListManager* clientBlockListManager_; + CryptoProvider* crypto_; + VCardStorage* vcardStorage_; + VCardManager* vcardManager_; }; CPPUNIT_TEST_SUITE_REGISTRATION(RosterControllerTest); diff --git a/Swift/Controllers/Roster/UnitTest/RosterTest.cpp b/Swift/Controllers/Roster/UnitTest/RosterTest.cpp index 314b5c6..dd22cb7 100644 --- a/Swift/Controllers/Roster/UnitTest/RosterTest.cpp +++ b/Swift/Controllers/Roster/UnitTest/RosterTest.cpp @@ -16,130 +16,130 @@ using namespace Swift; class RosterTest : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(RosterTest); - CPPUNIT_TEST(testGetGroup); - CPPUNIT_TEST(testRemoveContact); - CPPUNIT_TEST(testRemoveSecondContact); - CPPUNIT_TEST(testRemoveSecondContactSameBare); - CPPUNIT_TEST(testApplyPresenceLikeMUC); - CPPUNIT_TEST(testReSortLikeMUC); - CPPUNIT_TEST_SUITE_END(); - - public: - void setUp() { - jid1_ = JID("a@b.c"); - jid2_ = JID("b@c.d"); - jid3_ = JID("c@d.e"); - roster_ = new Roster(); - } - - void tearDown() { - delete roster_; - } - - void testGetGroup() { - roster_->addContact(jid1_, JID(), "Bert", "group1", ""); - roster_->addContact(jid2_, JID(), "Ernie", "group2", ""); - roster_->addContact(jid3_, JID(), "Cookie", "group1", ""); - - CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(roster_->getRoot()->getChildren().size())); - CPPUNIT_ASSERT_EQUAL(std::string("group1"), roster_->getRoot()->getChildren()[0]->getDisplayName()); - CPPUNIT_ASSERT_EQUAL(std::string("group2"), roster_->getRoot()->getChildren()[1]->getDisplayName()); - CPPUNIT_ASSERT_EQUAL(std::string("Bert"), static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren()[0]->getDisplayName()); - CPPUNIT_ASSERT_EQUAL(std::string("Cookie"), static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren()[1]->getDisplayName()); - CPPUNIT_ASSERT_EQUAL(std::string("Ernie"), static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[1])->getChildren()[0]->getDisplayName()); - - } - - void testRemoveContact() { - roster_->addContact(jid1_, jid1_, "Bert", "group1", ""); - CPPUNIT_ASSERT_EQUAL(std::string("Bert"), static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren()[0]->getDisplayName()); - - roster_->removeContact(jid1_); - CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren().size())); - } - - void testRemoveSecondContact() { - roster_->addContact(jid1_, jid1_, "Bert", "group1", ""); - roster_->addContact(jid2_, jid2_, "Cookie", "group1", ""); - CPPUNIT_ASSERT_EQUAL(std::string("Cookie"), static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren()[1]->getDisplayName()); - - roster_->removeContact(jid2_); - CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren().size())); - CPPUNIT_ASSERT_EQUAL(std::string("Bert"), static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren()[0]->getDisplayName()); - } - - void testRemoveSecondContactSameBare() { - JID jid4a("a@b/c"); - JID jid4b("a@b/d"); - roster_->addContact(jid4a, JID(), "Bert", "group1", ""); - roster_->addContact(jid4b, JID(), "Cookie", "group1", ""); - CPPUNIT_ASSERT_EQUAL(std::string("Cookie"), static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren()[1]->getDisplayName()); - - roster_->removeContact(jid4b); - CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren().size())); - CPPUNIT_ASSERT_EQUAL(std::string("Bert"), static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren()[0]->getDisplayName()); - } - - void testApplyPresenceLikeMUC() { - JID jid4a("a@b/c"); - JID jid4b("a@b/d"); - JID jid4c("a@b/e"); - roster_->addContact(jid4a, JID(), "Bird", "group1", ""); - roster_->addContact(jid4b, JID(), "Cookie", "group1", ""); - roster_->removeContact(jid4b); - roster_->addContact(jid4c, JID(), "Bert", "group1", ""); - roster_->addContact(jid4b, JID(), "Ernie", "group1", ""); - boost::shared_ptr<Presence> presence(new Presence()); - presence->setShow(StatusShow::DND); - presence->setFrom(jid4a); - roster_->applyOnItems(SetPresence(presence, JID::WithResource)); - presence->setFrom(jid4b); - roster_->applyOnItems(SetPresence(presence, JID::WithResource)); - presence->setFrom(jid4c); - roster_->applyOnItems(SetPresence(presence, JID::WithResource)); - - presence = boost::make_shared<Presence>(); - presence->setFrom(jid4b); - presence->setShow(StatusShow::Online); - roster_->applyOnItems(SetPresence(presence, JID::WithResource)); - std::vector<RosterItem*> children = static_cast<GroupRosterItem*>(roster_->getRoot()->getDisplayedChildren()[0])->getDisplayedChildren(); - CPPUNIT_ASSERT_EQUAL(3, static_cast<int>(children.size())); - - /* Check order */ - CPPUNIT_ASSERT_EQUAL(std::string("Ernie"), children[0]->getDisplayName()); - CPPUNIT_ASSERT_EQUAL(std::string("Bert"), children[1]->getDisplayName()); - CPPUNIT_ASSERT_EQUAL(std::string("Bird"), children[2]->getDisplayName()); - - presence = boost::make_shared<Presence>(); - presence->setFrom(jid4c); - presence->setType(Presence::Unavailable); - roster_->removeContact(jid4c); - roster_->applyOnItems(SetPresence(presence, JID::WithResource)); - - } - - void testReSortLikeMUC() { - JID jid4a("a@b/c"); - JID jid4b("a@b/d"); - JID jid4c("a@b/e"); - roster_->addContact(jid4a, JID(), "Bird", "group1", ""); - roster_->addContact(jid4b, JID(), "Cookie", "group2", ""); - roster_->addContact(jid4b, JID(), "Ernie", "group1", ""); - roster_->getGroup("group1")->setManualSort("2"); - roster_->getGroup("group2")->setManualSort("1"); - GroupRosterItem* root = roster_->getRoot(); - const std::vector<RosterItem*> kids = root->getDisplayedChildren(); - CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), kids.size()); - CPPUNIT_ASSERT_EQUAL(std::string("group2"), kids[0]->getDisplayName()); - CPPUNIT_ASSERT_EQUAL(std::string("group1"), kids[1]->getDisplayName()); - } - - private: - Roster *roster_; - JID jid1_; - JID jid2_; - JID jid3_; + CPPUNIT_TEST_SUITE(RosterTest); + CPPUNIT_TEST(testGetGroup); + CPPUNIT_TEST(testRemoveContact); + CPPUNIT_TEST(testRemoveSecondContact); + CPPUNIT_TEST(testRemoveSecondContactSameBare); + CPPUNIT_TEST(testApplyPresenceLikeMUC); + CPPUNIT_TEST(testReSortLikeMUC); + CPPUNIT_TEST_SUITE_END(); + + public: + void setUp() { + jid1_ = JID("a@b.c"); + jid2_ = JID("b@c.d"); + jid3_ = JID("c@d.e"); + roster_ = new Roster(); + } + + void tearDown() { + delete roster_; + } + + void testGetGroup() { + roster_->addContact(jid1_, JID(), "Bert", "group1", ""); + roster_->addContact(jid2_, JID(), "Ernie", "group2", ""); + roster_->addContact(jid3_, JID(), "Cookie", "group1", ""); + + CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(roster_->getRoot()->getChildren().size())); + CPPUNIT_ASSERT_EQUAL(std::string("group1"), roster_->getRoot()->getChildren()[0]->getDisplayName()); + CPPUNIT_ASSERT_EQUAL(std::string("group2"), roster_->getRoot()->getChildren()[1]->getDisplayName()); + CPPUNIT_ASSERT_EQUAL(std::string("Bert"), static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren()[0]->getDisplayName()); + CPPUNIT_ASSERT_EQUAL(std::string("Cookie"), static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren()[1]->getDisplayName()); + CPPUNIT_ASSERT_EQUAL(std::string("Ernie"), static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[1])->getChildren()[0]->getDisplayName()); + + } + + void testRemoveContact() { + roster_->addContact(jid1_, jid1_, "Bert", "group1", ""); + CPPUNIT_ASSERT_EQUAL(std::string("Bert"), static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren()[0]->getDisplayName()); + + roster_->removeContact(jid1_); + CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren().size())); + } + + void testRemoveSecondContact() { + roster_->addContact(jid1_, jid1_, "Bert", "group1", ""); + roster_->addContact(jid2_, jid2_, "Cookie", "group1", ""); + CPPUNIT_ASSERT_EQUAL(std::string("Cookie"), static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren()[1]->getDisplayName()); + + roster_->removeContact(jid2_); + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren().size())); + CPPUNIT_ASSERT_EQUAL(std::string("Bert"), static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren()[0]->getDisplayName()); + } + + void testRemoveSecondContactSameBare() { + JID jid4a("a@b/c"); + JID jid4b("a@b/d"); + roster_->addContact(jid4a, JID(), "Bert", "group1", ""); + roster_->addContact(jid4b, JID(), "Cookie", "group1", ""); + CPPUNIT_ASSERT_EQUAL(std::string("Cookie"), static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren()[1]->getDisplayName()); + + roster_->removeContact(jid4b); + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren().size())); + CPPUNIT_ASSERT_EQUAL(std::string("Bert"), static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren()[0]->getDisplayName()); + } + + void testApplyPresenceLikeMUC() { + JID jid4a("a@b/c"); + JID jid4b("a@b/d"); + JID jid4c("a@b/e"); + roster_->addContact(jid4a, JID(), "Bird", "group1", ""); + roster_->addContact(jid4b, JID(), "Cookie", "group1", ""); + roster_->removeContact(jid4b); + roster_->addContact(jid4c, JID(), "Bert", "group1", ""); + roster_->addContact(jid4b, JID(), "Ernie", "group1", ""); + boost::shared_ptr<Presence> presence(new Presence()); + presence->setShow(StatusShow::DND); + presence->setFrom(jid4a); + roster_->applyOnItems(SetPresence(presence, JID::WithResource)); + presence->setFrom(jid4b); + roster_->applyOnItems(SetPresence(presence, JID::WithResource)); + presence->setFrom(jid4c); + roster_->applyOnItems(SetPresence(presence, JID::WithResource)); + + presence = boost::make_shared<Presence>(); + presence->setFrom(jid4b); + presence->setShow(StatusShow::Online); + roster_->applyOnItems(SetPresence(presence, JID::WithResource)); + std::vector<RosterItem*> children = static_cast<GroupRosterItem*>(roster_->getRoot()->getDisplayedChildren()[0])->getDisplayedChildren(); + CPPUNIT_ASSERT_EQUAL(3, static_cast<int>(children.size())); + + /* Check order */ + CPPUNIT_ASSERT_EQUAL(std::string("Ernie"), children[0]->getDisplayName()); + CPPUNIT_ASSERT_EQUAL(std::string("Bert"), children[1]->getDisplayName()); + CPPUNIT_ASSERT_EQUAL(std::string("Bird"), children[2]->getDisplayName()); + + presence = boost::make_shared<Presence>(); + presence->setFrom(jid4c); + presence->setType(Presence::Unavailable); + roster_->removeContact(jid4c); + roster_->applyOnItems(SetPresence(presence, JID::WithResource)); + + } + + void testReSortLikeMUC() { + JID jid4a("a@b/c"); + JID jid4b("a@b/d"); + JID jid4c("a@b/e"); + roster_->addContact(jid4a, JID(), "Bird", "group1", ""); + roster_->addContact(jid4b, JID(), "Cookie", "group2", ""); + roster_->addContact(jid4b, JID(), "Ernie", "group1", ""); + roster_->getGroup("group1")->setManualSort("2"); + roster_->getGroup("group2")->setManualSort("1"); + GroupRosterItem* root = roster_->getRoot(); + const std::vector<RosterItem*> kids = root->getDisplayedChildren(); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), kids.size()); + CPPUNIT_ASSERT_EQUAL(std::string("group2"), kids[0]->getDisplayName()); + CPPUNIT_ASSERT_EQUAL(std::string("group1"), kids[1]->getDisplayName()); + } + + private: + Roster *roster_; + JID jid1_; + JID jid2_; + JID jid3_; }; CPPUNIT_TEST_SUITE_REGISTRATION(RosterTest); diff --git a/Swift/Controllers/Roster/UnitTest/TableRosterTest.cpp b/Swift/Controllers/Roster/UnitTest/TableRosterTest.cpp index 10030ef..086bd6f 100644 --- a/Swift/Controllers/Roster/UnitTest/TableRosterTest.cpp +++ b/Swift/Controllers/Roster/UnitTest/TableRosterTest.cpp @@ -9,8 +9,8 @@ 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; + os << "(" << i.section << ", " << i.row << ")"; + return os; } #include <cppunit/extensions/HelperMacros.h> @@ -27,67 +27,67 @@ std::ostream& operator<<(std::ostream& os, const Swift::TableRoster::Index& i) { using namespace Swift; class TableRosterTest : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(TableRosterTest); - CPPUNIT_TEST(testAddContact_EmptyRoster); - CPPUNIT_TEST_SUITE_END(); - - public: - void setUp() { - timerFactory = new DummyTimerFactory(); - roster = new Roster(); - jid1 = JID("jid1@example.com"); - jid2 = JID("jid2@example.com"); - } - - void tearDown() { - delete roster; - delete timerFactory; - } - - void testAddContact_EmptyRoster() { - /* - boost::shared_ptr<TableRoster> tableRoster(createTestling()); - - addContact(jid1, "1", "group1"); - - CPPUNIT_ASSERT_EQUAL(4, static_cast<int>(events.size())); - CPPUNIT_ASSERT(boost::get<BeginUpdatesEvent>(&events[0])); - CPPUNIT_ASSERT(boost::get<SectionsInsertedEvent>(&events[1])); - CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(boost::get<SectionsInsertedEvent>(events[1]).sections.size())); - CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(boost::get<SectionsInsertedEvent>(events[1]).sections[0])); - CPPUNIT_ASSERT(boost::get<RowsInsertedEvent>(&events[2])); - CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(boost::get<RowsInsertedEvent>(events[2]).rows.size())); - CPPUNIT_ASSERT_EQUAL(TableRoster::Index(0, 0), boost::get<RowsInsertedEvent>(events[2]).rows[0]); - CPPUNIT_ASSERT(boost::get<EndUpdatesEvent>(&events[3])); - - CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(tableRoster->getNumberOfSections())); - CPPUNIT_ASSERT_EQUAL(std::string("group1"), tableRoster->getSectionTitle(0)); - CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(tableRoster->getNumberOfRowsInSection(0))); - CPPUNIT_ASSERT_EQUAL(jid1, tableRoster->getItem(TableRoster::Index(0, 0)).jid); - */ - } - - private: - void addContact(const JID& jid, const std::string& name, const std::string& group) { - roster->addContact(jid, JID(), name, group, ""); - } - - TableRoster* createTestling() { - TableRoster* result = new TableRoster(roster, timerFactory, 10); - result->onUpdate.connect(boost::bind(&TableRosterTest::handleUpdate, this, _1)); - return result; - } - - void handleUpdate(const TableRoster::Update& update) { - updates.push_back(update); - } - - private: - DummyTimerFactory* timerFactory; - Roster* roster; - JID jid1; - JID jid2; - std::vector<TableRoster::Update> updates; + CPPUNIT_TEST_SUITE(TableRosterTest); + CPPUNIT_TEST(testAddContact_EmptyRoster); + CPPUNIT_TEST_SUITE_END(); + + public: + void setUp() { + timerFactory = new DummyTimerFactory(); + roster = new Roster(); + jid1 = JID("jid1@example.com"); + jid2 = JID("jid2@example.com"); + } + + void tearDown() { + delete roster; + delete timerFactory; + } + + void testAddContact_EmptyRoster() { + /* + boost::shared_ptr<TableRoster> tableRoster(createTestling()); + + addContact(jid1, "1", "group1"); + + CPPUNIT_ASSERT_EQUAL(4, static_cast<int>(events.size())); + CPPUNIT_ASSERT(boost::get<BeginUpdatesEvent>(&events[0])); + CPPUNIT_ASSERT(boost::get<SectionsInsertedEvent>(&events[1])); + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(boost::get<SectionsInsertedEvent>(events[1]).sections.size())); + CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(boost::get<SectionsInsertedEvent>(events[1]).sections[0])); + CPPUNIT_ASSERT(boost::get<RowsInsertedEvent>(&events[2])); + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(boost::get<RowsInsertedEvent>(events[2]).rows.size())); + CPPUNIT_ASSERT_EQUAL(TableRoster::Index(0, 0), boost::get<RowsInsertedEvent>(events[2]).rows[0]); + CPPUNIT_ASSERT(boost::get<EndUpdatesEvent>(&events[3])); + + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(tableRoster->getNumberOfSections())); + CPPUNIT_ASSERT_EQUAL(std::string("group1"), tableRoster->getSectionTitle(0)); + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(tableRoster->getNumberOfRowsInSection(0))); + CPPUNIT_ASSERT_EQUAL(jid1, tableRoster->getItem(TableRoster::Index(0, 0)).jid); + */ + } + + private: + void addContact(const JID& jid, const std::string& name, const std::string& group) { + roster->addContact(jid, JID(), name, group, ""); + } + + TableRoster* createTestling() { + TableRoster* result = new TableRoster(roster, timerFactory, 10); + result->onUpdate.connect(boost::bind(&TableRosterTest::handleUpdate, this, _1)); + return result; + } + + void handleUpdate(const TableRoster::Update& update) { + updates.push_back(update); + } + + private: + DummyTimerFactory* timerFactory; + Roster* roster; + JID jid1; + JID jid2; + std::vector<TableRoster::Update> updates; }; CPPUNIT_TEST_SUITE_REGISTRATION(TableRosterTest); diff --git a/Swift/Controllers/SettingConstants.h b/Swift/Controllers/SettingConstants.h index c4ac4ad..9343b7b 100644 --- a/Swift/Controllers/SettingConstants.h +++ b/Swift/Controllers/SettingConstants.h @@ -9,100 +9,100 @@ #include <Swift/Controllers/Settings/SettingsProvider.h> namespace Swift { - /** - * This class contains the major setting keys for Swift. - */ - class SettingConstants { - public: - /** - * The #IDLE_GOES_OFFLINE setting specifies whether to close the XMPP connection when - * the user went idle. - * - * True for automatic close of the XMPP connection and false for only changing the presence on idle. - */ - static const SettingsProvider::Setting<bool> IDLE_GOES_OFFLINE; - /** - * The #IDLE_TIMEOUT setting specifieds the seconds the user has to be inactive at the - * desktop so the user is regarded as idle. - */ - static const SettingsProvider::Setting<int> IDLE_TIMEOUT; - static const SettingsProvider::Setting<bool> SHOW_NOTIFICATIONS; - /** - * The #REQUEST_DELIVERYRECEIPTS settings specifies whether to request delivery receipts - * for messages to contacts that support message receipts. - */ - static const SettingsProvider::Setting<bool> REQUEST_DELIVERYRECEIPTS; - static const SettingsProvider::Setting<bool> FORGET_PASSWORDS; - static const SettingsProvider::Setting<bool> REMEMBER_RECENT_CHATS; - static const SettingsProvider::Setting<std::string> LAST_LOGIN_JID; - static const SettingsProvider::Setting<bool> LOGIN_AUTOMATICALLY; - /** - * The #SHOW_OFFLINE setting specifies whether or not to show offline contacts in the - * roster. - * - * If set true Swift will show offline contacts; else not. - */ - static const SettingsProvider::Setting<bool> SHOW_OFFLINE; - /** - * The #EXPANDED_ROSTER_GROUPS setting specifies the list of groups that are expanded - * in the roster UI. - * - * Its value is a string with group names seperated by newlines. - */ - static const SettingsProvider::Setting<std::string> EXPANDED_ROSTER_GROUPS; - static const SettingsProvider::Setting<bool> PLAY_SOUNDS; - /** - * The #HIGHLIGHT_RULES setting specifies the highlight rules and the associated actions. - * - * Its value is a Boost serialized representation. - */ - static const SettingsProvider::Setting<std::string> HIGHLIGHT_RULES; - static const SettingsProvider::Setting<bool> SPELL_CHECKER; - static const SettingsProvider::Setting<std::string> DICT_PATH; - static const SettingsProvider::Setting<std::string> PERSONAL_DICT_PATH; - static const SettingsProvider::Setting<std::string> DICT_FILE; - /** - * The #INVITE_AUTO_ACCEPT_MODE setting specifies how to handle invites to chat rooms. - * - * Supported values are: - * - "no" : It is up to the user whether to accept the invitation and enter a room or not. - * - "presence" : The invitation is automatically accepted if it is from a contact that is - * already allowed to see the user's presence status. - * - "domain" : The invitation is automatically accepted if it is from a contact that is - * already allowed to see the user's presence status or from a contact of user's domain. - */ - static const SettingsProvider::Setting<std::string> INVITE_AUTO_ACCEPT_MODE; - /** - * The #TRELLIS_GRID_SIZE setting specifies the dimensions of the grid used for the trellis - * layout. - * - * Its value is a Qt serialized representation. - */ - static const SettingsProvider::Setting<std::string> TRELLIS_GRID_SIZE; - /** - * The #TRELLIS_GRID_POSITIONS setting specifies where conversations to contacts or rooms go - * in the trellis grid. - * - * Its value is a Qt serialized representation. - */ - static const SettingsProvider::Setting<std::string> TRELLIS_GRID_POSITIONS; - /** - * The #DISCONNECT_ON_CARD_REMOVAL setting - * specifies whether or not to sign out the user when - * the smartcard is removed. - * - * If set true Swift will sign out the user when the - * smart card is removed; else not. - */ - static const SettingsProvider::Setting<bool> DISCONNECT_ON_CARD_REMOVAL; - /** - * The #SINGLE_SIGN_ON setting - * specifies whether to log in using Single Sign On. - * This is currently supported on Windows. - * - * If set true Swift will use GSSAPI authentication to - * log in the user; else not. - */ - static const SettingsProvider::Setting<bool> SINGLE_SIGN_ON; - }; + /** + * This class contains the major setting keys for Swift. + */ + class SettingConstants { + public: + /** + * The #IDLE_GOES_OFFLINE setting specifies whether to close the XMPP connection when + * the user went idle. + * + * True for automatic close of the XMPP connection and false for only changing the presence on idle. + */ + static const SettingsProvider::Setting<bool> IDLE_GOES_OFFLINE; + /** + * The #IDLE_TIMEOUT setting specifieds the seconds the user has to be inactive at the + * desktop so the user is regarded as idle. + */ + static const SettingsProvider::Setting<int> IDLE_TIMEOUT; + static const SettingsProvider::Setting<bool> SHOW_NOTIFICATIONS; + /** + * The #REQUEST_DELIVERYRECEIPTS settings specifies whether to request delivery receipts + * for messages to contacts that support message receipts. + */ + static const SettingsProvider::Setting<bool> REQUEST_DELIVERYRECEIPTS; + static const SettingsProvider::Setting<bool> FORGET_PASSWORDS; + static const SettingsProvider::Setting<bool> REMEMBER_RECENT_CHATS; + static const SettingsProvider::Setting<std::string> LAST_LOGIN_JID; + static const SettingsProvider::Setting<bool> LOGIN_AUTOMATICALLY; + /** + * The #SHOW_OFFLINE setting specifies whether or not to show offline contacts in the + * roster. + * + * If set true Swift will show offline contacts; else not. + */ + static const SettingsProvider::Setting<bool> SHOW_OFFLINE; + /** + * The #EXPANDED_ROSTER_GROUPS setting specifies the list of groups that are expanded + * in the roster UI. + * + * Its value is a string with group names seperated by newlines. + */ + static const SettingsProvider::Setting<std::string> EXPANDED_ROSTER_GROUPS; + static const SettingsProvider::Setting<bool> PLAY_SOUNDS; + /** + * The #HIGHLIGHT_RULES setting specifies the highlight rules and the associated actions. + * + * Its value is a Boost serialized representation. + */ + static const SettingsProvider::Setting<std::string> HIGHLIGHT_RULES; + static const SettingsProvider::Setting<bool> SPELL_CHECKER; + static const SettingsProvider::Setting<std::string> DICT_PATH; + static const SettingsProvider::Setting<std::string> PERSONAL_DICT_PATH; + static const SettingsProvider::Setting<std::string> DICT_FILE; + /** + * The #INVITE_AUTO_ACCEPT_MODE setting specifies how to handle invites to chat rooms. + * + * Supported values are: + * - "no" : It is up to the user whether to accept the invitation and enter a room or not. + * - "presence" : The invitation is automatically accepted if it is from a contact that is + * already allowed to see the user's presence status. + * - "domain" : The invitation is automatically accepted if it is from a contact that is + * already allowed to see the user's presence status or from a contact of user's domain. + */ + static const SettingsProvider::Setting<std::string> INVITE_AUTO_ACCEPT_MODE; + /** + * The #TRELLIS_GRID_SIZE setting specifies the dimensions of the grid used for the trellis + * layout. + * + * Its value is a Qt serialized representation. + */ + static const SettingsProvider::Setting<std::string> TRELLIS_GRID_SIZE; + /** + * The #TRELLIS_GRID_POSITIONS setting specifies where conversations to contacts or rooms go + * in the trellis grid. + * + * Its value is a Qt serialized representation. + */ + static const SettingsProvider::Setting<std::string> TRELLIS_GRID_POSITIONS; + /** + * The #DISCONNECT_ON_CARD_REMOVAL setting + * specifies whether or not to sign out the user when + * the smartcard is removed. + * + * If set true Swift will sign out the user when the + * smart card is removed; else not. + */ + static const SettingsProvider::Setting<bool> DISCONNECT_ON_CARD_REMOVAL; + /** + * The #SINGLE_SIGN_ON setting + * specifies whether to log in using Single Sign On. + * This is currently supported on Windows. + * + * If set true Swift will use GSSAPI authentication to + * log in the user; else not. + */ + static const SettingsProvider::Setting<bool> SINGLE_SIGN_ON; + }; } diff --git a/Swift/Controllers/Settings/DummySettingsProvider.h b/Swift/Controllers/Settings/DummySettingsProvider.h index 605153e..63c0767 100644 --- a/Swift/Controllers/Settings/DummySettingsProvider.h +++ b/Swift/Controllers/Settings/DummySettingsProvider.h @@ -13,44 +13,44 @@ namespace Swift { class DummySettingsProvider : public SettingsProvider { - public: - 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& ) {} - virtual bool getIsSettingFinal(const std::string& settingPath) {return finals.count(settingPath);} - void setFinal(const std::string& settingPath) { - finals.insert(settingPath); - } - virtual bool hasSetting(const std::string& key) { - return stringValues.find(key) != stringValues.end() || intValues.find(key) != intValues.end() || boolValues.find(key) != boolValues.end(); - } - private: - std::map<std::string, std::string> stringValues; - std::map<std::string, int> intValues; - std::map<std::string, bool> boolValues; - std::set<std::string> finals; + public: + 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& ) {} + virtual bool getIsSettingFinal(const std::string& settingPath) {return finals.count(settingPath);} + void setFinal(const std::string& settingPath) { + finals.insert(settingPath); + } + virtual bool hasSetting(const std::string& key) { + return stringValues.find(key) != stringValues.end() || intValues.find(key) != intValues.end() || boolValues.find(key) != boolValues.end(); + } + private: + std::map<std::string, std::string> stringValues; + std::map<std::string, int> intValues; + std::map<std::string, bool> boolValues; + std::set<std::string> finals; }; } diff --git a/Swift/Controllers/Settings/SettingsProvider.h b/Swift/Controllers/Settings/SettingsProvider.h index 29e26b5..a804235 100644 --- a/Swift/Controllers/Settings/SettingsProvider.h +++ b/Swift/Controllers/Settings/SettingsProvider.h @@ -15,57 +15,57 @@ namespace Swift { class SettingsProvider { - public: - template <typename T> - class Setting { - public: - Setting(const std::string& key, const T& defaultValue) : key(key), defaultValue(defaultValue) { - - } - - const std::string& getKey() const { - return key; - } - - const T& getDefaultValue() const { - return defaultValue; - } - - private: - std::string key; - T defaultValue; - }; - - public: - virtual ~SettingsProvider() {} - virtual std::string getSetting(const Setting<std::string>& setting) = 0; - virtual void storeSetting(const Setting<std::string>& setting, const std::string& value) = 0; - virtual bool getSetting(const Setting<bool>& setting) = 0; - virtual void storeSetting(const Setting<bool>& setting, const bool& value) = 0; - virtual int getSetting(const Setting<int>& setting) = 0; - virtual void storeSetting(const Setting<int>& setting, const int& value) = 0; - - virtual std::vector<std::string> getAvailableProfiles() = 0; - virtual void createProfile(const std::string& profile) = 0; - virtual void removeProfile(const std::string& profile) = 0; - /** A final setting is one that this settings provider says may not be overriden by lower priority profiles. - * e.g. An Administrator-set configuration to disallow saving user passwords could not be overridden by the user. - */ - template<typename T> - bool getIsSettingFinal(const Setting<T>& setting) { - return getIsSettingFinal(setting.getKey()); - } - virtual bool hasSetting(const std::string& key) = 0; - - friend class SettingsProviderHierachy; - protected: - virtual bool getIsSettingFinal(const std::string& settingPath) = 0; - - public: - /** - * Emitted when a setting is changed. - */ - boost::signal<void (const std::string& /*Setting's Path*/)> onSettingChanged; + public: + template <typename T> + class Setting { + public: + Setting(const std::string& key, const T& defaultValue) : key(key), defaultValue(defaultValue) { + + } + + const std::string& getKey() const { + return key; + } + + const T& getDefaultValue() const { + return defaultValue; + } + + private: + std::string key; + T defaultValue; + }; + + public: + virtual ~SettingsProvider() {} + virtual std::string getSetting(const Setting<std::string>& setting) = 0; + virtual void storeSetting(const Setting<std::string>& setting, const std::string& value) = 0; + virtual bool getSetting(const Setting<bool>& setting) = 0; + virtual void storeSetting(const Setting<bool>& setting, const bool& value) = 0; + virtual int getSetting(const Setting<int>& setting) = 0; + virtual void storeSetting(const Setting<int>& setting, const int& value) = 0; + + virtual std::vector<std::string> getAvailableProfiles() = 0; + virtual void createProfile(const std::string& profile) = 0; + virtual void removeProfile(const std::string& profile) = 0; + /** A final setting is one that this settings provider says may not be overriden by lower priority profiles. + * e.g. An Administrator-set configuration to disallow saving user passwords could not be overridden by the user. + */ + template<typename T> + bool getIsSettingFinal(const Setting<T>& setting) { + return getIsSettingFinal(setting.getKey()); + } + virtual bool hasSetting(const std::string& key) = 0; + + friend class SettingsProviderHierachy; + protected: + virtual bool getIsSettingFinal(const std::string& settingPath) = 0; + + public: + /** + * Emitted when a setting is changed. + */ + boost::signal<void (const std::string& /*Setting's Path*/)> onSettingChanged; }; } diff --git a/Swift/Controllers/Settings/SettingsProviderHierachy.cpp b/Swift/Controllers/Settings/SettingsProviderHierachy.cpp index a349417..5156d14 100644 --- a/Swift/Controllers/Settings/SettingsProviderHierachy.cpp +++ b/Swift/Controllers/Settings/SettingsProviderHierachy.cpp @@ -14,102 +14,102 @@ SettingsProviderHierachy::~SettingsProviderHierachy() { } bool SettingsProviderHierachy::hasSetting(const std::string& key) { - foreach (SettingsProvider* provider, providers_) { - if (provider->hasSetting(key)) { - return true; - } - } - return false; + foreach (SettingsProvider* provider, providers_) { + if (provider->hasSetting(key)) { + return true; + } + } + return false; } std::string SettingsProviderHierachy::getSetting(const Setting<std::string>& setting) { - std::string value = setting.getDefaultValue(); - foreach (SettingsProvider* provider, providers_) { - std::string providerSetting = provider->getSetting(setting); - if (provider->hasSetting(setting.getKey())) { - value = providerSetting; - } - if (provider->getIsSettingFinal(setting.getKey())) { - return value; - } - } - return value; + std::string value = setting.getDefaultValue(); + foreach (SettingsProvider* provider, providers_) { + std::string providerSetting = provider->getSetting(setting); + if (provider->hasSetting(setting.getKey())) { + value = providerSetting; + } + if (provider->getIsSettingFinal(setting.getKey())) { + return value; + } + } + return value; } void SettingsProviderHierachy::storeSetting(const Setting<std::string>& setting, const std::string& settingValue) { - if (!getIsSettingFinal(setting.getKey())) { - getWritableProvider()->storeSetting(setting, settingValue); - } + if (!getIsSettingFinal(setting.getKey())) { + getWritableProvider()->storeSetting(setting, settingValue); + } } bool SettingsProviderHierachy::getSetting(const Setting<bool>& setting) { - bool value = setting.getDefaultValue(); - foreach (SettingsProvider* provider, providers_) { - bool providerSetting = provider->getSetting(setting); - if (provider->hasSetting(setting.getKey())) { - value = providerSetting; - if (provider->getIsSettingFinal(setting.getKey())) { - return providerSetting; - } - } - } - return value; + bool value = setting.getDefaultValue(); + foreach (SettingsProvider* provider, providers_) { + bool providerSetting = provider->getSetting(setting); + if (provider->hasSetting(setting.getKey())) { + value = providerSetting; + if (provider->getIsSettingFinal(setting.getKey())) { + return providerSetting; + } + } + } + return value; } void SettingsProviderHierachy::storeSetting(const Setting<bool>& setting, const bool& settingValue) { - if (!getIsSettingFinal(setting.getKey())) { - getWritableProvider()->storeSetting(setting, settingValue); - } + if (!getIsSettingFinal(setting.getKey())) { + getWritableProvider()->storeSetting(setting, settingValue); + } } int SettingsProviderHierachy::getSetting(const Setting<int>& setting) { - int value = setting.getDefaultValue(); - foreach (SettingsProvider* provider, providers_) { - int providerSetting = provider->getSetting(setting); - if (provider->hasSetting(setting.getKey())) { - value = providerSetting; - if (provider->getIsSettingFinal(setting.getKey())) { - return providerSetting; - } - } - } - return value; + int value = setting.getDefaultValue(); + foreach (SettingsProvider* provider, providers_) { + int providerSetting = provider->getSetting(setting); + if (provider->hasSetting(setting.getKey())) { + value = providerSetting; + if (provider->getIsSettingFinal(setting.getKey())) { + return providerSetting; + } + } + } + return value; } void SettingsProviderHierachy::storeSetting(const Setting<int>& setting, const int& settingValue) { - if (!getIsSettingFinal(setting.getKey())) { - getWritableProvider()->storeSetting(setting, settingValue); - } + if (!getIsSettingFinal(setting.getKey())) { + getWritableProvider()->storeSetting(setting, settingValue); + } } std::vector<std::string> SettingsProviderHierachy::getAvailableProfiles() { - /* Always pull profiles from the topmost */ - return getWritableProvider()->getAvailableProfiles(); + /* Always pull profiles from the topmost */ + return getWritableProvider()->getAvailableProfiles(); } void SettingsProviderHierachy::createProfile(const std::string& profile) { - return getWritableProvider()->createProfile(profile); + return getWritableProvider()->createProfile(profile); } void SettingsProviderHierachy::removeProfile(const std::string& profile) { - return getWritableProvider()->removeProfile(profile); + return getWritableProvider()->removeProfile(profile); } bool SettingsProviderHierachy::getIsSettingFinal(const std::string& settingPath) { - bool isFinal = false; - foreach (SettingsProvider* provider, providers_) { - isFinal |= provider->getIsSettingFinal(settingPath); - } - return isFinal; + bool isFinal = false; + foreach (SettingsProvider* provider, providers_) { + isFinal |= provider->getIsSettingFinal(settingPath); + } + return isFinal; } SettingsProvider* SettingsProviderHierachy::getWritableProvider() { - return providers_.back(); + return providers_.back(); } void SettingsProviderHierachy::addProviderToTopOfStack(SettingsProvider* provider) { - providers_.push_back(provider); - provider->onSettingChanged.connect(onSettingChanged); + providers_.push_back(provider); + provider->onSettingChanged.connect(onSettingChanged); } } diff --git a/Swift/Controllers/Settings/SettingsProviderHierachy.h b/Swift/Controllers/Settings/SettingsProviderHierachy.h index 9efbdcb..a68ff36 100644 --- a/Swift/Controllers/Settings/SettingsProviderHierachy.h +++ b/Swift/Controllers/Settings/SettingsProviderHierachy.h @@ -11,34 +11,34 @@ namespace Swift { class SettingsProviderHierachy : public SettingsProvider { - public: - virtual ~SettingsProviderHierachy(); - virtual std::string getSetting(const Setting<std::string>& setting); - virtual void storeSetting(const Setting<std::string>& setting, const std::string& value); - virtual bool getSetting(const Setting<bool>& setting); - virtual void storeSetting(const Setting<bool>& setting, const bool& value); - virtual int getSetting(const Setting<int>& setting); - virtual void storeSetting(const Setting<int>& setting, const int& value); - virtual std::vector<std::string> getAvailableProfiles(); - virtual void createProfile(const std::string& profile); - virtual void removeProfile(const std::string& profile); - virtual bool hasSetting(const std::string& key); - protected: - virtual bool getIsSettingFinal(const std::string& settingPath); - - public: - /** - * Adds a provider less significant than any already added. - * This means that if an existing provider has a setting, this provider won't be asked. - * Any settings will be pushed into the topmost (least significant) provider. - * Does not take ownership of provider. - */ - void addProviderToTopOfStack(SettingsProvider* provider); - private: - SettingsProvider* getWritableProvider(); - private: - /* Start/Left is most significant (lowest), left overrides right.*/ - std::vector<SettingsProvider*> providers_; + public: + virtual ~SettingsProviderHierachy(); + virtual std::string getSetting(const Setting<std::string>& setting); + virtual void storeSetting(const Setting<std::string>& setting, const std::string& value); + virtual bool getSetting(const Setting<bool>& setting); + virtual void storeSetting(const Setting<bool>& setting, const bool& value); + virtual int getSetting(const Setting<int>& setting); + virtual void storeSetting(const Setting<int>& setting, const int& value); + virtual std::vector<std::string> getAvailableProfiles(); + virtual void createProfile(const std::string& profile); + virtual void removeProfile(const std::string& profile); + virtual bool hasSetting(const std::string& key); + protected: + virtual bool getIsSettingFinal(const std::string& settingPath); + + public: + /** + * Adds a provider less significant than any already added. + * This means that if an existing provider has a setting, this provider won't be asked. + * Any settings will be pushed into the topmost (least significant) provider. + * Does not take ownership of provider. + */ + void addProviderToTopOfStack(SettingsProvider* provider); + private: + SettingsProvider* getWritableProvider(); + private: + /* Start/Left is most significant (lowest), left overrides right.*/ + std::vector<SettingsProvider*> providers_; }; } diff --git a/Swift/Controllers/Settings/UnitTest/SettingsProviderHierachyTest.cpp b/Swift/Controllers/Settings/UnitTest/SettingsProviderHierachyTest.cpp index 11d5c11..5822add 100644 --- a/Swift/Controllers/Settings/UnitTest/SettingsProviderHierachyTest.cpp +++ b/Swift/Controllers/Settings/UnitTest/SettingsProviderHierachyTest.cpp @@ -15,77 +15,77 @@ using namespace Swift; using namespace std; class SettingsProviderHierachyTest : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(SettingsProviderHierachyTest); - CPPUNIT_TEST(testEmpty); - CPPUNIT_TEST(testTop); - CPPUNIT_TEST(testBottom); - CPPUNIT_TEST(testBoth); - CPPUNIT_TEST(testTopDefault); - CPPUNIT_TEST(testBottomOverrides); - CPPUNIT_TEST(testFinal); - CPPUNIT_TEST_SUITE_END(); + CPPUNIT_TEST_SUITE(SettingsProviderHierachyTest); + CPPUNIT_TEST(testEmpty); + CPPUNIT_TEST(testTop); + CPPUNIT_TEST(testBottom); + CPPUNIT_TEST(testBoth); + CPPUNIT_TEST(testTopDefault); + CPPUNIT_TEST(testBottomOverrides); + CPPUNIT_TEST(testFinal); + CPPUNIT_TEST_SUITE_END(); public: - SettingsProviderHierachyTest() : setting1("somekey", 42) {} + SettingsProviderHierachyTest() : setting1("somekey", 42) {} - void setUp() { - bottom = new DummySettingsProvider(); - top = new DummySettingsProvider(); - testling = new SettingsProviderHierachy(); - testling->addProviderToTopOfStack(bottom); - testling->addProviderToTopOfStack(top); - } + void setUp() { + bottom = new DummySettingsProvider(); + top = new DummySettingsProvider(); + testling = new SettingsProviderHierachy(); + testling->addProviderToTopOfStack(bottom); + testling->addProviderToTopOfStack(top); + } - void tearDown() { - delete testling; - delete top; - delete bottom; - } + void tearDown() { + delete testling; + delete top; + delete bottom; + } - void testEmpty() { - CPPUNIT_ASSERT_EQUAL(42, testling->getSetting(setting1)); - } + void testEmpty() { + CPPUNIT_ASSERT_EQUAL(42, testling->getSetting(setting1)); + } - void testTop() { - top->storeSetting(setting1, 37); - CPPUNIT_ASSERT_EQUAL(37, testling->getSetting(setting1)); - } + void testTop() { + top->storeSetting(setting1, 37); + CPPUNIT_ASSERT_EQUAL(37, testling->getSetting(setting1)); + } - void testBottom() { - bottom->storeSetting(setting1, 17); - CPPUNIT_ASSERT_EQUAL(17, testling->getSetting(setting1)); - } + void testBottom() { + bottom->storeSetting(setting1, 17); + CPPUNIT_ASSERT_EQUAL(17, testling->getSetting(setting1)); + } - void testBoth() { - bottom->storeSetting(setting1, 17); - top->storeSetting(setting1, 37); - CPPUNIT_ASSERT_EQUAL(37, testling->getSetting(setting1)); - } + void testBoth() { + bottom->storeSetting(setting1, 17); + top->storeSetting(setting1, 37); + CPPUNIT_ASSERT_EQUAL(37, testling->getSetting(setting1)); + } - void testTopDefault() { - bottom->storeSetting(setting1, 17); - top->storeSetting(setting1, 42); - CPPUNIT_ASSERT_EQUAL(42, testling->getSetting(setting1)); - } + void testTopDefault() { + bottom->storeSetting(setting1, 17); + top->storeSetting(setting1, 42); + CPPUNIT_ASSERT_EQUAL(42, testling->getSetting(setting1)); + } - void testBottomOverrides() { - bottom->storeSetting(setting1, 17); - bottom->setFinal(setting1.getKey()); - top->storeSetting(setting1, 5); - CPPUNIT_ASSERT_EQUAL(17, testling->getSetting(setting1)); - } + void testBottomOverrides() { + bottom->storeSetting(setting1, 17); + bottom->setFinal(setting1.getKey()); + top->storeSetting(setting1, 5); + CPPUNIT_ASSERT_EQUAL(17, testling->getSetting(setting1)); + } - void testFinal() { - bottom->storeSetting(setting1, 17); - bottom->setFinal(setting1.getKey()); - testling->storeSetting(setting1, 5); - CPPUNIT_ASSERT_EQUAL(17, testling->getSetting(setting1)); - } + void testFinal() { + bottom->storeSetting(setting1, 17); + bottom->setFinal(setting1.getKey()); + testling->storeSetting(setting1, 5); + CPPUNIT_ASSERT_EQUAL(17, testling->getSetting(setting1)); + } private: - SettingsProviderHierachy* testling; - DummySettingsProvider* bottom; - DummySettingsProvider* top; - SettingsProvider::Setting<int> setting1; + SettingsProviderHierachy* testling; + DummySettingsProvider* bottom; + DummySettingsProvider* top; + SettingsProvider::Setting<int> setting1; }; CPPUNIT_TEST_SUITE_REGISTRATION(SettingsProviderHierachyTest); diff --git a/Swift/Controllers/Settings/XMLSettingsProvider.cpp b/Swift/Controllers/Settings/XMLSettingsProvider.cpp index 548f36f..4dfb8bd 100644 --- a/Swift/Controllers/Settings/XMLSettingsProvider.cpp +++ b/Swift/Controllers/Settings/XMLSettingsProvider.cpp @@ -16,20 +16,20 @@ namespace Swift { XMLSettingsProvider::XMLSettingsProvider(const std::string& xmlConfig) : level_(0) { - if (!xmlConfig.empty()) { - PlatformXMLParserFactory factory; - XMLParser* parser = factory.createXMLParser(this); - if (parser->parse(xmlConfig)) { - SWIFT_LOG(debug) << "Found and parsed system config" << std::endl; - } - else { - SWIFT_LOG(debug) << "Found invalid system config" << std::endl; - } - delete parser; - } - else { - SWIFT_LOG(debug) << "No system config found" << std::endl; - } + if (!xmlConfig.empty()) { + PlatformXMLParserFactory factory; + XMLParser* parser = factory.createXMLParser(this); + if (parser->parse(xmlConfig)) { + SWIFT_LOG(debug) << "Found and parsed system config" << std::endl; + } + else { + SWIFT_LOG(debug) << "Found invalid system config" << std::endl; + } + delete parser; + } + else { + SWIFT_LOG(debug) << "No system config found" << std::endl; + } } XMLSettingsProvider::~XMLSettingsProvider() { @@ -37,89 +37,89 @@ XMLSettingsProvider::~XMLSettingsProvider() { } bool XMLSettingsProvider::hasSetting(const std::string& key) { - return (values_.find(key) != values_.end()); + return (values_.find(key) != values_.end()); } std::string XMLSettingsProvider::getSetting(const Setting<std::string>& setting) { - if (values_.find(setting.getKey()) != values_.end()) { - std::string value = values_[setting.getKey()]; - return value; - } - return setting.getDefaultValue(); + if (values_.find(setting.getKey()) != values_.end()) { + std::string value = values_[setting.getKey()]; + return value; + } + return setting.getDefaultValue(); } void XMLSettingsProvider::storeSetting(const Setting<std::string>& /*settingPath*/, const std::string& /*settingValue*/) { - assert(false); + assert(false); } bool XMLSettingsProvider::getSetting(const Setting<bool>& setting) { - if (values_.find(setting.getKey()) != values_.end()) { - std::string value = values_[setting.getKey()]; - return boost::iequals(value, "true") || value == "1"; - } - return setting.getDefaultValue(); + if (values_.find(setting.getKey()) != values_.end()) { + std::string value = values_[setting.getKey()]; + return boost::iequals(value, "true") || value == "1"; + } + return setting.getDefaultValue(); } void XMLSettingsProvider::storeSetting(const Setting<bool>& /*settingPath*/, const bool& /*settingValue*/) { - assert(false); + assert(false); } int XMLSettingsProvider::getSetting(const Setting<int>& setting) { - if (values_.find(setting.getKey()) != values_.end()) { - std::string value = values_[setting.getKey()]; - try { - return value.empty() ? setting.getDefaultValue() : boost::lexical_cast<int>(value);; - } - catch(boost::bad_lexical_cast &) {} - } - return setting.getDefaultValue(); + if (values_.find(setting.getKey()) != values_.end()) { + std::string value = values_[setting.getKey()]; + try { + return value.empty() ? setting.getDefaultValue() : boost::lexical_cast<int>(value);; + } + catch(boost::bad_lexical_cast &) {} + } + return setting.getDefaultValue(); } void XMLSettingsProvider::storeSetting(const Setting<int>& /*settingPath*/, const int& /*settingValue*/) { - assert(false); + assert(false); } std::vector<std::string> XMLSettingsProvider::getAvailableProfiles() { - assert(false); - return std::vector<std::string>(); + assert(false); + return std::vector<std::string>(); } void XMLSettingsProvider::createProfile(const std::string& /*profile*/) { - assert(false); + assert(false); } void XMLSettingsProvider::removeProfile(const std::string& /*profile*/) { - assert(false); + assert(false); } bool XMLSettingsProvider::getIsSettingFinal(const std::string& settingPath) { - return finals_.count(settingPath); + return finals_.count(settingPath); } void XMLSettingsProvider::handleStartElement(const std::string& element, const std::string& /*ns*/, const AttributeMap& attributes) { - level_++; - if (level_ == SettingLevel) { - if (attributes.getBoolAttribute("final", false)) { - finals_.insert(element); - } - currentElement_ = element; - currentText_ = ""; - } + level_++; + if (level_ == SettingLevel) { + if (attributes.getBoolAttribute("final", false)) { + finals_.insert(element); + } + currentElement_ = element; + currentText_ = ""; + } } void XMLSettingsProvider::handleEndElement(const std::string& /*element*/, const std::string& /*ns*/) { - if (level_ == SettingLevel) { - values_[currentElement_] = currentText_; - SWIFT_LOG(debug) << "Setting value of " << currentElement_ << " to " << currentText_ << std::endl; - } - level_--; + if (level_ == SettingLevel) { + values_[currentElement_] = currentText_; + SWIFT_LOG(debug) << "Setting value of " << currentElement_ << " to " << currentText_ << std::endl; + } + level_--; } void XMLSettingsProvider::handleCharacterData(const std::string& data) { - if (level_ >= SettingLevel) { - currentText_ += data; - } + if (level_ >= SettingLevel) { + currentText_ += data; + } } diff --git a/Swift/Controllers/Settings/XMLSettingsProvider.h b/Swift/Controllers/Settings/XMLSettingsProvider.h index 2dbb23c..5fd82cf 100644 --- a/Swift/Controllers/Settings/XMLSettingsProvider.h +++ b/Swift/Controllers/Settings/XMLSettingsProvider.h @@ -16,40 +16,40 @@ namespace Swift { class XMLSettingsProvider : public SettingsProvider, public XMLParserClient { - public: - XMLSettingsProvider(const std::string& xmlConfig); - virtual ~XMLSettingsProvider(); - virtual std::string getSetting(const Setting<std::string>& setting); - virtual void storeSetting(const Setting<std::string>& setting, const std::string& value); - virtual bool getSetting(const Setting<bool>& setting); - virtual void storeSetting(const Setting<bool>& setting, const bool& value); - virtual int getSetting(const Setting<int>& setting); - virtual void storeSetting(const Setting<int>& setting, const int& value); - virtual std::vector<std::string> getAvailableProfiles(); - virtual void createProfile(const std::string& profile); - virtual void removeProfile(const std::string& profile); - virtual bool hasSetting(const std::string& key); - - - virtual void handleStartElement(const std::string& element, const std::string& ns, const AttributeMap& attributes); - virtual void handleEndElement(const std::string& element, const std::string& ns); - virtual void handleCharacterData(const std::string& data); - - protected: - virtual bool getIsSettingFinal(const std::string& settingPath); - private: - std::map<std::string /*settingPath*/, std::string /*settingValue*/> values_; - /* Settings that are final*/ - std::set<std::string /*settingPath*/> finals_; - - enum Level { - TopLevel = 0, - SettingLevel = 2 - }; - - int level_; - std::string currentElement_; - std::string currentText_; + public: + XMLSettingsProvider(const std::string& xmlConfig); + virtual ~XMLSettingsProvider(); + virtual std::string getSetting(const Setting<std::string>& setting); + virtual void storeSetting(const Setting<std::string>& setting, const std::string& value); + virtual bool getSetting(const Setting<bool>& setting); + virtual void storeSetting(const Setting<bool>& setting, const bool& value); + virtual int getSetting(const Setting<int>& setting); + virtual void storeSetting(const Setting<int>& setting, const int& value); + virtual std::vector<std::string> getAvailableProfiles(); + virtual void createProfile(const std::string& profile); + virtual void removeProfile(const std::string& profile); + virtual bool hasSetting(const std::string& key); + + + virtual void handleStartElement(const std::string& element, const std::string& ns, const AttributeMap& attributes); + virtual void handleEndElement(const std::string& element, const std::string& ns); + virtual void handleCharacterData(const std::string& data); + + protected: + virtual bool getIsSettingFinal(const std::string& settingPath); + private: + std::map<std::string /*settingPath*/, std::string /*settingValue*/> values_; + /* Settings that are final*/ + std::set<std::string /*settingPath*/> finals_; + + enum Level { + TopLevel = 0, + SettingLevel = 2 + }; + + int level_; + std::string currentElement_; + std::string currentText_; }; } diff --git a/Swift/Controllers/ShowProfileController.cpp b/Swift/Controllers/ShowProfileController.cpp index 9e94392..bf5eb1e 100644 --- a/Swift/Controllers/ShowProfileController.cpp +++ b/Swift/Controllers/ShowProfileController.cpp @@ -25,57 +25,57 @@ 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)); + 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->onWindowAboutToBeClosed.disconnect(boost::bind(&ShowProfileController::handleProfileWindowAboutToBeClosed, this, _1)); - delete jidWndPair.second; - } + typedef std::pair<JID, ProfileWindow*> JIDProfileWindowPair; + foreach(const JIDProfileWindowPair& jidWndPair, openedProfileWindows) { + jidWndPair.second->onWindowAboutToBeClosed.disconnect(boost::bind(&ShowProfileController::handleProfileWindowAboutToBeClosed, this, _1)); + delete jidWndPair.second; + } - vcardManager->onVCardChanged.disconnect(boost::bind(&ShowProfileController::handleVCardChanged, this, _1, _2)); - uiEventStream->onUIEvent.disconnect(boost::bind(&ShowProfileController::handleUIEvent, this, _1)); + 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; - } + 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->onWindowAboutToBeClosed.connect(boost::bind(&ShowProfileController::handleProfileWindowAboutToBeClosed, this, _1)); - openedProfileWindows[showProfileEvent->getJID()] = newProfileWindow; - VCard::ref vcard = vcardManager->getVCardAndRequestWhenNeeded(showProfileEvent->getJID(), boost::posix_time::minutes(5)); - if (vcard) { - newProfileWindow->setVCard(vcard); - } else { - newProfileWindow->setProcessing(true); - } - newProfileWindow->show(); - } else { - openedProfileWindows[showProfileEvent->getJID()]->show(); - } + if (openedProfileWindows.find(showProfileEvent->getJID()) == openedProfileWindows.end()) { + ProfileWindow* newProfileWindow = profileWindowFactory->createProfileWindow(); + newProfileWindow->setJID(showProfileEvent->getJID()); + newProfileWindow->onWindowAboutToBeClosed.connect(boost::bind(&ShowProfileController::handleProfileWindowAboutToBeClosed, this, _1)); + openedProfileWindows[showProfileEvent->getJID()] = newProfileWindow; + VCard::ref vcard = vcardManager->getVCardAndRequestWhenNeeded(showProfileEvent->getJID(), boost::posix_time::minutes(5)); + 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; - } + if (openedProfileWindows.find(jid) == openedProfileWindows.end()) { + return; + } - ProfileWindow* profileWindow = openedProfileWindows[jid]; - profileWindow->setVCard(vcard); - profileWindow->setProcessing(false); - profileWindow->show(); + ProfileWindow* profileWindow = openedProfileWindows[jid]; + profileWindow->setVCard(vcard); + profileWindow->setProcessing(false); + profileWindow->show(); } void ShowProfileController::handleProfileWindowAboutToBeClosed(const JID& profileJid) { - openedProfileWindows.erase(profileJid); + openedProfileWindows.erase(profileJid); } } diff --git a/Swift/Controllers/ShowProfileController.h b/Swift/Controllers/ShowProfileController.h index 37fb615..4f23c19 100644 --- a/Swift/Controllers/ShowProfileController.h +++ b/Swift/Controllers/ShowProfileController.h @@ -18,25 +18,25 @@ #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 handleProfileWindowAboutToBeClosed(const JID& profileJid); - - private: - VCardManager* vcardManager; - ProfileWindowFactory* profileWindowFactory; - UIEventStream* uiEventStream; - std::map<JID, ProfileWindow*> openedProfileWindows; - }; + 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 handleProfileWindowAboutToBeClosed(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 43c8ed0..433937b 100644 --- a/Swift/Controllers/SoundEventController.cpp +++ b/Swift/Controllers/SoundEventController.cpp @@ -18,39 +18,39 @@ namespace Swift { 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_ = 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)); + settings_->onSettingChanged.connect(boost::bind(&SoundEventController::handleSettingChanged, this, _1)); - playSounds_ = settings->getSetting(SettingConstants::PLAY_SOUNDS); + playSounds_ = settings->getSetting(SettingConstants::PLAY_SOUNDS); } void SoundEventController::handleEventQueueEventAdded(boost::shared_ptr<StanzaEvent> event) { - if (playSounds_ && boost::dynamic_pointer_cast<IncomingFileTransferEvent>(event)) { - soundPlayer_->playSound(SoundPlayer::MessageReceived, ""); - } + if (playSounds_ && boost::dynamic_pointer_cast<IncomingFileTransferEvent>(event)) { + soundPlayer_->playSound(SoundPlayer::MessageReceived, ""); + } } void SoundEventController::handleHighlight(const HighlightAction& action) { - if (playSounds_ && action.playSound()) { - soundPlayer_->playSound(SoundPlayer::MessageReceived, action.getSoundFile()); - } + if (playSounds_ && action.playSound()) { + soundPlayer_->playSound(SoundPlayer::MessageReceived, action.getSoundFile()); + } } void SoundEventController::setPlaySounds(bool playSounds) { - playSounds_ = playSounds; - settings_->storeSetting(SettingConstants::PLAY_SOUNDS, playSounds); + playSounds_ = playSounds; + settings_->storeSetting(SettingConstants::PLAY_SOUNDS, playSounds); } void SoundEventController::handleSettingChanged(const std::string& settingPath) { - if (SettingConstants::PLAY_SOUNDS.getKey() == settingPath) { - playSounds_ = settings_->getSetting(SettingConstants::PLAY_SOUNDS); - } + if (SettingConstants::PLAY_SOUNDS.getKey() == settingPath) { + playSounds_ = settings_->getSetting(SettingConstants::PLAY_SOUNDS); + } } } diff --git a/Swift/Controllers/SoundEventController.h b/Swift/Controllers/SoundEventController.h index 88c7b00..3ea682a 100644 --- a/Swift/Controllers/SoundEventController.h +++ b/Swift/Controllers/SoundEventController.h @@ -13,22 +13,22 @@ #include <Swift/Controllers/XMPPEvents/StanzaEvent.h> namespace Swift { - class EventController; - class SoundPlayer; - class HighlightManager; - class SoundEventController { - public: - SoundEventController(EventController* eventController, SoundPlayer* soundPlayer, SettingsProvider* settings, HighlightManager* highlightManager); - void setPlaySounds(bool 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_; - }; + class EventController; + class SoundPlayer; + class HighlightManager; + class SoundEventController { + public: + SoundEventController(EventController* eventController, SoundPlayer* soundPlayer, SettingsProvider* settings, HighlightManager* highlightManager); + void setPlaySounds(bool 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 e38cd7c..8525c6c 100644 --- a/Swift/Controllers/SoundPlayer.h +++ b/Swift/Controllers/SoundPlayer.h @@ -9,10 +9,10 @@ #include <string> namespace Swift { - class SoundPlayer { - public: - virtual ~SoundPlayer() {} - enum SoundEffect{MessageReceived}; - virtual void playSound(SoundEffect sound, const std::string& soundResource) = 0; - }; + class SoundPlayer { + public: + virtual ~SoundPlayer() {} + enum SoundEffect{MessageReceived}; + virtual void playSound(SoundEffect sound, const std::string& soundResource) = 0; + }; } diff --git a/Swift/Controllers/StatusCache.cpp b/Swift/Controllers/StatusCache.cpp index d00d7f6..ce4391d 100644 --- a/Swift/Controllers/StatusCache.cpp +++ b/Swift/Controllers/StatusCache.cpp @@ -24,9 +24,9 @@ namespace Swift { static const size_t MAX_ENTRIES = 200; StatusCache::StatusCache(ApplicationPathProvider* paths) { - paths_ = paths; - path_ = paths_->getDataDir() / "StatusCache"; - loadRecents(); + paths_ = paths; + path_ = paths_->getDataDir() / "StatusCache"; + loadRecents(); } StatusCache::~StatusCache() { @@ -34,71 +34,71 @@ 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; + 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(); + 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_); - 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; - } + try { + if (boost::filesystem::exists(path_)) { + ByteArray data; + readByteArrayFromFile(data, path_); + 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; - } + 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 index 0ed85d6..033cde0 100644 --- a/Swift/Controllers/StatusCache.h +++ b/Swift/Controllers/StatusCache.h @@ -17,24 +17,24 @@ #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_; - }; + 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/StatusTracker.cpp b/Swift/Controllers/StatusTracker.cpp index e42b99e..51db328 100644 --- a/Swift/Controllers/StatusTracker.cpp +++ b/Swift/Controllers/StatusTracker.cpp @@ -13,46 +13,46 @@ namespace Swift { StatusTracker::StatusTracker() { - isAutoAway_ = false; - queuedPresence_ = boost::make_shared<Presence>(); + isAutoAway_ = false; + queuedPresence_ = boost::make_shared<Presence>(); } boost::shared_ptr<Presence> StatusTracker::getNextPresence() { - boost::shared_ptr<Presence> presence; - if (isAutoAway_) { - presence = boost::make_shared<Presence>(); - presence->setShow(StatusShow::Away); - presence->setStatus(queuedPresence_->getStatus()); - presence->addPayload(boost::make_shared<Idle>(isAutoAwaySince_)); - } else { - presence = queuedPresence_; - } - return presence; + boost::shared_ptr<Presence> presence; + if (isAutoAway_) { + presence = boost::make_shared<Presence>(); + presence->setShow(StatusShow::Away); + presence->setStatus(queuedPresence_->getStatus()); + presence->addPayload(boost::make_shared<Idle>(isAutoAwaySince_)); + } else { + presence = queuedPresence_; + } + return presence; } void StatusTracker::setRequestedPresence(boost::shared_ptr<Presence> presence) { - isAutoAway_ = false; - queuedPresence_ = presence; -// if (presence->getType() == Presence::Unavailable) { -// queuedPresence_ = boost::make_shared<Presence>(); -// } + isAutoAway_ = false; + queuedPresence_ = presence; +// if (presence->getType() == Presence::Unavailable) { +// queuedPresence_ = boost::make_shared<Presence>(); +// } } bool StatusTracker::goAutoAway(const int& seconds) { - if (queuedPresence_->getShow() != StatusShow::Online) { - return false; - } - isAutoAway_ = true; - isAutoAwaySince_ = boost::posix_time::second_clock::universal_time() - boost::posix_time::seconds(seconds); - return true; + if (queuedPresence_->getShow() != StatusShow::Online) { + return false; + } + isAutoAway_ = true; + isAutoAwaySince_ = boost::posix_time::second_clock::universal_time() - boost::posix_time::seconds(seconds); + return true; } bool StatusTracker::goAutoUnAway() { - if (!isAutoAway_) { - return false; - } - isAutoAway_ = false; - return true; + if (!isAutoAway_) { + return false; + } + isAutoAway_ = false; + return true; } } diff --git a/Swift/Controllers/StatusTracker.h b/Swift/Controllers/StatusTracker.h index 092ce43..cf92781 100644 --- a/Swift/Controllers/StatusTracker.h +++ b/Swift/Controllers/StatusTracker.h @@ -13,16 +13,16 @@ namespace Swift { - class StatusTracker { - public: - StatusTracker(); - boost::shared_ptr<Presence> getNextPresence(); - void setRequestedPresence(boost::shared_ptr<Presence> presence); - bool goAutoAway(const int& seconds); - bool goAutoUnAway(); - private: - boost::shared_ptr<Presence> queuedPresence_; - bool isAutoAway_; - boost::posix_time::ptime isAutoAwaySince_; - }; + class StatusTracker { + public: + StatusTracker(); + boost::shared_ptr<Presence> getNextPresence(); + void setRequestedPresence(boost::shared_ptr<Presence> presence); + bool goAutoAway(const int& seconds); + bool goAutoUnAway(); + private: + boost::shared_ptr<Presence> queuedPresence_; + bool isAutoAway_; + boost::posix_time::ptime isAutoAwaySince_; + }; } diff --git a/Swift/Controllers/StatusUtil.cpp b/Swift/Controllers/StatusUtil.cpp index 0c5bc21..1034863 100644 --- a/Swift/Controllers/StatusUtil.cpp +++ b/Swift/Controllers/StatusUtil.cpp @@ -13,16 +13,16 @@ namespace Swift { std::string statusShowTypeToFriendlyName(StatusShow::Type type) { - switch (type) { - case StatusShow::Online: return QT_TRANSLATE_NOOP("", "Available"); - case StatusShow::FFC: return QT_TRANSLATE_NOOP("", "Available"); - case StatusShow::Away: return QT_TRANSLATE_NOOP("", "Away"); - case StatusShow::XA: return QT_TRANSLATE_NOOP("", "Away"); - case StatusShow::DND: return QT_TRANSLATE_NOOP("", "Busy"); - case StatusShow::None: return QT_TRANSLATE_NOOP("", "Offline"); - } - assert(false); - return ""; + switch (type) { + case StatusShow::Online: return QT_TRANSLATE_NOOP("", "Available"); + case StatusShow::FFC: return QT_TRANSLATE_NOOP("", "Available"); + case StatusShow::Away: return QT_TRANSLATE_NOOP("", "Away"); + case StatusShow::XA: return QT_TRANSLATE_NOOP("", "Away"); + case StatusShow::DND: return QT_TRANSLATE_NOOP("", "Busy"); + case StatusShow::None: return QT_TRANSLATE_NOOP("", "Offline"); + } + assert(false); + return ""; } } diff --git a/Swift/Controllers/StatusUtil.h b/Swift/Controllers/StatusUtil.h index 871ca0a..6872bf7 100644 --- a/Swift/Controllers/StatusUtil.h +++ b/Swift/Controllers/StatusUtil.h @@ -11,6 +11,6 @@ #include <Swiften/Elements/StatusShow.h> namespace Swift { - std::string statusShowTypeToFriendlyName(StatusShow::Type type); + std::string statusShowTypeToFriendlyName(StatusShow::Type type); } diff --git a/Swift/Controllers/Storages/AvatarFileStorage.cpp b/Swift/Controllers/Storages/AvatarFileStorage.cpp index 56e27e1..cded945 100644 --- a/Swift/Controllers/Storages/AvatarFileStorage.cpp +++ b/Swift/Controllers/Storages/AvatarFileStorage.cpp @@ -19,88 +19,88 @@ namespace Swift { AvatarFileStorage::AvatarFileStorage(const boost::filesystem::path& avatarsDir, const boost::filesystem::path& avatarsFile, CryptoProvider* crypto) : avatarsDir(avatarsDir), avatarsFile(avatarsFile), crypto(crypto) { - if (boost::filesystem::exists(avatarsFile)) { - try { - boost::filesystem::ifstream file(avatarsFile); - std::string line; - if (file.is_open()) { - while (!file.eof()) { - getline(file, line); - std::pair<std::string, std::string> r = String::getSplittedAtFirst(line, ' '); - JID jid(r.second); - if (jid.isValid()) { - jidAvatars.insert(std::make_pair(jid, r.first)); - } - else if (!r.first.empty() || !r.second.empty()) { - std::cerr << "Invalid entry in avatars file: " << r.second << std::endl; - } - } - } - } - catch (...) { - std::cerr << "Error reading avatars file" << std::endl; - } - } + if (boost::filesystem::exists(avatarsFile)) { + try { + boost::filesystem::ifstream file(avatarsFile); + std::string line; + if (file.is_open()) { + while (!file.eof()) { + getline(file, line); + std::pair<std::string, std::string> r = String::getSplittedAtFirst(line, ' '); + JID jid(r.second); + if (jid.isValid()) { + jidAvatars.insert(std::make_pair(jid, r.first)); + } + else if (!r.first.empty() || !r.second.empty()) { + std::cerr << "Invalid entry in avatars file: " << r.second << std::endl; + } + } + } + } + catch (...) { + std::cerr << "Error reading avatars file" << std::endl; + } + } } -bool AvatarFileStorage::hasAvatar(const std::string& hash) const { - return boost::filesystem::exists(getAvatarPath(hash)); +bool AvatarFileStorage::hasAvatar(const std::string& hash) const { + return boost::filesystem::exists(getAvatarPath(hash)); } void AvatarFileStorage::addAvatar(const std::string& hash, const ByteArray& avatar) { - assert(Hexify::hexify(crypto->getSHA1Hash(avatar)) == hash); + assert(Hexify::hexify(crypto->getSHA1Hash(avatar)) == hash); - boost::filesystem::path avatarPath = getAvatarPath(hash); - if (!boost::filesystem::exists(avatarPath.parent_path())) { - try { - boost::filesystem::create_directories(avatarPath.parent_path()); - } - catch (const boost::filesystem::filesystem_error& e) { - std::cerr << "ERROR: " << e.what() << std::endl; - } - } - boost::filesystem::ofstream file(avatarPath, boost::filesystem::ofstream::binary|boost::filesystem::ofstream::out); - file.write(reinterpret_cast<const char*>(vecptr(avatar)), static_cast<std::streamsize>(avatar.size())); - file.close(); + boost::filesystem::path avatarPath = getAvatarPath(hash); + if (!boost::filesystem::exists(avatarPath.parent_path())) { + try { + boost::filesystem::create_directories(avatarPath.parent_path()); + } + catch (const boost::filesystem::filesystem_error& e) { + std::cerr << "ERROR: " << e.what() << std::endl; + } + } + boost::filesystem::ofstream file(avatarPath, boost::filesystem::ofstream::binary|boost::filesystem::ofstream::out); + file.write(reinterpret_cast<const char*>(vecptr(avatar)), static_cast<std::streamsize>(avatar.size())); + file.close(); } boost::filesystem::path AvatarFileStorage::getAvatarPath(const std::string& hash) const { - return avatarsDir / hash; + return avatarsDir / hash; } ByteArray AvatarFileStorage::getAvatar(const std::string& hash) const { - ByteArray data; - readByteArrayFromFile(data, getAvatarPath(hash)); - return data; + ByteArray data; + readByteArrayFromFile(data, getAvatarPath(hash)); + return data; } void AvatarFileStorage::setAvatarForJID(const JID& jid, const std::string& hash) { - std::pair<JIDAvatarMap::iterator, bool> r = jidAvatars.insert(std::make_pair(jid, hash)); - if (r.second) { - saveJIDAvatars(); - } - else if (r.first->second != hash) { - r.first->second = hash; - saveJIDAvatars(); - } + std::pair<JIDAvatarMap::iterator, bool> r = jidAvatars.insert(std::make_pair(jid, hash)); + if (r.second) { + saveJIDAvatars(); + } + else if (r.first->second != hash) { + r.first->second = hash; + saveJIDAvatars(); + } } std::string AvatarFileStorage::getAvatarForJID(const JID& jid) const { - JIDAvatarMap::const_iterator i = jidAvatars.find(jid); - return i == jidAvatars.end() ? "" : i->second; + JIDAvatarMap::const_iterator i = jidAvatars.find(jid); + return i == jidAvatars.end() ? "" : i->second; } void AvatarFileStorage::saveJIDAvatars() { - try { - boost::filesystem::ofstream file(avatarsFile); - for (JIDAvatarMap::const_iterator i = jidAvatars.begin(); i != jidAvatars.end(); ++i) { - file << i->second << " " << i->first.toString() << std::endl; - } - file.close(); - } - catch (...) { - std::cerr << "Error writing avatars file" << std::endl; - } + try { + boost::filesystem::ofstream file(avatarsFile); + for (JIDAvatarMap::const_iterator i = jidAvatars.begin(); i != jidAvatars.end(); ++i) { + file << i->second << " " << i->first.toString() << std::endl; + } + file.close(); + } + catch (...) { + std::cerr << "Error writing avatars file" << std::endl; + } } } diff --git a/Swift/Controllers/Storages/AvatarFileStorage.h b/Swift/Controllers/Storages/AvatarFileStorage.h index 9c6f617..41c7106 100644 --- a/Swift/Controllers/Storages/AvatarFileStorage.h +++ b/Swift/Controllers/Storages/AvatarFileStorage.h @@ -16,30 +16,30 @@ #include <Swiften/JID/JID.h> namespace Swift { - class CryptoProvider; + class CryptoProvider; - class AvatarFileStorage : public AvatarStorage { - public: - AvatarFileStorage(const boost::filesystem::path& avatarsDir, const boost::filesystem::path& avatarsFile, CryptoProvider* crypto); + class AvatarFileStorage : public AvatarStorage { + public: + AvatarFileStorage(const boost::filesystem::path& avatarsDir, const boost::filesystem::path& avatarsFile, CryptoProvider* crypto); - virtual bool hasAvatar(const std::string& hash) const; - virtual void addAvatar(const std::string& hash, const ByteArray& avatar); - virtual ByteArray getAvatar(const std::string& hash) const; + virtual bool hasAvatar(const std::string& hash) const; + virtual void addAvatar(const std::string& hash, const ByteArray& avatar); + virtual ByteArray getAvatar(const std::string& hash) const; - virtual boost::filesystem::path getAvatarPath(const std::string& hash) const; + virtual boost::filesystem::path getAvatarPath(const std::string& hash) const; - virtual void setAvatarForJID(const JID& jid, const std::string& hash); - virtual std::string getAvatarForJID(const JID& jid) const; + virtual void setAvatarForJID(const JID& jid, const std::string& hash); + virtual std::string getAvatarForJID(const JID& jid) const; - private: - void saveJIDAvatars(); + private: + void saveJIDAvatars(); - private: - boost::filesystem::path avatarsDir; - boost::filesystem::path avatarsFile; - CryptoProvider* crypto; - typedef std::map<JID, std::string> JIDAvatarMap; - JIDAvatarMap jidAvatars; - }; + private: + boost::filesystem::path avatarsDir; + boost::filesystem::path avatarsFile; + CryptoProvider* crypto; + typedef std::map<JID, std::string> JIDAvatarMap; + JIDAvatarMap jidAvatars; + }; } diff --git a/Swift/Controllers/Storages/CapsFileStorage.cpp b/Swift/Controllers/Storages/CapsFileStorage.cpp index 7b99fe0..21a99bc 100644 --- a/Swift/Controllers/Storages/CapsFileStorage.cpp +++ b/Swift/Controllers/Storages/CapsFileStorage.cpp @@ -20,15 +20,15 @@ CapsFileStorage::CapsFileStorage(const boost::filesystem::path& path) : path(pat } DiscoInfo::ref CapsFileStorage::getDiscoInfo(const std::string& hash) const { - return DiscoInfoPersister().loadPayloadGeneric(getCapsPath(hash)); + return DiscoInfoPersister().loadPayloadGeneric(getCapsPath(hash)); } void CapsFileStorage::setDiscoInfo(const std::string& hash, DiscoInfo::ref discoInfo) { - DiscoInfo::ref bareDiscoInfo(new DiscoInfo(*discoInfo.get())); - bareDiscoInfo->setNode(""); - DiscoInfoPersister().savePayload(bareDiscoInfo, getCapsPath(hash)); + DiscoInfo::ref bareDiscoInfo(new DiscoInfo(*discoInfo.get())); + bareDiscoInfo->setNode(""); + DiscoInfoPersister().savePayload(bareDiscoInfo, getCapsPath(hash)); } boost::filesystem::path CapsFileStorage::getCapsPath(const std::string& hash) const { - return path / (Hexify::hexify(Base64::decode(hash)) + ".xml"); + return path / (Hexify::hexify(Base64::decode(hash)) + ".xml"); } diff --git a/Swift/Controllers/Storages/CapsFileStorage.h b/Swift/Controllers/Storages/CapsFileStorage.h index 06dfd91..7df23f1 100644 --- a/Swift/Controllers/Storages/CapsFileStorage.h +++ b/Swift/Controllers/Storages/CapsFileStorage.h @@ -13,17 +13,17 @@ #include <Swiften/Disco/CapsStorage.h> namespace Swift { - class CapsFileStorage : public CapsStorage { - public: - CapsFileStorage(const boost::filesystem::path& path); + class CapsFileStorage : public CapsStorage { + public: + CapsFileStorage(const boost::filesystem::path& path); - virtual DiscoInfo::ref getDiscoInfo(const std::string& hash) const; - virtual void setDiscoInfo(const std::string& hash, DiscoInfo::ref discoInfo); + virtual DiscoInfo::ref getDiscoInfo(const std::string& hash) const; + virtual void setDiscoInfo(const std::string& hash, DiscoInfo::ref discoInfo); - private: - boost::filesystem::path getCapsPath(const std::string& hash) const; + private: + boost::filesystem::path getCapsPath(const std::string& hash) const; - private: - boost::filesystem::path path; - }; + private: + boost::filesystem::path path; + }; } diff --git a/Swift/Controllers/Storages/CertificateFileStorage.cpp b/Swift/Controllers/Storages/CertificateFileStorage.cpp index a549165..3fe6d54 100644 --- a/Swift/Controllers/Storages/CertificateFileStorage.cpp +++ b/Swift/Controllers/Storages/CertificateFileStorage.cpp @@ -22,42 +22,42 @@ CertificateFileStorage::CertificateFileStorage(const boost::filesystem::path& pa } bool CertificateFileStorage::hasCertificate(Certificate::ref certificate) const { - boost::filesystem::path certificatePath = getCertificatePath(certificate); - if (boost::filesystem::exists(certificatePath)) { - ByteArray data; - readByteArrayFromFile(data, certificatePath); - Certificate::ref storedCertificate(certificateFactory->createCertificateFromDER(data)); - if (storedCertificate && storedCertificate->toDER() == certificate->toDER()) { - return true; - } - else { - SWIFT_LOG(warning) << "Stored certificate does not match received certificate" << std::endl; - return false; - } - } - else { - return false; - } + boost::filesystem::path certificatePath = getCertificatePath(certificate); + if (boost::filesystem::exists(certificatePath)) { + ByteArray data; + readByteArrayFromFile(data, certificatePath); + Certificate::ref storedCertificate(certificateFactory->createCertificateFromDER(data)); + if (storedCertificate && storedCertificate->toDER() == certificate->toDER()) { + return true; + } + else { + SWIFT_LOG(warning) << "Stored certificate does not match received certificate" << std::endl; + return false; + } + } + else { + return false; + } } void CertificateFileStorage::addCertificate(Certificate::ref certificate) { - boost::filesystem::path certificatePath = getCertificatePath(certificate); - if (!boost::filesystem::exists(certificatePath.parent_path())) { - try { - boost::filesystem::create_directories(certificatePath.parent_path()); - } - catch (const boost::filesystem::filesystem_error& e) { - std::cerr << "ERROR: " << e.what() << std::endl; - } - } - 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)), boost::numeric_cast<std::streamsize>(data.size())); - file.close(); + boost::filesystem::path certificatePath = getCertificatePath(certificate); + if (!boost::filesystem::exists(certificatePath.parent_path())) { + try { + boost::filesystem::create_directories(certificatePath.parent_path()); + } + catch (const boost::filesystem::filesystem_error& e) { + std::cerr << "ERROR: " << e.what() << std::endl; + } + } + 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)), boost::numeric_cast<std::streamsize>(data.size())); + file.close(); } boost::filesystem::path CertificateFileStorage::getCertificatePath(Certificate::ref certificate) const { - return path / Hexify::hexify(crypto->getSHA1Hash(certificate->toDER())); + return path / Hexify::hexify(crypto->getSHA1Hash(certificate->toDER())); } } diff --git a/Swift/Controllers/Storages/CertificateFileStorage.h b/Swift/Controllers/Storages/CertificateFileStorage.h index f7d3cb3..d2c228d 100644 --- a/Swift/Controllers/Storages/CertificateFileStorage.h +++ b/Swift/Controllers/Storages/CertificateFileStorage.h @@ -11,23 +11,23 @@ #include <Swift/Controllers/Storages/CertificateStorage.h> namespace Swift { - class CertificateFactory; - class CryptoProvider; + class CertificateFactory; + class CryptoProvider; - class CertificateFileStorage : public CertificateStorage { - public: - CertificateFileStorage(const boost::filesystem::path& path, CertificateFactory* certificateFactory, CryptoProvider* crypto); + class CertificateFileStorage : public CertificateStorage { + public: + CertificateFileStorage(const boost::filesystem::path& path, CertificateFactory* certificateFactory, CryptoProvider* crypto); - virtual bool hasCertificate(Certificate::ref certificate) const; - virtual void addCertificate(Certificate::ref certificate); + virtual bool hasCertificate(Certificate::ref certificate) const; + virtual void addCertificate(Certificate::ref certificate); - private: - boost::filesystem::path getCertificatePath(Certificate::ref certificate) const; + private: + boost::filesystem::path getCertificatePath(Certificate::ref certificate) const; - private: - boost::filesystem::path path; - CertificateFactory* certificateFactory; - CryptoProvider* crypto; - }; + private: + boost::filesystem::path path; + CertificateFactory* certificateFactory; + CryptoProvider* crypto; + }; } diff --git a/Swift/Controllers/Storages/CertificateFileStorageFactory.h b/Swift/Controllers/Storages/CertificateFileStorageFactory.h index da8e66e..8ab99f4 100644 --- a/Swift/Controllers/Storages/CertificateFileStorageFactory.h +++ b/Swift/Controllers/Storages/CertificateFileStorageFactory.h @@ -10,21 +10,21 @@ #include <Swift/Controllers/Storages/CertificateStorageFactory.h> namespace Swift { - class CertificateFactory; - class CryptoProvider; + class CertificateFactory; + class CryptoProvider; - class CertificateFileStorageFactory : public CertificateStorageFactory { - public: - CertificateFileStorageFactory(const boost::filesystem::path& basePath, CertificateFactory* certificateFactory, CryptoProvider* crypto) : basePath(basePath), certificateFactory(certificateFactory), crypto(crypto) {} + class CertificateFileStorageFactory : public CertificateStorageFactory { + public: + CertificateFileStorageFactory(const boost::filesystem::path& basePath, CertificateFactory* certificateFactory, CryptoProvider* crypto) : basePath(basePath), certificateFactory(certificateFactory), crypto(crypto) {} - virtual CertificateStorage* createCertificateStorage(const JID& profile) const { - boost::filesystem::path profilePath = basePath / profile.toString(); - return new CertificateFileStorage(profilePath / "certificates", certificateFactory, crypto); - } + virtual CertificateStorage* createCertificateStorage(const JID& profile) const { + boost::filesystem::path profilePath = basePath / profile.toString(); + return new CertificateFileStorage(profilePath / "certificates", certificateFactory, crypto); + } - private: - boost::filesystem::path basePath; - CertificateFactory* certificateFactory; - CryptoProvider* crypto; - }; + private: + boost::filesystem::path basePath; + CertificateFactory* certificateFactory; + CryptoProvider* crypto; + }; } diff --git a/Swift/Controllers/Storages/CertificateMemoryStorage.cpp b/Swift/Controllers/Storages/CertificateMemoryStorage.cpp index cd3c8fa..08c6ee7 100644 --- a/Swift/Controllers/Storages/CertificateMemoryStorage.cpp +++ b/Swift/Controllers/Storages/CertificateMemoryStorage.cpp @@ -14,14 +14,14 @@ CertificateMemoryStorage::CertificateMemoryStorage() { } bool CertificateMemoryStorage::hasCertificate(Certificate::ref certificate) const { - foreach(Certificate::ref storedCert, certificates) { - if (storedCert->toDER() == certificate->toDER()) { - return true; - } - } - return false; + foreach(Certificate::ref storedCert, certificates) { + if (storedCert->toDER() == certificate->toDER()) { + return true; + } + } + return false; } void CertificateMemoryStorage::addCertificate(Certificate::ref certificate) { - certificates.push_back(certificate); + certificates.push_back(certificate); } diff --git a/Swift/Controllers/Storages/CertificateMemoryStorage.h b/Swift/Controllers/Storages/CertificateMemoryStorage.h index 8bf7986..4870385 100644 --- a/Swift/Controllers/Storages/CertificateMemoryStorage.h +++ b/Swift/Controllers/Storages/CertificateMemoryStorage.h @@ -11,15 +11,15 @@ #include <Swift/Controllers/Storages/CertificateStorage.h> namespace Swift { - class CertificateMemoryStorage : public CertificateStorage { - public: - CertificateMemoryStorage(); + class CertificateMemoryStorage : public CertificateStorage { + public: + CertificateMemoryStorage(); - virtual bool hasCertificate(Certificate::ref certificate) const; - virtual void addCertificate(Certificate::ref certificate); + virtual bool hasCertificate(Certificate::ref certificate) const; + virtual void addCertificate(Certificate::ref certificate); - private: - std::vector<Certificate::ref> certificates; - }; + private: + std::vector<Certificate::ref> certificates; + }; } diff --git a/Swift/Controllers/Storages/CertificateStorage.h b/Swift/Controllers/Storages/CertificateStorage.h index 470b420..87a566b 100644 --- a/Swift/Controllers/Storages/CertificateStorage.h +++ b/Swift/Controllers/Storages/CertificateStorage.h @@ -11,12 +11,12 @@ #include <Swiften/TLS/Certificate.h> namespace Swift { - class CertificateStorage { - public: - virtual ~CertificateStorage(); + class CertificateStorage { + public: + virtual ~CertificateStorage(); - virtual bool hasCertificate(Certificate::ref certificate) const = 0; - virtual void addCertificate(Certificate::ref certificate) = 0; - }; + virtual bool hasCertificate(Certificate::ref certificate) const = 0; + virtual void addCertificate(Certificate::ref certificate) = 0; + }; } diff --git a/Swift/Controllers/Storages/CertificateStorageFactory.h b/Swift/Controllers/Storages/CertificateStorageFactory.h index 44605df..25fa232 100644 --- a/Swift/Controllers/Storages/CertificateStorageFactory.h +++ b/Swift/Controllers/Storages/CertificateStorageFactory.h @@ -7,13 +7,13 @@ #pragma once namespace Swift { - class CertificateStorage; - class JID; + class CertificateStorage; + class JID; - class CertificateStorageFactory { - public: - virtual ~CertificateStorageFactory(); + class CertificateStorageFactory { + public: + virtual ~CertificateStorageFactory(); - virtual CertificateStorage* createCertificateStorage(const JID& profile) const = 0; - }; + virtual CertificateStorage* createCertificateStorage(const JID& profile) const = 0; + }; } diff --git a/Swift/Controllers/Storages/CertificateStorageTrustChecker.h b/Swift/Controllers/Storages/CertificateStorageTrustChecker.h index 7f2f43e..3c708a3 100644 --- a/Swift/Controllers/Storages/CertificateStorageTrustChecker.h +++ b/Swift/Controllers/Storages/CertificateStorageTrustChecker.h @@ -11,25 +11,25 @@ #include <Swift/Controllers/Storages/CertificateStorage.h> namespace Swift { - /** - * A certificate trust checker that trusts certificates in a certificate storage. - */ - class CertificateStorageTrustChecker : public CertificateTrustChecker { - public: - CertificateStorageTrustChecker(CertificateStorage* storage) : storage(storage) { - } + /** + * A certificate trust checker that trusts certificates in a certificate storage. + */ + class CertificateStorageTrustChecker : public CertificateTrustChecker { + public: + CertificateStorageTrustChecker(CertificateStorage* storage) : storage(storage) { + } - virtual bool isCertificateTrusted(const std::vector<Certificate::ref>& certificateChain) { - lastCertificateChain = std::vector<Certificate::ref>(certificateChain.begin(), certificateChain.end()); - return certificateChain.empty() ? false : storage->hasCertificate(certificateChain[0]); - } + virtual bool isCertificateTrusted(const std::vector<Certificate::ref>& certificateChain) { + lastCertificateChain = std::vector<Certificate::ref>(certificateChain.begin(), certificateChain.end()); + return certificateChain.empty() ? false : storage->hasCertificate(certificateChain[0]); + } - const std::vector<Certificate::ref>& getLastCertificateChain() const { - return lastCertificateChain; - } + const std::vector<Certificate::ref>& getLastCertificateChain() const { + return lastCertificateChain; + } - private: - CertificateStorage* storage; - std::vector<Certificate::ref> lastCertificateChain; - }; + private: + CertificateStorage* storage; + std::vector<Certificate::ref> lastCertificateChain; + }; } diff --git a/Swift/Controllers/Storages/FileStorages.cpp b/Swift/Controllers/Storages/FileStorages.cpp index 7e564bf..7ba2b0f 100644 --- a/Swift/Controllers/Storages/FileStorages.cpp +++ b/Swift/Controllers/Storages/FileStorages.cpp @@ -17,47 +17,47 @@ namespace Swift { FileStorages::FileStorages(const boost::filesystem::path& baseDir, const JID& jid, CryptoProvider* crypto) { - boost::filesystem::path profile = stringToPath(jid.toBare()); - vcardStorage = new VCardFileStorage(baseDir / profile / "vcards", crypto); - capsStorage = new CapsFileStorage(baseDir / "caps"); - avatarStorage = new AvatarFileStorage(baseDir / "avatars", baseDir / profile / "avatars", crypto); - rosterStorage = new RosterFileStorage(baseDir / profile / "roster.xml"); + boost::filesystem::path profile = stringToPath(jid.toBare()); + vcardStorage = new VCardFileStorage(baseDir / profile / "vcards", crypto); + capsStorage = new CapsFileStorage(baseDir / "caps"); + avatarStorage = new AvatarFileStorage(baseDir / "avatars", baseDir / profile / "avatars", crypto); + rosterStorage = new RosterFileStorage(baseDir / profile / "roster.xml"); #ifdef SWIFT_EXPERIMENTAL_HISTORY - historyStorage = new SQLiteHistoryStorage(baseDir / "history.db"); + historyStorage = new SQLiteHistoryStorage(baseDir / "history.db"); #else - historyStorage = NULL; + historyStorage = NULL; #endif } FileStorages::~FileStorages() { - delete rosterStorage; - delete avatarStorage; - delete capsStorage; - delete vcardStorage; - delete historyStorage; + delete rosterStorage; + delete avatarStorage; + delete capsStorage; + delete vcardStorage; + delete historyStorage; } VCardStorage* FileStorages::getVCardStorage() const { - return vcardStorage; + return vcardStorage; } CapsStorage* FileStorages::getCapsStorage() const { - return capsStorage; + return capsStorage; } AvatarStorage* FileStorages::getAvatarStorage() const { - return avatarStorage; + return avatarStorage; } RosterStorage* FileStorages::getRosterStorage() const { - return rosterStorage; + return rosterStorage; } HistoryStorage* FileStorages::getHistoryStorage() const { #ifdef SWIFT_EXPERIMENTAL_HISTORY - return historyStorage; + return historyStorage; #else - return NULL; + return NULL; #endif } diff --git a/Swift/Controllers/Storages/FileStorages.h b/Swift/Controllers/Storages/FileStorages.h index 195d0fa..e71d665 100644 --- a/Swift/Controllers/Storages/FileStorages.h +++ b/Swift/Controllers/Storages/FileStorages.h @@ -11,47 +11,47 @@ #include <Swiften/Client/Storages.h> namespace Swift { - class VCardFileStorage; - class AvatarFileStorage; - class CapsFileStorage; - class RosterFileStorage; - class HistoryStorage; - class JID; - class CryptoProvider; + class VCardFileStorage; + class AvatarFileStorage; + class CapsFileStorage; + class RosterFileStorage; + class HistoryStorage; + class JID; + class CryptoProvider; - /** - * A storages implementation that stores all controller data on disk. - */ - class FileStorages : public Storages { - public: - /** - * Creates the storages interface. - * - * All data will be stored relative to a base directory, and - * for some controllers, in a subdirectory for the given profile. - * The data is stored in the following places: - * - Avatars: $basedir/avatars - * - VCards: $basedir/$profile/vcards - * - Entity capabilities: $basedir/caps - * - * \param baseDir the base dir to store data relative to - * \param jid the subdir in which profile-specific data will be stored. - * The bare JID will be used as the subdir name. - */ - FileStorages(const boost::filesystem::path& baseDir, const JID& jid, CryptoProvider*); - ~FileStorages(); + /** + * A storages implementation that stores all controller data on disk. + */ + class FileStorages : public Storages { + public: + /** + * Creates the storages interface. + * + * All data will be stored relative to a base directory, and + * for some controllers, in a subdirectory for the given profile. + * The data is stored in the following places: + * - Avatars: $basedir/avatars + * - VCards: $basedir/$profile/vcards + * - Entity capabilities: $basedir/caps + * + * \param baseDir the base dir to store data relative to + * \param jid the subdir in which profile-specific data will be stored. + * The bare JID will be used as the subdir name. + */ + FileStorages(const boost::filesystem::path& baseDir, const JID& jid, CryptoProvider*); + ~FileStorages(); - virtual VCardStorage* getVCardStorage() const; - virtual AvatarStorage* getAvatarStorage() const; - virtual CapsStorage* getCapsStorage() const; - virtual RosterStorage* getRosterStorage() const; - virtual HistoryStorage* getHistoryStorage() const; + virtual VCardStorage* getVCardStorage() const; + virtual AvatarStorage* getAvatarStorage() const; + virtual CapsStorage* getCapsStorage() const; + virtual RosterStorage* getRosterStorage() const; + virtual HistoryStorage* getHistoryStorage() const; - private: - VCardFileStorage* vcardStorage; - AvatarFileStorage* avatarStorage; - CapsFileStorage* capsStorage; - RosterFileStorage* rosterStorage; - HistoryStorage* historyStorage; - }; + private: + VCardFileStorage* vcardStorage; + AvatarFileStorage* avatarStorage; + CapsFileStorage* capsStorage; + RosterFileStorage* rosterStorage; + HistoryStorage* historyStorage; + }; } diff --git a/Swift/Controllers/Storages/FileStoragesFactory.h b/Swift/Controllers/Storages/FileStoragesFactory.h index 66b3841..ec0106e 100644 --- a/Swift/Controllers/Storages/FileStoragesFactory.h +++ b/Swift/Controllers/Storages/FileStoragesFactory.h @@ -10,18 +10,18 @@ #include <Swift/Controllers/Storages/StoragesFactory.h> namespace Swift { - class CryptoProvider; + class CryptoProvider; - class FileStoragesFactory : public StoragesFactory { - public: - FileStoragesFactory(const boost::filesystem::path& basePath, CryptoProvider* crypto) : basePath(basePath), crypto(crypto) {} + class FileStoragesFactory : public StoragesFactory { + public: + FileStoragesFactory(const boost::filesystem::path& basePath, CryptoProvider* crypto) : basePath(basePath), crypto(crypto) {} - virtual Storages* createStorages(const JID& profile) const { - return new FileStorages(basePath, profile, crypto); - } + virtual Storages* createStorages(const JID& profile) const { + return new FileStorages(basePath, profile, crypto); + } - private: - boost::filesystem::path basePath; - CryptoProvider* crypto; - }; + private: + boost::filesystem::path basePath; + CryptoProvider* crypto; + }; } diff --git a/Swift/Controllers/Storages/MemoryStoragesFactory.h b/Swift/Controllers/Storages/MemoryStoragesFactory.h index 6f6523c..28e9138 100644 --- a/Swift/Controllers/Storages/MemoryStoragesFactory.h +++ b/Swift/Controllers/Storages/MemoryStoragesFactory.h @@ -11,17 +11,17 @@ #include <Swift/Controllers/Storages/StoragesFactory.h> namespace Swift { - class JID; - class CryptoProvider; + class JID; + class CryptoProvider; - class MemoryStoragesFactory : public StoragesFactory { - public: - MemoryStoragesFactory(CryptoProvider* cryptoProvider) : cryptoProvider_(cryptoProvider) {} + class MemoryStoragesFactory : public StoragesFactory { + public: + MemoryStoragesFactory(CryptoProvider* cryptoProvider) : cryptoProvider_(cryptoProvider) {} - virtual Storages* createStorages(const JID& /*profile*/) const { - return new MemoryStorages(cryptoProvider_); - } - private: - CryptoProvider* cryptoProvider_; - }; + virtual Storages* createStorages(const JID& /*profile*/) const { + return new MemoryStorages(cryptoProvider_); + } + private: + CryptoProvider* cryptoProvider_; + }; } diff --git a/Swift/Controllers/Storages/RosterFileStorage.cpp b/Swift/Controllers/Storages/RosterFileStorage.cpp index c55bcf1..6cc5c61 100644 --- a/Swift/Controllers/Storages/RosterFileStorage.cpp +++ b/Swift/Controllers/Storages/RosterFileStorage.cpp @@ -18,9 +18,9 @@ RosterFileStorage::RosterFileStorage(const boost::filesystem::path& path) : path } boost::shared_ptr<RosterPayload> RosterFileStorage::getRoster() const { - return RosterPersister().loadPayloadGeneric(path); + return RosterPersister().loadPayloadGeneric(path); } void RosterFileStorage::setRoster(boost::shared_ptr<RosterPayload> roster) { - RosterPersister().savePayload(roster, path); + RosterPersister().savePayload(roster, path); } diff --git a/Swift/Controllers/Storages/RosterFileStorage.h b/Swift/Controllers/Storages/RosterFileStorage.h index d100793..dd1a6c9 100644 --- a/Swift/Controllers/Storages/RosterFileStorage.h +++ b/Swift/Controllers/Storages/RosterFileStorage.h @@ -11,14 +11,14 @@ #include <Swiften/Roster/RosterStorage.h> namespace Swift { - class RosterFileStorage : public RosterStorage { - public: - RosterFileStorage(const boost::filesystem::path& path); + class RosterFileStorage : public RosterStorage { + public: + RosterFileStorage(const boost::filesystem::path& path); - virtual boost::shared_ptr<RosterPayload> getRoster() const; - virtual void setRoster(boost::shared_ptr<RosterPayload>); + virtual boost::shared_ptr<RosterPayload> getRoster() const; + virtual void setRoster(boost::shared_ptr<RosterPayload>); - private: - boost::filesystem::path path; - }; + private: + boost::filesystem::path path; + }; } diff --git a/Swift/Controllers/Storages/StoragesFactory.h b/Swift/Controllers/Storages/StoragesFactory.h index 4eb991b..771230b 100644 --- a/Swift/Controllers/Storages/StoragesFactory.h +++ b/Swift/Controllers/Storages/StoragesFactory.h @@ -7,13 +7,13 @@ #pragma once namespace Swift { - class Storages; - class JID; + class Storages; + class JID; - class StoragesFactory { - public: - virtual ~StoragesFactory() {} + class StoragesFactory { + public: + virtual ~StoragesFactory() {} - virtual Storages* createStorages(const JID& profile) const = 0; - }; + virtual Storages* createStorages(const JID& profile) const = 0; + }; } diff --git a/Swift/Controllers/Storages/VCardFileStorage.cpp b/Swift/Controllers/Storages/VCardFileStorage.cpp index a93e286..720165a 100644 --- a/Swift/Controllers/Storages/VCardFileStorage.cpp +++ b/Swift/Controllers/Storages/VCardFileStorage.cpp @@ -28,100 +28,100 @@ using namespace Swift; typedef GenericPayloadPersister<VCard, VCardParser, VCardSerializer> VCardPersister; VCardFileStorage::VCardFileStorage(boost::filesystem::path dir, CryptoProvider* crypto) : VCardStorage(crypto), vcardsPath(dir), crypto(crypto) { - cacheFile = vcardsPath / "phashes"; - if (boost::filesystem::exists(cacheFile)) { - try { - boost::filesystem::ifstream file(cacheFile); - std::string line; - if (file.is_open()) { - while (!file.eof()) { - getline(file, line); - std::pair<std::string, std::string> r = String::getSplittedAtFirst(line, ' '); - JID jid(r.second); - if (jid.isValid()) { - photoHashes.insert(std::make_pair(jid, r.first)); - } - else if (!r.first.empty() || !r.second.empty()) { - std::cerr << "Invalid entry in phashes file" << std::endl; - } - } - } - } - catch (...) { - std::cerr << "Error reading phashes file" << std::endl; - } - } + cacheFile = vcardsPath / "phashes"; + if (boost::filesystem::exists(cacheFile)) { + try { + boost::filesystem::ifstream file(cacheFile); + std::string line; + if (file.is_open()) { + while (!file.eof()) { + getline(file, line); + std::pair<std::string, std::string> r = String::getSplittedAtFirst(line, ' '); + JID jid(r.second); + if (jid.isValid()) { + photoHashes.insert(std::make_pair(jid, r.first)); + } + else if (!r.first.empty() || !r.second.empty()) { + std::cerr << "Invalid entry in phashes file" << std::endl; + } + } + } + } + catch (...) { + std::cerr << "Error reading phashes file" << std::endl; + } + } } boost::shared_ptr<VCard> VCardFileStorage::getVCard(const JID& jid) const { - boost::shared_ptr<VCard> result = VCardPersister().loadPayloadGeneric(getVCardPath(jid)); - getAndUpdatePhotoHash(jid, result); - return result; + boost::shared_ptr<VCard> result = VCardPersister().loadPayloadGeneric(getVCardPath(jid)); + getAndUpdatePhotoHash(jid, result); + return result; } boost::posix_time::ptime VCardFileStorage::getVCardWriteTime(const JID& jid) const { - if (vcardWriteTimes.find(jid) == vcardWriteTimes.end()) { - return boost::posix_time::ptime(); - } - else { - return vcardWriteTimes.at(jid); - } + if (vcardWriteTimes.find(jid) == vcardWriteTimes.end()) { + return boost::posix_time::ptime(); + } + else { + return vcardWriteTimes.at(jid); + } } void VCardFileStorage::setVCard(const JID& jid, VCard::ref v) { - vcardWriteTimes[jid] = boost::posix_time::second_clock::universal_time(); - VCardPersister().savePayload(v, getVCardPath(jid)); - getAndUpdatePhotoHash(jid, v); + vcardWriteTimes[jid] = boost::posix_time::second_clock::universal_time(); + VCardPersister().savePayload(v, getVCardPath(jid)); + getAndUpdatePhotoHash(jid, v); } boost::filesystem::path VCardFileStorage::getVCardPath(const JID& jid) const { - try { - std::string file(jid.toString()); - String::replaceAll(file, '/', "%2f"); - return boost::filesystem::path(vcardsPath / stringToPath(file + ".xml")); - } - catch (const boost::filesystem::filesystem_error& e) { - std::cerr << "ERROR: " << e.what() << std::endl; - return boost::filesystem::path(); - } + try { + std::string file(jid.toString()); + String::replaceAll(file, '/', "%2f"); + return boost::filesystem::path(vcardsPath / stringToPath(file + ".xml")); + } + catch (const boost::filesystem::filesystem_error& e) { + std::cerr << "ERROR: " << e.what() << std::endl; + return boost::filesystem::path(); + } } std::string VCardFileStorage::getPhotoHash(const JID& jid) const { - PhotoHashMap::const_iterator i = photoHashes.find(jid); - if (i != photoHashes.end()) { - return i->second; - } - else { - VCard::ref vCard = getVCard(jid); - return getAndUpdatePhotoHash(jid, vCard); - } + PhotoHashMap::const_iterator i = photoHashes.find(jid); + if (i != photoHashes.end()) { + return i->second; + } + else { + VCard::ref vCard = getVCard(jid); + return getAndUpdatePhotoHash(jid, vCard); + } } std::string VCardFileStorage::getAndUpdatePhotoHash(const JID& jid, VCard::ref vCard) const { - std::string hash; - if (vCard && !vCard->getPhoto().empty()) { - hash = Hexify::hexify(crypto->getSHA1Hash(vCard->getPhoto())); - } - std::pair<PhotoHashMap::iterator, bool> r = photoHashes.insert(std::make_pair(jid, hash)); - if (r.second) { - savePhotoHashes(); - } - else if (r.first->second != hash) { - r.first->second = hash; - savePhotoHashes(); - } - return hash; + std::string hash; + if (vCard && !vCard->getPhoto().empty()) { + hash = Hexify::hexify(crypto->getSHA1Hash(vCard->getPhoto())); + } + std::pair<PhotoHashMap::iterator, bool> r = photoHashes.insert(std::make_pair(jid, hash)); + if (r.second) { + savePhotoHashes(); + } + else if (r.first->second != hash) { + r.first->second = hash; + savePhotoHashes(); + } + return hash; } void VCardFileStorage::savePhotoHashes() const { - try { - boost::filesystem::ofstream file(cacheFile); - for (PhotoHashMap::const_iterator i = photoHashes.begin(); i != photoHashes.end(); ++i) { - file << i->second << " " << i->first.toString() << std::endl; - } - file.close(); - } - catch (...) { - std::cerr << "Error writing vcards file" << std::endl; - } + try { + boost::filesystem::ofstream file(cacheFile); + for (PhotoHashMap::const_iterator i = photoHashes.begin(); i != photoHashes.end(); ++i) { + file << i->second << " " << i->first.toString() << std::endl; + } + file.close(); + } + catch (...) { + std::cerr << "Error writing vcards file" << std::endl; + } } diff --git a/Swift/Controllers/Storages/VCardFileStorage.h b/Swift/Controllers/Storages/VCardFileStorage.h index 56e06f2..971a3f9 100644 --- a/Swift/Controllers/Storages/VCardFileStorage.h +++ b/Swift/Controllers/Storages/VCardFileStorage.h @@ -15,30 +15,30 @@ #include <Swiften/VCards/VCardStorage.h> namespace Swift { - class CryptoProvider; + class CryptoProvider; - class VCardFileStorage : public VCardStorage { - public: - VCardFileStorage(boost::filesystem::path dir, CryptoProvider* crypto); + class VCardFileStorage : public VCardStorage { + public: + VCardFileStorage(boost::filesystem::path dir, CryptoProvider* crypto); - virtual VCard::ref getVCard(const JID& jid) const; - virtual boost::posix_time::ptime getVCardWriteTime(const JID& jid) const; - virtual void setVCard(const JID& jid, VCard::ref v); + virtual VCard::ref getVCard(const JID& jid) const; + virtual boost::posix_time::ptime getVCardWriteTime(const JID& jid) const; + virtual void setVCard(const JID& jid, VCard::ref v); - virtual std::string getPhotoHash(const JID&) const; + virtual std::string getPhotoHash(const JID&) const; - private: - boost::filesystem::path getVCardPath(const JID&) const; + private: + boost::filesystem::path getVCardPath(const JID&) const; - std::string getAndUpdatePhotoHash(const JID& jid, VCard::ref vcard) const; - void savePhotoHashes() const; + std::string getAndUpdatePhotoHash(const JID& jid, VCard::ref vcard) const; + void savePhotoHashes() const; - private: - boost::filesystem::path vcardsPath; - CryptoProvider* crypto; - boost::filesystem::path cacheFile; - typedef std::map<JID, std::string> PhotoHashMap; - mutable PhotoHashMap photoHashes; - std::map<JID, boost::posix_time::ptime> vcardWriteTimes; - }; + private: + boost::filesystem::path vcardsPath; + CryptoProvider* crypto; + boost::filesystem::path cacheFile; + typedef std::map<JID, std::string> PhotoHashMap; + mutable PhotoHashMap photoHashes; + std::map<JID, boost::posix_time::ptime> vcardWriteTimes; + }; } diff --git a/Swift/Controllers/SystemTray.h b/Swift/Controllers/SystemTray.h index fd8fe01..094857f 100644 --- a/Swift/Controllers/SystemTray.h +++ b/Swift/Controllers/SystemTray.h @@ -9,11 +9,11 @@ #include <Swiften/Elements/StatusShow.h> namespace Swift { - class SystemTray { - public: - virtual ~SystemTray(){} - virtual void setUnreadMessages(bool some) = 0; - virtual void setStatusType(StatusShow::Type type) = 0; - virtual void setConnecting() = 0; - }; + class SystemTray { + public: + virtual ~SystemTray(){} + virtual void setUnreadMessages(bool some) = 0; + virtual void setStatusType(StatusShow::Type type) = 0; + virtual void setConnecting() = 0; + }; } diff --git a/Swift/Controllers/SystemTrayController.cpp b/Swift/Controllers/SystemTrayController.cpp index e4029e0..72d3403 100644 --- a/Swift/Controllers/SystemTrayController.cpp +++ b/Swift/Controllers/SystemTrayController.cpp @@ -14,29 +14,29 @@ namespace Swift { SystemTrayController::SystemTrayController(EventController* eventController, SystemTray* systemTray) { - systemTray_ = systemTray; - eventController_ = eventController; - eventController_->onEventQueueLengthChange.connect(boost::bind(&SystemTrayController::handleEventQueueLengthChange, this, _1)); + systemTray_ = systemTray; + eventController_ = eventController; + eventController_->onEventQueueLengthChange.connect(boost::bind(&SystemTrayController::handleEventQueueLengthChange, this, _1)); } void SystemTrayController::handleEventQueueLengthChange(int /*length*/) { - EventList events = eventController_->getEvents(); - bool found = false; - for (EventList::iterator it = events.begin(); it != events.end(); ++it) { - if (boost::dynamic_pointer_cast<MessageEvent>(*it)) { - found = true; - break; - } - } - systemTray_->setUnreadMessages(found); + EventList events = eventController_->getEvents(); + bool found = false; + for (EventList::iterator it = events.begin(); it != events.end(); ++it) { + if (boost::dynamic_pointer_cast<MessageEvent>(*it)) { + found = true; + break; + } + } + systemTray_->setUnreadMessages(found); } void SystemTrayController::setMyStatusType(StatusShow::Type type) { - systemTray_->setStatusType(type); + systemTray_->setStatusType(type); } void SystemTrayController::setConnecting() { - systemTray_->setConnecting(); + systemTray_->setConnecting(); } } diff --git a/Swift/Controllers/SystemTrayController.h b/Swift/Controllers/SystemTrayController.h index f19b127..850ac71 100644 --- a/Swift/Controllers/SystemTrayController.h +++ b/Swift/Controllers/SystemTrayController.h @@ -9,19 +9,19 @@ #include <Swiften/Elements/StatusShow.h> namespace Swift { - class EventController; - class SystemTray; + class EventController; + class SystemTray; - class SystemTrayController { - public: - SystemTrayController(EventController* eventController, SystemTray* systemTray); - void setMyStatusType(StatusShow::Type type); - void setConnecting(); - private: - void handleEventQueueLengthChange(int length); + class SystemTrayController { + public: + SystemTrayController(EventController* eventController, SystemTray* systemTray); + void setMyStatusType(StatusShow::Type type); + void setConnecting(); + private: + void handleEventQueueLengthChange(int length); - private: - EventController* eventController_; - SystemTray* systemTray_; - }; + private: + EventController* eventController_; + SystemTray* systemTray_; + }; } diff --git a/Swift/Controllers/Translator.cpp b/Swift/Controllers/Translator.cpp index 13230ab..b62fd28 100644 --- a/Swift/Controllers/Translator.cpp +++ b/Swift/Controllers/Translator.cpp @@ -11,9 +11,9 @@ namespace Swift { static struct DefaultTranslator : public Translator { - virtual std::string translate(const std::string& text, const std::string&) { - return text; - } + virtual std::string translate(const std::string& text, const std::string&) { + return text; + } } defaultTranslator; Translator* Translator::translator = &defaultTranslator; @@ -22,7 +22,7 @@ Translator::~Translator() { } void Translator::setInstance(Translator* t) { - translator = t; + translator = t; } } diff --git a/Swift/Controllers/Translator.h b/Swift/Controllers/Translator.h index 801e8b5..5c52e9f 100644 --- a/Swift/Controllers/Translator.h +++ b/Swift/Controllers/Translator.h @@ -9,19 +9,19 @@ #include <string> namespace Swift { - class Translator { - public: - virtual ~Translator(); + class Translator { + public: + virtual ~Translator(); - virtual std::string translate(const std::string& text, const std::string& context) = 0; + virtual std::string translate(const std::string& text, const std::string& context) = 0; - static void setInstance(Translator* translator); + static void setInstance(Translator* translator); - static Translator* getInstance() { - return translator; - } + static Translator* getInstance() { + return translator; + } - private: - static Translator* translator; - }; + private: + static Translator* translator; + }; } diff --git a/Swift/Controllers/UIEvents/AcceptWhiteboardSessionUIEvent.h b/Swift/Controllers/UIEvents/AcceptWhiteboardSessionUIEvent.h index 93cad03..b46774c 100644 --- a/Swift/Controllers/UIEvents/AcceptWhiteboardSessionUIEvent.h +++ b/Swift/Controllers/UIEvents/AcceptWhiteboardSessionUIEvent.h @@ -13,12 +13,12 @@ #include <Swift/Controllers/UIEvents/UIEvent.h> namespace Swift { - class AcceptWhiteboardSessionUIEvent : public UIEvent { - typedef boost::shared_ptr<AcceptWhiteboardSessionUIEvent> ref; - public: - AcceptWhiteboardSessionUIEvent(const JID& jid) : jid_(jid) {} - const JID& getContact() const {return jid_;} - private: - JID jid_; - }; + class AcceptWhiteboardSessionUIEvent : public UIEvent { + typedef boost::shared_ptr<AcceptWhiteboardSessionUIEvent> ref; + public: + AcceptWhiteboardSessionUIEvent(const JID& jid) : jid_(jid) {} + const JID& getContact() const {return jid_;} + private: + JID jid_; + }; } diff --git a/Swift/Controllers/UIEvents/AddContactUIEvent.h b/Swift/Controllers/UIEvents/AddContactUIEvent.h index 127dba2..d2176ac 100644 --- a/Swift/Controllers/UIEvents/AddContactUIEvent.h +++ b/Swift/Controllers/UIEvents/AddContactUIEvent.h @@ -12,25 +12,25 @@ #include <Swift/Controllers/UIEvents/UIEvent.h> 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) {} - - const std::string& getName() const { - return name_; - } - - const JID& getJID() const { - return jid_; - } - - const std::set<std::string>& getGroups() const { - return groups_; - } - - private: - JID jid_; - std::string name_; - std::set<std::string> groups_; - }; + 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) {} + + const std::string& getName() const { + return name_; + } + + const JID& getJID() const { + return jid_; + } + + const std::set<std::string>& getGroups() const { + return groups_; + } + + private: + JID jid_; + std::string name_; + std::set<std::string> groups_; + }; } diff --git a/Swift/Controllers/UIEvents/AddMUCBookmarkUIEvent.h b/Swift/Controllers/UIEvents/AddMUCBookmarkUIEvent.h index d19a402..526fc0d 100644 --- a/Swift/Controllers/UIEvents/AddMUCBookmarkUIEvent.h +++ b/Swift/Controllers/UIEvents/AddMUCBookmarkUIEvent.h @@ -13,12 +13,12 @@ #include <Swift/Controllers/UIEvents/UIEvent.h> namespace Swift { - class AddMUCBookmarkUIEvent : public UIEvent { - public: - AddMUCBookmarkUIEvent(const MUCBookmark& bookmark) : bookmark(bookmark) {} - const MUCBookmark& getBookmark() { return bookmark; } + class AddMUCBookmarkUIEvent : public UIEvent { + public: + AddMUCBookmarkUIEvent(const MUCBookmark& bookmark) : bookmark(bookmark) {} + const MUCBookmark& getBookmark() { return bookmark; } - private: - MUCBookmark bookmark; - }; + private: + MUCBookmark bookmark; + }; } diff --git a/Swift/Controllers/UIEvents/CancelWhiteboardSessionUIEvent.h b/Swift/Controllers/UIEvents/CancelWhiteboardSessionUIEvent.h index f5c3b0e..62751b6 100644 --- a/Swift/Controllers/UIEvents/CancelWhiteboardSessionUIEvent.h +++ b/Swift/Controllers/UIEvents/CancelWhiteboardSessionUIEvent.h @@ -13,12 +13,12 @@ #include <Swift/Controllers/UIEvents/UIEvent.h> namespace Swift { - class CancelWhiteboardSessionUIEvent : public UIEvent { - typedef boost::shared_ptr<CancelWhiteboardSessionUIEvent> ref; - public: - CancelWhiteboardSessionUIEvent(const JID& jid) : jid_(jid) {} - const JID& getContact() const {return jid_;} - private: - JID jid_; - }; + class CancelWhiteboardSessionUIEvent : public UIEvent { + typedef boost::shared_ptr<CancelWhiteboardSessionUIEvent> ref; + public: + CancelWhiteboardSessionUIEvent(const JID& jid) : jid_(jid) {} + const JID& getContact() const {return jid_;} + private: + JID jid_; + }; } diff --git a/Swift/Controllers/UIEvents/CreateImpromptuMUCUIEvent.h b/Swift/Controllers/UIEvents/CreateImpromptuMUCUIEvent.h index 57e181d..b566be6 100644 --- a/Swift/Controllers/UIEvents/CreateImpromptuMUCUIEvent.h +++ b/Swift/Controllers/UIEvents/CreateImpromptuMUCUIEvent.h @@ -11,16 +11,16 @@ namespace Swift { class CreateImpromptuMUCUIEvent : public UIEvent { - public: - CreateImpromptuMUCUIEvent(const std::vector<JID>& jids, const JID& roomJID = JID(), const std::string reason = "") : jids_(jids), roomJID_(roomJID), reason_(reason) { } + public: + CreateImpromptuMUCUIEvent(const std::vector<JID>& jids, const JID& roomJID = JID(), const std::string reason = "") : jids_(jids), roomJID_(roomJID), reason_(reason) { } - std::vector<JID> getJIDs() const { return jids_; } - JID getRoomJID() const { return roomJID_; } - std::string getReason() const { return reason_; } - private: - std::vector<JID> jids_; - JID roomJID_; - std::string reason_; + std::vector<JID> getJIDs() const { return jids_; } + JID getRoomJID() const { return roomJID_; } + std::string getReason() const { return reason_; } + private: + std::vector<JID> jids_; + JID roomJID_; + std::string reason_; }; } diff --git a/Swift/Controllers/UIEvents/EditMUCBookmarkUIEvent.h b/Swift/Controllers/UIEvents/EditMUCBookmarkUIEvent.h index 602f45e..b3d3118 100644 --- a/Swift/Controllers/UIEvents/EditMUCBookmarkUIEvent.h +++ b/Swift/Controllers/UIEvents/EditMUCBookmarkUIEvent.h @@ -13,15 +13,15 @@ #include <Swift/Controllers/UIEvents/UIEvent.h> namespace Swift { - class EditMUCBookmarkUIEvent : public UIEvent { - public: - EditMUCBookmarkUIEvent(const MUCBookmark& oldBookmark, const MUCBookmark& newBookmark) : oldBookmark(oldBookmark) , newBookmark(newBookmark) {} + class EditMUCBookmarkUIEvent : public UIEvent { + public: + 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; - MUCBookmark newBookmark; - }; + private: + MUCBookmark oldBookmark; + MUCBookmark newBookmark; + }; } diff --git a/Swift/Controllers/UIEvents/InviteToMUCUIEvent.h b/Swift/Controllers/UIEvents/InviteToMUCUIEvent.h index 70c46b0..e1416de 100644 --- a/Swift/Controllers/UIEvents/InviteToMUCUIEvent.h +++ b/Swift/Controllers/UIEvents/InviteToMUCUIEvent.h @@ -21,28 +21,28 @@ #include <Swift/Controllers/UIEvents/UIEvent.h> namespace Swift { - class InviteToMUCUIEvent : public UIEvent { - public: - typedef boost::shared_ptr<InviteToMUCUIEvent> ref; - - InviteToMUCUIEvent(const JID& room, const std::vector<JID>& JIDsToInvite, const std::string& reason) : room_(room), invite_(JIDsToInvite), reason_(reason) { - } - - const JID& getRoom() const { - return room_; - } - - const std::vector<JID> getInvites() const { - return invite_; - } - - const std::string getReason() const { - return reason_; - } - - private: - JID room_; - std::vector<JID> invite_; - std::string reason_; - }; + class InviteToMUCUIEvent : public UIEvent { + public: + typedef boost::shared_ptr<InviteToMUCUIEvent> ref; + + InviteToMUCUIEvent(const JID& room, const std::vector<JID>& JIDsToInvite, const std::string& reason) : room_(room), invite_(JIDsToInvite), reason_(reason) { + } + + const JID& getRoom() const { + return room_; + } + + const std::vector<JID> getInvites() const { + return invite_; + } + + const std::string getReason() const { + return reason_; + } + + private: + JID room_; + std::vector<JID> invite_; + std::string reason_; + }; } diff --git a/Swift/Controllers/UIEvents/JoinMUCUIEvent.h b/Swift/Controllers/UIEvents/JoinMUCUIEvent.h index 8d74858..076b5b6 100644 --- a/Swift/Controllers/UIEvents/JoinMUCUIEvent.h +++ b/Swift/Controllers/UIEvents/JoinMUCUIEvent.h @@ -16,25 +16,25 @@ #include <Swift/Controllers/UIEvents/UIEvent.h> 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, bool isImpromptu = false, bool isContinuation = false) : jid_(jid), nick_(nick), joinAutomatically_(joinAutomaticallyInFuture), createAsReservedRoomIfNew_(createAsReservedRoomIfNew), password_(password), isImpromptuMUC_(isImpromptu), isContinuation_(isContinuation) {} - const boost::optional<std::string>& getNick() const {return nick_;} - const JID& getJID() const {return jid_;} - bool getShouldJoinAutomatically() const {return joinAutomatically_;} - bool getCreateAsReservedRoomIfNew() const {return createAsReservedRoomIfNew_;} - const boost::optional<std::string>& getPassword() const {return password_;} - bool isImpromptu() const {return isImpromptuMUC_;} - bool isContinuation() const {return isContinuation_;} + 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, bool isImpromptu = false, bool isContinuation = false) : jid_(jid), nick_(nick), joinAutomatically_(joinAutomaticallyInFuture), createAsReservedRoomIfNew_(createAsReservedRoomIfNew), password_(password), isImpromptuMUC_(isImpromptu), isContinuation_(isContinuation) {} + const boost::optional<std::string>& getNick() const {return nick_;} + const JID& getJID() const {return jid_;} + bool getShouldJoinAutomatically() const {return joinAutomatically_;} + bool getCreateAsReservedRoomIfNew() const {return createAsReservedRoomIfNew_;} + const boost::optional<std::string>& getPassword() const {return password_;} + bool isImpromptu() const {return isImpromptuMUC_;} + bool isContinuation() const {return isContinuation_;} - private: - JID jid_; - boost::optional<std::string> nick_; - bool joinAutomatically_; - bool createAsReservedRoomIfNew_; - boost::optional<std::string> password_; - bool isImpromptuMUC_; - bool isContinuation_; - }; + private: + JID jid_; + boost::optional<std::string> nick_; + bool joinAutomatically_; + bool createAsReservedRoomIfNew_; + boost::optional<std::string> password_; + bool isImpromptuMUC_; + bool isContinuation_; + }; } diff --git a/Swift/Controllers/UIEvents/RemoveMUCBookmarkUIEvent.h b/Swift/Controllers/UIEvents/RemoveMUCBookmarkUIEvent.h index f6655e4..2803197 100644 --- a/Swift/Controllers/UIEvents/RemoveMUCBookmarkUIEvent.h +++ b/Swift/Controllers/UIEvents/RemoveMUCBookmarkUIEvent.h @@ -13,12 +13,12 @@ #include <Swift/Controllers/UIEvents/UIEvent.h> namespace Swift { - class RemoveMUCBookmarkUIEvent : public UIEvent { - public: - RemoveMUCBookmarkUIEvent(const MUCBookmark& bookmark) : bookmark(bookmark) {} - const MUCBookmark& getBookmark() { return bookmark; } + class RemoveMUCBookmarkUIEvent : public UIEvent { + public: + RemoveMUCBookmarkUIEvent(const MUCBookmark& bookmark) : bookmark(bookmark) {} + const MUCBookmark& getBookmark() { return bookmark; } - private: - MUCBookmark bookmark; - }; + private: + MUCBookmark bookmark; + }; } diff --git a/Swift/Controllers/UIEvents/RemoveRosterItemUIEvent.h b/Swift/Controllers/UIEvents/RemoveRosterItemUIEvent.h index 95b59b1..0f4a89d 100644 --- a/Swift/Controllers/UIEvents/RemoveRosterItemUIEvent.h +++ b/Swift/Controllers/UIEvents/RemoveRosterItemUIEvent.h @@ -13,12 +13,12 @@ namespace Swift { class RemoveRosterItemUIEvent : public UIEvent { - public: - RemoveRosterItemUIEvent(const JID& jid) : jid_(jid) {} - virtual ~RemoveRosterItemUIEvent() {} - JID getJID() {return jid_;} - private: - JID jid_; + public: + RemoveRosterItemUIEvent(const JID& jid) : jid_(jid) {} + virtual ~RemoveRosterItemUIEvent() {} + JID getJID() {return jid_;} + private: + JID jid_; }; diff --git a/Swift/Controllers/UIEvents/RenameGroupUIEvent.h b/Swift/Controllers/UIEvents/RenameGroupUIEvent.h index cea1afc..ea19efe 100644 --- a/Swift/Controllers/UIEvents/RenameGroupUIEvent.h +++ b/Swift/Controllers/UIEvents/RenameGroupUIEvent.h @@ -11,21 +11,21 @@ #include <Swift/Controllers/UIEvents/UIEvent.h> namespace Swift { - class RenameGroupUIEvent : public UIEvent { - public: - RenameGroupUIEvent(const std::string& group, const std::string& newName) : group(group), newName(newName) { - } + class RenameGroupUIEvent : public UIEvent { + public: + RenameGroupUIEvent(const std::string& group, const std::string& newName) : group(group), newName(newName) { + } - const std::string& getGroup() const { - return group; - } + const std::string& getGroup() const { + return group; + } - const std::string& getNewName() const { - return newName; - } + const std::string& getNewName() const { + return newName; + } - private: - std::string group; - std::string newName; - }; + private: + std::string group; + std::string newName; + }; } diff --git a/Swift/Controllers/UIEvents/RenameRosterItemUIEvent.h b/Swift/Controllers/UIEvents/RenameRosterItemUIEvent.h index fbf3814..7d370e2 100644 --- a/Swift/Controllers/UIEvents/RenameRosterItemUIEvent.h +++ b/Swift/Controllers/UIEvents/RenameRosterItemUIEvent.h @@ -13,15 +13,15 @@ #include <Swift/Controllers/UIEvents/UIEvent.h> namespace Swift { - class RenameRosterItemUIEvent : public UIEvent { - public: - RenameRosterItemUIEvent(const JID& jid, const std::string& newName) : jid_(jid), newName_(newName) {} + class RenameRosterItemUIEvent : public UIEvent { + public: + RenameRosterItemUIEvent(const JID& jid, const std::string& newName) : jid_(jid), newName_(newName) {} - const JID& getJID() const {return jid_;} - const std::string& getNewName() const {return newName_;} + const JID& getJID() const {return jid_;} + const std::string& getNewName() const {return newName_;} - private: - JID jid_; - std::string newName_; - }; + private: + JID jid_; + std::string newName_; + }; } diff --git a/Swift/Controllers/UIEvents/RequestAdHocUIEvent.h b/Swift/Controllers/UIEvents/RequestAdHocUIEvent.h index afc0a34..f6fa1c7 100644 --- a/Swift/Controllers/UIEvents/RequestAdHocUIEvent.h +++ b/Swift/Controllers/UIEvents/RequestAdHocUIEvent.h @@ -10,11 +10,11 @@ #include <Swift/Controllers/UIInterfaces/MainWindow.h> namespace Swift { - class RequestAdHocUIEvent : public UIEvent { - public: - RequestAdHocUIEvent(const DiscoItems::Item& command) : command_(command) {} - const DiscoItems::Item& getCommand() const {return command_;} - private: - DiscoItems::Item command_; - }; + class RequestAdHocUIEvent : public UIEvent { + public: + RequestAdHocUIEvent(const DiscoItems::Item& command) : command_(command) {} + const DiscoItems::Item& getCommand() const {return command_;} + private: + DiscoItems::Item command_; + }; } diff --git a/Swift/Controllers/UIEvents/RequestAdHocWithJIDUIEvent.h b/Swift/Controllers/UIEvents/RequestAdHocWithJIDUIEvent.h index 5c7e97a..8d8bd19 100644 --- a/Swift/Controllers/UIEvents/RequestAdHocWithJIDUIEvent.h +++ b/Swift/Controllers/UIEvents/RequestAdHocWithJIDUIEvent.h @@ -9,13 +9,13 @@ #include <Swift/Controllers/UIEvents/UIEvent.h> namespace Swift { - class RequestAdHocWithJIDUIEvent : public UIEvent { - public: - RequestAdHocWithJIDUIEvent(const JID& jid, const std::string& node) : jid_(jid), node_(node) {} - JID getJID() const { return jid_; } - std::string getNode() const { return node_; } - private: - JID jid_; - std::string node_; - }; + class RequestAdHocWithJIDUIEvent : public UIEvent { + public: + RequestAdHocWithJIDUIEvent(const JID& jid, const std::string& node) : jid_(jid), node_(node) {} + JID getJID() const { return jid_; } + std::string getNode() const { return node_; } + private: + JID jid_; + std::string node_; + }; } diff --git a/Swift/Controllers/UIEvents/RequestAddUserDialogUIEvent.h b/Swift/Controllers/UIEvents/RequestAddUserDialogUIEvent.h index 73ad20e..474d155 100644 --- a/Swift/Controllers/UIEvents/RequestAddUserDialogUIEvent.h +++ b/Swift/Controllers/UIEvents/RequestAddUserDialogUIEvent.h @@ -13,18 +13,18 @@ #include <Swift/Controllers/UIEvents/UIEvent.h> namespace Swift { - class RequestAddUserDialogUIEvent : public UIEvent { + class RequestAddUserDialogUIEvent : public UIEvent { - public: - RequestAddUserDialogUIEvent(const JID& predefinedJID, const std::string& predefinedName) : preJID_(predefinedJID), preName_(predefinedName) {} - RequestAddUserDialogUIEvent() : preJID_(), preName_() {} + public: + 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_; - std::string preName_; + private: + JID preJID_; + std::string preName_; - }; + }; } diff --git a/Swift/Controllers/UIEvents/RequestChangeBlockStateUIEvent.h b/Swift/Controllers/UIEvents/RequestChangeBlockStateUIEvent.h index 6594897..4dcf8be 100644 --- a/Swift/Controllers/UIEvents/RequestChangeBlockStateUIEvent.h +++ b/Swift/Controllers/UIEvents/RequestChangeBlockStateUIEvent.h @@ -19,25 +19,25 @@ namespace Swift { class RequestChangeBlockStateUIEvent : public UIEvent { - public: - enum BlockState { - Blocked, - Unblocked - }; - - public: - RequestChangeBlockStateUIEvent(BlockState newState, const JID& contact) : state_(newState), contact_(contact) {} - - BlockState getBlockState() const { - return state_; - } - - JID getContact() const { - return contact_; - } - private: - BlockState state_; - JID contact_; + public: + enum BlockState { + Blocked, + Unblocked + }; + + public: + RequestChangeBlockStateUIEvent(BlockState newState, const JID& contact) : state_(newState), contact_(contact) {} + + BlockState getBlockState() const { + return state_; + } + + JID getContact() const { + return contact_; + } + private: + BlockState state_; + JID contact_; }; } diff --git a/Swift/Controllers/UIEvents/RequestChatUIEvent.h b/Swift/Controllers/UIEvents/RequestChatUIEvent.h index 95d6075..4eca5d4 100644 --- a/Swift/Controllers/UIEvents/RequestChatUIEvent.h +++ b/Swift/Controllers/UIEvents/RequestChatUIEvent.h @@ -11,11 +11,11 @@ #include <Swift/Controllers/UIEvents/UIEvent.h> namespace Swift { - class RequestChatUIEvent : public UIEvent { - public: - RequestChatUIEvent(const JID& contact) : contact_(contact) {} - JID getContact() {return contact_;} - private: - JID contact_; - }; + class RequestChatUIEvent : public UIEvent { + public: + RequestChatUIEvent(const JID& contact) : contact_(contact) {} + JID getContact() {return contact_;} + private: + JID contact_; + }; } diff --git a/Swift/Controllers/UIEvents/RequestChatWithUserDialogUIEvent.h b/Swift/Controllers/UIEvents/RequestChatWithUserDialogUIEvent.h index 76aa1f7..08804f4 100644 --- a/Swift/Controllers/UIEvents/RequestChatWithUserDialogUIEvent.h +++ b/Swift/Controllers/UIEvents/RequestChatWithUserDialogUIEvent.h @@ -9,7 +9,7 @@ #include <Swift/Controllers/UIEvents/UIEvent.h> namespace Swift { - class RequestChatWithUserDialogUIEvent : public UIEvent { + class RequestChatWithUserDialogUIEvent : public UIEvent { - }; + }; } diff --git a/Swift/Controllers/UIEvents/RequestContactEditorUIEvent.h b/Swift/Controllers/UIEvents/RequestContactEditorUIEvent.h index 61ddbe9..5693ab1 100644 --- a/Swift/Controllers/UIEvents/RequestContactEditorUIEvent.h +++ b/Swift/Controllers/UIEvents/RequestContactEditorUIEvent.h @@ -11,18 +11,18 @@ #include <Swift/Controllers/UIEvents/UIEvent.h> namespace Swift { - class RequestContactEditorUIEvent : public UIEvent { - public: - typedef boost::shared_ptr<RequestContactEditorUIEvent> ref; + class RequestContactEditorUIEvent : public UIEvent { + public: + typedef boost::shared_ptr<RequestContactEditorUIEvent> ref; - RequestContactEditorUIEvent(const JID& jid) : jid(jid) { - } + RequestContactEditorUIEvent(const JID& jid) : jid(jid) { + } - const JID& getJID() const { - return jid; - } + const JID& getJID() const { + return jid; + } - private: - JID jid; - }; + private: + JID jid; + }; } diff --git a/Swift/Controllers/UIEvents/RequestHighlightEditorUIEvent.h b/Swift/Controllers/UIEvents/RequestHighlightEditorUIEvent.h index 42e22a2..0bfa458 100644 --- a/Swift/Controllers/UIEvents/RequestHighlightEditorUIEvent.h +++ b/Swift/Controllers/UIEvents/RequestHighlightEditorUIEvent.h @@ -10,7 +10,7 @@ namespace Swift { - class RequestHighlightEditorUIEvent : public UIEvent { - }; + class RequestHighlightEditorUIEvent : public UIEvent { + }; } diff --git a/Swift/Controllers/UIEvents/RequestHistoryUIEvent.h b/Swift/Controllers/UIEvents/RequestHistoryUIEvent.h index 025e91f..8282204 100644 --- a/Swift/Controllers/UIEvents/RequestHistoryUIEvent.h +++ b/Swift/Controllers/UIEvents/RequestHistoryUIEvent.h @@ -9,6 +9,6 @@ #include <Swift/Controllers/UIEvents/UIEvent.h> namespace Swift { - class RequestHistoryUIEvent : public UIEvent { - }; + class RequestHistoryUIEvent : public UIEvent { + }; } diff --git a/Swift/Controllers/UIEvents/RequestInviteToMUCUIEvent.h b/Swift/Controllers/UIEvents/RequestInviteToMUCUIEvent.h index 3733532..9a1abb1 100644 --- a/Swift/Controllers/UIEvents/RequestInviteToMUCUIEvent.h +++ b/Swift/Controllers/UIEvents/RequestInviteToMUCUIEvent.h @@ -21,34 +21,34 @@ #include <Swift/Controllers/UIEvents/UIEvent.h> namespace Swift { - class RequestInviteToMUCUIEvent : public UIEvent { - public: - typedef boost::shared_ptr<RequestInviteToMUCUIEvent> ref; - - enum ImpromptuMode { - Impromptu, - NotImpromptu - }; - - RequestInviteToMUCUIEvent(const JID& room, const std::vector<JID>& JIDsToInvite, ImpromptuMode impromptu) : room_(room), invite_(JIDsToInvite) { - isImpromptu_ = impromptu == Impromptu; - } - - const JID& getRoom() const { - return room_; - } - - const std::vector<JID> getInvites() const { - return invite_; - } - - bool isImpromptu() const { - return isImpromptu_; - } - - private: - JID room_; - std::vector<JID> invite_; - bool isImpromptu_; - }; + class RequestInviteToMUCUIEvent : public UIEvent { + public: + typedef boost::shared_ptr<RequestInviteToMUCUIEvent> ref; + + enum ImpromptuMode { + Impromptu, + NotImpromptu + }; + + RequestInviteToMUCUIEvent(const JID& room, const std::vector<JID>& JIDsToInvite, ImpromptuMode impromptu) : room_(room), invite_(JIDsToInvite) { + isImpromptu_ = impromptu == Impromptu; + } + + const JID& getRoom() const { + return room_; + } + + const std::vector<JID> getInvites() const { + return invite_; + } + + bool isImpromptu() const { + return isImpromptu_; + } + + private: + JID room_; + std::vector<JID> invite_; + bool isImpromptu_; + }; } diff --git a/Swift/Controllers/UIEvents/RequestJoinMUCUIEvent.h b/Swift/Controllers/UIEvents/RequestJoinMUCUIEvent.h index a3ba6c8..a2a4183 100644 --- a/Swift/Controllers/UIEvents/RequestJoinMUCUIEvent.h +++ b/Swift/Controllers/UIEvents/RequestJoinMUCUIEvent.h @@ -15,18 +15,18 @@ #include <Swift/Controllers/UIEvents/UIEvent.h> namespace Swift { - class RequestJoinMUCUIEvent : public UIEvent { - public: - typedef boost::shared_ptr<RequestJoinMUCUIEvent> ref; + class RequestJoinMUCUIEvent : public UIEvent { + public: + typedef boost::shared_ptr<RequestJoinMUCUIEvent> ref; - RequestJoinMUCUIEvent(const JID& room = JID()) : room(room) { - } + RequestJoinMUCUIEvent(const JID& room = JID()) : room(room) { + } - const JID& getRoom() const { - return room; - } + const JID& getRoom() const { + return room; + } - private: - JID room; - }; + private: + JID room; + }; } diff --git a/Swift/Controllers/UIEvents/RequestProfileEditorUIEvent.h b/Swift/Controllers/UIEvents/RequestProfileEditorUIEvent.h index 1907242..1a02af4 100644 --- a/Swift/Controllers/UIEvents/RequestProfileEditorUIEvent.h +++ b/Swift/Controllers/UIEvents/RequestProfileEditorUIEvent.h @@ -9,8 +9,8 @@ #include <Swift/Controllers/UIEvents/UIEvent.h> namespace Swift { - class RequestProfileEditorUIEvent : public UIEvent { - public: - RequestProfileEditorUIEvent() {} - }; + class RequestProfileEditorUIEvent : public UIEvent { + public: + RequestProfileEditorUIEvent() {} + }; } diff --git a/Swift/Controllers/UIEvents/RequestWhiteboardUIEvent.h b/Swift/Controllers/UIEvents/RequestWhiteboardUIEvent.h index 625736f..9c2b01d 100644 --- a/Swift/Controllers/UIEvents/RequestWhiteboardUIEvent.h +++ b/Swift/Controllers/UIEvents/RequestWhiteboardUIEvent.h @@ -17,11 +17,11 @@ #include <Swift/Controllers/UIEvents/UIEvent.h> namespace Swift { - class RequestWhiteboardUIEvent : public UIEvent { - public: - RequestWhiteboardUIEvent(const JID& contact) : contact_(contact) {} - const JID& getContact() const {return contact_;} - private: - JID contact_; - }; + class RequestWhiteboardUIEvent : public UIEvent { + public: + RequestWhiteboardUIEvent(const JID& contact) : contact_(contact) {} + const JID& getContact() const {return contact_;} + private: + JID contact_; + }; } diff --git a/Swift/Controllers/UIEvents/RequestXMLConsoleUIEvent.h b/Swift/Controllers/UIEvents/RequestXMLConsoleUIEvent.h index 41eecc4..4d780be 100644 --- a/Swift/Controllers/UIEvents/RequestXMLConsoleUIEvent.h +++ b/Swift/Controllers/UIEvents/RequestXMLConsoleUIEvent.h @@ -9,6 +9,6 @@ #include <Swift/Controllers/UIEvents/UIEvent.h> namespace Swift { - class RequestXMLConsoleUIEvent : public UIEvent { - }; + class RequestXMLConsoleUIEvent : public UIEvent { + }; } diff --git a/Swift/Controllers/UIEvents/SendFileUIEvent.h b/Swift/Controllers/UIEvents/SendFileUIEvent.h index ea29453..72452df 100644 --- a/Swift/Controllers/UIEvents/SendFileUIEvent.h +++ b/Swift/Controllers/UIEvents/SendFileUIEvent.h @@ -19,23 +19,23 @@ #include <Swift/Controllers/UIEvents/UIEvent.h> namespace Swift { - class SendFileUIEvent : public UIEvent { - public: - typedef boost::shared_ptr<SendFileUIEvent> ref; - - SendFileUIEvent(const JID& jid, const std::string& filename) : jid(jid), filename(filename) { - } - - const JID& getJID() const { - return jid; - } - - const std::string& getFilename() const { - return filename; - } - - private: - JID jid; - std::string filename; - }; + class SendFileUIEvent : public UIEvent { + public: + typedef boost::shared_ptr<SendFileUIEvent> ref; + + SendFileUIEvent(const JID& jid, const std::string& filename) : jid(jid), filename(filename) { + } + + const JID& getJID() const { + return jid; + } + + const std::string& getFilename() const { + return filename; + } + + private: + JID jid; + std::string filename; + }; } diff --git a/Swift/Controllers/UIEvents/ShowProfileForRosterItemUIEvent.h b/Swift/Controllers/UIEvents/ShowProfileForRosterItemUIEvent.h index 586f036..88528d7 100644 --- a/Swift/Controllers/UIEvents/ShowProfileForRosterItemUIEvent.h +++ b/Swift/Controllers/UIEvents/ShowProfileForRosterItemUIEvent.h @@ -19,14 +19,14 @@ 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_; + 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 0d16cb6..a1b6efb 100644 --- a/Swift/Controllers/UIEvents/ShowWhiteboardUIEvent.h +++ b/Swift/Controllers/UIEvents/ShowWhiteboardUIEvent.h @@ -17,12 +17,12 @@ #include <Swift/Controllers/UIEvents/UIEvent.h> namespace Swift { - class ShowWhiteboardUIEvent : public UIEvent { - public: - ShowWhiteboardUIEvent(const JID& contact) : contact_(contact) {} - const JID& getContact() const {return contact_;} - private: - JID contact_; - }; + class ShowWhiteboardUIEvent : public UIEvent { + public: + ShowWhiteboardUIEvent(const JID& contact) : contact_(contact) {} + const JID& getContact() const {return contact_;} + private: + JID contact_; + }; } diff --git a/Swift/Controllers/UIEvents/UIEvent.h b/Swift/Controllers/UIEvents/UIEvent.h index 548f356..333582d 100644 --- a/Swift/Controllers/UIEvents/UIEvent.h +++ b/Swift/Controllers/UIEvents/UIEvent.h @@ -9,10 +9,10 @@ #include <boost/shared_ptr.hpp> namespace Swift { - class UIEvent { - public: - typedef boost::shared_ptr<UIEvent> ref; + class UIEvent { + public: + typedef boost::shared_ptr<UIEvent> ref; - virtual ~UIEvent(); - }; + virtual ~UIEvent(); + }; } diff --git a/Swift/Controllers/UIEvents/UIEventStream.h b/Swift/Controllers/UIEvents/UIEventStream.h index a630522..7ff1b54 100644 --- a/Swift/Controllers/UIEvents/UIEventStream.h +++ b/Swift/Controllers/UIEvents/UIEventStream.h @@ -13,12 +13,12 @@ #include <Swift/Controllers/UIEvents/UIEvent.h> namespace Swift { - class UIEventStream { - public: - boost::signal<void (boost::shared_ptr<UIEvent>)> onUIEvent; + class UIEventStream { + public: + boost::signal<void (boost::shared_ptr<UIEvent>)> onUIEvent; - void send(boost::shared_ptr<UIEvent> event) { - onUIEvent(event); - } - }; + void send(boost::shared_ptr<UIEvent> event) { + onUIEvent(event); + } + }; } diff --git a/Swift/Controllers/UIInterfaces/AdHocCommandWindow.h b/Swift/Controllers/UIInterfaces/AdHocCommandWindow.h index e5d95fa..06d3988 100644 --- a/Swift/Controllers/UIInterfaces/AdHocCommandWindow.h +++ b/Swift/Controllers/UIInterfaces/AdHocCommandWindow.h @@ -9,10 +9,10 @@ #include <Swiften/Base/boost_bsignals.h> namespace Swift { - class AdHocCommandWindow { - public: - virtual ~AdHocCommandWindow() {} - virtual void setOnline(bool /*online*/) {} - boost::signal<void ()> onClosing; - }; + class AdHocCommandWindow { + public: + virtual ~AdHocCommandWindow() {} + virtual void setOnline(bool /*online*/) {} + boost::signal<void ()> onClosing; + }; } diff --git a/Swift/Controllers/UIInterfaces/AdHocCommandWindowFactory.h b/Swift/Controllers/UIInterfaces/AdHocCommandWindowFactory.h index d7b456d..d3003f7 100644 --- a/Swift/Controllers/UIInterfaces/AdHocCommandWindowFactory.h +++ b/Swift/Controllers/UIInterfaces/AdHocCommandWindowFactory.h @@ -12,9 +12,9 @@ namespace Swift { class AdHocCommandWindow; - class AdHocCommandWindowFactory { - public: - virtual ~AdHocCommandWindowFactory() {} - virtual AdHocCommandWindow* createAdHocCommandWindow(boost::shared_ptr<OutgoingAdHocCommandSession> command) = 0; - }; + class AdHocCommandWindowFactory { + public: + virtual ~AdHocCommandWindowFactory() {} + virtual AdHocCommandWindow* createAdHocCommandWindow(boost::shared_ptr<OutgoingAdHocCommandSession> command) = 0; + }; } diff --git a/Swift/Controllers/UIInterfaces/BlockListEditorWidget.h b/Swift/Controllers/UIInterfaces/BlockListEditorWidget.h index 201377d..ebfa0c4 100644 --- a/Swift/Controllers/UIInterfaces/BlockListEditorWidget.h +++ b/Swift/Controllers/UIInterfaces/BlockListEditorWidget.h @@ -19,22 +19,22 @@ namespace Swift { - class ClientBlockListManager; + class ClientBlockListManager; - class BlockListEditorWidget { - public: - virtual ~BlockListEditorWidget() {} + class BlockListEditorWidget { + public: + virtual ~BlockListEditorWidget() {} - virtual void show() = 0; - virtual void hide() = 0; + virtual void show() = 0; + virtual void hide() = 0; - virtual void setCurrentBlockList(const std::vector<JID>& blockedJIDs) = 0; - virtual void setBusy(bool isBusy) = 0; - virtual void setError(const std::string&) = 0; + virtual void setCurrentBlockList(const std::vector<JID>& blockedJIDs) = 0; + virtual void setBusy(bool isBusy) = 0; + virtual void setError(const std::string&) = 0; - virtual std::vector<JID> getCurrentBlockList() const = 0; + virtual std::vector<JID> getCurrentBlockList() const = 0; - boost::signal<void (const std::vector<JID>& /* blockedJID */)> onSetNewBlockList; - }; + boost::signal<void (const std::vector<JID>& /* blockedJID */)> onSetNewBlockList; + }; } diff --git a/Swift/Controllers/UIInterfaces/BlockListEditorWidgetFactory.h b/Swift/Controllers/UIInterfaces/BlockListEditorWidgetFactory.h index eb91ac1..05e7f3a 100644 --- a/Swift/Controllers/UIInterfaces/BlockListEditorWidgetFactory.h +++ b/Swift/Controllers/UIInterfaces/BlockListEditorWidgetFactory.h @@ -8,13 +8,13 @@ namespace Swift { - class BlockListEditorWidget; + class BlockListEditorWidget; - class BlockListEditorWidgetFactory { - public: - virtual ~BlockListEditorWidgetFactory() {} + class BlockListEditorWidgetFactory { + public: + virtual ~BlockListEditorWidgetFactory() {} - virtual BlockListEditorWidget* createBlockListEditorWidget() = 0; - }; + virtual BlockListEditorWidget* createBlockListEditorWidget() = 0; + }; } diff --git a/Swift/Controllers/UIInterfaces/ChatListWindow.h b/Swift/Controllers/UIInterfaces/ChatListWindow.h index 8b5036b..a94e14e 100644 --- a/Swift/Controllers/UIInterfaces/ChatListWindow.h +++ b/Swift/Controllers/UIInterfaces/ChatListWindow.h @@ -19,83 +19,83 @@ #include <Swiften/MUC/MUCBookmark.h> namespace Swift { - class ChatListWindow { - public: - class Chat { - public: - Chat() : statusType(StatusShow::None), isMUC(false), unreadCount(0), isPrivateMessage(false) {} - Chat(const JID& jid, const std::string& chatName, const std::string& activity, int unreadCount, StatusShow::Type statusType, const boost::filesystem::path& avatarPath, bool isMUC, bool isPrivateMessage = false, const std::string& nick = "", const boost::optional<std::string> password = boost::optional<std::string>()) - : jid(jid), chatName(chatName), activity(activity), statusType(statusType), isMUC(isMUC), nick(nick), password(password), unreadCount(unreadCount), avatarPath(avatarPath), isPrivateMessage(isPrivateMessage) {} - /** Assume that nicks and other transient features aren't important for equality */ - bool operator==(const Chat& other) const { - if (impromptuJIDs.empty()) { - return jid.toBare() == other.jid.toBare() - && isMUC == other.isMUC; - } else { /* compare the chat occupant lists */ - typedef std::map<std::string, JID> JIDMap; - foreach (const JIDMap::value_type& jid, impromptuJIDs) { - bool found = false; - foreach (const JIDMap::value_type& otherJID, other.impromptuJIDs) { - if (jid.second.toBare() == otherJID.second.toBare()) { - found = true; - break; - } - } - if (!found) { - return false; - } - } - return true; - } - } - void setUnreadCount(int unread) { - unreadCount = unread; - } - void setStatusType(StatusShow::Type type) { - statusType = type; - } - void setAvatarPath(const boost::filesystem::path& path) { - avatarPath = path; - } - std::string getImpromptuTitle() const { - typedef std::pair<std::string, JID> StringJIDPair; - std::string title; - foreach(StringJIDPair pair, impromptuJIDs) { - if (title.empty()) { - title += pair.first; - } else { - title += ", " + pair.first; - } - } - return title; - } - JID jid; - std::string chatName; - std::string activity; - StatusShow::Type statusType; - bool isMUC; - std::string nick; - boost::optional<std::string> password; - int unreadCount; - boost::filesystem::path avatarPath; - std::map<std::string, JID> impromptuJIDs; - bool isPrivateMessage; - }; - virtual ~ChatListWindow(); + class ChatListWindow { + public: + class Chat { + public: + Chat() : statusType(StatusShow::None), isMUC(false), unreadCount(0), isPrivateMessage(false) {} + Chat(const JID& jid, const std::string& chatName, const std::string& activity, int unreadCount, StatusShow::Type statusType, const boost::filesystem::path& avatarPath, bool isMUC, bool isPrivateMessage = false, const std::string& nick = "", const boost::optional<std::string> password = boost::optional<std::string>()) + : jid(jid), chatName(chatName), activity(activity), statusType(statusType), isMUC(isMUC), nick(nick), password(password), unreadCount(unreadCount), avatarPath(avatarPath), isPrivateMessage(isPrivateMessage) {} + /** Assume that nicks and other transient features aren't important for equality */ + bool operator==(const Chat& other) const { + if (impromptuJIDs.empty()) { + return jid.toBare() == other.jid.toBare() + && isMUC == other.isMUC; + } else { /* compare the chat occupant lists */ + typedef std::map<std::string, JID> JIDMap; + foreach (const JIDMap::value_type& jid, impromptuJIDs) { + bool found = false; + foreach (const JIDMap::value_type& otherJID, other.impromptuJIDs) { + if (jid.second.toBare() == otherJID.second.toBare()) { + found = true; + break; + } + } + if (!found) { + return false; + } + } + return true; + } + } + void setUnreadCount(int unread) { + unreadCount = unread; + } + void setStatusType(StatusShow::Type type) { + statusType = type; + } + void setAvatarPath(const boost::filesystem::path& path) { + avatarPath = path; + } + std::string getImpromptuTitle() const { + typedef std::pair<std::string, JID> StringJIDPair; + std::string title; + foreach(StringJIDPair pair, impromptuJIDs) { + if (title.empty()) { + title += pair.first; + } else { + title += ", " + pair.first; + } + } + return title; + } + JID jid; + std::string chatName; + std::string activity; + StatusShow::Type statusType; + bool isMUC; + std::string nick; + boost::optional<std::string> password; + int unreadCount; + boost::filesystem::path avatarPath; + std::map<std::string, JID> impromptuJIDs; + bool isPrivateMessage; + }; + virtual ~ChatListWindow(); - virtual void setBookmarksEnabled(bool enabled) = 0; - virtual void addMUCBookmark(const MUCBookmark& bookmark) = 0; - virtual void addWhiteboardSession(const ChatListWindow::Chat& chat) = 0; - virtual void removeWhiteboardSession(const JID& jid) = 0; - virtual void removeMUCBookmark(const MUCBookmark& bookmark) = 0; - virtual void setRecents(const std::list<Chat>& recents) = 0; - virtual void setUnreadCount(int unread) = 0; - virtual void clearBookmarks() = 0; - virtual void setOnline(bool isOnline) = 0; + virtual void setBookmarksEnabled(bool enabled) = 0; + virtual void addMUCBookmark(const MUCBookmark& bookmark) = 0; + virtual void addWhiteboardSession(const ChatListWindow::Chat& chat) = 0; + virtual void removeWhiteboardSession(const JID& jid) = 0; + virtual void removeMUCBookmark(const MUCBookmark& bookmark) = 0; + virtual void setRecents(const std::list<Chat>& recents) = 0; + virtual void setUnreadCount(int unread) = 0; + virtual void clearBookmarks() = 0; + virtual void setOnline(bool isOnline) = 0; - boost::signal<void (const MUCBookmark&)> onMUCBookmarkActivated; - boost::signal<void (const Chat&)> onRecentActivated; - boost::signal<void (const JID&)> onWhiteboardActivated; - boost::signal<void ()> onClearRecentsRequested; - }; + boost::signal<void (const MUCBookmark&)> onMUCBookmarkActivated; + boost::signal<void (const Chat&)> onRecentActivated; + boost::signal<void (const JID&)> onWhiteboardActivated; + boost::signal<void ()> onClearRecentsRequested; + }; } diff --git a/Swift/Controllers/UIInterfaces/ChatListWindowFactory.h b/Swift/Controllers/UIInterfaces/ChatListWindowFactory.h index fcd979b..3ae1ec6 100644 --- a/Swift/Controllers/UIInterfaces/ChatListWindowFactory.h +++ b/Swift/Controllers/UIInterfaces/ChatListWindowFactory.h @@ -9,10 +9,10 @@ #include <Swift/Controllers/UIInterfaces/ChatListWindow.h> namespace Swift { - class UIEventStream; - class ChatListWindowFactory { - public: - virtual ~ChatListWindowFactory() {} - virtual ChatListWindow* createChatListWindow(UIEventStream* uiEventStream) = 0; - }; + class UIEventStream; + class ChatListWindowFactory { + public: + virtual ~ChatListWindowFactory() {} + virtual ChatListWindow* createChatListWindow(UIEventStream* uiEventStream) = 0; + }; } diff --git a/Swift/Controllers/UIInterfaces/ChatWindow.h b/Swift/Controllers/UIInterfaces/ChatWindow.h index 05331bb..310c967 100644 --- a/Swift/Controllers/UIInterfaces/ChatWindow.h +++ b/Swift/Controllers/UIInterfaces/ChatWindow.h @@ -26,233 +26,233 @@ #include <Swift/Controllers/HighlightManager.h> namespace Swift { - class AvatarManager; - class TreeWidget; - class Roster; - class TabComplete; - class RosterItem; - class ContactRosterItem; - class FileTransferController; - class UserSearchWindow; - - - class ChatWindow { - public: - class ChatMessagePart { - public: - virtual ~ChatMessagePart() {} - }; - - class ChatMessage { - public: - ChatMessage() {} - ChatMessage(const std::string& text) { - append(boost::make_shared<ChatTextMessagePart>(text)); - } - void append(const boost::shared_ptr<ChatMessagePart>& part) { - parts_.push_back(part); - } - - const std::vector<boost::shared_ptr<ChatMessagePart> >& getParts() const { - return parts_; - } - - void setFullMessageHighlightAction(const HighlightAction& action) { - fullMessageHighlightAction_ = action; - } - - const HighlightAction& getFullMessageHighlightAction() const { - return fullMessageHighlightAction_; - } - - bool isMeCommand() const { - bool isMeCommand = false; - if (!parts_.empty()) { - boost::shared_ptr<ChatTextMessagePart> textPart = boost::dynamic_pointer_cast<ChatTextMessagePart>(parts_[0]); - if (textPart) { - if (boost::starts_with(textPart->text, "/me ")) { - isMeCommand = true; - } - } - } - return isMeCommand; - } - - private: - std::vector<boost::shared_ptr<ChatMessagePart> > parts_; - HighlightAction fullMessageHighlightAction_; - }; - - class ChatTextMessagePart : public ChatMessagePart { - public: - ChatTextMessagePart(const std::string& text) : text(text) {} - std::string text; - }; - - class ChatURIMessagePart : public ChatMessagePart { - public: - ChatURIMessagePart(const std::string& target) : target(target) {} - std::string target; - }; - - class ChatEmoticonMessagePart : public ChatMessagePart { - public: - std::string imagePath; - std::string alternativeText; - }; - - class ChatHighlightingMessagePart : public ChatMessagePart { - public: - HighlightAction action; - std::string text; - }; - - - enum AckState {Pending, Received, Failed}; - enum ReceiptState {ReceiptRequested, ReceiptReceived, ReceiptFailed}; - enum OccupantAction {Kick, Ban, MakeModerator, MakeParticipant, MakeVisitor, AddContact, ShowProfile}; - enum RoomAction {ChangeSubject, Configure, Affiliations, Destroy, Invite}; - enum FileTransferState { - Initialisation, ///< Collecting information required for sending the request out. - WaitingForAccept, ///< The file transfer request was send out. - Negotiating, ///< The other party accepted the file transfer request and a suitable transfer method is negotiated. - Transferring, ///< The negotiation was successful and the file is currently transferred. - Canceled, ///< Someone actively canceled the transfer. - Finished, ///< The file was transferred successfully. - FTFailed ///< The negotiation, the transfer itself or the verification failed. - }; - enum WhiteboardSessionState {WhiteboardAccepted, WhiteboardTerminated, WhiteboardRejected}; - enum BlockingState {BlockingUnsupported, IsBlocked, IsUnblocked}; - enum Direction { UnknownDirection, DefaultDirection }; - enum MUCType { StandardMUC, ImpromptuMUC }; - enum TimestampBehaviour { KeepTimestamp, UpdateTimestamp }; - enum RoomBookmarkState { RoomNotBookmarked, RoomBookmarked, RoomAutoJoined }; - - ChatWindow() {} - virtual ~ChatWindow() {} - - /** Add message to window. - * @return id of added message (for acks). - */ - virtual std::string addMessage(const ChatMessage& message, const std::string& senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time) = 0; - /** Adds action to window. - * @return id of added message (for acks); - */ - virtual std::string addAction(const ChatMessage& message, const std::string& senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time) = 0; - - /** Adds system message to window - * @return id of added message (for replacement) - */ - virtual std::string addSystemMessage(const ChatMessage& message, Direction direction) = 0; - virtual void addPresenceMessage(const ChatMessage& message, Direction direction) = 0; - - virtual void addErrorMessage(const ChatMessage& message) = 0; - virtual void replaceMessage(const ChatMessage& message, const std::string& id, const boost::posix_time::ptime& time) = 0; - virtual void replaceSystemMessage(const ChatMessage& message, const std::string& id, const TimestampBehaviour timestampBehaviour) = 0; - virtual void replaceWithAction(const ChatMessage& message, const std::string& id, const boost::posix_time::ptime& time) = 0; - - // File transfer related stuff - virtual std::string addFileTransfer(const std::string& senderName, bool senderIsSelf, const std::string& filename, const boost::uintmax_t sizeInBytes, const std::string& description) = 0; - virtual void setFileTransferProgress(std::string, const int percentageDone) = 0; - virtual void setFileTransferStatus(std::string, const FileTransferState state, const std::string& msg = "") = 0; - virtual void addMUCInvitation(const std::string& senderName, const JID& jid, const std::string& reason, const std::string& password, bool direct = true, bool isImpromptu = false, bool isContinuation = false) = 0; - - virtual std::string addWhiteboardRequest(bool senderIsSelf) = 0; - virtual void setWhiteboardSessionStatus(std::string id, const ChatWindow::WhiteboardSessionState state) = 0; - - // message receipts - virtual void setMessageReceiptState(const std::string& id, ChatWindow::ReceiptState state) = 0; - - virtual void setContactChatState(ChatState::ChatStateType state) = 0; - virtual void setName(const std::string& name) = 0; - virtual void show() = 0; - virtual bool isVisible() const = 0; - virtual void activate() = 0; - virtual void setAvailableSecurityLabels(const std::vector<SecurityLabelsCatalog::Item>& labels) = 0; - virtual void setSecurityLabelsEnabled(bool enabled) = 0; - virtual void setCorrectionEnabled(Tristate enabled) = 0; - virtual void setFileTransferEnabled(Tristate enabled) = 0; - virtual void setUnreadMessageCount(int count) = 0; - virtual void convertToMUC(MUCType mucType) = 0; -// virtual TreeWidget *getTreeWidget() = 0; - virtual void setSecurityLabelsError() = 0; - virtual SecurityLabelsCatalog::Item getSelectedSecurityLabel() = 0; - virtual void setOnline(bool online) = 0; - virtual void setRosterModel(Roster* model) = 0; - virtual void setTabComplete(TabComplete* completer) = 0; - virtual void replaceLastMessage(const ChatMessage& message, const TimestampBehaviour timestampBehaviour) = 0; - virtual void setAckState(const std::string& id, AckState state) = 0; - virtual void flash() = 0; - virtual void setSubject(const std::string& subject) = 0; - virtual void setAffiliations(MUCOccupant::Affiliation, const std::vector<JID>&) = 0; - virtual void setAvailableRoomActions(const std::vector<RoomAction> &actions) = 0; - virtual void setBlockingState(BlockingState state) = 0; - virtual void setCanInitiateImpromptuChats(bool supportsImpromptu) = 0; - virtual void showBookmarkWindow(const MUCBookmark& bookmark) = 0; - virtual void setBookmarkState(RoomBookmarkState bookmarkState) = 0; - - /** - * A handle that uniquely identities an alert message. - */ - typedef int AlertID; - /** - * Set an alert on the window. - * @param alertText Description of alert (required). - * @param buttonText Button text to use (optional, no button is shown if empty). - * @return A handle to the alert message. - */ - virtual AlertID addAlert(const std::string& alertText) = 0; - /** - * Removes an alert. - * @param id An alert ID previously returned from setAlert - */ - virtual void removeAlert(const AlertID id) = 0; - - /** - * Actions that can be performed on the selected occupant. - */ - virtual void setAvailableOccupantActions(const std::vector<OccupantAction>& actions) = 0; - - /** - * A room configuration has been requested, show the form. - * If the form is cancelled, must emit onConfigurationFormCancelled(). - */ - virtual void showRoomConfigurationForm(Form::ref) = 0; - - boost::signal<void ()> onClosed; - boost::signal<void ()> onAllMessagesRead; - boost::signal<void (const std::string&, bool isCorrection)> onSendMessageRequest; - boost::signal<void ()> onSendCorrectionMessageRequest; - boost::signal<void ()> onUserTyping; - boost::signal<void ()> onUserCancelsTyping; - boost::signal<void ()> onAlertButtonClicked; - boost::signal<void (ContactRosterItem*)> onOccupantSelectionChanged; - boost::signal<void (ChatWindow::OccupantAction, ContactRosterItem*)> onOccupantActionSelected; - boost::signal<void (const std::string&)> onChangeSubjectRequest; - boost::signal<void ()> onBookmarkRequest; - boost::signal<void (Form::ref)> onConfigureRequest; - boost::signal<void ()> onDestroyRequest; - boost::signal<void (const std::vector<JID>&)> onInviteToChat; - boost::signal<void ()> onConfigurationFormCancelled; - boost::signal<void ()> onGetAffiliationsRequest; - boost::signal<void (MUCOccupant::Affiliation, const JID&)> onSetAffiliationRequest; - boost::signal<void (const std::vector<std::pair<MUCOccupant::Affiliation, JID> >& changes)> onChangeAffiliationsRequest; - boost::signal<void ()> onLogCleared; - - // File transfer related - boost::signal<void (std::string /* id */)> onFileTransferCancel; - boost::signal<void (std::string /* id */, std::string /* description */)> onFileTransferStart; - boost::signal<void (std::string /* id */, std::string /* path */)> onFileTransferAccept; - boost::signal<void (std::string /* path */)> onSendFileRequest; - - //Whiteboard related - boost::signal<void ()> onWhiteboardSessionAccept; - boost::signal<void ()> onWhiteboardSessionCancel; - boost::signal<void ()> onWhiteboardWindowShow; - - // Blocking Command related - boost::signal<void ()> onBlockUserRequest; - boost::signal<void ()> onUnblockUserRequest; - }; + class AvatarManager; + class TreeWidget; + class Roster; + class TabComplete; + class RosterItem; + class ContactRosterItem; + class FileTransferController; + class UserSearchWindow; + + + class ChatWindow { + public: + class ChatMessagePart { + public: + virtual ~ChatMessagePart() {} + }; + + class ChatMessage { + public: + ChatMessage() {} + ChatMessage(const std::string& text) { + append(boost::make_shared<ChatTextMessagePart>(text)); + } + void append(const boost::shared_ptr<ChatMessagePart>& part) { + parts_.push_back(part); + } + + const std::vector<boost::shared_ptr<ChatMessagePart> >& getParts() const { + return parts_; + } + + void setFullMessageHighlightAction(const HighlightAction& action) { + fullMessageHighlightAction_ = action; + } + + const HighlightAction& getFullMessageHighlightAction() const { + return fullMessageHighlightAction_; + } + + bool isMeCommand() const { + bool isMeCommand = false; + if (!parts_.empty()) { + boost::shared_ptr<ChatTextMessagePart> textPart = boost::dynamic_pointer_cast<ChatTextMessagePart>(parts_[0]); + if (textPart) { + if (boost::starts_with(textPart->text, "/me ")) { + isMeCommand = true; + } + } + } + return isMeCommand; + } + + private: + std::vector<boost::shared_ptr<ChatMessagePart> > parts_; + HighlightAction fullMessageHighlightAction_; + }; + + class ChatTextMessagePart : public ChatMessagePart { + public: + ChatTextMessagePart(const std::string& text) : text(text) {} + std::string text; + }; + + class ChatURIMessagePart : public ChatMessagePart { + public: + ChatURIMessagePart(const std::string& target) : target(target) {} + std::string target; + }; + + class ChatEmoticonMessagePart : public ChatMessagePart { + public: + std::string imagePath; + std::string alternativeText; + }; + + class ChatHighlightingMessagePart : public ChatMessagePart { + public: + HighlightAction action; + std::string text; + }; + + + enum AckState {Pending, Received, Failed}; + enum ReceiptState {ReceiptRequested, ReceiptReceived, ReceiptFailed}; + enum OccupantAction {Kick, Ban, MakeModerator, MakeParticipant, MakeVisitor, AddContact, ShowProfile}; + enum RoomAction {ChangeSubject, Configure, Affiliations, Destroy, Invite}; + enum FileTransferState { + Initialisation, ///< Collecting information required for sending the request out. + WaitingForAccept, ///< The file transfer request was send out. + Negotiating, ///< The other party accepted the file transfer request and a suitable transfer method is negotiated. + Transferring, ///< The negotiation was successful and the file is currently transferred. + Canceled, ///< Someone actively canceled the transfer. + Finished, ///< The file was transferred successfully. + FTFailed ///< The negotiation, the transfer itself or the verification failed. + }; + enum WhiteboardSessionState {WhiteboardAccepted, WhiteboardTerminated, WhiteboardRejected}; + enum BlockingState {BlockingUnsupported, IsBlocked, IsUnblocked}; + enum Direction { UnknownDirection, DefaultDirection }; + enum MUCType { StandardMUC, ImpromptuMUC }; + enum TimestampBehaviour { KeepTimestamp, UpdateTimestamp }; + enum RoomBookmarkState { RoomNotBookmarked, RoomBookmarked, RoomAutoJoined }; + + ChatWindow() {} + virtual ~ChatWindow() {} + + /** Add message to window. + * @return id of added message (for acks). + */ + virtual std::string addMessage(const ChatMessage& message, const std::string& senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time) = 0; + /** Adds action to window. + * @return id of added message (for acks); + */ + virtual std::string addAction(const ChatMessage& message, const std::string& senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time) = 0; + + /** Adds system message to window + * @return id of added message (for replacement) + */ + virtual std::string addSystemMessage(const ChatMessage& message, Direction direction) = 0; + virtual void addPresenceMessage(const ChatMessage& message, Direction direction) = 0; + + virtual void addErrorMessage(const ChatMessage& message) = 0; + virtual void replaceMessage(const ChatMessage& message, const std::string& id, const boost::posix_time::ptime& time) = 0; + virtual void replaceSystemMessage(const ChatMessage& message, const std::string& id, const TimestampBehaviour timestampBehaviour) = 0; + virtual void replaceWithAction(const ChatMessage& message, const std::string& id, const boost::posix_time::ptime& time) = 0; + + // File transfer related stuff + virtual std::string addFileTransfer(const std::string& senderName, bool senderIsSelf, const std::string& filename, const boost::uintmax_t sizeInBytes, const std::string& description) = 0; + virtual void setFileTransferProgress(std::string, const int percentageDone) = 0; + virtual void setFileTransferStatus(std::string, const FileTransferState state, const std::string& msg = "") = 0; + virtual void addMUCInvitation(const std::string& senderName, const JID& jid, const std::string& reason, const std::string& password, bool direct = true, bool isImpromptu = false, bool isContinuation = false) = 0; + + virtual std::string addWhiteboardRequest(bool senderIsSelf) = 0; + virtual void setWhiteboardSessionStatus(std::string id, const ChatWindow::WhiteboardSessionState state) = 0; + + // message receipts + virtual void setMessageReceiptState(const std::string& id, ChatWindow::ReceiptState state) = 0; + + virtual void setContactChatState(ChatState::ChatStateType state) = 0; + virtual void setName(const std::string& name) = 0; + virtual void show() = 0; + virtual bool isVisible() const = 0; + virtual void activate() = 0; + virtual void setAvailableSecurityLabels(const std::vector<SecurityLabelsCatalog::Item>& labels) = 0; + virtual void setSecurityLabelsEnabled(bool enabled) = 0; + virtual void setCorrectionEnabled(Tristate enabled) = 0; + virtual void setFileTransferEnabled(Tristate enabled) = 0; + virtual void setUnreadMessageCount(int count) = 0; + virtual void convertToMUC(MUCType mucType) = 0; +// virtual TreeWidget *getTreeWidget() = 0; + virtual void setSecurityLabelsError() = 0; + virtual SecurityLabelsCatalog::Item getSelectedSecurityLabel() = 0; + virtual void setOnline(bool online) = 0; + virtual void setRosterModel(Roster* model) = 0; + virtual void setTabComplete(TabComplete* completer) = 0; + virtual void replaceLastMessage(const ChatMessage& message, const TimestampBehaviour timestampBehaviour) = 0; + virtual void setAckState(const std::string& id, AckState state) = 0; + virtual void flash() = 0; + virtual void setSubject(const std::string& subject) = 0; + virtual void setAffiliations(MUCOccupant::Affiliation, const std::vector<JID>&) = 0; + virtual void setAvailableRoomActions(const std::vector<RoomAction> &actions) = 0; + virtual void setBlockingState(BlockingState state) = 0; + virtual void setCanInitiateImpromptuChats(bool supportsImpromptu) = 0; + virtual void showBookmarkWindow(const MUCBookmark& bookmark) = 0; + virtual void setBookmarkState(RoomBookmarkState bookmarkState) = 0; + + /** + * A handle that uniquely identities an alert message. + */ + typedef int AlertID; + /** + * Set an alert on the window. + * @param alertText Description of alert (required). + * @param buttonText Button text to use (optional, no button is shown if empty). + * @return A handle to the alert message. + */ + virtual AlertID addAlert(const std::string& alertText) = 0; + /** + * Removes an alert. + * @param id An alert ID previously returned from setAlert + */ + virtual void removeAlert(const AlertID id) = 0; + + /** + * Actions that can be performed on the selected occupant. + */ + virtual void setAvailableOccupantActions(const std::vector<OccupantAction>& actions) = 0; + + /** + * A room configuration has been requested, show the form. + * If the form is cancelled, must emit onConfigurationFormCancelled(). + */ + virtual void showRoomConfigurationForm(Form::ref) = 0; + + boost::signal<void ()> onClosed; + boost::signal<void ()> onAllMessagesRead; + boost::signal<void (const std::string&, bool isCorrection)> onSendMessageRequest; + boost::signal<void ()> onSendCorrectionMessageRequest; + boost::signal<void ()> onUserTyping; + boost::signal<void ()> onUserCancelsTyping; + boost::signal<void ()> onAlertButtonClicked; + boost::signal<void (ContactRosterItem*)> onOccupantSelectionChanged; + boost::signal<void (ChatWindow::OccupantAction, ContactRosterItem*)> onOccupantActionSelected; + boost::signal<void (const std::string&)> onChangeSubjectRequest; + boost::signal<void ()> onBookmarkRequest; + boost::signal<void (Form::ref)> onConfigureRequest; + boost::signal<void ()> onDestroyRequest; + boost::signal<void (const std::vector<JID>&)> onInviteToChat; + boost::signal<void ()> onConfigurationFormCancelled; + boost::signal<void ()> onGetAffiliationsRequest; + boost::signal<void (MUCOccupant::Affiliation, const JID&)> onSetAffiliationRequest; + boost::signal<void (const std::vector<std::pair<MUCOccupant::Affiliation, JID> >& changes)> onChangeAffiliationsRequest; + boost::signal<void ()> onLogCleared; + + // File transfer related + boost::signal<void (std::string /* id */)> onFileTransferCancel; + boost::signal<void (std::string /* id */, std::string /* description */)> onFileTransferStart; + boost::signal<void (std::string /* id */, std::string /* path */)> onFileTransferAccept; + boost::signal<void (std::string /* path */)> onSendFileRequest; + + //Whiteboard related + boost::signal<void ()> onWhiteboardSessionAccept; + boost::signal<void ()> onWhiteboardSessionCancel; + boost::signal<void ()> onWhiteboardWindowShow; + + // Blocking Command related + boost::signal<void ()> onBlockUserRequest; + boost::signal<void ()> onUnblockUserRequest; + }; } diff --git a/Swift/Controllers/UIInterfaces/ChatWindowFactory.h b/Swift/Controllers/UIInterfaces/ChatWindowFactory.h index 7c47e2a..38706ab 100644 --- a/Swift/Controllers/UIInterfaces/ChatWindowFactory.h +++ b/Swift/Controllers/UIInterfaces/ChatWindowFactory.h @@ -10,17 +10,17 @@ #include "Swiften/JID/JID.h" namespace Swift { - class ChatWindow; - class UIEventStream; - class ChatWindowFactory { - public: - virtual ~ChatWindowFactory() {} - /** - * Transfers ownership of result. - */ - virtual ChatWindow* createChatWindow(const JID &contact, UIEventStream* eventStream) = 0; + class ChatWindow; + class UIEventStream; + class ChatWindowFactory { + public: + virtual ~ChatWindowFactory() {} + /** + * Transfers ownership of result. + */ + virtual ChatWindow* createChatWindow(const JID &contact, UIEventStream* eventStream) = 0; - }; + }; } #endif diff --git a/Swift/Controllers/UIInterfaces/ContactEditWindow.h b/Swift/Controllers/UIInterfaces/ContactEditWindow.h index 407959a..055c0f0 100644 --- a/Swift/Controllers/UIInterfaces/ContactEditWindow.h +++ b/Swift/Controllers/UIInterfaces/ContactEditWindow.h @@ -15,22 +15,22 @@ #include <Swiften/Base/boost_bsignals.h> namespace Swift { - class JID; - class VCardManager; + class JID; + class VCardManager; - class ContactEditWindow { - public: - virtual ~ContactEditWindow() {} + class ContactEditWindow { + public: + virtual ~ContactEditWindow() {} - virtual void setEnabled(bool b) = 0; + virtual void setEnabled(bool b) = 0; - virtual void setNameSuggestions(const std::vector<std::string>& suggestions) = 0; - virtual void setContact(const JID& jid, const std::string& name, const std::vector<std::string>& groups, const std::set<std::string>& allGroups) = 0; + virtual void setNameSuggestions(const std::vector<std::string>& suggestions) = 0; + virtual void setContact(const JID& jid, const std::string& name, const std::vector<std::string>& groups, const std::set<std::string>& allGroups) = 0; - virtual void show() = 0; - virtual void hide() = 0; + virtual void show() = 0; + virtual void hide() = 0; - boost::signal<void ()> onRemoveContactRequest; - boost::signal<void (const std::string& /* name */, const std::set<std::string>& /* groups */)> onChangeContactRequest; - }; + boost::signal<void ()> onRemoveContactRequest; + boost::signal<void (const std::string& /* name */, const std::set<std::string>& /* groups */)> onChangeContactRequest; + }; } diff --git a/Swift/Controllers/UIInterfaces/ContactEditWindowFactory.h b/Swift/Controllers/UIInterfaces/ContactEditWindowFactory.h index 6955a69..f5a84d5 100644 --- a/Swift/Controllers/UIInterfaces/ContactEditWindowFactory.h +++ b/Swift/Controllers/UIInterfaces/ContactEditWindowFactory.h @@ -9,10 +9,10 @@ #include <Swift/Controllers/UIInterfaces/ContactEditWindow.h> namespace Swift { - class ContactEditWindowFactory { - public: - virtual ~ContactEditWindowFactory() {} + class ContactEditWindowFactory { + public: + virtual ~ContactEditWindowFactory() {} - virtual ContactEditWindow* createContactEditWindow() = 0; - }; + virtual ContactEditWindow* createContactEditWindow() = 0; + }; } diff --git a/Swift/Controllers/UIInterfaces/EventWindow.h b/Swift/Controllers/UIInterfaces/EventWindow.h index 5ce99d8..1d254f4 100644 --- a/Swift/Controllers/UIInterfaces/EventWindow.h +++ b/Swift/Controllers/UIInterfaces/EventWindow.h @@ -11,19 +11,19 @@ #include <Swift/Controllers/XMPPEvents/StanzaEvent.h> namespace Swift { - class EventWindow { - public: - EventWindow(bool candelete = true) : canDelete_(candelete) {} + class EventWindow { + public: + EventWindow(bool candelete = true) : canDelete_(candelete) {} - bool canDelete() const { - return canDelete_; - } + bool canDelete() const { + return canDelete_; + } - virtual ~EventWindow() {} - virtual void addEvent(boost::shared_ptr<StanzaEvent> event, bool active) = 0; - virtual void removeEvent(boost::shared_ptr<StanzaEvent> event) = 0; + virtual ~EventWindow() {} + virtual void addEvent(boost::shared_ptr<StanzaEvent> event, bool active) = 0; + virtual void removeEvent(boost::shared_ptr<StanzaEvent> event) = 0; - private: - bool canDelete_; - }; + private: + bool canDelete_; + }; } diff --git a/Swift/Controllers/UIInterfaces/EventWindowFactory.h b/Swift/Controllers/UIInterfaces/EventWindowFactory.h index 7c9c87d..76638da 100644 --- a/Swift/Controllers/UIInterfaces/EventWindowFactory.h +++ b/Swift/Controllers/UIInterfaces/EventWindowFactory.h @@ -7,17 +7,17 @@ #pragma once namespace Swift { - class EventWindow; + class EventWindow; - class EventWindowFactory { - public: - virtual ~EventWindowFactory() {} - /** - * Transfers ownership of result. - */ - virtual EventWindow* createEventWindow() = 0; + class EventWindowFactory { + public: + virtual ~EventWindowFactory() {} + /** + * Transfers ownership of result. + */ + virtual EventWindow* createEventWindow() = 0; - }; + }; } diff --git a/Swift/Controllers/UIInterfaces/FileTransferListWidget.h b/Swift/Controllers/UIInterfaces/FileTransferListWidget.h index 01dcfd3..5a9eaeb 100644 --- a/Swift/Controllers/UIInterfaces/FileTransferListWidget.h +++ b/Swift/Controllers/UIInterfaces/FileTransferListWidget.h @@ -12,12 +12,12 @@ class FileTransferOverview; class FileTransferListWidget { public: - virtual ~FileTransferListWidget() {} + virtual ~FileTransferListWidget() {} - virtual void show() = 0; - virtual void activate() = 0; + virtual void show() = 0; + virtual void activate() = 0; - virtual void setFileTransferOverview(FileTransferOverview*) = 0; + virtual void setFileTransferOverview(FileTransferOverview*) = 0; }; } diff --git a/Swift/Controllers/UIInterfaces/FileTransferListWidgetFactory.h b/Swift/Controllers/UIInterfaces/FileTransferListWidgetFactory.h index 6da2d07..da9fd37 100644 --- a/Swift/Controllers/UIInterfaces/FileTransferListWidgetFactory.h +++ b/Swift/Controllers/UIInterfaces/FileTransferListWidgetFactory.h @@ -18,9 +18,9 @@ namespace Swift { class FileTransferListWidgetFactory { public: - virtual ~FileTransferListWidgetFactory() {} + virtual ~FileTransferListWidgetFactory() {} - virtual FileTransferListWidget* createFileTransferListWidget() = 0; + virtual FileTransferListWidget* createFileTransferListWidget() = 0; }; } diff --git a/Swift/Controllers/UIInterfaces/HighlightEditorWidget.h b/Swift/Controllers/UIInterfaces/HighlightEditorWidget.h index 4745035..ff888e6 100644 --- a/Swift/Controllers/UIInterfaces/HighlightEditorWidget.h +++ b/Swift/Controllers/UIInterfaces/HighlightEditorWidget.h @@ -8,15 +8,15 @@ namespace Swift { - class HighlightManager; + class HighlightManager; - class HighlightEditorWidget { - public: - virtual ~HighlightEditorWidget() {} + class HighlightEditorWidget { + public: + virtual ~HighlightEditorWidget() {} - virtual void show() = 0; + virtual void show() = 0; - virtual void setHighlightManager(HighlightManager* highlightManager) = 0; - }; + virtual void setHighlightManager(HighlightManager* highlightManager) = 0; + }; } diff --git a/Swift/Controllers/UIInterfaces/HighlightEditorWidgetFactory.h b/Swift/Controllers/UIInterfaces/HighlightEditorWidgetFactory.h index ade575b..363e666 100644 --- a/Swift/Controllers/UIInterfaces/HighlightEditorWidgetFactory.h +++ b/Swift/Controllers/UIInterfaces/HighlightEditorWidgetFactory.h @@ -8,13 +8,13 @@ namespace Swift { - class HighlightEditorWidget; + class HighlightEditorWidget; - class HighlightEditorWidgetFactory { - public: - virtual ~HighlightEditorWidgetFactory() {} + class HighlightEditorWidgetFactory { + public: + virtual ~HighlightEditorWidgetFactory() {} - virtual HighlightEditorWidget* createHighlightEditorWidget() = 0; - }; + virtual HighlightEditorWidget* createHighlightEditorWidget() = 0; + }; } diff --git a/Swift/Controllers/UIInterfaces/HighlightEditorWindow.h b/Swift/Controllers/UIInterfaces/HighlightEditorWindow.h index 12adb3d..8cca4f9 100644 --- a/Swift/Controllers/UIInterfaces/HighlightEditorWindow.h +++ b/Swift/Controllers/UIInterfaces/HighlightEditorWindow.h @@ -14,14 +14,14 @@ class HighlightManager; class HighlightEditorWindow { public: - HighlightEditorWindow(); - virtual ~HighlightEditorWindow(); - virtual void show() = 0; - virtual void setHighlightManager(HighlightManager *highlightManager) = 0; - virtual void setContactSuggestions(const std::vector<Contact::ref>& suggestions) = 0; + HighlightEditorWindow(); + virtual ~HighlightEditorWindow(); + virtual void show() = 0; + virtual void setHighlightManager(HighlightManager *highlightManager) = 0; + virtual void setContactSuggestions(const std::vector<Contact::ref>& suggestions) = 0; public: - boost::signal<void (const std::string&)> onContactSuggestionsRequested; + boost::signal<void (const std::string&)> onContactSuggestionsRequested; }; } diff --git a/Swift/Controllers/UIInterfaces/HighlightEditorWindowFactory.h b/Swift/Controllers/UIInterfaces/HighlightEditorWindowFactory.h index 18fbeb7..ea05425 100644 --- a/Swift/Controllers/UIInterfaces/HighlightEditorWindowFactory.h +++ b/Swift/Controllers/UIInterfaces/HighlightEditorWindowFactory.h @@ -13,12 +13,12 @@ #pragma once namespace Swift { - class HighlightEditorWindow; + class HighlightEditorWindow; - class HighlightEditorWindowFactory { - public : - virtual ~HighlightEditorWindowFactory() {} + class HighlightEditorWindowFactory { + public : + virtual ~HighlightEditorWindowFactory() {} - virtual HighlightEditorWindow* createHighlightEditorWindow() = 0; - }; + virtual HighlightEditorWindow* createHighlightEditorWindow() = 0; + }; } diff --git a/Swift/Controllers/UIInterfaces/HistoryWindow.h b/Swift/Controllers/UIInterfaces/HistoryWindow.h index 6d50f4b..db1a4b1 100644 --- a/Swift/Controllers/UIInterfaces/HistoryWindow.h +++ b/Swift/Controllers/UIInterfaces/HistoryWindow.h @@ -9,26 +9,26 @@ #include <Swift/Controllers/Roster/Roster.h> namespace Swift { - class HistoryWindow { - public: - virtual ~HistoryWindow() {} + class HistoryWindow { + public: + virtual ~HistoryWindow() {} - virtual void activate() = 0; - virtual void setRosterModel(Roster*) = 0; - virtual void addMessage(const std::string &message, const std::string &senderName, bool senderIsSelf, const std::string& avatarPath, const boost::posix_time::ptime& time, bool addAtTheTop) = 0; - virtual void resetConversationView() = 0; - virtual void resetConversationViewTopInsertPoint() = 0; // this is a temporary fix used in adding messages at the top - virtual void setDate(const boost::gregorian::date& date) = 0; + virtual void activate() = 0; + virtual void setRosterModel(Roster*) = 0; + virtual void addMessage(const std::string &message, const std::string &senderName, bool senderIsSelf, const std::string& avatarPath, const boost::posix_time::ptime& time, bool addAtTheTop) = 0; + virtual void resetConversationView() = 0; + virtual void resetConversationViewTopInsertPoint() = 0; // this is a temporary fix used in adding messages at the top + virtual void setDate(const boost::gregorian::date& date) = 0; - virtual std::string getSearchBoxText() = 0; - virtual boost::gregorian::date getLastVisibleDate() = 0; + virtual std::string getSearchBoxText() = 0; + virtual boost::gregorian::date getLastVisibleDate() = 0; - boost::signal<void (RosterItem*)> onSelectedContactChanged; - boost::signal<void (const std::string&)> onReturnPressed; - boost::signal<void (const boost::gregorian::date&)> onScrollReachedTop; - boost::signal<void (const boost::gregorian::date&)> onScrollReachedBottom; - boost::signal<void ()> onPreviousButtonClicked; - boost::signal<void ()> onNextButtonClicked; - boost::signal<void (const boost::gregorian::date&)> onCalendarClicked; - }; + boost::signal<void (RosterItem*)> onSelectedContactChanged; + boost::signal<void (const std::string&)> onReturnPressed; + boost::signal<void (const boost::gregorian::date&)> onScrollReachedTop; + boost::signal<void (const boost::gregorian::date&)> onScrollReachedBottom; + boost::signal<void ()> onPreviousButtonClicked; + boost::signal<void ()> onNextButtonClicked; + boost::signal<void (const boost::gregorian::date&)> onCalendarClicked; + }; } diff --git a/Swift/Controllers/UIInterfaces/HistoryWindowFactory.h b/Swift/Controllers/UIInterfaces/HistoryWindowFactory.h index 807fec5..ab4cf0d 100644 --- a/Swift/Controllers/UIInterfaces/HistoryWindowFactory.h +++ b/Swift/Controllers/UIInterfaces/HistoryWindowFactory.h @@ -9,10 +9,10 @@ #include <Swift/Controllers/UIInterfaces/HistoryWindow.h> namespace Swift { - class UIEventStream; - class HistoryWindowFactory { - public: - virtual ~HistoryWindowFactory() {} - virtual HistoryWindow* createHistoryWindow(UIEventStream* eventStream) = 0; - }; + class UIEventStream; + class HistoryWindowFactory { + public: + virtual ~HistoryWindowFactory() {} + virtual HistoryWindow* createHistoryWindow(UIEventStream* eventStream) = 0; + }; } diff --git a/Swift/Controllers/UIInterfaces/JoinMUCWindow.h b/Swift/Controllers/UIInterfaces/JoinMUCWindow.h index 62818c5..4d6cea1 100644 --- a/Swift/Controllers/UIInterfaces/JoinMUCWindow.h +++ b/Swift/Controllers/UIInterfaces/JoinMUCWindow.h @@ -13,14 +13,14 @@ #include <Swiften/JID/JID.h> namespace Swift { - class JoinMUCWindow { - public: - virtual ~JoinMUCWindow() {} + class JoinMUCWindow { + public: + virtual ~JoinMUCWindow() {} - virtual void setNick(const std::string& nick) = 0; - virtual void setMUC(const std::string& nick) = 0; - virtual void show() = 0; + virtual void setNick(const std::string& nick) = 0; + virtual void setMUC(const std::string& nick) = 0; + virtual void show() = 0; - boost::signal<void ()> onSearchMUC; - }; + boost::signal<void ()> onSearchMUC; + }; } diff --git a/Swift/Controllers/UIInterfaces/JoinMUCWindowFactory.h b/Swift/Controllers/UIInterfaces/JoinMUCWindowFactory.h index a711294..5e8b1d0 100644 --- a/Swift/Controllers/UIInterfaces/JoinMUCWindowFactory.h +++ b/Swift/Controllers/UIInterfaces/JoinMUCWindowFactory.h @@ -9,11 +9,11 @@ #include <Swift/Controllers/UIInterfaces/JoinMUCWindow.h> namespace Swift { - class UIEventStream; - class JoinMUCWindowFactory { - public: - virtual ~JoinMUCWindowFactory() {} + class UIEventStream; + class JoinMUCWindowFactory { + public: + virtual ~JoinMUCWindowFactory() {} - virtual JoinMUCWindow* createJoinMUCWindow(UIEventStream* uiEventStream) = 0; - }; + virtual JoinMUCWindow* createJoinMUCWindow(UIEventStream* uiEventStream) = 0; + }; } diff --git a/Swift/Controllers/UIInterfaces/LoginWindow.h b/Swift/Controllers/UIInterfaces/LoginWindow.h index 5a7e178..cedc549 100644 --- a/Swift/Controllers/UIInterfaces/LoginWindow.h +++ b/Swift/Controllers/UIInterfaces/LoginWindow.h @@ -16,27 +16,27 @@ #include <Swiften/TLS/CertificateWithKey.h> namespace Swift { - class MainWindow; - class LoginWindow { - public: - virtual ~LoginWindow() {} - virtual void selectUser(const std::string&) = 0; - virtual void morphInto(MainWindow *mainWindow) = 0; - virtual void loggedOut() = 0; - virtual void setShowNotificationToggle(bool) = 0; - virtual void setMessage(const std::string&) = 0; - virtual void setIsLoggingIn(bool loggingIn) = 0; - virtual void addAvailableAccount(const std::string& defaultJID, const std::string& defaultPassword, const std::string& defaultCertificate, const ClientOptions& options) = 0; - virtual void removeAvailableAccount(const std::string& jid) = 0; - /** The certificate is what is used for login, the certificatePath is used for remembering paths to populate the loginwindow with*/ - boost::signal<void (const std::string&, const std::string&, const std::string& /*CertificatePath*/, CertificateWithKey::ref /* clientCertificate */, const ClientOptions& /*options*/, bool /* remember password*/, bool /* login automatically */)> onLoginRequest; - virtual void setLoginAutomatically(bool loginAutomatically) = 0; - virtual void quit() = 0; - /** Blocking request whether a cert should be permanently trusted.*/ - virtual bool askUserToTrustCertificatePermanently(const std::string& message, const std::vector<Certificate::ref>& certificateChain) = 0; + class MainWindow; + class LoginWindow { + public: + virtual ~LoginWindow() {} + virtual void selectUser(const std::string&) = 0; + virtual void morphInto(MainWindow *mainWindow) = 0; + virtual void loggedOut() = 0; + virtual void setShowNotificationToggle(bool) = 0; + virtual void setMessage(const std::string&) = 0; + virtual void setIsLoggingIn(bool loggingIn) = 0; + virtual void addAvailableAccount(const std::string& defaultJID, const std::string& defaultPassword, const std::string& defaultCertificate, const ClientOptions& options) = 0; + virtual void removeAvailableAccount(const std::string& jid) = 0; + /** The certificate is what is used for login, the certificatePath is used for remembering paths to populate the loginwindow with*/ + boost::signal<void (const std::string&, const std::string&, const std::string& /*CertificatePath*/, CertificateWithKey::ref /* clientCertificate */, const ClientOptions& /*options*/, bool /* remember password*/, bool /* login automatically */)> onLoginRequest; + virtual void setLoginAutomatically(bool loginAutomatically) = 0; + virtual void quit() = 0; + /** Blocking request whether a cert should be permanently trusted.*/ + virtual bool askUserToTrustCertificatePermanently(const std::string& message, const std::vector<Certificate::ref>& certificateChain) = 0; - boost::signal<void ()> onCancelLoginRequest; - boost::signal<void ()> onQuitRequest; - boost::signal<void (const std::string&)> onPurgeSavedLoginRequest; - }; + boost::signal<void ()> onCancelLoginRequest; + boost::signal<void ()> onQuitRequest; + boost::signal<void (const std::string&)> onPurgeSavedLoginRequest; + }; } diff --git a/Swift/Controllers/UIInterfaces/LoginWindowFactory.h b/Swift/Controllers/UIInterfaces/LoginWindowFactory.h index c040833..485f975 100644 --- a/Swift/Controllers/UIInterfaces/LoginWindowFactory.h +++ b/Swift/Controllers/UIInterfaces/LoginWindowFactory.h @@ -10,20 +10,20 @@ namespace Swift { - class LoginWindow; - - class UIEventStream; - - class LoginWindowFactory { - public: - virtual ~LoginWindowFactory() {} - - /** - * Transfers ownership of result. - */ - virtual LoginWindow* createLoginWindow(UIEventStream* uiEventStream) = 0; - - }; + class LoginWindow; + + class UIEventStream; + + class LoginWindowFactory { + public: + virtual ~LoginWindowFactory() {} + + /** + * Transfers ownership of result. + */ + virtual LoginWindow* createLoginWindow(UIEventStream* uiEventStream) = 0; + + }; } #endif diff --git a/Swift/Controllers/UIInterfaces/MUCSearchWindow.h b/Swift/Controllers/UIInterfaces/MUCSearchWindow.h index 10c6b38..d6c0065 100644 --- a/Swift/Controllers/UIInterfaces/MUCSearchWindow.h +++ b/Swift/Controllers/UIInterfaces/MUCSearchWindow.h @@ -18,18 +18,18 @@ namespace Swift { - class MUCSearchWindow { - public: - virtual ~MUCSearchWindow() {} + class MUCSearchWindow { + public: + virtual ~MUCSearchWindow() {} - virtual void clearList() = 0; - virtual void addService(const MUCService& service) = 0; - virtual void addSavedServices(const std::list<JID>& services) = 0; - virtual void setSearchInProgress(bool searching) = 0; + virtual void clearList() = 0; + virtual void addService(const MUCService& service) = 0; + virtual void addSavedServices(const std::list<JID>& services) = 0; + virtual void setSearchInProgress(bool searching) = 0; - virtual void show() = 0; + virtual void show() = 0; - boost::signal<void (const JID&)> onSearchService; - boost::signal<void (const boost::optional<JID>&)> onFinished; - }; + boost::signal<void (const JID&)> onSearchService; + boost::signal<void (const boost::optional<JID>&)> onFinished; + }; } diff --git a/Swift/Controllers/UIInterfaces/MUCSearchWindowFactory.h b/Swift/Controllers/UIInterfaces/MUCSearchWindowFactory.h index 38492cd..6e26ac3 100644 --- a/Swift/Controllers/UIInterfaces/MUCSearchWindowFactory.h +++ b/Swift/Controllers/UIInterfaces/MUCSearchWindowFactory.h @@ -9,11 +9,11 @@ #include <Swift/Controllers/UIInterfaces/MUCSearchWindow.h> namespace Swift { - class UIEventStream; - class MUCSearchWindowFactory { - public: - virtual ~MUCSearchWindowFactory() {} + class UIEventStream; + class MUCSearchWindowFactory { + public: + virtual ~MUCSearchWindowFactory() {} - virtual MUCSearchWindow* createMUCSearchWindow() = 0; - }; + virtual MUCSearchWindow* createMUCSearchWindow() = 0; + }; } diff --git a/Swift/Controllers/UIInterfaces/MainWindow.h b/Swift/Controllers/UIInterfaces/MainWindow.h index aa8314d..d8bcb58 100644 --- a/Swift/Controllers/UIInterfaces/MainWindow.h +++ b/Swift/Controllers/UIInterfaces/MainWindow.h @@ -19,36 +19,36 @@ #include <Swift/Controllers/Roster/ContactRosterItem.h> namespace Swift { - class Roster; - - class MainWindow { - public: - MainWindow(bool candelete = true) : canDelete_(candelete) {} - virtual ~MainWindow() {} - - bool canDelete() const { - return canDelete_; - } - - virtual void setMyNick(const std::string& name) = 0; - virtual void setMyJID(const JID& jid) = 0; - virtual void setMyAvatarPath(const std::string& path) = 0; - virtual void setMyStatusText(const std::string& status) = 0; - virtual void setMyStatusType(StatusShow::Type type) = 0; - virtual void setMyContactRosterItem(boost::shared_ptr<ContactRosterItem> contact) = 0; - /** Must be able to cope with NULL to clear the roster */ - virtual void setRosterModel(Roster* roster) = 0; - virtual void setConnecting() = 0; - virtual void setBlockingCommandAvailable(bool isAvailable) = 0; - virtual void setAvailableAdHocCommands(const std::vector<DiscoItems::Item>& commands) = 0; - virtual void setStreamEncryptionStatus(bool tlsInPlaceAndValid) = 0; - virtual void openCertificateDialog(const std::vector<Certificate::ref>& chain) = 0; - - boost::signal<void (StatusShow::Type, const std::string&)> onChangeStatusRequest; - boost::signal<void ()> onSignOutRequest; - boost::signal<void ()> onShowCertificateRequest; - - private: - bool canDelete_; - }; + class Roster; + + class MainWindow { + public: + MainWindow(bool candelete = true) : canDelete_(candelete) {} + virtual ~MainWindow() {} + + bool canDelete() const { + return canDelete_; + } + + virtual void setMyNick(const std::string& name) = 0; + virtual void setMyJID(const JID& jid) = 0; + virtual void setMyAvatarPath(const std::string& path) = 0; + virtual void setMyStatusText(const std::string& status) = 0; + virtual void setMyStatusType(StatusShow::Type type) = 0; + virtual void setMyContactRosterItem(boost::shared_ptr<ContactRosterItem> contact) = 0; + /** Must be able to cope with NULL to clear the roster */ + virtual void setRosterModel(Roster* roster) = 0; + virtual void setConnecting() = 0; + virtual void setBlockingCommandAvailable(bool isAvailable) = 0; + virtual void setAvailableAdHocCommands(const std::vector<DiscoItems::Item>& commands) = 0; + virtual void setStreamEncryptionStatus(bool tlsInPlaceAndValid) = 0; + virtual void openCertificateDialog(const std::vector<Certificate::ref>& chain) = 0; + + boost::signal<void (StatusShow::Type, const std::string&)> onChangeStatusRequest; + boost::signal<void ()> onSignOutRequest; + boost::signal<void ()> onShowCertificateRequest; + + private: + bool canDelete_; + }; } diff --git a/Swift/Controllers/UIInterfaces/MainWindowFactory.h b/Swift/Controllers/UIInterfaces/MainWindowFactory.h index 5c24187..c0110cf 100644 --- a/Swift/Controllers/UIInterfaces/MainWindowFactory.h +++ b/Swift/Controllers/UIInterfaces/MainWindowFactory.h @@ -11,17 +11,17 @@ #include "Swift/Controllers/UIEvents/UIEventStream.h" namespace Swift { - class MainWindow; + class MainWindow; - class MainWindowFactory { - public: - virtual ~MainWindowFactory() {} - /** - * Transfers ownership of result. - */ - virtual MainWindow* createMainWindow(UIEventStream* eventStream) = 0; + class MainWindowFactory { + public: + virtual ~MainWindowFactory() {} + /** + * Transfers ownership of result. + */ + virtual MainWindow* createMainWindow(UIEventStream* eventStream) = 0; - }; + }; } #endif diff --git a/Swift/Controllers/UIInterfaces/ProfileWindow.h b/Swift/Controllers/UIInterfaces/ProfileWindow.h index f396499..8aa620c 100644 --- a/Swift/Controllers/UIInterfaces/ProfileWindow.h +++ b/Swift/Controllers/UIInterfaces/ProfileWindow.h @@ -12,24 +12,24 @@ #include <Swiften/Elements/VCard.h> namespace Swift { - class JID; + class JID; - class ProfileWindow { - public: - virtual ~ProfileWindow() {} + class ProfileWindow { + public: + virtual ~ProfileWindow() {} - virtual void setJID(const JID& jid) = 0; - virtual void setVCard(VCard::ref vcard) = 0; + 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 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; + virtual void show() = 0; + virtual void hide() = 0; - boost::signal<void (VCard::ref)> onVCardChangeRequest; - boost::signal<void (const JID&)> onWindowAboutToBeClosed; - }; + boost::signal<void (VCard::ref)> onVCardChangeRequest; + boost::signal<void (const JID&)> onWindowAboutToBeClosed; + }; } diff --git a/Swift/Controllers/UIInterfaces/ProfileWindowFactory.h b/Swift/Controllers/UIInterfaces/ProfileWindowFactory.h index 5137151..6c2c6e5 100644 --- a/Swift/Controllers/UIInterfaces/ProfileWindowFactory.h +++ b/Swift/Controllers/UIInterfaces/ProfileWindowFactory.h @@ -9,10 +9,10 @@ #include <Swift/Controllers/UIInterfaces/ProfileWindow.h> namespace Swift { - class ProfileWindowFactory { - public: - virtual ~ProfileWindowFactory() {} + class ProfileWindowFactory { + public: + virtual ~ProfileWindowFactory() {} - virtual ProfileWindow* createProfileWindow() = 0; - }; + virtual ProfileWindow* createProfileWindow() = 0; + }; } diff --git a/Swift/Controllers/UIInterfaces/UIFactory.h b/Swift/Controllers/UIInterfaces/UIFactory.h index dd9d0df..a0976dc 100644 --- a/Swift/Controllers/UIInterfaces/UIFactory.h +++ b/Swift/Controllers/UIInterfaces/UIFactory.h @@ -25,25 +25,25 @@ #include <Swift/Controllers/UIInterfaces/XMLConsoleWidgetFactory.h> namespace Swift { - class UIFactory : - public ChatListWindowFactory, - public ChatWindowFactory, - public HistoryWindowFactory, - public EventWindowFactory, - public LoginWindowFactory, - public MainWindowFactory, - public MUCSearchWindowFactory, - public XMLConsoleWidgetFactory, - public UserSearchWindowFactory, - public JoinMUCWindowFactory, - public ProfileWindowFactory, - public ContactEditWindowFactory, - public AdHocCommandWindowFactory, - public FileTransferListWidgetFactory, - public WhiteboardWindowFactory, - public HighlightEditorWindowFactory, - public BlockListEditorWidgetFactory { - public: - virtual ~UIFactory() {} - }; + class UIFactory : + public ChatListWindowFactory, + public ChatWindowFactory, + public HistoryWindowFactory, + public EventWindowFactory, + public LoginWindowFactory, + public MainWindowFactory, + public MUCSearchWindowFactory, + public XMLConsoleWidgetFactory, + public UserSearchWindowFactory, + public JoinMUCWindowFactory, + public ProfileWindowFactory, + public ContactEditWindowFactory, + public AdHocCommandWindowFactory, + public FileTransferListWidgetFactory, + public WhiteboardWindowFactory, + public HighlightEditorWindowFactory, + public BlockListEditorWidgetFactory { + public: + virtual ~UIFactory() {} + }; } diff --git a/Swift/Controllers/UIInterfaces/UserSearchWindow.h b/Swift/Controllers/UIInterfaces/UserSearchWindow.h index da33db3..4ddc29b 100644 --- a/Swift/Controllers/UIInterfaces/UserSearchWindow.h +++ b/Swift/Controllers/UIInterfaces/UserSearchWindow.h @@ -17,40 +17,40 @@ namespace Swift { - class UserSearchWindow { - public: - enum Type {AddContact, ChatToContact, InviteToChat}; - virtual ~UserSearchWindow() {} - - virtual void clear() = 0; - virtual void setResults(const std::vector<UserSearchResult>& results) = 0; - virtual void setResultsForm(const Form::ref results) = 0; - virtual void addSavedServices(const std::vector<JID>& services) = 0; - virtual void setSelectedService(const JID& service) = 0; - virtual void setServerSupportsSearch(bool support) = 0; - virtual void setSearchError(bool support) = 0; - virtual void setSearchFields(boost::shared_ptr<SearchPayload> fields) = 0; - virtual void setNameSuggestions(const std::vector<std::string>& suggestions) = 0; - virtual void prepopulateJIDAndName(const JID& jid, const std::string& name) = 0; - virtual void setContactSuggestions(const std::vector<Contact::ref>& suggestions) = 0; - virtual void setJIDs(const std::vector<JID>&) = 0; - virtual void setRoomJID(const JID& roomJID) = 0; - virtual std::string getReason() const = 0; - virtual std::vector<JID> getJIDs() const = 0; - virtual void setCanStartImpromptuChats(bool supportsImpromptu) = 0; - virtual void updateContacts(const std::vector<Contact::ref>& contacts) = 0; - virtual void addContacts(const std::vector<Contact::ref>& contacts) = 0; - virtual void setCanSupplyDescription(bool allowed) = 0; - virtual void setWarning(const boost::optional<std::string>& message) = 0; - - virtual void show() = 0; - - boost::signal<void (const JID&)> onFormRequested; - boost::signal<void (boost::shared_ptr<SearchPayload>, const JID&)> onSearchRequested; - boost::signal<void (const JID&)> onNameSuggestionRequested; - boost::signal<void (const std::string&)> onContactSuggestionsRequested; - boost::signal<void (const std::vector<JID>&)> onJIDUpdateRequested; - boost::signal<void (const std::vector<JID>&)> onJIDAddRequested; - boost::signal<void (const JID&)> onJIDEditFieldChanged; - }; + class UserSearchWindow { + public: + enum Type {AddContact, ChatToContact, InviteToChat}; + virtual ~UserSearchWindow() {} + + virtual void clear() = 0; + virtual void setResults(const std::vector<UserSearchResult>& results) = 0; + virtual void setResultsForm(const Form::ref results) = 0; + virtual void addSavedServices(const std::vector<JID>& services) = 0; + virtual void setSelectedService(const JID& service) = 0; + virtual void setServerSupportsSearch(bool support) = 0; + virtual void setSearchError(bool support) = 0; + virtual void setSearchFields(boost::shared_ptr<SearchPayload> fields) = 0; + virtual void setNameSuggestions(const std::vector<std::string>& suggestions) = 0; + virtual void prepopulateJIDAndName(const JID& jid, const std::string& name) = 0; + virtual void setContactSuggestions(const std::vector<Contact::ref>& suggestions) = 0; + virtual void setJIDs(const std::vector<JID>&) = 0; + virtual void setRoomJID(const JID& roomJID) = 0; + virtual std::string getReason() const = 0; + virtual std::vector<JID> getJIDs() const = 0; + virtual void setCanStartImpromptuChats(bool supportsImpromptu) = 0; + virtual void updateContacts(const std::vector<Contact::ref>& contacts) = 0; + virtual void addContacts(const std::vector<Contact::ref>& contacts) = 0; + virtual void setCanSupplyDescription(bool allowed) = 0; + virtual void setWarning(const boost::optional<std::string>& message) = 0; + + virtual void show() = 0; + + boost::signal<void (const JID&)> onFormRequested; + boost::signal<void (boost::shared_ptr<SearchPayload>, const JID&)> onSearchRequested; + boost::signal<void (const JID&)> onNameSuggestionRequested; + boost::signal<void (const std::string&)> onContactSuggestionsRequested; + boost::signal<void (const std::vector<JID>&)> onJIDUpdateRequested; + boost::signal<void (const std::vector<JID>&)> onJIDAddRequested; + boost::signal<void (const JID&)> onJIDEditFieldChanged; + }; } diff --git a/Swift/Controllers/UIInterfaces/UserSearchWindowFactory.h b/Swift/Controllers/UIInterfaces/UserSearchWindowFactory.h index 4eee510..d5d6135 100644 --- a/Swift/Controllers/UIInterfaces/UserSearchWindowFactory.h +++ b/Swift/Controllers/UIInterfaces/UserSearchWindowFactory.h @@ -11,11 +11,11 @@ #include <Swift/Controllers/UIInterfaces/UserSearchWindow.h> namespace Swift { - class UIEventStream; - class UserSearchWindowFactory { - public: - virtual ~UserSearchWindowFactory() {} + class UIEventStream; + class UserSearchWindowFactory { + public: + virtual ~UserSearchWindowFactory() {} - virtual UserSearchWindow* createUserSearchWindow(UserSearchWindow::Type type, UIEventStream* eventStream, const std::set<std::string>& groups) = 0; - }; + virtual UserSearchWindow* createUserSearchWindow(UserSearchWindow::Type type, UIEventStream* eventStream, const std::set<std::string>& groups) = 0; + }; } diff --git a/Swift/Controllers/UIInterfaces/WhiteboardWindow.h b/Swift/Controllers/UIInterfaces/WhiteboardWindow.h index 84aefde..f3b35db 100644 --- a/Swift/Controllers/UIInterfaces/WhiteboardWindow.h +++ b/Swift/Controllers/UIInterfaces/WhiteboardWindow.h @@ -17,16 +17,16 @@ #include <Swiften/Base/boost_bsignals.h> namespace Swift { - class WhiteboardSession; - class WhiteboardElement; + class WhiteboardSession; + class WhiteboardElement; - class WhiteboardWindow { - public: - virtual ~WhiteboardWindow() {} + class WhiteboardWindow { + public: + virtual ~WhiteboardWindow() {} - virtual void show() = 0; - virtual void setSession(boost::shared_ptr<WhiteboardSession> session) = 0; - virtual void activateWindow() = 0; - virtual void setName(const std::string& name) = 0; - }; + virtual void show() = 0; + virtual void setSession(boost::shared_ptr<WhiteboardSession> session) = 0; + virtual void activateWindow() = 0; + virtual void setName(const std::string& name) = 0; + }; } diff --git a/Swift/Controllers/UIInterfaces/WhiteboardWindowFactory.h b/Swift/Controllers/UIInterfaces/WhiteboardWindowFactory.h index 2be0f9c..163368b 100644 --- a/Swift/Controllers/UIInterfaces/WhiteboardWindowFactory.h +++ b/Swift/Controllers/UIInterfaces/WhiteboardWindowFactory.h @@ -7,13 +7,13 @@ #pragma once namespace Swift { - class WhiteboardSession; - class WhiteboardWindow; + class WhiteboardSession; + class WhiteboardWindow; - class WhiteboardWindowFactory { - public : - virtual ~WhiteboardWindowFactory() {} + class WhiteboardWindowFactory { + public : + virtual ~WhiteboardWindowFactory() {} - virtual WhiteboardWindow* createWhiteboardWindow(boost::shared_ptr<WhiteboardSession> whiteboardSession) = 0; - }; + virtual WhiteboardWindow* createWhiteboardWindow(boost::shared_ptr<WhiteboardSession> whiteboardSession) = 0; + }; } diff --git a/Swift/Controllers/UIInterfaces/XMLConsoleWidget.h b/Swift/Controllers/UIInterfaces/XMLConsoleWidget.h index 7e477a9..872b9de 100644 --- a/Swift/Controllers/UIInterfaces/XMLConsoleWidget.h +++ b/Swift/Controllers/UIInterfaces/XMLConsoleWidget.h @@ -9,14 +9,14 @@ #include <Swiften/Base/SafeByteArray.h> namespace Swift { - class XMLConsoleWidget { - public: - virtual ~XMLConsoleWidget(); + class XMLConsoleWidget { + public: + virtual ~XMLConsoleWidget(); - virtual void handleDataRead(const SafeByteArray& data) = 0; - virtual void handleDataWritten(const SafeByteArray& data) = 0; + virtual void handleDataRead(const SafeByteArray& data) = 0; + virtual void handleDataWritten(const SafeByteArray& data) = 0; - virtual void show() = 0; - virtual void activate() = 0; - }; + virtual void show() = 0; + virtual void activate() = 0; + }; } diff --git a/Swift/Controllers/UIInterfaces/XMLConsoleWidgetFactory.h b/Swift/Controllers/UIInterfaces/XMLConsoleWidgetFactory.h index 69b3e16..bbc055e 100644 --- a/Swift/Controllers/UIInterfaces/XMLConsoleWidgetFactory.h +++ b/Swift/Controllers/UIInterfaces/XMLConsoleWidgetFactory.h @@ -9,11 +9,11 @@ #include <Swift/Controllers/UIInterfaces/XMLConsoleWidget.h> namespace Swift { - class UIEventStream; - class XMLConsoleWidgetFactory { - public: - virtual ~XMLConsoleWidgetFactory() {} + class UIEventStream; + class XMLConsoleWidgetFactory { + public: + virtual ~XMLConsoleWidgetFactory() {} - virtual XMLConsoleWidget* createXMLConsoleWidget() = 0; - }; + virtual XMLConsoleWidget* createXMLConsoleWidget() = 0; + }; } diff --git a/Swift/Controllers/UnitTest/ChatMessageSummarizerTest.cpp b/Swift/Controllers/UnitTest/ChatMessageSummarizerTest.cpp index 118c502..59c57b9 100644 --- a/Swift/Controllers/UnitTest/ChatMessageSummarizerTest.cpp +++ b/Swift/Controllers/UnitTest/ChatMessageSummarizerTest.cpp @@ -13,109 +13,109 @@ using namespace Swift; using namespace std; class ChatMessageSummarizerTest : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(ChatMessageSummarizerTest); - CPPUNIT_TEST(testEmpty); - CPPUNIT_TEST(testCurrentNone); - CPPUNIT_TEST(testCurrentCount); - CPPUNIT_TEST(testCurrentCountOthersNone); - CPPUNIT_TEST(testCurrentCountOtherCount); - CPPUNIT_TEST(testCurrentNoneOtherCount); - CPPUNIT_TEST(testCurrentCountOthersCount); - CPPUNIT_TEST(testCurrentNoneOthersCount); - CPPUNIT_TEST(testCurrentCountSomeOthersCount); - CPPUNIT_TEST_SUITE_END(); + CPPUNIT_TEST_SUITE(ChatMessageSummarizerTest); + CPPUNIT_TEST(testEmpty); + CPPUNIT_TEST(testCurrentNone); + CPPUNIT_TEST(testCurrentCount); + CPPUNIT_TEST(testCurrentCountOthersNone); + CPPUNIT_TEST(testCurrentCountOtherCount); + CPPUNIT_TEST(testCurrentNoneOtherCount); + CPPUNIT_TEST(testCurrentCountOthersCount); + CPPUNIT_TEST(testCurrentNoneOthersCount); + CPPUNIT_TEST(testCurrentCountSomeOthersCount); + CPPUNIT_TEST_SUITE_END(); public: - ChatMessageSummarizerTest() {} - - void setUp() { - - } - - void testEmpty() { - string current(""); - vector<UnreadPair> unreads; - ChatMessageSummarizer summary; - CPPUNIT_ASSERT_EQUAL(current, summary.getSummary(current, unreads)); - } - - void testCurrentNone() { - string current("Bob"); - vector<UnreadPair> unreads; - unreads.push_back(UnreadPair("Bob", 0)); - ChatMessageSummarizer summary; - CPPUNIT_ASSERT_EQUAL(current, summary.getSummary(current, unreads)); - } - - void testCurrentCount() { - string current("Bob"); - vector<UnreadPair> unreads; - unreads.push_back(UnreadPair("Bob", 3)); - ChatMessageSummarizer summary; - CPPUNIT_ASSERT_EQUAL(string("Bob (3)"), summary.getSummary(current, unreads)); - } - - void testCurrentCountOthersNone() { - string current("Bob"); - vector<UnreadPair> unreads; - unreads.push_back(UnreadPair("Bert", 0)); - unreads.push_back(UnreadPair("Bob", 3)); - unreads.push_back(UnreadPair("Betty", 0)); - ChatMessageSummarizer summary; - CPPUNIT_ASSERT_EQUAL(string("Bob (3)"), summary.getSummary(current, unreads)); - } - - void testCurrentCountOtherCount() { - string current("Bob"); - vector<UnreadPair> unreads; - unreads.push_back(UnreadPair("Bert", 0)); - unreads.push_back(UnreadPair("Bob", 3)); - unreads.push_back(UnreadPair("Betty", 7)); - ChatMessageSummarizer summary; - CPPUNIT_ASSERT_EQUAL(string("Bob (3); Betty (7)"), summary.getSummary(current, unreads)); - } - - void testCurrentNoneOtherCount() { - string current("Bob"); - vector<UnreadPair> unreads; - unreads.push_back(UnreadPair("Bert", 0)); - unreads.push_back(UnreadPair("Bob", 0)); - unreads.push_back(UnreadPair("Betty", 7)); - ChatMessageSummarizer summary; - CPPUNIT_ASSERT_EQUAL(string("Bob; Betty (7)"), summary.getSummary(current, unreads)); - } - - void testCurrentNoneOthersCount() { - string current("Bob"); - vector<UnreadPair> unreads; - unreads.push_back(UnreadPair("Bert", 2)); - unreads.push_back(UnreadPair("Bob", 0)); - unreads.push_back(UnreadPair("Betty", 7)); - ChatMessageSummarizer summary; - CPPUNIT_ASSERT_EQUAL(string("Bob and 2 others (9)"), summary.getSummary(current, unreads)); - } - - void testCurrentCountOthersCount() { - string current("Bob"); - vector<UnreadPair> unreads; - unreads.push_back(UnreadPair("Bert", 2)); - unreads.push_back(UnreadPair("Bob", 11)); - unreads.push_back(UnreadPair("Betty", 7)); - ChatMessageSummarizer summary; - CPPUNIT_ASSERT_EQUAL(string("Bob (11) and 2 others (9)"), summary.getSummary(current, unreads)); - } - - void testCurrentCountSomeOthersCount() { - string current("Bob"); - vector<UnreadPair> unreads; - unreads.push_back(UnreadPair("Bert", 2)); - unreads.push_back(UnreadPair("Beverly", 0)); - unreads.push_back(UnreadPair("Bob", 11)); - unreads.push_back(UnreadPair("Beatrice", 0)); - unreads.push_back(UnreadPair("Betty", 7)); - ChatMessageSummarizer summary; - CPPUNIT_ASSERT_EQUAL(string("Bob (11) and 2 others (9)"), summary.getSummary(current, unreads)); - } + ChatMessageSummarizerTest() {} + + void setUp() { + + } + + void testEmpty() { + string current(""); + vector<UnreadPair> unreads; + ChatMessageSummarizer summary; + CPPUNIT_ASSERT_EQUAL(current, summary.getSummary(current, unreads)); + } + + void testCurrentNone() { + string current("Bob"); + vector<UnreadPair> unreads; + unreads.push_back(UnreadPair("Bob", 0)); + ChatMessageSummarizer summary; + CPPUNIT_ASSERT_EQUAL(current, summary.getSummary(current, unreads)); + } + + void testCurrentCount() { + string current("Bob"); + vector<UnreadPair> unreads; + unreads.push_back(UnreadPair("Bob", 3)); + ChatMessageSummarizer summary; + CPPUNIT_ASSERT_EQUAL(string("Bob (3)"), summary.getSummary(current, unreads)); + } + + void testCurrentCountOthersNone() { + string current("Bob"); + vector<UnreadPair> unreads; + unreads.push_back(UnreadPair("Bert", 0)); + unreads.push_back(UnreadPair("Bob", 3)); + unreads.push_back(UnreadPair("Betty", 0)); + ChatMessageSummarizer summary; + CPPUNIT_ASSERT_EQUAL(string("Bob (3)"), summary.getSummary(current, unreads)); + } + + void testCurrentCountOtherCount() { + string current("Bob"); + vector<UnreadPair> unreads; + unreads.push_back(UnreadPair("Bert", 0)); + unreads.push_back(UnreadPair("Bob", 3)); + unreads.push_back(UnreadPair("Betty", 7)); + ChatMessageSummarizer summary; + CPPUNIT_ASSERT_EQUAL(string("Bob (3); Betty (7)"), summary.getSummary(current, unreads)); + } + + void testCurrentNoneOtherCount() { + string current("Bob"); + vector<UnreadPair> unreads; + unreads.push_back(UnreadPair("Bert", 0)); + unreads.push_back(UnreadPair("Bob", 0)); + unreads.push_back(UnreadPair("Betty", 7)); + ChatMessageSummarizer summary; + CPPUNIT_ASSERT_EQUAL(string("Bob; Betty (7)"), summary.getSummary(current, unreads)); + } + + void testCurrentNoneOthersCount() { + string current("Bob"); + vector<UnreadPair> unreads; + unreads.push_back(UnreadPair("Bert", 2)); + unreads.push_back(UnreadPair("Bob", 0)); + unreads.push_back(UnreadPair("Betty", 7)); + ChatMessageSummarizer summary; + CPPUNIT_ASSERT_EQUAL(string("Bob and 2 others (9)"), summary.getSummary(current, unreads)); + } + + void testCurrentCountOthersCount() { + string current("Bob"); + vector<UnreadPair> unreads; + unreads.push_back(UnreadPair("Bert", 2)); + unreads.push_back(UnreadPair("Bob", 11)); + unreads.push_back(UnreadPair("Betty", 7)); + ChatMessageSummarizer summary; + CPPUNIT_ASSERT_EQUAL(string("Bob (11) and 2 others (9)"), summary.getSummary(current, unreads)); + } + + void testCurrentCountSomeOthersCount() { + string current("Bob"); + vector<UnreadPair> unreads; + unreads.push_back(UnreadPair("Bert", 2)); + unreads.push_back(UnreadPair("Beverly", 0)); + unreads.push_back(UnreadPair("Bob", 11)); + unreads.push_back(UnreadPair("Beatrice", 0)); + unreads.push_back(UnreadPair("Betty", 7)); + ChatMessageSummarizer summary; + CPPUNIT_ASSERT_EQUAL(string("Bob (11) and 2 others (9)"), summary.getSummary(current, unreads)); + } }; diff --git a/Swift/Controllers/UnitTest/ContactSuggesterTest.cpp b/Swift/Controllers/UnitTest/ContactSuggesterTest.cpp index 9b625fe..2bfca4b 100644 --- a/Swift/Controllers/UnitTest/ContactSuggesterTest.cpp +++ b/Swift/Controllers/UnitTest/ContactSuggesterTest.cpp @@ -18,111 +18,111 @@ using namespace Swift; class ContactSuggesterTest : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(ContactSuggesterTest); - CPPUNIT_TEST(equalityTest); - CPPUNIT_TEST(lexicographicalSortTest); - CPPUNIT_TEST(sortTest); - CPPUNIT_TEST_SUITE_END(); + CPPUNIT_TEST_SUITE(ContactSuggesterTest); + CPPUNIT_TEST(equalityTest); + CPPUNIT_TEST(lexicographicalSortTest); + CPPUNIT_TEST(sortTest); + CPPUNIT_TEST_SUITE_END(); public: - std::vector<std::string> wordList() { - const std::string words[] = { - "abc", - "ab", - "bc", - "d" - }; - - return std::vector<std::string>(words, words+sizeof(words)/sizeof(*words)); - } - - std::vector<StatusShow::Type> statusList() { - StatusShow::Type types[] = { - StatusShow::Online, - StatusShow::Away, - StatusShow::FFC, - StatusShow::XA, - StatusShow::DND, - StatusShow::None - }; - - return std::vector<StatusShow::Type>(types, types+sizeof(types)/sizeof(*types)); - } - - std::vector<Contact::ref> contactList() { - std::vector<Contact::ref> contacts; - std::vector<std::string> words = wordList(); - std::vector<StatusShow::Type> statuses = statusList(); - foreach (const std::string& name, words) { - foreach (const std::string& jid, words) { - foreach (const StatusShow::Type& status, statuses) { - contacts.push_back(boost::make_shared<Contact>(name, jid, status, "")); - } - } - } - return contacts; - } - - /* a = a */ - bool isReflexive(const boost::function<bool (const Contact::ref&, const Contact::ref&)>& comparitor) { - std::vector<Contact::ref> contacts = contactList(); - foreach (const Contact::ref& a, contacts) { - if (!comparitor(a, a)) { - return false; - } - } - return true; - } - - /* a = b -> b = a */ - bool isSymmetric(const boost::function<bool (const Contact::ref&, const Contact::ref&)>& comparitor) { - std::vector<Contact::ref> contacts = contactList(); - foreach (const Contact::ref& a, contacts) { - foreach (const Contact::ref& b, contacts) { - if (comparitor(a, b)) { - if (!comparitor(b, a)) { - return false; - } - } - } - } - return true; - } - - /* a = b && b = c -> a = c */ - bool isTransitive(const boost::function<bool (const Contact::ref&, const Contact::ref&)>& comparitor) { - std::vector<Contact::ref> contacts = contactList(); - foreach (const Contact::ref& a, contacts) { - foreach (const Contact::ref& b, contacts) { - foreach (const Contact::ref& c, contacts) { - if (comparitor(a, b) && comparitor(b, c)) { - if (!comparitor(a, c)) { - return false; - } - } - } - } - } - return true; - } - - void equalityTest() { - CPPUNIT_ASSERT(isReflexive(Contact::equalityPredicate)); - CPPUNIT_ASSERT(isSymmetric(Contact::equalityPredicate)); - CPPUNIT_ASSERT(isTransitive(Contact::equalityPredicate)); - } - - void lexicographicalSortTest() { - CPPUNIT_ASSERT(isTransitive(Contact::lexicographicalSortPredicate)); - } - - void sortTest() { - std::vector<std::string> words = wordList(); - foreach (const std::string& word, words) { - CPPUNIT_ASSERT(isTransitive(boost::bind(Contact::sortPredicate, _1, _2, word))); - } - } + std::vector<std::string> wordList() { + const std::string words[] = { + "abc", + "ab", + "bc", + "d" + }; + + return std::vector<std::string>(words, words+sizeof(words)/sizeof(*words)); + } + + std::vector<StatusShow::Type> statusList() { + StatusShow::Type types[] = { + StatusShow::Online, + StatusShow::Away, + StatusShow::FFC, + StatusShow::XA, + StatusShow::DND, + StatusShow::None + }; + + return std::vector<StatusShow::Type>(types, types+sizeof(types)/sizeof(*types)); + } + + std::vector<Contact::ref> contactList() { + std::vector<Contact::ref> contacts; + std::vector<std::string> words = wordList(); + std::vector<StatusShow::Type> statuses = statusList(); + foreach (const std::string& name, words) { + foreach (const std::string& jid, words) { + foreach (const StatusShow::Type& status, statuses) { + contacts.push_back(boost::make_shared<Contact>(name, jid, status, "")); + } + } + } + return contacts; + } + + /* a = a */ + bool isReflexive(const boost::function<bool (const Contact::ref&, const Contact::ref&)>& comparitor) { + std::vector<Contact::ref> contacts = contactList(); + foreach (const Contact::ref& a, contacts) { + if (!comparitor(a, a)) { + return false; + } + } + return true; + } + + /* a = b -> b = a */ + bool isSymmetric(const boost::function<bool (const Contact::ref&, const Contact::ref&)>& comparitor) { + std::vector<Contact::ref> contacts = contactList(); + foreach (const Contact::ref& a, contacts) { + foreach (const Contact::ref& b, contacts) { + if (comparitor(a, b)) { + if (!comparitor(b, a)) { + return false; + } + } + } + } + return true; + } + + /* a = b && b = c -> a = c */ + bool isTransitive(const boost::function<bool (const Contact::ref&, const Contact::ref&)>& comparitor) { + std::vector<Contact::ref> contacts = contactList(); + foreach (const Contact::ref& a, contacts) { + foreach (const Contact::ref& b, contacts) { + foreach (const Contact::ref& c, contacts) { + if (comparitor(a, b) && comparitor(b, c)) { + if (!comparitor(a, c)) { + return false; + } + } + } + } + } + return true; + } + + void equalityTest() { + CPPUNIT_ASSERT(isReflexive(Contact::equalityPredicate)); + CPPUNIT_ASSERT(isSymmetric(Contact::equalityPredicate)); + CPPUNIT_ASSERT(isTransitive(Contact::equalityPredicate)); + } + + void lexicographicalSortTest() { + CPPUNIT_ASSERT(isTransitive(Contact::lexicographicalSortPredicate)); + } + + void sortTest() { + std::vector<std::string> words = wordList(); + foreach (const std::string& word, words) { + CPPUNIT_ASSERT(isTransitive(boost::bind(Contact::sortPredicate, _1, _2, word))); + } + } }; diff --git a/Swift/Controllers/UnitTest/HighlightRuleTest.cpp b/Swift/Controllers/UnitTest/HighlightRuleTest.cpp index 62c403f..8d49d5d 100644 --- a/Swift/Controllers/UnitTest/HighlightRuleTest.cpp +++ b/Swift/Controllers/UnitTest/HighlightRuleTest.cpp @@ -21,304 +21,304 @@ 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); - } + 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; + void tearDown() { + delete emptyRule; - delete keywordRule; - delete keywordChatRule; - delete keywordNickChatRule; - delete nickChatRule; - delete nickRule; - - delete senderRule; - delete senderChatRule; - delete senderKeywordChatRule; - delete senderKeywordNickChatRule; + 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 senderKeywordNickWordChatRule; + delete senderKeywordNickCaseChatRule; + delete senderKeywordNickCaseWordChatRule; - delete senderKeywordNickMUCRule; - } + 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); + 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", "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("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("", "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("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("", "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("", "", "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); - } + 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); + 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("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("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("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("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); - } + 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); + 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("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", "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("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("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); - } + 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); + 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("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", "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("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); + 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); - } + // 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); + 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(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(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", "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", "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); - } + 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 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); + 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("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("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); - } + 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); + 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("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("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); - } + 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); + 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("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("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); - } + 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); + 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); - } + 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; + private: + HighlightRule* emptyRule; - HighlightRule* keywordRule; - HighlightRule* keywordChatRule; - HighlightRule* keywordNickChatRule; - HighlightRule* nickChatRule; - HighlightRule* nickRule; + HighlightRule* keywordRule; + HighlightRule* keywordChatRule; + HighlightRule* keywordNickChatRule; + HighlightRule* nickChatRule; + HighlightRule* nickRule; - HighlightRule* senderRule; - HighlightRule* senderChatRule; - HighlightRule* senderKeywordChatRule; - HighlightRule* senderKeywordNickChatRule; + HighlightRule* senderRule; + HighlightRule* senderChatRule; + HighlightRule* senderKeywordChatRule; + HighlightRule* senderKeywordNickChatRule; - HighlightRule* senderKeywordNickWordChatRule; - HighlightRule* senderKeywordNickCaseChatRule; - HighlightRule* senderKeywordNickCaseWordChatRule; + HighlightRule* senderKeywordNickWordChatRule; + HighlightRule* senderKeywordNickCaseChatRule; + HighlightRule* senderKeywordNickCaseWordChatRule; - HighlightRule* senderKeywordNickMUCRule; + HighlightRule* senderKeywordNickMUCRule; }; CPPUNIT_TEST_SUITE_REGISTRATION(HighlightRuleTest); diff --git a/Swift/Controllers/UnitTest/MockChatWindow.h b/Swift/Controllers/UnitTest/MockChatWindow.h index 20c51bc..b4588e7 100644 --- a/Swift/Controllers/UnitTest/MockChatWindow.h +++ b/Swift/Controllers/UnitTest/MockChatWindow.h @@ -13,103 +13,103 @@ #include <Swift/Controllers/UIInterfaces/ChatWindow.h> namespace Swift { - class MockChatWindow : public ChatWindow { - public: - MockChatWindow() : labelsEnabled_(false), impromptuMUCSupported_(false) {} - virtual ~MockChatWindow(); - - virtual std::string addMessage(const ChatMessage& message, const std::string& /*senderName*/, bool /*senderIsSelf*/, boost::shared_ptr<SecurityLabel> /*label*/, const std::string& /*avatarPath*/, const boost::posix_time::ptime& /*time*/) { - lastMessageBody_ = bodyFromMessage(message); - return "id"; - } - - virtual std::string addAction(const ChatMessage& /*message*/, const std::string& /*senderName*/, bool /*senderIsSelf*/, boost::shared_ptr<SecurityLabel> /*label*/, const std::string& /*avatarPath*/, const boost::posix_time::ptime& /*time*/) {return "id";} - - virtual std::string addSystemMessage(const ChatMessage& message, Direction /*direction*/) { - lastAddedSystemMessage_ = message; - return "id"; - } - - virtual void addPresenceMessage(const ChatMessage& message, Direction /*direction*/) { - lastAddedPresence_ = message; - } - - virtual void addErrorMessage(const ChatMessage& /*message*/) {} - virtual void replaceMessage(const ChatMessage& /*message*/, const std::string& /*id*/, const boost::posix_time::ptime& /*time*/) {} - virtual void replaceWithAction(const ChatMessage& /*message*/, const std::string& /*id*/, const boost::posix_time::ptime& /*time*/) {} - virtual void replaceLastMessage(const ChatMessage& message, const TimestampBehaviour /*timestampBehaviour*/) { - lastReplacedMessage_ = message; - } - virtual void replaceSystemMessage(const ChatMessage& /*message*/, const std::string& /*id*/, const TimestampBehaviour /*timestampBehaviour*/) {} - - // File transfer related stuff - virtual std::string addFileTransfer(const std::string& /*senderName*/, bool /*senderIsSelf*/,const std::string& /*filename*/, const boost::uintmax_t /*sizeInBytes*/, const std::string& /*description*/) { 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 bool isVisible() const { return true; } - 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(MUCType /*mucType*/) {} - virtual void setSecurityLabelsError() {} - virtual SecurityLabelsCatalog::Item getSelectedSecurityLabel() {return label_;} - virtual void setOnline(bool /*online*/) {} - virtual void setRosterModel(Roster* roster) { roster_ = roster; } - Roster* getRosterModel() { return roster_; } - virtual void setTabComplete(TabComplete*) {} - - void setAckState(const std::string& /*id*/, AckState /*state*/) {} - virtual void flash() {} - virtual AlertID addAlert(const std::string& /*alertText*/) { return 0; } - virtual void removeAlert(const AlertID /*id*/) {} - virtual void setCorrectionEnabled(Tristate /*enabled*/) {} - virtual void setFileTransferEnabled(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, bool = false, bool = false) {} - - 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 setBlockingState(BlockingState) {} - virtual void setCanInitiateImpromptuChats(bool supportsImpromptu) { - impromptuMUCSupported_ = supportsImpromptu; - } - - virtual void showBookmarkWindow(const MUCBookmark& /*bookmark*/) {} - virtual void setBookmarkState(RoomBookmarkState) {} - - static std::string bodyFromMessage(const ChatMessage& message) { - boost::shared_ptr<ChatTextMessagePart> text; - foreach (boost::shared_ptr<ChatMessagePart> part, message.getParts()) { - if ((text = boost::dynamic_pointer_cast<ChatTextMessagePart>(part))) { - return text->text; - } - } - return ""; - } - - std::string name_; - std::string lastMessageBody_; - ChatMessage lastAddedPresence_; - ChatMessage lastReplacedMessage_; - ChatMessage lastAddedSystemMessage_; - std::vector<SecurityLabelsCatalog::Item> labels_; - bool labelsEnabled_; - bool impromptuMUCSupported_; - SecurityLabelsCatalog::Item label_; - Roster* roster_; - }; + class MockChatWindow : public ChatWindow { + public: + MockChatWindow() : labelsEnabled_(false), impromptuMUCSupported_(false) {} + virtual ~MockChatWindow(); + + virtual std::string addMessage(const ChatMessage& message, const std::string& /*senderName*/, bool /*senderIsSelf*/, boost::shared_ptr<SecurityLabel> /*label*/, const std::string& /*avatarPath*/, const boost::posix_time::ptime& /*time*/) { + lastMessageBody_ = bodyFromMessage(message); + return "id"; + } + + virtual std::string addAction(const ChatMessage& /*message*/, const std::string& /*senderName*/, bool /*senderIsSelf*/, boost::shared_ptr<SecurityLabel> /*label*/, const std::string& /*avatarPath*/, const boost::posix_time::ptime& /*time*/) {return "id";} + + virtual std::string addSystemMessage(const ChatMessage& message, Direction /*direction*/) { + lastAddedSystemMessage_ = message; + return "id"; + } + + virtual void addPresenceMessage(const ChatMessage& message, Direction /*direction*/) { + lastAddedPresence_ = message; + } + + virtual void addErrorMessage(const ChatMessage& /*message*/) {} + virtual void replaceMessage(const ChatMessage& /*message*/, const std::string& /*id*/, const boost::posix_time::ptime& /*time*/) {} + virtual void replaceWithAction(const ChatMessage& /*message*/, const std::string& /*id*/, const boost::posix_time::ptime& /*time*/) {} + virtual void replaceLastMessage(const ChatMessage& message, const TimestampBehaviour /*timestampBehaviour*/) { + lastReplacedMessage_ = message; + } + virtual void replaceSystemMessage(const ChatMessage& /*message*/, const std::string& /*id*/, const TimestampBehaviour /*timestampBehaviour*/) {} + + // File transfer related stuff + virtual std::string addFileTransfer(const std::string& /*senderName*/, bool /*senderIsSelf*/,const std::string& /*filename*/, const boost::uintmax_t /*sizeInBytes*/, const std::string& /*description*/) { 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 bool isVisible() const { return true; } + 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(MUCType /*mucType*/) {} + virtual void setSecurityLabelsError() {} + virtual SecurityLabelsCatalog::Item getSelectedSecurityLabel() {return label_;} + virtual void setOnline(bool /*online*/) {} + virtual void setRosterModel(Roster* roster) { roster_ = roster; } + Roster* getRosterModel() { return roster_; } + virtual void setTabComplete(TabComplete*) {} + + void setAckState(const std::string& /*id*/, AckState /*state*/) {} + virtual void flash() {} + virtual AlertID addAlert(const std::string& /*alertText*/) { return 0; } + virtual void removeAlert(const AlertID /*id*/) {} + virtual void setCorrectionEnabled(Tristate /*enabled*/) {} + virtual void setFileTransferEnabled(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, bool = false, bool = false) {} + + 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 setBlockingState(BlockingState) {} + virtual void setCanInitiateImpromptuChats(bool supportsImpromptu) { + impromptuMUCSupported_ = supportsImpromptu; + } + + virtual void showBookmarkWindow(const MUCBookmark& /*bookmark*/) {} + virtual void setBookmarkState(RoomBookmarkState) {} + + static std::string bodyFromMessage(const ChatMessage& message) { + boost::shared_ptr<ChatTextMessagePart> text; + foreach (boost::shared_ptr<ChatMessagePart> part, message.getParts()) { + if ((text = boost::dynamic_pointer_cast<ChatTextMessagePart>(part))) { + return text->text; + } + } + return ""; + } + + std::string name_; + std::string lastMessageBody_; + ChatMessage lastAddedPresence_; + ChatMessage lastReplacedMessage_; + ChatMessage lastAddedSystemMessage_; + std::vector<SecurityLabelsCatalog::Item> labels_; + bool labelsEnabled_; + bool impromptuMUCSupported_; + SecurityLabelsCatalog::Item label_; + Roster* roster_; + }; } diff --git a/Swift/Controllers/UnitTest/MockMainWindow.h b/Swift/Controllers/UnitTest/MockMainWindow.h index af4267f..9177bdc 100644 --- a/Swift/Controllers/UnitTest/MockMainWindow.h +++ b/Swift/Controllers/UnitTest/MockMainWindow.h @@ -9,24 +9,24 @@ #include <Swift/Controllers/UIInterfaces/MainWindow.h> 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 setMyContactRosterItem(boost::shared_ptr<ContactRosterItem> /*contact*/) {} - 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*/) {} - virtual void setBlockingCommandAvailable(bool /*isAvailable*/) {} - Roster* roster; + 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 setMyContactRosterItem(boost::shared_ptr<ContactRosterItem> /*contact*/) {} + 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*/) {} + virtual void setBlockingCommandAvailable(bool /*isAvailable*/) {} + Roster* roster; - }; + }; } diff --git a/Swift/Controllers/UnitTest/MockMainWindowFactory.h b/Swift/Controllers/UnitTest/MockMainWindowFactory.h index 0298bf2..4af0c79 100644 --- a/Swift/Controllers/UnitTest/MockMainWindowFactory.h +++ b/Swift/Controllers/UnitTest/MockMainWindowFactory.h @@ -11,18 +11,18 @@ namespace Swift { - class MockMainWindowFactory : public MainWindowFactory { - public: - MockMainWindowFactory() : last(NULL) {} - - virtual ~MockMainWindowFactory() {} - - /** - * Transfers ownership of result. - */ - virtual MainWindow* createMainWindow(UIEventStream*) {last = new MockMainWindow();return last;} - MockMainWindow* last; - }; + class MockMainWindowFactory : public MainWindowFactory { + public: + MockMainWindowFactory() : last(NULL) {} + + virtual ~MockMainWindowFactory() {} + + /** + * Transfers ownership of result. + */ + virtual MainWindow* createMainWindow(UIEventStream*) {last = new MockMainWindow();return last;} + MockMainWindow* last; + }; } diff --git a/Swift/Controllers/UnitTest/PresenceNotifierTest.cpp b/Swift/Controllers/UnitTest/PresenceNotifierTest.cpp index 40530dc..e1284fd 100644 --- a/Swift/Controllers/UnitTest/PresenceNotifierTest.cpp +++ b/Swift/Controllers/UnitTest/PresenceNotifierTest.cpp @@ -26,297 +26,297 @@ using namespace Swift; class PresenceNotifierTest : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(PresenceNotifierTest); - CPPUNIT_TEST(testReceiveFirstPresenceCreatesAvailableNotification); - CPPUNIT_TEST(testReceiveSecondPresenceCreatesStatusChangeNotification); - CPPUNIT_TEST(testReceiveUnavailablePresenceAfterAvailablePresenceCreatesUnavailableNotification); - CPPUNIT_TEST(testReceiveUnavailablePresenceWithoutAvailableDoesNotCreateNotification); - CPPUNIT_TEST(testReceiveAvailablePresenceAfterUnavailableCreatesAvailableNotification); - CPPUNIT_TEST(testReceiveAvailablePresenceAfterReconnectCreatesAvailableNotification); - CPPUNIT_TEST(testReceiveAvailablePresenceFromMUCDoesNotCreateNotification); - CPPUNIT_TEST(testNotificationSubjectContainsNameForJIDInRoster); - CPPUNIT_TEST(testNotificationSubjectContainsJIDForJIDNotInRoster); - CPPUNIT_TEST(testNotificationSubjectContainsStatus); - CPPUNIT_TEST(testNotificationMessageContainsStatusMessage); - CPPUNIT_TEST(testNotificationPicture); - CPPUNIT_TEST(testNotificationActivationEmitsSignal); - CPPUNIT_TEST(testReceiveFirstPresenceWithQuietPeriodDoesNotNotify); - CPPUNIT_TEST(testReceiveFirstPresenceWithQuietPeriodDoesNotCountAsQuietPeriod); - CPPUNIT_TEST(testReceivePresenceDuringQuietPeriodDoesNotNotify); - CPPUNIT_TEST(testReceivePresenceDuringQuietPeriodResetsTimer); - CPPUNIT_TEST(testReceivePresenceAfterQuietPeriodNotifies); - CPPUNIT_TEST(testReceiveFirstPresenceAfterReconnectWithQuietPeriodDoesNotNotify); - CPPUNIT_TEST_SUITE_END(); - - public: - void setUp() { - stanzaChannel = new DummyStanzaChannel(); - notifier = new LoggingNotifier(); - mucRegistry = new MUCRegistry(); - user1 = JID("user1@bar.com/bla"); - user2 = JID("user2@foo.com/baz"); - avatarManager = new DummyAvatarManager(); - roster = new XMPPRosterImpl(); - nickResolver = new NickResolver(JID("foo@bar.com"), roster, NULL, mucRegistry); - presenceOracle = new PresenceOracle(stanzaChannel, roster); - timerFactory = new DummyTimerFactory(); - } - - void tearDown() { - delete timerFactory; - delete presenceOracle; - delete nickResolver; - delete roster; - delete avatarManager; - delete mucRegistry; - delete notifier; - delete stanzaChannel; - } - - void testReceiveFirstPresenceCreatesAvailableNotification() { - boost::shared_ptr<PresenceNotifier> testling = createNotifier(); - - sendPresence(user1, StatusShow::Online); - - CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size())); - CPPUNIT_ASSERT_EQUAL(Notifier::ContactAvailable, notifier->notifications[0].type); - } - - void testReceiveSecondPresenceCreatesStatusChangeNotification() { - boost::shared_ptr<PresenceNotifier> testling = createNotifier(); - sendPresence(user1, StatusShow::Away); - notifier->notifications.clear(); - - sendPresence(user1, StatusShow::Online); - - CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size())); - CPPUNIT_ASSERT_EQUAL(Notifier::ContactStatusChange, notifier->notifications[0].type); - } - - void testReceiveUnavailablePresenceAfterAvailablePresenceCreatesUnavailableNotification() { - boost::shared_ptr<PresenceNotifier> testling = createNotifier(); - sendPresence(user1, StatusShow::Away); - notifier->notifications.clear(); - - sendUnavailablePresence(user1); - - CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size())); - CPPUNIT_ASSERT_EQUAL(Notifier::ContactUnavailable, notifier->notifications[0].type); - } - - void testReceiveUnavailablePresenceWithoutAvailableDoesNotCreateNotification() { - boost::shared_ptr<PresenceNotifier> testling = createNotifier(); - - sendUnavailablePresence(user1); - - CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(notifier->notifications.size())); - } - - void testReceiveAvailablePresenceAfterUnavailableCreatesAvailableNotification() { - boost::shared_ptr<PresenceNotifier> testling = createNotifier(); - sendPresence(user1, StatusShow::Away); - sendUnavailablePresence(user1); - notifier->notifications.clear(); - - sendPresence(user1, StatusShow::Away); - - CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size())); - CPPUNIT_ASSERT_EQUAL(Notifier::ContactAvailable, notifier->notifications[0].type); - } - - void testReceiveAvailablePresenceAfterReconnectCreatesAvailableNotification() { - boost::shared_ptr<PresenceNotifier> testling = createNotifier(); - sendPresence(user1, StatusShow::Away); - stanzaChannel->setAvailable(false); - stanzaChannel->setAvailable(true); - notifier->notifications.clear(); - - sendPresence(user1, StatusShow::Away); - - CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size())); - CPPUNIT_ASSERT_EQUAL(Notifier::ContactAvailable, notifier->notifications[0].type); - } + CPPUNIT_TEST_SUITE(PresenceNotifierTest); + CPPUNIT_TEST(testReceiveFirstPresenceCreatesAvailableNotification); + CPPUNIT_TEST(testReceiveSecondPresenceCreatesStatusChangeNotification); + CPPUNIT_TEST(testReceiveUnavailablePresenceAfterAvailablePresenceCreatesUnavailableNotification); + CPPUNIT_TEST(testReceiveUnavailablePresenceWithoutAvailableDoesNotCreateNotification); + CPPUNIT_TEST(testReceiveAvailablePresenceAfterUnavailableCreatesAvailableNotification); + CPPUNIT_TEST(testReceiveAvailablePresenceAfterReconnectCreatesAvailableNotification); + CPPUNIT_TEST(testReceiveAvailablePresenceFromMUCDoesNotCreateNotification); + CPPUNIT_TEST(testNotificationSubjectContainsNameForJIDInRoster); + CPPUNIT_TEST(testNotificationSubjectContainsJIDForJIDNotInRoster); + CPPUNIT_TEST(testNotificationSubjectContainsStatus); + CPPUNIT_TEST(testNotificationMessageContainsStatusMessage); + CPPUNIT_TEST(testNotificationPicture); + CPPUNIT_TEST(testNotificationActivationEmitsSignal); + CPPUNIT_TEST(testReceiveFirstPresenceWithQuietPeriodDoesNotNotify); + CPPUNIT_TEST(testReceiveFirstPresenceWithQuietPeriodDoesNotCountAsQuietPeriod); + CPPUNIT_TEST(testReceivePresenceDuringQuietPeriodDoesNotNotify); + CPPUNIT_TEST(testReceivePresenceDuringQuietPeriodResetsTimer); + CPPUNIT_TEST(testReceivePresenceAfterQuietPeriodNotifies); + CPPUNIT_TEST(testReceiveFirstPresenceAfterReconnectWithQuietPeriodDoesNotNotify); + CPPUNIT_TEST_SUITE_END(); + + public: + void setUp() { + stanzaChannel = new DummyStanzaChannel(); + notifier = new LoggingNotifier(); + mucRegistry = new MUCRegistry(); + user1 = JID("user1@bar.com/bla"); + user2 = JID("user2@foo.com/baz"); + avatarManager = new DummyAvatarManager(); + roster = new XMPPRosterImpl(); + nickResolver = new NickResolver(JID("foo@bar.com"), roster, NULL, mucRegistry); + presenceOracle = new PresenceOracle(stanzaChannel, roster); + timerFactory = new DummyTimerFactory(); + } + + void tearDown() { + delete timerFactory; + delete presenceOracle; + delete nickResolver; + delete roster; + delete avatarManager; + delete mucRegistry; + delete notifier; + delete stanzaChannel; + } + + void testReceiveFirstPresenceCreatesAvailableNotification() { + boost::shared_ptr<PresenceNotifier> testling = createNotifier(); + + sendPresence(user1, StatusShow::Online); + + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size())); + CPPUNIT_ASSERT_EQUAL(Notifier::ContactAvailable, notifier->notifications[0].type); + } + + void testReceiveSecondPresenceCreatesStatusChangeNotification() { + boost::shared_ptr<PresenceNotifier> testling = createNotifier(); + sendPresence(user1, StatusShow::Away); + notifier->notifications.clear(); + + sendPresence(user1, StatusShow::Online); + + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size())); + CPPUNIT_ASSERT_EQUAL(Notifier::ContactStatusChange, notifier->notifications[0].type); + } + + void testReceiveUnavailablePresenceAfterAvailablePresenceCreatesUnavailableNotification() { + boost::shared_ptr<PresenceNotifier> testling = createNotifier(); + sendPresence(user1, StatusShow::Away); + notifier->notifications.clear(); + + sendUnavailablePresence(user1); + + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size())); + CPPUNIT_ASSERT_EQUAL(Notifier::ContactUnavailable, notifier->notifications[0].type); + } + + void testReceiveUnavailablePresenceWithoutAvailableDoesNotCreateNotification() { + boost::shared_ptr<PresenceNotifier> testling = createNotifier(); + + sendUnavailablePresence(user1); + + CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(notifier->notifications.size())); + } + + void testReceiveAvailablePresenceAfterUnavailableCreatesAvailableNotification() { + boost::shared_ptr<PresenceNotifier> testling = createNotifier(); + sendPresence(user1, StatusShow::Away); + sendUnavailablePresence(user1); + notifier->notifications.clear(); + + sendPresence(user1, StatusShow::Away); + + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size())); + CPPUNIT_ASSERT_EQUAL(Notifier::ContactAvailable, notifier->notifications[0].type); + } + + void testReceiveAvailablePresenceAfterReconnectCreatesAvailableNotification() { + boost::shared_ptr<PresenceNotifier> testling = createNotifier(); + sendPresence(user1, StatusShow::Away); + stanzaChannel->setAvailable(false); + stanzaChannel->setAvailable(true); + notifier->notifications.clear(); + + sendPresence(user1, StatusShow::Away); + + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size())); + CPPUNIT_ASSERT_EQUAL(Notifier::ContactAvailable, notifier->notifications[0].type); + } - void testReceiveAvailablePresenceFromMUCDoesNotCreateNotification() { - boost::shared_ptr<PresenceNotifier> testling = createNotifier(); - mucRegistry->addMUC(JID("teaparty@wonderland.lit")); + void testReceiveAvailablePresenceFromMUCDoesNotCreateNotification() { + boost::shared_ptr<PresenceNotifier> testling = createNotifier(); + mucRegistry->addMUC(JID("teaparty@wonderland.lit")); - sendPresence(JID("teaparty@wonderland.lit/Alice"), StatusShow::Away); + sendPresence(JID("teaparty@wonderland.lit/Alice"), StatusShow::Away); - CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(notifier->notifications.size())); - } + CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(notifier->notifications.size())); + } - void testNotificationPicture() { - boost::shared_ptr<PresenceNotifier> testling = createNotifier(); - avatarManager->avatars[user1] = createByteArray("abcdef"); + void testNotificationPicture() { + boost::shared_ptr<PresenceNotifier> testling = createNotifier(); + avatarManager->avatars[user1] = createByteArray("abcdef"); - sendPresence(user1, StatusShow::Online); + sendPresence(user1, StatusShow::Online); - CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size())); - CPPUNIT_ASSERT_EQUAL(boost::filesystem::path("/avatars/user1@bar.com/bla"), notifier->notifications[0].picture); - } + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size())); + CPPUNIT_ASSERT_EQUAL(boost::filesystem::path("/avatars/user1@bar.com/bla"), notifier->notifications[0].picture); + } - void testNotificationActivationEmitsSignal() { - boost::shared_ptr<PresenceNotifier> testling = createNotifier(); + void testNotificationActivationEmitsSignal() { + boost::shared_ptr<PresenceNotifier> testling = createNotifier(); - sendPresence(user1, StatusShow::Online); - CPPUNIT_ASSERT(notifier->notifications[0].callback); - notifier->notifications[0].callback(); + sendPresence(user1, StatusShow::Online); + CPPUNIT_ASSERT(notifier->notifications[0].callback); + notifier->notifications[0].callback(); - CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(activatedNotifications.size())); - CPPUNIT_ASSERT_EQUAL(user1, activatedNotifications[0]); - } + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(activatedNotifications.size())); + CPPUNIT_ASSERT_EQUAL(user1, activatedNotifications[0]); + } - void testNotificationSubjectContainsNameForJIDInRoster() { - boost::shared_ptr<PresenceNotifier> testling = createNotifier(); - roster->addContact(user1.toBare(), "User 1", std::vector<std::string>(), RosterItemPayload::Both); + void testNotificationSubjectContainsNameForJIDInRoster() { + boost::shared_ptr<PresenceNotifier> testling = createNotifier(); + roster->addContact(user1.toBare(), "User 1", std::vector<std::string>(), RosterItemPayload::Both); - sendPresence(user1, StatusShow::Online); + sendPresence(user1, StatusShow::Online); - CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size())); - std::string subject = notifier->notifications[0].subject; - CPPUNIT_ASSERT(subject.find("User 1") != std::string::npos); - } + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size())); + std::string subject = notifier->notifications[0].subject; + CPPUNIT_ASSERT(subject.find("User 1") != std::string::npos); + } - void testNotificationSubjectContainsJIDForJIDNotInRoster() { - boost::shared_ptr<PresenceNotifier> testling = createNotifier(); + void testNotificationSubjectContainsJIDForJIDNotInRoster() { + boost::shared_ptr<PresenceNotifier> testling = createNotifier(); - sendPresence(user1, StatusShow::Online); + sendPresence(user1, StatusShow::Online); - CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size())); - std::string subject = notifier->notifications[0].subject; - CPPUNIT_ASSERT(subject.find(user1.toBare().toString()) != std::string::npos); - } + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size())); + std::string subject = notifier->notifications[0].subject; + CPPUNIT_ASSERT(subject.find(user1.toBare().toString()) != std::string::npos); + } - void testNotificationSubjectContainsStatus() { - boost::shared_ptr<PresenceNotifier> testling = createNotifier(); + void testNotificationSubjectContainsStatus() { + boost::shared_ptr<PresenceNotifier> testling = createNotifier(); - sendPresence(user1, StatusShow::Away); + sendPresence(user1, StatusShow::Away); - CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size())); - std::string subject = notifier->notifications[0].subject; - CPPUNIT_ASSERT(subject.find("Away") != std::string::npos); - } + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size())); + std::string subject = notifier->notifications[0].subject; + CPPUNIT_ASSERT(subject.find("Away") != std::string::npos); + } - void testNotificationMessageContainsStatusMessage() { - boost::shared_ptr<PresenceNotifier> testling = createNotifier(); + void testNotificationMessageContainsStatusMessage() { + boost::shared_ptr<PresenceNotifier> testling = createNotifier(); - sendPresence(user1, StatusShow::Away); + sendPresence(user1, StatusShow::Away); - CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size())); - CPPUNIT_ASSERT(notifier->notifications[0].description.find("Status Message") != std::string::npos); - } + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size())); + CPPUNIT_ASSERT(notifier->notifications[0].description.find("Status Message") != std::string::npos); + } - void testReceiveFirstPresenceWithQuietPeriodDoesNotNotify() { - boost::shared_ptr<PresenceNotifier> testling = createNotifier(); - testling->setInitialQuietPeriodMS(10); + void testReceiveFirstPresenceWithQuietPeriodDoesNotNotify() { + boost::shared_ptr<PresenceNotifier> testling = createNotifier(); + testling->setInitialQuietPeriodMS(10); - sendPresence(user1, StatusShow::Online); + sendPresence(user1, StatusShow::Online); - CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(notifier->notifications.size())); - } + CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(notifier->notifications.size())); + } - void testReceivePresenceDuringQuietPeriodDoesNotNotify() { - boost::shared_ptr<PresenceNotifier> testling = createNotifier(); - testling->setInitialQuietPeriodMS(10); + void testReceivePresenceDuringQuietPeriodDoesNotNotify() { + boost::shared_ptr<PresenceNotifier> testling = createNotifier(); + testling->setInitialQuietPeriodMS(10); - sendPresence(user1, StatusShow::Online); - timerFactory->setTime(1); - sendPresence(user2, StatusShow::Away); + sendPresence(user1, StatusShow::Online); + timerFactory->setTime(1); + sendPresence(user2, StatusShow::Away); - CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(notifier->notifications.size())); - } + CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(notifier->notifications.size())); + } - void testReceivePresenceDuringQuietPeriodResetsTimer() { - boost::shared_ptr<PresenceNotifier> testling = createNotifier(); - testling->setInitialQuietPeriodMS(10); + void testReceivePresenceDuringQuietPeriodResetsTimer() { + boost::shared_ptr<PresenceNotifier> testling = createNotifier(); + testling->setInitialQuietPeriodMS(10); - sendPresence(user1, StatusShow::Online); - timerFactory->setTime(9); - sendPresence(user2, StatusShow::Away); - timerFactory->setTime(18); - sendPresence(user1, StatusShow::Away); + sendPresence(user1, StatusShow::Online); + timerFactory->setTime(9); + sendPresence(user2, StatusShow::Away); + timerFactory->setTime(18); + sendPresence(user1, StatusShow::Away); - CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(notifier->notifications.size())); - } + CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(notifier->notifications.size())); + } - void testReceivePresenceAfterQuietPeriodNotifies() { - boost::shared_ptr<PresenceNotifier> testling = createNotifier(); - testling->setInitialQuietPeriodMS(10); - - sendPresence(user1, StatusShow::Online); - timerFactory->setTime(11); - sendPresence(user2, StatusShow::Away); - - CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size())); - } - - void testReceiveFirstPresenceWithQuietPeriodDoesNotCountAsQuietPeriod() { - boost::shared_ptr<PresenceNotifier> testling = createNotifier(); - testling->setInitialQuietPeriodMS(10); - - timerFactory->setTime(11); - sendPresence(user1, StatusShow::Away); - - CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(notifier->notifications.size())); - } - - void testReceiveFirstPresenceAfterReconnectWithQuietPeriodDoesNotNotify() { - boost::shared_ptr<PresenceNotifier> testling = createNotifier(); - testling->setInitialQuietPeriodMS(10); - sendPresence(user1, StatusShow::Online); - timerFactory->setTime(15); - notifier->notifications.clear(); - - stanzaChannel->setAvailable(false); - stanzaChannel->setAvailable(true); - sendPresence(user1, StatusShow::Online); - timerFactory->setTime(21); - sendPresence(user2, StatusShow::Online); - - CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(notifier->notifications.size())); - } - - - private: - boost::shared_ptr<PresenceNotifier> createNotifier() { - boost::shared_ptr<PresenceNotifier> result(new PresenceNotifier(stanzaChannel, notifier, mucRegistry, avatarManager, nickResolver, presenceOracle, timerFactory)); - result->onNotificationActivated.connect(boost::bind(&PresenceNotifierTest::handleNotificationActivated, this, _1)); - result->setInitialQuietPeriodMS(0); - return result; - } - - void sendPresence(const JID& jid, StatusShow::Type type) { - boost::shared_ptr<Presence> presence(new Presence()); - presence->setFrom(jid); - presence->setShow(type); - presence->setStatus("Status Message"); - stanzaChannel->onPresenceReceived(presence); - } - - void sendUnavailablePresence(const JID& jid) { - boost::shared_ptr<Presence> presence(new Presence()); - presence->setType(Presence::Unavailable); - presence->setFrom(jid); - stanzaChannel->onPresenceReceived(presence); - } - - void handleNotificationActivated(const JID& j) { - activatedNotifications.push_back(j); - } - - private: - DummyStanzaChannel* stanzaChannel; - LoggingNotifier* notifier; - MUCRegistry* mucRegistry; - DummyAvatarManager* avatarManager; - XMPPRosterImpl* roster; - NickResolver* nickResolver; - PresenceOracle* presenceOracle; - DummyTimerFactory* timerFactory; - JID user1; - JID user2; - std::vector<JID> activatedNotifications; + void testReceivePresenceAfterQuietPeriodNotifies() { + boost::shared_ptr<PresenceNotifier> testling = createNotifier(); + testling->setInitialQuietPeriodMS(10); + + sendPresence(user1, StatusShow::Online); + timerFactory->setTime(11); + sendPresence(user2, StatusShow::Away); + + CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size())); + } + + void testReceiveFirstPresenceWithQuietPeriodDoesNotCountAsQuietPeriod() { + boost::shared_ptr<PresenceNotifier> testling = createNotifier(); + testling->setInitialQuietPeriodMS(10); + + timerFactory->setTime(11); + sendPresence(user1, StatusShow::Away); + + CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(notifier->notifications.size())); + } + + void testReceiveFirstPresenceAfterReconnectWithQuietPeriodDoesNotNotify() { + boost::shared_ptr<PresenceNotifier> testling = createNotifier(); + testling->setInitialQuietPeriodMS(10); + sendPresence(user1, StatusShow::Online); + timerFactory->setTime(15); + notifier->notifications.clear(); + + stanzaChannel->setAvailable(false); + stanzaChannel->setAvailable(true); + sendPresence(user1, StatusShow::Online); + timerFactory->setTime(21); + sendPresence(user2, StatusShow::Online); + + CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(notifier->notifications.size())); + } + + + private: + boost::shared_ptr<PresenceNotifier> createNotifier() { + boost::shared_ptr<PresenceNotifier> result(new PresenceNotifier(stanzaChannel, notifier, mucRegistry, avatarManager, nickResolver, presenceOracle, timerFactory)); + result->onNotificationActivated.connect(boost::bind(&PresenceNotifierTest::handleNotificationActivated, this, _1)); + result->setInitialQuietPeriodMS(0); + return result; + } + + void sendPresence(const JID& jid, StatusShow::Type type) { + boost::shared_ptr<Presence> presence(new Presence()); + presence->setFrom(jid); + presence->setShow(type); + presence->setStatus("Status Message"); + stanzaChannel->onPresenceReceived(presence); + } + + void sendUnavailablePresence(const JID& jid) { + boost::shared_ptr<Presence> presence(new Presence()); + presence->setType(Presence::Unavailable); + presence->setFrom(jid); + stanzaChannel->onPresenceReceived(presence); + } + + void handleNotificationActivated(const JID& j) { + activatedNotifications.push_back(j); + } + + private: + DummyStanzaChannel* stanzaChannel; + LoggingNotifier* notifier; + MUCRegistry* mucRegistry; + DummyAvatarManager* avatarManager; + XMPPRosterImpl* roster; + NickResolver* nickResolver; + PresenceOracle* presenceOracle; + DummyTimerFactory* timerFactory; + JID user1; + JID user2; + std::vector<JID> activatedNotifications; }; CPPUNIT_TEST_SUITE_REGISTRATION(PresenceNotifierTest); diff --git a/Swift/Controllers/UnitTest/PreviousStatusStoreTest.cpp b/Swift/Controllers/UnitTest/PreviousStatusStoreTest.cpp index 266cd64..be35468 100644 --- a/Swift/Controllers/UnitTest/PreviousStatusStoreTest.cpp +++ b/Swift/Controllers/UnitTest/PreviousStatusStoreTest.cpp @@ -12,33 +12,33 @@ using namespace Swift; class PreviousStatusStoreTest : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(PreviousStatusStoreTest); - CPPUNIT_TEST(testGetAll); - //CPPUNIT_TEST(testGetAllLimited); - //CPPUNIT_TEST(testGetSuggestionsInexact); - //CPPUNIT_TEST(testGetSuggestionsExact); - CPPUNIT_TEST_SUITE_END(); + CPPUNIT_TEST_SUITE(PreviousStatusStoreTest); + CPPUNIT_TEST(testGetAll); + //CPPUNIT_TEST(testGetAllLimited); + //CPPUNIT_TEST(testGetSuggestionsInexact); + //CPPUNIT_TEST(testGetSuggestionsExact); + CPPUNIT_TEST_SUITE_END(); public: - void setUp() { - store_ = new PreviousStatusStore(); - store_->addStatus(StatusShow::Online, "At home in the study"); - store_->addStatus(StatusShow::DND, "In a meeting"); - store_->addStatus(StatusShow::DND, "With a client"); - store_->addStatus(StatusShow::Away, "Walking the elephant"); - store_->addStatus(StatusShow::Online, "In the office, at my desk"); - } + void setUp() { + store_ = new PreviousStatusStore(); + store_->addStatus(StatusShow::Online, "At home in the study"); + store_->addStatus(StatusShow::DND, "In a meeting"); + store_->addStatus(StatusShow::DND, "With a client"); + store_->addStatus(StatusShow::Away, "Walking the elephant"); + store_->addStatus(StatusShow::Online, "In the office, at my desk"); + } - void tearDown() { - delete store_; - } + void tearDown() { + delete store_; + } - void testGetAll() { + void testGetAll() { - } + } private: - PreviousStatusStore* store_; + PreviousStatusStore* store_; }; CPPUNIT_TEST_SUITE_REGISTRATION(PreviousStatusStoreTest); diff --git a/Swift/Controllers/WhiteboardManager.cpp b/Swift/Controllers/WhiteboardManager.cpp index f62a94a..91f01c8 100644 --- a/Swift/Controllers/WhiteboardManager.cpp +++ b/Swift/Controllers/WhiteboardManager.cpp @@ -25,121 +25,121 @@ #include <Swift/Controllers/UIEvents/ShowWhiteboardUIEvent.h> namespace Swift { - typedef std::pair<JID, WhiteboardWindow*> JIDWhiteboardWindowPair; + typedef std::pair<JID, WhiteboardWindow*> JIDWhiteboardWindowPair; - WhiteboardManager::WhiteboardManager(WhiteboardWindowFactory* whiteboardWindowFactory, UIEventStream* uiEventStream, NickResolver* nickResolver, WhiteboardSessionManager* whiteboardSessionManager) : whiteboardWindowFactory_(whiteboardWindowFactory), uiEventStream_(uiEventStream), nickResolver_(nickResolver), whiteboardSessionManager_(whiteboardSessionManager) { + WhiteboardManager::WhiteboardManager(WhiteboardWindowFactory* whiteboardWindowFactory, UIEventStream* uiEventStream, NickResolver* nickResolver, WhiteboardSessionManager* whiteboardSessionManager) : whiteboardWindowFactory_(whiteboardWindowFactory), uiEventStream_(uiEventStream), nickResolver_(nickResolver), whiteboardSessionManager_(whiteboardSessionManager) { #ifdef SWIFT_EXPERIMENTAL_WB - whiteboardSessionManager_->onSessionRequest.connect(boost::bind(&WhiteboardManager::handleIncomingSession, this, _1)); + whiteboardSessionManager_->onSessionRequest.connect(boost::bind(&WhiteboardManager::handleIncomingSession, this, _1)); #endif - uiEventConnection_ = uiEventStream_->onUIEvent.connect(boost::bind(&WhiteboardManager::handleUIEvent, this, _1)); - } - - WhiteboardManager::~WhiteboardManager() { - foreach (JIDWhiteboardWindowPair whiteboardWindowPair, whiteboardWindows_) { - delete whiteboardWindowPair.second; - } - } - - WhiteboardWindow* WhiteboardManager::createNewWhiteboardWindow(const JID& contact, WhiteboardSession::ref session) { - WhiteboardWindow *window = whiteboardWindowFactory_->createWhiteboardWindow(session); - window->setName(nickResolver_->jidToNick(contact)); - whiteboardWindows_[contact.toBare()] = window; - return window; - } - - WhiteboardWindow* WhiteboardManager::findWhiteboardWindow(const JID& contact) { - if (whiteboardWindows_.find(contact.toBare()) == whiteboardWindows_.end()) { - return NULL; - } - return whiteboardWindows_[contact.toBare()]; - } - - void WhiteboardManager::handleUIEvent(boost::shared_ptr<UIEvent> event) { - boost::shared_ptr<RequestWhiteboardUIEvent> requestWhiteboardEvent = boost::dynamic_pointer_cast<RequestWhiteboardUIEvent>(event); - if (requestWhiteboardEvent) { - requestSession(requestWhiteboardEvent->getContact()); - } - boost::shared_ptr<AcceptWhiteboardSessionUIEvent> sessionAcceptEvent = boost::dynamic_pointer_cast<AcceptWhiteboardSessionUIEvent>(event); - if (sessionAcceptEvent) { - acceptSession(sessionAcceptEvent->getContact()); - } - boost::shared_ptr<CancelWhiteboardSessionUIEvent> sessionCancelEvent = boost::dynamic_pointer_cast<CancelWhiteboardSessionUIEvent>(event); - if (sessionCancelEvent) { - cancelSession(sessionCancelEvent->getContact()); - } - boost::shared_ptr<ShowWhiteboardUIEvent> showWindowEvent = boost::dynamic_pointer_cast<ShowWhiteboardUIEvent>(event); - if (showWindowEvent) { - WhiteboardWindow* window = findWhiteboardWindow(showWindowEvent->getContact()); - if (window != NULL) { - window->activateWindow(); - } - } - } - - void WhiteboardManager::acceptSession(const JID& from) { - IncomingWhiteboardSession::ref session = boost::dynamic_pointer_cast<IncomingWhiteboardSession>(whiteboardSessionManager_->getSession(from)); - WhiteboardWindow* window = findWhiteboardWindow(from); - if (session && window) { - session->accept(); - window->show(); - } - } - - void WhiteboardManager::requestSession(const JID& contact) { - WhiteboardSession::ref session = whiteboardSessionManager_->requestSession(contact); - session->onSessionTerminated.connect(boost::bind(&WhiteboardManager::handleSessionTerminate, this, _1)); - session->onRequestAccepted.connect(boost::bind(&WhiteboardManager::handleSessionAccept, this, _1)); - session->onRequestRejected.connect(boost::bind(&WhiteboardManager::handleRequestReject, this, _1)); - - WhiteboardWindow* window = findWhiteboardWindow(contact); - if (window == NULL) { - createNewWhiteboardWindow(contact, session); - } else { - window->setSession(session); - } - onSessionRequest(session->getTo(), true); - } - - void WhiteboardManager::cancelSession(const JID& from) { - WhiteboardSession::ref session = whiteboardSessionManager_->getSession(from); - if (session) { - session->cancel(); - } - } - - void WhiteboardManager::handleIncomingSession(IncomingWhiteboardSession::ref session) { - session->onSessionTerminated.connect(boost::bind(&WhiteboardManager::handleSessionTerminate, this, _1)); - session->onRequestAccepted.connect(boost::bind(&WhiteboardManager::handleSessionAccept, this, _1)); - - WhiteboardWindow* window = findWhiteboardWindow(session->getTo()); - if (window == NULL) { - createNewWhiteboardWindow(session->getTo(), session); - } else { - window->setSession(session); - } - - onSessionRequest(session->getTo(), false); - } - - void WhiteboardManager::handleSessionTerminate(const JID& contact) { - onSessionTerminate(contact); - } - - void WhiteboardManager::handleSessionCancel(const JID& contact) { - onSessionTerminate(contact); - } - - void WhiteboardManager::handleSessionAccept(const JID& contact) { - WhiteboardWindow* window = findWhiteboardWindow(contact); - if (window != NULL) { - window->show(); - } - onRequestAccepted(contact); - } - - void WhiteboardManager::handleRequestReject(const JID& contact) { - onRequestRejected(contact); - } + uiEventConnection_ = uiEventStream_->onUIEvent.connect(boost::bind(&WhiteboardManager::handleUIEvent, this, _1)); + } + + WhiteboardManager::~WhiteboardManager() { + foreach (JIDWhiteboardWindowPair whiteboardWindowPair, whiteboardWindows_) { + delete whiteboardWindowPair.second; + } + } + + WhiteboardWindow* WhiteboardManager::createNewWhiteboardWindow(const JID& contact, WhiteboardSession::ref session) { + WhiteboardWindow *window = whiteboardWindowFactory_->createWhiteboardWindow(session); + window->setName(nickResolver_->jidToNick(contact)); + whiteboardWindows_[contact.toBare()] = window; + return window; + } + + WhiteboardWindow* WhiteboardManager::findWhiteboardWindow(const JID& contact) { + if (whiteboardWindows_.find(contact.toBare()) == whiteboardWindows_.end()) { + return NULL; + } + return whiteboardWindows_[contact.toBare()]; + } + + void WhiteboardManager::handleUIEvent(boost::shared_ptr<UIEvent> event) { + boost::shared_ptr<RequestWhiteboardUIEvent> requestWhiteboardEvent = boost::dynamic_pointer_cast<RequestWhiteboardUIEvent>(event); + if (requestWhiteboardEvent) { + requestSession(requestWhiteboardEvent->getContact()); + } + boost::shared_ptr<AcceptWhiteboardSessionUIEvent> sessionAcceptEvent = boost::dynamic_pointer_cast<AcceptWhiteboardSessionUIEvent>(event); + if (sessionAcceptEvent) { + acceptSession(sessionAcceptEvent->getContact()); + } + boost::shared_ptr<CancelWhiteboardSessionUIEvent> sessionCancelEvent = boost::dynamic_pointer_cast<CancelWhiteboardSessionUIEvent>(event); + if (sessionCancelEvent) { + cancelSession(sessionCancelEvent->getContact()); + } + boost::shared_ptr<ShowWhiteboardUIEvent> showWindowEvent = boost::dynamic_pointer_cast<ShowWhiteboardUIEvent>(event); + if (showWindowEvent) { + WhiteboardWindow* window = findWhiteboardWindow(showWindowEvent->getContact()); + if (window != NULL) { + window->activateWindow(); + } + } + } + + void WhiteboardManager::acceptSession(const JID& from) { + IncomingWhiteboardSession::ref session = boost::dynamic_pointer_cast<IncomingWhiteboardSession>(whiteboardSessionManager_->getSession(from)); + WhiteboardWindow* window = findWhiteboardWindow(from); + if (session && window) { + session->accept(); + window->show(); + } + } + + void WhiteboardManager::requestSession(const JID& contact) { + WhiteboardSession::ref session = whiteboardSessionManager_->requestSession(contact); + session->onSessionTerminated.connect(boost::bind(&WhiteboardManager::handleSessionTerminate, this, _1)); + session->onRequestAccepted.connect(boost::bind(&WhiteboardManager::handleSessionAccept, this, _1)); + session->onRequestRejected.connect(boost::bind(&WhiteboardManager::handleRequestReject, this, _1)); + + WhiteboardWindow* window = findWhiteboardWindow(contact); + if (window == NULL) { + createNewWhiteboardWindow(contact, session); + } else { + window->setSession(session); + } + onSessionRequest(session->getTo(), true); + } + + void WhiteboardManager::cancelSession(const JID& from) { + WhiteboardSession::ref session = whiteboardSessionManager_->getSession(from); + if (session) { + session->cancel(); + } + } + + void WhiteboardManager::handleIncomingSession(IncomingWhiteboardSession::ref session) { + session->onSessionTerminated.connect(boost::bind(&WhiteboardManager::handleSessionTerminate, this, _1)); + session->onRequestAccepted.connect(boost::bind(&WhiteboardManager::handleSessionAccept, this, _1)); + + WhiteboardWindow* window = findWhiteboardWindow(session->getTo()); + if (window == NULL) { + createNewWhiteboardWindow(session->getTo(), session); + } else { + window->setSession(session); + } + + onSessionRequest(session->getTo(), false); + } + + void WhiteboardManager::handleSessionTerminate(const JID& contact) { + onSessionTerminate(contact); + } + + void WhiteboardManager::handleSessionCancel(const JID& contact) { + onSessionTerminate(contact); + } + + void WhiteboardManager::handleSessionAccept(const JID& contact) { + WhiteboardWindow* window = findWhiteboardWindow(contact); + if (window != NULL) { + window->show(); + } + onRequestAccepted(contact); + } + + void WhiteboardManager::handleRequestReject(const JID& contact) { + onRequestRejected(contact); + } } diff --git a/Swift/Controllers/WhiteboardManager.h b/Swift/Controllers/WhiteboardManager.h index 863dd60..35ed9bd 100644 --- a/Swift/Controllers/WhiteboardManager.h +++ b/Swift/Controllers/WhiteboardManager.h @@ -26,40 +26,40 @@ #include <Swift/Controllers/UIInterfaces/WhiteboardWindowFactory.h> namespace Swift { - class WhiteboardSessionManager; - class NickResolver; + class WhiteboardSessionManager; + class NickResolver; - class WhiteboardManager { - public: - WhiteboardManager(WhiteboardWindowFactory* whiteboardWindowFactory, UIEventStream* uiEventStream, NickResolver* nickResolver, WhiteboardSessionManager* whiteboardSessionManager); - ~WhiteboardManager(); + class WhiteboardManager { + public: + WhiteboardManager(WhiteboardWindowFactory* whiteboardWindowFactory, UIEventStream* uiEventStream, NickResolver* nickResolver, WhiteboardSessionManager* whiteboardSessionManager); + ~WhiteboardManager(); - WhiteboardWindow* createNewWhiteboardWindow(const JID& contact, WhiteboardSession::ref session); + WhiteboardWindow* createNewWhiteboardWindow(const JID& contact, WhiteboardSession::ref session); - public: - boost::signal< void (const JID&, bool senderIsSelf)> onSessionRequest; - boost::signal< void (const JID&)> onSessionTerminate; - boost::signal< void (const JID&)> onRequestAccepted; - boost::signal< void (const JID&)> onRequestRejected; + public: + boost::signal< void (const JID&, bool senderIsSelf)> onSessionRequest; + boost::signal< void (const JID&)> onSessionTerminate; + boost::signal< void (const JID&)> onRequestAccepted; + boost::signal< void (const JID&)> onRequestRejected; - private: - void handleUIEvent(boost::shared_ptr<UIEvent> event); - void handleSessionTerminate(const JID& contact); - void handleSessionCancel(const JID& contact); - void handleSessionAccept(const JID& contact); - void handleRequestReject(const JID& contact); - void handleIncomingSession(IncomingWhiteboardSession::ref session); - void acceptSession(const JID& from); - void requestSession(const JID& contact); - void cancelSession(const JID& from); - WhiteboardWindow* findWhiteboardWindow(const JID& contact); + private: + void handleUIEvent(boost::shared_ptr<UIEvent> event); + void handleSessionTerminate(const JID& contact); + void handleSessionCancel(const JID& contact); + void handleSessionAccept(const JID& contact); + void handleRequestReject(const JID& contact); + void handleIncomingSession(IncomingWhiteboardSession::ref session); + void acceptSession(const JID& from); + void requestSession(const JID& contact); + void cancelSession(const JID& from); + WhiteboardWindow* findWhiteboardWindow(const JID& contact); - private: - std::map<JID, WhiteboardWindow*> whiteboardWindows_; - WhiteboardWindowFactory* whiteboardWindowFactory_; - UIEventStream* uiEventStream_; - NickResolver* nickResolver_; - boost::bsignals::scoped_connection uiEventConnection_; - WhiteboardSessionManager* whiteboardSessionManager_; - }; + private: + std::map<JID, WhiteboardWindow*> whiteboardWindows_; + WhiteboardWindowFactory* whiteboardWindowFactory_; + UIEventStream* uiEventStream_; + NickResolver* nickResolver_; + boost::bsignals::scoped_connection uiEventConnection_; + WhiteboardSessionManager* whiteboardSessionManager_; + }; } diff --git a/Swift/Controllers/XMLConsoleController.cpp b/Swift/Controllers/XMLConsoleController.cpp index 22be4f6..175a4eb 100644 --- a/Swift/Controllers/XMLConsoleController.cpp +++ b/Swift/Controllers/XMLConsoleController.cpp @@ -12,34 +12,34 @@ namespace Swift { XMLConsoleController::XMLConsoleController(UIEventStream* uiEventStream, XMLConsoleWidgetFactory* xmlConsoleWidgetFactory) : xmlConsoleWidgetFactory(xmlConsoleWidgetFactory), xmlConsoleWidget(NULL) { - uiEventStream->onUIEvent.connect(boost::bind(&XMLConsoleController::handleUIEvent, this, _1)); + uiEventStream->onUIEvent.connect(boost::bind(&XMLConsoleController::handleUIEvent, this, _1)); } XMLConsoleController::~XMLConsoleController() { - delete xmlConsoleWidget; + delete xmlConsoleWidget; } void XMLConsoleController::handleUIEvent(boost::shared_ptr<UIEvent> rawEvent) { - boost::shared_ptr<RequestXMLConsoleUIEvent> event = boost::dynamic_pointer_cast<RequestXMLConsoleUIEvent>(rawEvent); - if (event != NULL) { - if (xmlConsoleWidget == NULL) { - xmlConsoleWidget = xmlConsoleWidgetFactory->createXMLConsoleWidget(); - } - xmlConsoleWidget->show(); - xmlConsoleWidget->activate(); - } + boost::shared_ptr<RequestXMLConsoleUIEvent> event = boost::dynamic_pointer_cast<RequestXMLConsoleUIEvent>(rawEvent); + if (event != NULL) { + if (xmlConsoleWidget == NULL) { + xmlConsoleWidget = xmlConsoleWidgetFactory->createXMLConsoleWidget(); + } + xmlConsoleWidget->show(); + xmlConsoleWidget->activate(); + } } void XMLConsoleController::handleDataRead(const SafeByteArray& data) { - if (xmlConsoleWidget) { - xmlConsoleWidget->handleDataRead(data); - } + if (xmlConsoleWidget) { + xmlConsoleWidget->handleDataRead(data); + } } void XMLConsoleController::handleDataWritten(const SafeByteArray& data) { - if (xmlConsoleWidget) { - xmlConsoleWidget->handleDataWritten(data); - } + if (xmlConsoleWidget) { + xmlConsoleWidget->handleDataWritten(data); + } } } diff --git a/Swift/Controllers/XMLConsoleController.h b/Swift/Controllers/XMLConsoleController.h index bd4d256..eac27d3 100644 --- a/Swift/Controllers/XMLConsoleController.h +++ b/Swift/Controllers/XMLConsoleController.h @@ -15,24 +15,24 @@ #include <Swift/Controllers/UIEvents/UIEventStream.h> namespace Swift { - - class XMLConsoleWidgetFactory; - class XMLConsoleWidget; - - class XMLConsoleController { - public: - XMLConsoleController(UIEventStream* uiEventStream, XMLConsoleWidgetFactory* xmlConsoleWidgetFactory); - ~XMLConsoleController(); - - public: - void handleDataRead(const SafeByteArray& data); - void handleDataWritten(const SafeByteArray& data); - - private: - void handleUIEvent(boost::shared_ptr<UIEvent> event); - - private: - XMLConsoleWidgetFactory* xmlConsoleWidgetFactory; - XMLConsoleWidget* xmlConsoleWidget; - }; + + class XMLConsoleWidgetFactory; + class XMLConsoleWidget; + + class XMLConsoleController { + public: + XMLConsoleController(UIEventStream* uiEventStream, XMLConsoleWidgetFactory* xmlConsoleWidgetFactory); + ~XMLConsoleController(); + + public: + void handleDataRead(const SafeByteArray& data); + void handleDataWritten(const SafeByteArray& data); + + private: + void handleUIEvent(boost::shared_ptr<UIEvent> event); + + private: + XMLConsoleWidgetFactory* xmlConsoleWidgetFactory; + XMLConsoleWidget* xmlConsoleWidget; + }; } diff --git a/Swift/Controllers/XMPPEvents/ErrorEvent.h b/Swift/Controllers/XMPPEvents/ErrorEvent.h index 0b18dfc..959f210 100644 --- a/Swift/Controllers/XMPPEvents/ErrorEvent.h +++ b/Swift/Controllers/XMPPEvents/ErrorEvent.h @@ -17,16 +17,16 @@ #include <Swift/Controllers/XMPPEvents/StanzaEvent.h> 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_;} - - private: - JID jid_; - std::string text_; - }; + 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_;} + + private: + JID jid_; + std::string text_; + }; } diff --git a/Swift/Controllers/XMPPEvents/EventController.cpp b/Swift/Controllers/XMPPEvents/EventController.cpp index bbe7356..4c6b3bc 100644 --- a/Swift/Controllers/XMPPEvents/EventController.cpp +++ b/Swift/Controllers/XMPPEvents/EventController.cpp @@ -25,56 +25,56 @@ EventController::EventController() { } EventController::~EventController() { - foreach(boost::shared_ptr<StanzaEvent> event, events_) { - event->onConclusion.disconnect(boost::bind(&EventController::handleEventConcluded, this, event)); - } + foreach(boost::shared_ptr<StanzaEvent> event, events_) { + event->onConclusion.disconnect(boost::bind(&EventController::handleEventConcluded, this, event)); + } } void EventController::handleIncomingEvent(boost::shared_ptr<StanzaEvent> sourceEvent) { - boost::shared_ptr<MessageEvent> messageEvent = boost::dynamic_pointer_cast<MessageEvent>(sourceEvent); - boost::shared_ptr<SubscriptionRequestEvent> subscriptionEvent = boost::dynamic_pointer_cast<SubscriptionRequestEvent>(sourceEvent); - boost::shared_ptr<ErrorEvent> errorEvent = boost::dynamic_pointer_cast<ErrorEvent>(sourceEvent); - boost::shared_ptr<MUCInviteEvent> mucInviteEvent = boost::dynamic_pointer_cast<MUCInviteEvent>(sourceEvent); - boost::shared_ptr<IncomingFileTransferEvent> incomingFileTransferEvent = boost::dynamic_pointer_cast<IncomingFileTransferEvent>(sourceEvent); + boost::shared_ptr<MessageEvent> messageEvent = boost::dynamic_pointer_cast<MessageEvent>(sourceEvent); + boost::shared_ptr<SubscriptionRequestEvent> subscriptionEvent = boost::dynamic_pointer_cast<SubscriptionRequestEvent>(sourceEvent); + boost::shared_ptr<ErrorEvent> errorEvent = boost::dynamic_pointer_cast<ErrorEvent>(sourceEvent); + boost::shared_ptr<MUCInviteEvent> mucInviteEvent = boost::dynamic_pointer_cast<MUCInviteEvent>(sourceEvent); + boost::shared_ptr<IncomingFileTransferEvent> incomingFileTransferEvent = boost::dynamic_pointer_cast<IncomingFileTransferEvent>(sourceEvent); - /* If it's a duplicate subscription request, remove the previous request first */ - if (subscriptionEvent) { - EventList existingEvents(events_); - foreach(boost::shared_ptr<StanzaEvent> existingEvent, existingEvents) { - boost::shared_ptr<SubscriptionRequestEvent> existingSubscriptionEvent = boost::dynamic_pointer_cast<SubscriptionRequestEvent>(existingEvent); - if (existingSubscriptionEvent) { - if (existingSubscriptionEvent->getJID() == subscriptionEvent->getJID()) { - existingEvent->conclude(); - } - } - } - } + /* If it's a duplicate subscription request, remove the previous request first */ + if (subscriptionEvent) { + EventList existingEvents(events_); + foreach(boost::shared_ptr<StanzaEvent> existingEvent, existingEvents) { + boost::shared_ptr<SubscriptionRequestEvent> existingSubscriptionEvent = boost::dynamic_pointer_cast<SubscriptionRequestEvent>(existingEvent); + if (existingSubscriptionEvent) { + if (existingSubscriptionEvent->getJID() == subscriptionEvent->getJID()) { + existingEvent->conclude(); + } + } + } + } - if ((messageEvent && messageEvent->isReadable()) || subscriptionEvent || errorEvent || mucInviteEvent || incomingFileTransferEvent) { - events_.push_back(sourceEvent); - sourceEvent->onConclusion.connect(boost::bind(&EventController::handleEventConcluded, this, sourceEvent)); - onEventQueueLengthChange(boost::numeric_cast<int>(events_.size())); - onEventQueueEventAdded(sourceEvent); - if (sourceEvent->getConcluded()) { - handleEventConcluded(sourceEvent); - } - } + if ((messageEvent && messageEvent->isReadable()) || subscriptionEvent || errorEvent || mucInviteEvent || incomingFileTransferEvent) { + events_.push_back(sourceEvent); + sourceEvent->onConclusion.connect(boost::bind(&EventController::handleEventConcluded, this, sourceEvent)); + onEventQueueLengthChange(boost::numeric_cast<int>(events_.size())); + onEventQueueEventAdded(sourceEvent); + if (sourceEvent->getConcluded()) { + handleEventConcluded(sourceEvent); + } + } } 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(boost::numeric_cast<int>(events_.size())); + event->onConclusion.disconnect(boost::bind(&EventController::handleEventConcluded, this, event)); + events_.erase(std::remove(events_.begin(), events_.end(), event), events_.end()); + onEventQueueLengthChange(boost::numeric_cast<int>(events_.size())); } void EventController::disconnectAll() { - onEventQueueLengthChange.disconnect_all_slots(); - onEventQueueEventAdded.disconnect_all_slots(); + onEventQueueLengthChange.disconnect_all_slots(); + onEventQueueEventAdded.disconnect_all_slots(); } void EventController::clear() { - events_.clear(); - onEventQueueLengthChange(0); + events_.clear(); + onEventQueueLengthChange(0); } } diff --git a/Swift/Controllers/XMPPEvents/EventController.h b/Swift/Controllers/XMPPEvents/EventController.h index 35938ac..3081449 100644 --- a/Swift/Controllers/XMPPEvents/EventController.h +++ b/Swift/Controllers/XMPPEvents/EventController.h @@ -16,21 +16,21 @@ #include <Swift/Controllers/XMPPEvents/StanzaEvent.h> namespace Swift { - typedef std::vector<boost::shared_ptr<StanzaEvent> > EventList; - class EventController { - public: - EventController(); - ~EventController(); - - void handleIncomingEvent(boost::shared_ptr<StanzaEvent> sourceEvent); - boost::signal<void (int)> onEventQueueLengthChange; - boost::signal<void (boost::shared_ptr<StanzaEvent>)> onEventQueueEventAdded; - const EventList& getEvents() const {return events_;} - void disconnectAll(); - void clear(); - - private: - void handleEventConcluded(boost::shared_ptr<StanzaEvent> event); - EventList events_; - }; + typedef std::vector<boost::shared_ptr<StanzaEvent> > EventList; + class EventController { + public: + EventController(); + ~EventController(); + + void handleIncomingEvent(boost::shared_ptr<StanzaEvent> sourceEvent); + boost::signal<void (int)> onEventQueueLengthChange; + boost::signal<void (boost::shared_ptr<StanzaEvent>)> onEventQueueEventAdded; + const EventList& getEvents() const {return events_;} + void disconnectAll(); + void clear(); + + private: + void handleEventConcluded(boost::shared_ptr<StanzaEvent> event); + EventList events_; + }; } diff --git a/Swift/Controllers/XMPPEvents/IncomingFileTransferEvent.h b/Swift/Controllers/XMPPEvents/IncomingFileTransferEvent.h index 24af640..4c128e8 100644 --- a/Swift/Controllers/XMPPEvents/IncomingFileTransferEvent.h +++ b/Swift/Controllers/XMPPEvents/IncomingFileTransferEvent.h @@ -13,18 +13,18 @@ #include <Swift/Controllers/XMPPEvents/StanzaEvent.h> namespace Swift { - class IncomingFileTransferEvent : public StanzaEvent { - public: - typedef boost::shared_ptr<IncomingFileTransferEvent> ref; + class IncomingFileTransferEvent : public StanzaEvent { + public: + typedef boost::shared_ptr<IncomingFileTransferEvent> ref; - IncomingFileTransferEvent(const JID& sender) : sender_(sender) {} + IncomingFileTransferEvent(const JID& sender) : sender_(sender) {} - const JID& getSender() const { - return sender_; - } + const JID& getSender() const { + return sender_; + } - private: - JID sender_; - }; + private: + JID sender_; + }; } diff --git a/Swift/Controllers/XMPPEvents/MUCInviteEvent.h b/Swift/Controllers/XMPPEvents/MUCInviteEvent.h index 1ae9891..7d333fb 100644 --- a/Swift/Controllers/XMPPEvents/MUCInviteEvent.h +++ b/Swift/Controllers/XMPPEvents/MUCInviteEvent.h @@ -22,26 +22,26 @@ namespace Swift { - class MUCInviteEvent : public StanzaEvent { - public: - typedef boost::shared_ptr<MUCInviteEvent> ref; - - public: - MUCInviteEvent(const JID& inviter, const JID& roomJID, const std::string& reason, const std::string& password, bool direct, bool impromptu) : inviter_(inviter), roomJID_(roomJID), reason_(reason), password_(password), direct_(direct), impromptu_(impromptu) {} - - const JID& getInviter() const { return inviter_; } - const JID& getRoomJID() const { return roomJID_; } - const std::string& getReason() const { return reason_; } - const std::string& getPassword() const { return password_; } - bool getDirect() const { return direct_; } - bool getImpromptu() const { return impromptu_; } - - private: - JID inviter_; - JID roomJID_; - std::string reason_; - std::string password_; - bool direct_; - bool impromptu_; - }; + class MUCInviteEvent : public StanzaEvent { + public: + typedef boost::shared_ptr<MUCInviteEvent> ref; + + public: + MUCInviteEvent(const JID& inviter, const JID& roomJID, const std::string& reason, const std::string& password, bool direct, bool impromptu) : inviter_(inviter), roomJID_(roomJID), reason_(reason), password_(password), direct_(direct), impromptu_(impromptu) {} + + const JID& getInviter() const { return inviter_; } + const JID& getRoomJID() const { return roomJID_; } + const std::string& getReason() const { return reason_; } + const std::string& getPassword() const { return password_; } + bool getDirect() const { return direct_; } + bool getImpromptu() const { return impromptu_; } + + private: + JID inviter_; + JID roomJID_; + std::string reason_; + std::string password_; + bool direct_; + bool impromptu_; + }; } diff --git a/Swift/Controllers/XMPPEvents/MessageEvent.h b/Swift/Controllers/XMPPEvents/MessageEvent.h index b5b1215..4ec0406 100644 --- a/Swift/Controllers/XMPPEvents/MessageEvent.h +++ b/Swift/Controllers/XMPPEvents/MessageEvent.h @@ -4,7 +4,7 @@ * See the COPYING file for more information. */ -#pragma once +#pragma once #include <cassert> @@ -15,34 +15,34 @@ #include <Swift/Controllers/XMPPEvents/StanzaEvent.h> namespace Swift { - class MessageEvent : public StanzaEvent { - public: - typedef boost::shared_ptr<MessageEvent> ref; + class MessageEvent : public StanzaEvent { + 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_;} + boost::shared_ptr<Message> getStanza() {return stanza_;} - bool isReadable() { - return getStanza()->isError() || !getStanza()->getBody().get_value_or("").empty(); - } + bool isReadable() { + return getStanza()->isError() || !getStanza()->getBody().get_value_or("").empty(); + } - void read() { - assert (isReadable()); - conclude(); - } + void read() { + assert (isReadable()); + conclude(); + } - void setTargetsMe(bool targetsMe) { - targetsMe_ = targetsMe; - } + void setTargetsMe(bool targetsMe) { + targetsMe_ = targetsMe; + } - bool targetsMe() const { - return targetsMe_; - } + bool targetsMe() const { + return targetsMe_; + } - private: - boost::shared_ptr<Message> stanza_; - bool targetsMe_; - }; + private: + boost::shared_ptr<Message> stanza_; + bool targetsMe_; + }; } diff --git a/Swift/Controllers/XMPPEvents/StanzaEvent.h b/Swift/Controllers/XMPPEvents/StanzaEvent.h index e8d5eb9..fe97e23 100644 --- a/Swift/Controllers/XMPPEvents/StanzaEvent.h +++ b/Swift/Controllers/XMPPEvents/StanzaEvent.h @@ -12,18 +12,18 @@ #include <Swiften/Base/boost_bsignals.h> namespace Swift { - class StanzaEvent { - public: - 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_;} - boost::posix_time::ptime getTime() {return time_;} - private: - bool concluded_; - boost::posix_time::ptime time_; - }; + class StanzaEvent { + public: + 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_;} + boost::posix_time::ptime getTime() {return time_;} + private: + bool concluded_; + boost::posix_time::ptime time_; + }; } diff --git a/Swift/Controllers/XMPPEvents/SubscriptionRequestEvent.h b/Swift/Controllers/XMPPEvents/SubscriptionRequestEvent.h index a22399b..92922e9 100644 --- a/Swift/Controllers/XMPPEvents/SubscriptionRequestEvent.h +++ b/Swift/Controllers/XMPPEvents/SubscriptionRequestEvent.h @@ -17,31 +17,31 @@ #include <Swift/Controllers/XMPPEvents/StanzaEvent.h> 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_;} - boost::signal<void()> onAccept; - boost::signal<void()> onDecline; - void accept() { - onAccept(); - conclude(); - } - - void decline() { - onDecline(); - conclude(); - } - - void defer() { - conclude(); - } - - private: - JID jid_; - std::string reason_; - }; + 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_;} + boost::signal<void()> onAccept; + boost::signal<void()> onDecline; + void accept() { + onAccept(); + conclude(); + } + + void decline() { + onDecline(); + conclude(); + } + + void defer() { + conclude(); + } + + private: + JID jid_; + std::string reason_; + }; } diff --git a/Swift/Controllers/XMPPURIController.cpp b/Swift/Controllers/XMPPURIController.cpp index 3deb2d8..57c0ca4 100644 --- a/Swift/Controllers/XMPPURIController.cpp +++ b/Swift/Controllers/XMPPURIController.cpp @@ -19,21 +19,21 @@ using namespace Swift; XMPPURIController::XMPPURIController(URIHandler* uriHandler, UIEventStream* uiEventStream) : uriHandler(uriHandler), uiEventStream(uiEventStream) { - uriHandler->onURI.connect(boost::bind(&XMPPURIController::handleURI, this, _1)); + uriHandler->onURI.connect(boost::bind(&XMPPURIController::handleURI, this, _1)); } XMPPURIController::~XMPPURIController() { - uriHandler->onURI.disconnect(boost::bind(&XMPPURIController::handleURI, this, _1)); + uriHandler->onURI.disconnect(boost::bind(&XMPPURIController::handleURI, this, _1)); } void XMPPURIController::handleURI(const std::string& s) { - XMPPURI uri = XMPPURI::fromString(s); - if (!uri.isNull()) { - if (uri.getQueryType() == "join") { - uiEventStream->send(boost::make_shared<RequestJoinMUCUIEvent>(uri.getPath())); - } - else { - uiEventStream->send(boost::make_shared<RequestChatUIEvent>(uri.getPath())); - } - } + XMPPURI uri = XMPPURI::fromString(s); + if (!uri.isNull()) { + if (uri.getQueryType() == "join") { + uiEventStream->send(boost::make_shared<RequestJoinMUCUIEvent>(uri.getPath())); + } + else { + uiEventStream->send(boost::make_shared<RequestChatUIEvent>(uri.getPath())); + } + } } diff --git a/Swift/Controllers/XMPPURIController.h b/Swift/Controllers/XMPPURIController.h index 4938ad7..4d2fb5c 100644 --- a/Swift/Controllers/XMPPURIController.h +++ b/Swift/Controllers/XMPPURIController.h @@ -11,23 +11,23 @@ #include <Swiften/Base/boost_bsignals.h> namespace Swift { - class URIHandler; - class JID; - class UIEventStream; + class URIHandler; + class JID; + class UIEventStream; - class XMPPURIController { - public: - XMPPURIController(URIHandler* uriHandler, UIEventStream* uiEventStream); - ~XMPPURIController(); + class XMPPURIController { + public: + XMPPURIController(URIHandler* uriHandler, UIEventStream* uiEventStream); + ~XMPPURIController(); - boost::signal<void (const JID&)> onStartChat; - boost::signal<void (const JID&)> onJoinMUC; + boost::signal<void (const JID&)> onStartChat; + boost::signal<void (const JID&)> onJoinMUC; - private: - void handleURI(const std::string&); + private: + void handleURI(const std::string&); - private: - URIHandler* uriHandler; - UIEventStream* uiEventStream; - }; + private: + URIHandler* uriHandler; + UIEventStream* uiEventStream; + }; } |