summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swift/Controllers/Chat/MUCController.cpp')
-rw-r--r--Swift/Controllers/Chat/MUCController.cpp282
1 files changed, 214 insertions, 68 deletions
diff --git a/Swift/Controllers/Chat/MUCController.cpp b/Swift/Controllers/Chat/MUCController.cpp
index 50eee68..37631a5 100644
--- a/Swift/Controllers/Chat/MUCController.cpp
+++ b/Swift/Controllers/Chat/MUCController.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Kevin Smith
+ * Copyright (c) 2010-2013 Kevin Smith
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
@@ -19,11 +19,13 @@
#include <Swiften/Base/foreach.h>
#include <Swift/Controllers/XMPPEvents/EventController.h>
#include <Swift/Controllers/UIInterfaces/ChatWindow.h>
-#include <Swift/Controllers/UIInterfaces/InviteToChatWindow.h>
#include <Swift/Controllers/UIInterfaces/ChatWindowFactory.h>
#include <Swift/Controllers/UIEvents/UIEventStream.h>
#include <Swift/Controllers/UIEvents/RequestChatUIEvent.h>
#include <Swift/Controllers/UIEvents/RequestAddUserDialogUIEvent.h>
+#include <Swift/Controllers/UIEvents/ShowProfileForRosterItemUIEvent.h>
+#include <Swift/Controllers/UIEvents/RequestInviteToMUCUIEvent.h>
+#include <Swift/Controllers/UIEvents/InviteToMUCUIEvent.h>
#include <Swift/Controllers/Roster/GroupRosterItem.h>
#include <Swift/Controllers/Roster/ContactRosterItem.h>
#include <Swiften/Avatars/AvatarManager.h>
@@ -35,7 +37,10 @@
#include <Swift/Controllers/Roster/SetPresence.h>
#include <Swiften/Disco/EntityCapsProvider.h>
#include <Swiften/Roster/XMPPRoster.h>
+#include <Swift/Controllers/Highlighter.h>
+#include <Swift/Controllers/Chat/ChatMessageParser.h>
+#include <Swiften/Base/Log.h>
#define MUC_JOIN_WARNING_TIMEOUT_MILLISECONDS 60000
@@ -61,22 +66,24 @@ MUCController::MUCController (
EntityCapsProvider* entityCapsProvider,
XMPPRoster* roster,
HistoryController* historyController,
- MUCRegistry* mucRegistry) :
- ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, muc->getJID(), presenceOracle, avatarManager, useDelayForLatency, uiEventStream, eventController, timerFactory, entityCapsProvider, historyController, mucRegistry), muc_(muc), nick_(nick), desiredNick_(nick), password_(password) {
+ MUCRegistry* mucRegistry,
+ HighlightManager* highlightManager,
+ ChatMessageParser* chatMessageParser,
+ bool isImpromptu,
+ AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider) :
+ 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) {
parting_ = true;
joined_ = false;
lastWasPresence_ = false;
shouldJoinOnReconnect_ = true;
doneGettingHistory_ = false;
events_ = uiEventStream;
- inviteWindow_ = NULL;
xmppRoster_ = roster;
roster_ = new Roster(false, true);
completer_ = new TabComplete();
chatWindow_->setRosterModel(roster_);
chatWindow_->setTabComplete(completer_);
- chatWindow_->setName(muc->getJID().getNode());
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));
@@ -84,7 +91,7 @@ MUCController::MUCController (
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_->onInvitePersonToThisMUCRequest.connect(boost::bind(&MUCController::handleInvitePersonToThisMUCRequest, 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));
muc_->onJoinComplete.connect(boost::bind(&MUCController::handleJoinComplete, this, _1));
@@ -94,24 +101,34 @@ MUCController::MUCController (
muc_->onOccupantLeft.connect(boost::bind(&MUCController::handleOccupantLeft, this, _1, _2, _3));
muc_->onOccupantRoleChanged.connect(boost::bind(&MUCController::handleOccupantRoleChanged, this, _1, _2, _3));
muc_->onOccupantAffiliationChanged.connect(boost::bind(&MUCController::handleOccupantAffiliationChanged, this, _1, _2, _3));
- muc_->onConfigurationFailed.connect(boost::bind(&MUCController::handleConfigurationFailed, this, _1));
- muc_->onConfigurationFormReceived.connect(boost::bind(&MUCController::handleConfigurationFormReceived, this, _1));
muc_->onRoleChangeFailed.connect(boost::bind(&MUCController::handleOccupantRoleChangeFailed, this, _1, _2, _3));
muc_->onAffiliationListReceived.connect(boost::bind(&MUCController::handleAffiliationListReceived, this, _1, _2));
+ muc_->onConfigurationFailed.connect(boost::bind(&MUCController::handleConfigurationFailed, this, _1));
+ muc_->onConfigurationFormReceived.connect(boost::bind(&MUCController::handleConfigurationFormReceived, this, _1));
+ highlighter_->setMode(Highlighter::MUCMode);
+ highlighter_->setNick(nick_);
if (timerFactory) {
loginCheckTimer_ = boost::shared_ptr<Timer>(timerFactory->createTimer(MUC_JOIN_WARNING_TIMEOUT_MILLISECONDS));
loginCheckTimer_->onTick.connect(boost::bind(&MUCController::handleJoinTimeoutTick, this));
loginCheckTimer_->start();
}
- chatWindow_->convertToMUC();
+ if (isImpromptu) {
+ muc_->onUnlocked.connect(boost::bind(&MUCController::handleRoomUnlocked, this));
+ chatWindow_->convertToMUC(true);
+ } else {
+ chatWindow_->convertToMUC();
+ chatWindow_->setName(muc->getJID().getNode());
+ }
setOnline(true);
if (avatarManager_ != NULL) {
avatarChangedConnection_ = (avatarManager_->onAvatarChanged.connect(boost::bind(&MUCController::handleAvatarChanged, this, _1)));
}
handleBareJIDCapsChanged(muc->getJID());
+ eventStream_->onUIEvent.connect(boost::bind(&MUCController::handleUIEvent, this, _1));
}
MUCController::~MUCController() {
+ eventStream_->onUIEvent.disconnect(boost::bind(&MUCController::handleUIEvent, this, _1));
chatWindow_->setRosterModel(NULL);
delete roster_;
if (loginCheckTimer_) {
@@ -146,6 +163,7 @@ void MUCController::handleWindowOccupantSelectionChanged(ContactRosterItem* item
if (muc_->getOccupant(item->getJID().getResource()).getRealJID()) {
actions.push_back(ChatWindow::AddContact);
}
+ actions.push_back(ChatWindow::ShowProfile);
}
chatWindow_->setAvailableOccupantActions(actions);
}
@@ -164,6 +182,7 @@ void MUCController::handleActionRequestedOnOccupant(ChatWindow::OccupantAction a
case ChatWindow::MakeParticipant: muc_->changeOccupantRole(mucJID, MUCOccupant::Participant);break;
case ChatWindow::MakeVisitor: muc_->changeOccupantRole(mucJID, MUCOccupant::Visitor);break;
case ChatWindow::AddContact: if (occupant.getRealJID()) events_->send(boost::make_shared<RequestAddUserDialogUIEvent>(realJID, occupant.getNick()));break;
+ case ChatWindow::ShowProfile: events_->send(boost::make_shared<ShowProfileForRosterItemUIEvent>(mucJID));break;
}
}
@@ -217,9 +236,31 @@ const std::string& MUCController::getNick() {
return nick_;
}
+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(str(format(QT_TRANSLATE_NOOP("", "Room %1% is not responding. This operation may never complete.")) % toJID_.toString()));
+ 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() {
@@ -228,6 +269,9 @@ void MUCController::receivedActivity() {
}
}
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wswitch-enum"
+
void MUCController::handleJoinFailed(boost::shared_ptr<ErrorPayload> error) {
receivedActivity();
std::string errorMessage = QT_TRANSLATE_NOOP("", "Unable to enter this room");
@@ -267,20 +311,29 @@ void MUCController::handleJoinFailed(boost::shared_ptr<ErrorPayload> error) {
}
}
errorMessage = str(format(QT_TRANSLATE_NOOP("", "Couldn't join room: %1%.")) % errorMessage);
- chatWindow_->addErrorMessage(errorMessage);
+ chatWindow_->addErrorMessage(chatMessageParser_->parseMessageBody(errorMessage));
parting_ = true;
- if (!rejoinNick.empty()) {
- nick_ = rejoinNick;
+ 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 = str(format(QT_TRANSLATE_NOOP("", "You have entered room %1% as %2%.")) % toJID_.toString() % nick);
- nick_ = nick;
- chatWindow_->addSystemMessage(joinMessage);
+ std::string joinMessage;
+ if (isImpromptu_) {
+ joinMessage = str(format(QT_TRANSLATE_NOOP("", "You have entered chat as %1%.")) % nick);
+ } else {
+ joinMessage = str(format(QT_TRANSLATE_NOOP("", "You have entered room %1% as %2%.")) % toJID_.toString() % nick);
+ }
+ setNick(nick);
+ chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(joinMessage), ChatWindow::DefaultDirection);
#ifdef SWIFT_EXPERIMENTAL_HISTORY
addRecentLogs();
@@ -292,14 +345,17 @@ void MUCController::handleJoinComplete(const std::string& nick) {
MUCOccupant occupant = muc_->getOccupant(nick);
setAvailableRoomActions(occupant.getAffiliation(), occupant.getRole());
onUserJoined();
+
+ if (isImpromptu_) {
+ setImpromptuWindowTitle();
+ }
}
void MUCController::handleAvatarChanged(const JID& jid) {
if (parting_ || !jid.equals(toJID_, JID::WithoutResource)) {
return;
}
- std::string path = avatarManager_->getAvatarPath(jid).string();
- roster_->applyOnItems(SetAvatar(jid, path, JID::WithResource));
+ roster_->applyOnItems(SetAvatar(jid, avatarManager_->getAvatarPath(jid), JID::WithResource));
}
void MUCController::handleWindowClosed() {
@@ -323,22 +379,26 @@ void MUCController::handleOccupantJoined(const MUCOccupant& occupant) {
NickJoinPart event(occupant.getNick(), Join);
appendToJoinParts(joinParts_, event);
std::string groupName(roleToGroupName(occupant.getRole()));
- roster_->addContact(jid, realJID, occupant.getNick(), groupName, avatarManager_->getAvatarPath(jid).string());
+ roster_->addContact(jid, realJID, occupant.getNick(), groupName, avatarManager_->getAvatarPath(jid));
roster_->getGroup(groupName)->setManualSort(roleToSortName(occupant.getRole()));
if (joined_) {
std::string joinString;
MUCOccupant::Role role = occupant.getRole();
if (role != MUCOccupant::NoRole && role != MUCOccupant::Participant) {
- joinString = str(format(QT_TRANSLATE_NOOP("", "%1% has entered the room as a %2%.")) % occupant.getNick() % roleToFriendlyName(role));
+ 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 room.")) % occupant.getNick());
+ 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) {
@@ -348,7 +408,7 @@ void MUCController::handleOccupantJoined(const MUCOccupant& occupant) {
void MUCController::addPresenceMessage(const std::string& message) {
lastWasPresence_ = true;
- chatWindow_->addPresenceMessage(message);
+ chatWindow_->addPresenceMessage(chatMessageParser_->parseMessageBody(message), ChatWindow::DefaultDirection);
}
@@ -386,6 +446,7 @@ std::string MUCController::roleToFriendlyName(MUCOccupant::Role role) {
case MUCOccupant::Visitor: return QT_TRANSLATE_NOOP("", "visitor");
case MUCOccupant::NoRole: return "";
}
+ assert(false);
return "";
}
@@ -396,6 +457,7 @@ std::string MUCController::roleToSortName(MUCOccupant::Role role) {
case MUCOccupant::Visitor: return "3";
case MUCOccupant::NoRole: return "4";
}
+ assert(false);
return "5";
}
@@ -433,7 +495,7 @@ void MUCController::preHandleIncomingMessage(boost::shared_ptr<MessageEvent> mes
joined_ = true;
if (message->hasSubject() && message->getBody().empty()) {
- chatWindow_->addSystemMessage(str(format(QT_TRANSLATE_NOOP("", "The room subject is now: %1%")) % message->getSubject()));;
+ 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;
}
@@ -448,10 +510,13 @@ void MUCController::preHandleIncomingMessage(boost::shared_ptr<MessageEvent> mes
}
}
-void MUCController::postHandleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent) {
+void MUCController::postHandleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent, const HighlightAction& highlight) {
boost::shared_ptr<Message> message = messageEvent->getStanza();
if (joined_ && messageEvent->getStanza()->getFrom().getResource() != nick_ && messageTargetsMe(message) && !message->getPayload<Delay>()) {
eventController_->handleIncomingEvent(messageEvent);
+ if (!messageEvent->getConcluded()) {
+ highlighter_->handleHighlightAction(highlight);
+ }
}
}
@@ -465,9 +530,9 @@ void MUCController::handleOccupantRoleChanged(const std::string& nick, const MUC
realJID = occupant.getRealJID().get();
}
std::string group(roleToGroupName(occupant.getRole()));
- roster_->addContact(jid, realJID, nick, group, avatarManager_->getAvatarPath(jid).string());
+ roster_->addContact(jid, realJID, nick, group, avatarManager_->getAvatarPath(jid));
roster_->getGroup(group)->setManualSort(roleToSortName(occupant.getRole()));
- chatWindow_->addSystemMessage(str(format(QT_TRANSLATE_NOOP("", "%1% is now a %2%")) % nick % roleToFriendlyName(occupant.getRole())));
+ 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());
}
@@ -487,7 +552,6 @@ std::string MUCController::roleToGroupName(MUCOccupant::Role role) {
case MUCOccupant::Participant: result = QT_TRANSLATE_NOOP("", "Participants"); break;
case MUCOccupant::Visitor: result = QT_TRANSLATE_NOOP("", "Visitors"); break;
case MUCOccupant::NoRole: result = QT_TRANSLATE_NOOP("", "Occupants"); break;
- default: assert(false);
}
return result;
}
@@ -500,11 +564,16 @@ void MUCController::setOnline(bool online) {
processUserPart();
} else {
if (shouldJoinOnReconnect_) {
- chatWindow_->addSystemMessage(str(format(QT_TRANSLATE_NOOP("", "Trying to enter room %1%")) % toJID_.toString()));
+ renameCounter_ = 0;
+ if (isImpromptu_) {
+ chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(QT_TRANSLATE_NOOP("", "Trying to enter chat")), ChatWindow::DefaultDirection);
+ } else {
+ chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(str(format(QT_TRANSLATE_NOOP("", "Trying to enter room %1%")) % toJID_.toString())), ChatWindow::DefaultDirection);
+ }
if (loginCheckTimer_) {
loginCheckTimer_->start();
}
- nick_ = desiredNick_;
+ setNick(desiredNick_);
rejoin();
}
}
@@ -573,6 +642,10 @@ void MUCController::handleOccupantLeft(const MUCOccupant& occupant, MUC::Leaving
if (clearAfter) {
clearPresenceQueue();
}
+
+ if (isImpromptu_) {
+ setImpromptuWindowTitle();
+ }
}
void MUCController::handleOccupantPresenceChange(boost::shared_ptr<Presence> presence) {
@@ -598,7 +671,7 @@ boost::optional<boost::posix_time::ptime> MUCController::getMessageTimestamp(boo
}
void MUCController::updateJoinParts() {
- chatWindow_->replaceLastMessage(generateJoinPartString(joinParts_));
+ chatWindow_->replaceLastMessage(chatMessageParser_->parseMessageBody(generateJoinPartString(joinParts_, isImpromptu())));
}
void MUCController::appendToJoinParts(std::vector<NickJoinPart>& joinParts, const NickJoinPart& newEvent) {
@@ -611,7 +684,8 @@ void MUCController::appendToJoinParts(std::vector<NickJoinPart>& joinParts, cons
switch (newEvent.type) {
case Join: type = (type == Part) ? PartThenJoin : Join; break;
case Part: type = (type == Join) ? JoinThenPart : Part; break;
- default: /*Nothing to see here */;break;
+ case PartThenJoin: break;
+ case JoinThenPart: break;
}
(*it).type = type;
break;
@@ -638,7 +712,7 @@ std::string MUCController::concatenateListOfNames(const std::vector<NickJoinPart
return result;
}
-std::string MUCController::generateJoinPartString(const std::vector<NickJoinPart>& joinParts) {
+std::string MUCController::generateJoinPartString(const std::vector<NickJoinPart>& joinParts, bool isImpromptu) {
std::vector<NickJoinPart> sorted[4];
std::string eventStrings[4];
foreach (NickJoinPart event, joinParts) {
@@ -653,34 +727,34 @@ std::string MUCController::generateJoinPartString(const std::vector<NickJoinPart
switch (i) {
case Join:
if (sorted[i].size() > 1) {
- eventString = QT_TRANSLATE_NOOP("", "%1% have entered the room");
+ eventString = (isImpromptu ? QT_TRANSLATE_NOOP("", "%1% have joined the chat") : QT_TRANSLATE_NOOP("", "%1% have entered the room"));
}
else {
- eventString = QT_TRANSLATE_NOOP("", "%1% has entered the room");
+ 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 = QT_TRANSLATE_NOOP("", "%1% have left the room");
+ eventString = (isImpromptu ? QT_TRANSLATE_NOOP("", "%1% have left the chat") : QT_TRANSLATE_NOOP("", "%1% have left the room"));
}
else {
- eventString = QT_TRANSLATE_NOOP("", "%1% has left the room");
+ 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 = QT_TRANSLATE_NOOP("", "%1% have entered then left the room");
+ eventString = (isImpromptu ? QT_TRANSLATE_NOOP("", "%1% have joined then left the chat") : QT_TRANSLATE_NOOP("", "%1% have entered then left the room"));
}
else {
- eventString = QT_TRANSLATE_NOOP("", "%1% has entered then left the room");
+ 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 = QT_TRANSLATE_NOOP("", "%1% have left then returned to the room");
+ 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 = QT_TRANSLATE_NOOP("", "%1% has left then returned to the room");
+ 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;
}
@@ -717,17 +791,29 @@ void MUCController::handleConfigureRequest(Form::ref form) {
void MUCController::handleConfigurationFailed(ErrorPayload::ref error) {
std::string errorMessage = getErrorMessage(error);
errorMessage = str(format(QT_TRANSLATE_NOOP("", "Room configuration failed: %1%.")) % errorMessage);
- chatWindow_->addErrorMessage(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(errorMessage);
+ chatWindow_->addErrorMessage(chatMessageParser_->parseMessageBody(errorMessage));
+}
+
+void MUCController::configureAsImpromptuRoom(Form::ref form) {
+ muc_->configureRoom(buildImpromptuRoomConfiguration(form));
+ isImpromptuAlreadyConfigured_ = true;
+ onImpromptuConfigCompleted();
}
void MUCController::handleConfigurationFormReceived(Form::ref form) {
- chatWindow_->showRoomConfigurationForm(form);
+ if (isImpromptu_) {
+ if (!isImpromptuAlreadyConfigured_) {
+ configureAsImpromptuRoom(form);
+ }
+ } else {
+ chatWindow_->showRoomConfigurationForm(form);
+ }
}
void MUCController::handleConfigurationCancelled() {
@@ -738,32 +824,18 @@ void MUCController::handleDestroyRoomRequest() {
muc_->destroyRoom();
}
-void MUCController::handleInvitePersonToThisMUCRequest() {
- if (!inviteWindow_) {
- inviteWindow_ = chatWindow_->createInviteToChatWindow();
- inviteWindow_->onCompleted.connect(boost::bind(&MUCController::handleInviteToMUCWindowCompleted, this));
- inviteWindow_->onDismissed.connect(boost::bind(&MUCController::handleInviteToMUCWindowDismissed, this));
- }
- std::vector<std::pair<JID, std::string> > autoCompletes;
- foreach (XMPPRosterItem item, xmppRoster_->getItems()) {
- std::pair<JID, std::string> jidName;
- jidName.first = item.getJID();
- jidName.second = item.getName();
- autoCompletes.push_back(jidName);
- //std::cerr << "MUCController adding " << item.getJID().toString() << std::endl;
- }
- inviteWindow_->setAutoCompletions(autoCompletes);
-}
-
-void MUCController::handleInviteToMUCWindowDismissed() {
- inviteWindow_= NULL;
+void MUCController::handleInvitePersonToThisMUCRequest(const std::vector<JID>& jidsToInvite) {
+ boost::shared_ptr<UIEvent> event(new RequestInviteToMUCUIEvent(muc_->getJID(), jidsToInvite));
+ eventStream_->send(event);
}
-void MUCController::handleInviteToMUCWindowCompleted() {
- foreach (const JID& jid, inviteWindow_->getJIDs()) {
- muc_->invitePerson(jid, inviteWindow_->getReason());
+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_);
+ }
}
- inviteWindow_ = NULL;
}
void MUCController::handleGetAffiliationsRequest() {
@@ -811,7 +883,7 @@ void MUCController::addRecentLogs() {
bool senderIsSelf = nick_ == message.getFromJID().getResource();
// the chatWindow uses utc timestamps
- addMessage(message.getMessage(), senderDisplayNameFromMessage(message.getFromJID()), senderIsSelf, boost::shared_ptr<SecurityLabel>(new SecurityLabel()), std::string(avatarManager_->getAvatarPath(message.getFromJID()).string()), message.getTime() - boost::posix_time::hours(message.getOffset()));
+ addMessage(message.getMessage(), senderDisplayNameFromMessage(message.getFromJID()), senderIsSelf, boost::shared_ptr<SecurityLabel>(new SecurityLabel()), avatarManager_->getAvatarPath(message.getFromJID()), message.getTime() - boost::posix_time::hours(message.getOffset()), HighlightAction());
}
}
@@ -840,4 +912,78 @@ void MUCController::checkDuplicates(boost::shared_ptr<Message> newMessage) {
}
}
+void MUCController::setNick(const std::string& 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;
+}
+
+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);
+}
+
+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();
+ }
+ }
+}
+
}