summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swift/Controllers/Chat')
-rw-r--r--Swift/Controllers/Chat/ChatsManager.cpp21
1 files changed, 21 insertions, 0 deletions
diff --git a/Swift/Controllers/Chat/ChatsManager.cpp b/Swift/Controllers/Chat/ChatsManager.cpp
index 232d903..b9e2cf4 100644
--- a/Swift/Controllers/Chat/ChatsManager.cpp
+++ b/Swift/Controllers/Chat/ChatsManager.cpp
@@ -1,91 +1,93 @@
/*
* Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/Controllers/Chat/ChatsManager.h>
#include <memory>
#include <boost/algorithm/string.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/bind.hpp>
#include <boost/serialization/map.hpp>
#include <boost/serialization/optional.hpp>
#include <boost/serialization/split_free.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/vector.hpp>
#include <Swiften/Avatars/AvatarManager.h>
#include <Swiften/Base/Log.h>
#include <Swiften/Client/ClientBlockListManager.h>
#include <Swiften/Client/NickResolver.h>
#include <Swiften/Client/StanzaChannel.h>
#include <Swiften/Disco/DiscoServiceWalker.h>
+#include <Swiften/Disco/FeatureOracle.h>
#include <Swiften/Elements/CarbonsReceived.h>
#include <Swiften/Elements/CarbonsSent.h>
#include <Swiften/Elements/ChatState.h>
#include <Swiften/Elements/DeliveryReceipt.h>
#include <Swiften/Elements/DeliveryReceiptRequest.h>
#include <Swiften/Elements/Forwarded.h>
#include <Swiften/Elements/MUCInvitationPayload.h>
#include <Swiften/Elements/MUCUserPayload.h>
#include <Swiften/MUC/MUCBookmarkManager.h>
#include <Swiften/MUC/MUCManager.h>
#include <Swiften/Presence/PresenceSender.h>
#include <Swiften/Roster/XMPPRoster.h>
#include <Swiften/StringCodecs/Base64.h>
#include <Swiften/VCards/VCardManager.h>
#include <Swift/Controllers/Chat/AutoAcceptMUCInviteDecider.h>
#include <Swift/Controllers/Chat/ChatController.h>
#include <Swift/Controllers/Chat/ChatControllerBase.h>
#include <Swift/Controllers/Chat/ChatMessageParser.h>
#include <Swift/Controllers/Chat/MUCController.h>
#include <Swift/Controllers/Chat/MUCSearchController.h>
#include <Swift/Controllers/Chat/UserSearchController.h>
#include <Swift/Controllers/FileTransfer/FileTransferController.h>
#include <Swift/Controllers/FileTransfer/FileTransferOverview.h>
#include <Swift/Controllers/ProfileSettingsProvider.h>
#include <Swift/Controllers/SettingConstants.h>
#include <Swift/Controllers/Settings/SettingsProvider.h>
#include <Swift/Controllers/UIEvents/AddMUCBookmarkUIEvent.h>
#include <Swift/Controllers/UIEvents/CreateImpromptuMUCUIEvent.h>
#include <Swift/Controllers/UIEvents/EditMUCBookmarkUIEvent.h>
#include <Swift/Controllers/UIEvents/InviteToMUCUIEvent.h>
#include <Swift/Controllers/UIEvents/JoinMUCUIEvent.h>
#include <Swift/Controllers/UIEvents/RemoveMUCBookmarkUIEvent.h>
#include <Swift/Controllers/UIEvents/RequestChatUIEvent.h>
#include <Swift/Controllers/UIEvents/RequestJoinMUCUIEvent.h>
+#include <Swift/Controllers/UIEvents/SendFileUIEvent.h>
#include <Swift/Controllers/UIInterfaces/ChatListWindowFactory.h>
#include <Swift/Controllers/UIInterfaces/JoinMUCWindow.h>
#include <Swift/Controllers/UIInterfaces/JoinMUCWindowFactory.h>
#include <Swift/Controllers/WhiteboardManager.h>
#include <Swift/Controllers/XMPPEvents/EventController.h>
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;
@@ -172,60 +174,61 @@ ChatsManager::ChatsManager(
joinMUCWindow_ = nullptr;
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));
+ ftOverview_->onNewFileTransferController.disconnect(boost::bind(&ChatsManager::handleNewFileTransferController, this, _1));
delete joinMUCWindow_;
for (JIDChatControllerPair controllerPair : chatControllers_) {
delete controllerPair.second;
}
for (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_) {
for (ChatListWindow::Chat& chat : recentsLimited) {
chat.activity = "";
}
}
class RemoveRecent {
public:
static bool ifPrivateMessage(const ChatListWindow::Chat& chat) {
return chat.isPrivateMessage;
}
@@ -535,60 +538,78 @@ void ChatsManager::finalizeImpromptuJoin(MUC::ref muc, const std::vector<JID>& j
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);
}
for (const JID& jid : missingJIDsToInvite) {
muc->invitePerson(jid, reason, true);
}
}
void ChatsManager::handleUIEvent(std::shared_ptr<UIEvent> event) {
std::shared_ptr<RequestChatUIEvent> chatEvent = std::dynamic_pointer_cast<RequestChatUIEvent>(event);
if (chatEvent) {
handleChatRequest(chatEvent->getContact());
return;
}
std::shared_ptr<RemoveMUCBookmarkUIEvent> removeMUCBookmarkEvent = std::dynamic_pointer_cast<RemoveMUCBookmarkUIEvent>(event);
if (removeMUCBookmarkEvent) {
mucBookmarkManager_->removeBookmark(removeMUCBookmarkEvent->getBookmark());
return;
}
std::shared_ptr<AddMUCBookmarkUIEvent> addMUCBookmarkEvent = std::dynamic_pointer_cast<AddMUCBookmarkUIEvent>(event);
if (addMUCBookmarkEvent) {
mucBookmarkManager_->addBookmark(addMUCBookmarkEvent->getBookmark());
return;
}
+ std::shared_ptr<SendFileUIEvent> sendFileEvent = std::dynamic_pointer_cast<SendFileUIEvent>(event);
+ if (sendFileEvent) {
+ JID fileReceiver = sendFileEvent->getJID();
+ if (fileReceiver.isBare()) {
+ // See if there is a chat controller for a conversation with a bound
+ // full JID. Check if this JID supports file transfer and use it instead
+ // of the bare JID.
+ ChatController* controller = getChatControllerIfExists(fileReceiver, false);
+ if (controller) {
+ JID controllerJID = controller->getToJID();
+ if (!controllerJID.isBare() && (FeatureOracle(entityCapsProvider_, presenceOracle_).isFileTransferSupported(controllerJID) == Yes)) {
+ fileReceiver = controllerJID;
+ }
+ }
+ }
+ ftOverview_->sendFile(fileReceiver, sendFileEvent->getFilename());
+ return;
+ }
std::shared_ptr<CreateImpromptuMUCUIEvent> createImpromptuMUCEvent = std::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();
}
std::shared_ptr<EditMUCBookmarkUIEvent> editMUCBookmarkEvent = std::dynamic_pointer_cast<EditMUCBookmarkUIEvent>(event);
if (editMUCBookmarkEvent) {
mucBookmarkManager_->replaceBookmark(editMUCBookmarkEvent->getOldBookmark(), editMUCBookmarkEvent->getNewBookmark());
}
else if (JoinMUCUIEvent::ref joinEvent = std::dynamic_pointer_cast<JoinMUCUIEvent>(event)) {
handleJoinMUCRequest(joinEvent->getJID(), joinEvent->getPassword(), joinEvent->getNick(), joinEvent->getShouldJoinAutomatically(), joinEvent->getCreateAsReservedRoomIfNew(), joinEvent->isImpromptu());
mucControllers_[joinEvent->getJID()]->activateChatWindow();
}
else if (std::shared_ptr<RequestJoinMUCUIEvent> joinEvent = std::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();
}