summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swift/Controllers')
-rw-r--r--Swift/Controllers/Chat/ChatsManager.cpp17
-rw-r--r--Swift/Controllers/Chat/MUCController.cpp4
-rw-r--r--Swift/Controllers/Chat/MUCController.h1
-rw-r--r--Swift/Controllers/UIInterfaces/ChatListWindow.h7
4 files changed, 23 insertions, 6 deletions
diff --git a/Swift/Controllers/Chat/ChatsManager.cpp b/Swift/Controllers/Chat/ChatsManager.cpp
index 654f735..1698b4a 100644
--- a/Swift/Controllers/Chat/ChatsManager.cpp
+++ b/Swift/Controllers/Chat/ChatsManager.cpp
@@ -1,123 +1,129 @@
/*
* Copyright (c) 2010-2014 Kevin Smith
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#include <Swift/Controllers/Chat/ChatsManager.h>
#include <boost/bind.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/smart_ptr/make_shared.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
+#include <boost/serialization/optional.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/map.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/split_free.hpp>
#include <Swiften/Base/foreach.h>
#include <Swiften/Presence/PresenceSender.h>
#include <Swiften/Client/NickResolver.h>
#include <Swiften/MUC/MUCManager.h>
#include <Swiften/Elements/ChatState.h>
#include <Swiften/Elements/MUCUserPayload.h>
#include <Swiften/Elements/DeliveryReceipt.h>
#include <Swiften/Elements/DeliveryReceiptRequest.h>
#include <Swiften/MUC/MUCBookmarkManager.h>
#include <Swiften/Avatars/AvatarManager.h>
#include <Swiften/Elements/MUCInvitationPayload.h>
#include <Swiften/Roster/XMPPRoster.h>
#include <Swiften/Client/ClientBlockListManager.h>
#include <Swiften/Client/StanzaChannel.h>
#include <Swiften/VCards/VCardManager.h>
#include <Swift/Controllers/Chat/ChatController.h>
#include <Swift/Controllers/Chat/ChatControllerBase.h>
#include <Swift/Controllers/Chat/MUCSearchController.h>
#include <Swift/Controllers/Chat/AutoAcceptMUCInviteDecider.h>
#include <Swift/Controllers/XMPPEvents/EventController.h>
#include <Swift/Controllers/Chat/MUCController.h>
#include <Swift/Controllers/UIEvents/RequestChatUIEvent.h>
#include <Swift/Controllers/UIEvents/CreateImpromptuMUCUIEvent.h>
#include <Swift/Controllers/UIEvents/JoinMUCUIEvent.h>
#include <Swift/Controllers/UIEvents/RequestJoinMUCUIEvent.h>
#include <Swift/Controllers/UIEvents/AddMUCBookmarkUIEvent.h>
#include <Swift/Controllers/UIEvents/RemoveMUCBookmarkUIEvent.h>
#include <Swift/Controllers/UIEvents/EditMUCBookmarkUIEvent.h>
#include <Swift/Controllers/UIEvents/InviteToMUCUIEvent.h>
#include <Swift/Controllers/UIInterfaces/ChatListWindowFactory.h>
#include <Swift/Controllers/UIInterfaces/JoinMUCWindow.h>
#include <Swift/Controllers/UIInterfaces/JoinMUCWindowFactory.h>
#include <Swift/Controllers/FileTransfer/FileTransferController.h>
#include <Swift/Controllers/FileTransfer/FileTransferOverview.h>
#include <Swift/Controllers/ProfileSettingsProvider.h>
#include <Swift/Controllers/Settings/SettingsProvider.h>
#include <Swift/Controllers/SettingConstants.h>
#include <Swift/Controllers/WhiteboardManager.h>
#include <Swift/Controllers/Chat/ChatMessageParser.h>
#include <Swift/Controllers/Chat/UserSearchController.h>
#include <Swiften/Disco/DiscoServiceWalker.h>
#include <Swiften/Client/ClientBlockListManager.h>
#include <Swiften/StringCodecs/Base64.h>
#include <Swiften/Base/Log.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*/) {
+ 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;
+ }
}
}
}
namespace Swift {
typedef std::pair<JID, ChatController*> JIDChatControllerPair;
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,
@@ -337,86 +343,91 @@ void ChatsManager::setupBookmarks() {
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);
}
}
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);
}
void ChatsManager::handleMUCBookmarkRemoved(const MUCBookmark& bookmark) {
chatListWindow_->removeMUCBookmark(bookmark);
}
ChatListWindow::Chat ChatsManager::createChatListChatItem(const JID& jid, const std::string& activity) {
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, nick);
+ ChatListWindow::Chat chat = ChatListWindow::Chat(jid, jid.toString(), activity, unreadCount, type, boost::filesystem::path(), true, nick, password);
typedef std::pair<std::string, JID> StringJIDPair;
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, nick);
+ return ChatListWindow::Chat(jid, jid.toString(), activity, unreadCount, type, boost::filesystem::path(), true, 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_->getHighestPriorityPresence(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);
}
}
void ChatsManager::handleChatActivity(const JID& jid, const std::string& activity, bool isMUC) {
if (mucRegistry_->isMUC(jid.toBare()) && !isMUC) {
/* Don't include PMs in MUC rooms.*/
return;
}
ChatListWindow::Chat chat = createChatListChatItem(jid, activity);
/* FIXME: handle nick changes */
appendRecent(chat);
handleUnreadCountChanged(NULL);
saveRecents();
}
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 */
diff --git a/Swift/Controllers/Chat/MUCController.cpp b/Swift/Controllers/Chat/MUCController.cpp
index 4860fc8..6bc7067 100644
--- a/Swift/Controllers/Chat/MUCController.cpp
+++ b/Swift/Controllers/Chat/MUCController.cpp
@@ -211,70 +211,74 @@ void MUCController::handleBareJIDCapsChanged(const JID& /*jid*/) {
}
/**
* 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
#ifdef SWIFT_EXPERIMENTAL_HISTORY
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_);
}
}
}
bool MUCController::isJoined() {
return joined_;
}
const std::string& MUCController::getNick() {
return nick_;
}
+const boost::optional<std::string> MUCController::getPassword() const {
+ return password_;
+}
+
bool MUCController::isImpromptu() const {
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;
}
void MUCController::sendInvites(const std::vector<JID>& jids, const std::string& reason) const {
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);
}
void MUCController::receivedActivity() {
if (loginCheckTimer_) {
loginCheckTimer_->stop();
}
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wswitch-enum"
diff --git a/Swift/Controllers/Chat/MUCController.h b/Swift/Controllers/Chat/MUCController.h
index e78ff77..feffaba 100644
--- a/Swift/Controllers/Chat/MUCController.h
+++ b/Swift/Controllers/Chat/MUCController.h
@@ -30,70 +30,71 @@ namespace Swift {
class IQRouter;
class ChatWindowFactory;
class Roster;
class AvatarManager;
class UIEventStream;
class TimerFactory;
class TabComplete;
class XMPPRoster;
class HighlightManager;
class UIEvent;
class VCardManager;
class RosterVCardProvider;
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, ChatMessageParser* chatMessageParser, bool isImpromptu, AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider, VCardManager* vcardManager);
virtual ~MUCController();
boost::signal<void ()> onUserLeft;
boost::signal<void ()> onUserJoined;
boost::signal<void ()> onImpromptuConfigCompleted;
virtual void setOnline(bool online);
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);
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:
void preSendMessageRequest(boost::shared_ptr<Message> message);
bool isIncomingMessageFromMe(boost::shared_ptr<Message> message);
std::string senderDisplayNameFromMessage(const JID& from);
boost::optional<boost::posix_time::ptime> getMessageTimestamp(boost::shared_ptr<Message> message) const;
void preHandleIncomingMessage(boost::shared_ptr<MessageEvent>);
void postHandleIncomingMessage(boost::shared_ptr<MessageEvent>, const HighlightAction&);
void cancelReplaces();
void logMessage(const std::string& message, const JID& fromJID, const JID& toJID, const boost::posix_time::ptime& timeStamp, bool isIncoming);
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 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);
diff --git a/Swift/Controllers/UIInterfaces/ChatListWindow.h b/Swift/Controllers/UIInterfaces/ChatListWindow.h
index 67cd0ff..38d8c3e 100644
--- a/Swift/Controllers/UIInterfaces/ChatListWindow.h
+++ b/Swift/Controllers/UIInterfaces/ChatListWindow.h
@@ -1,96 +1,97 @@
/*
- * Copyright (c) 2010-2011 Kevin Smith
+ * Copyright (c) 2010-2014 Kevin Smith
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#pragma once
#include <list>
#include <set>
#include <map>
#include <boost/shared_ptr.hpp>
#include <Swiften/MUC/MUCBookmark.h>
#include <Swiften/Elements/StatusShow.h>
#include <boost/filesystem/path.hpp>
#include <Swiften/Base/foreach.h>
#include <Swiften/Base/boost_bsignals.h>
namespace Swift {
class ChatListWindow {
public:
class Chat {
public:
Chat() : statusType(StatusShow::None), isMUC(false), unreadCount(0) {}
- Chat(const JID& jid, const std::string& chatName, const std::string& activity, int unreadCount, StatusShow::Type statusType, const boost::filesystem::path& avatarPath, bool isMUC, const std::string& nick = "")
- : jid(jid), chatName(chatName), activity(activity), statusType(statusType), isMUC(isMUC), nick(nick), unreadCount(unreadCount), avatarPath(avatarPath) {}
+ Chat(const JID& jid, const std::string& chatName, const std::string& activity, int unreadCount, StatusShow::Type statusType, const boost::filesystem::path& avatarPath, bool isMUC, const std::string& nick = "", const boost::optional<std::string> password = boost::optional<std::string>())
+ : jid(jid), chatName(chatName), activity(activity), statusType(statusType), isMUC(isMUC), nick(nick), password(password), unreadCount(unreadCount), avatarPath(avatarPath) {}
/** 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;
};
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;
boost::signal<void (const MUCBookmark&)> onMUCBookmarkActivated;
boost::signal<void (const Chat&)> onRecentActivated;
boost::signal<void (const JID&)> onWhiteboardActivated;
boost::signal<void ()> onClearRecentsRequested;
};
}