summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Smith <git@kismith.co.uk>2011-10-02 17:38:56 (GMT)
committerKevin Smith <git@kismith.co.uk>2011-10-03 07:02:37 (GMT)
commit4ea336d9d124f1c761b22943eaf6771e16a61e58 (patch)
tree7bcb7ac4366cf31a2f98654a5859de0b32fb318a /Swift/Controllers
parent123502d97dc20357ea03fd7f238f117aeb2d05c3 (diff)
downloadswift-contrib-4ea336d9d124f1c761b22943eaf6771e16a61e58.zip
swift-contrib-4ea336d9d124f1c761b22943eaf6771e16a61e58.tar.bz2
Simple MUC invites.
Resolves: #152
Diffstat (limited to 'Swift/Controllers')
-rw-r--r--Swift/Controllers/Chat/ChatControllerBase.cpp30
-rw-r--r--Swift/Controllers/Chat/ChatControllerBase.h1
-rw-r--r--Swift/Controllers/Chat/ChatsManager.cpp7
-rw-r--r--Swift/Controllers/Chat/MUCController.cpp5
-rw-r--r--Swift/Controllers/Chat/MUCController.h1
-rw-r--r--Swift/Controllers/UIInterfaces/ChatWindow.h3
-rw-r--r--Swift/Controllers/UnitTest/MockChatWindow.h1
7 files changed, 35 insertions, 13 deletions
diff --git a/Swift/Controllers/Chat/ChatControllerBase.cpp b/Swift/Controllers/Chat/ChatControllerBase.cpp
index df59c2f..4bcb4c7 100644
--- a/Swift/Controllers/Chat/ChatControllerBase.cpp
+++ b/Swift/Controllers/Chat/ChatControllerBase.cpp
@@ -10,28 +10,29 @@
#include <map>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/algorithm/string.hpp>
#include <Swift/Controllers/Intl.h>
#include <Swiften/Base/format.h>
-#include "Swiften/Base/String.h"
-#include "Swiften/Client/StanzaChannel.h"
-#include "Swiften/Elements/Delay.h"
-#include "Swiften/Base/foreach.h"
-#include "Swift/Controllers/XMPPEvents/EventController.h"
-#include "Swiften/Disco/EntityCapsProvider.h"
-#include "Swift/Controllers/UIInterfaces/ChatWindow.h"
-#include "Swift/Controllers/UIInterfaces/ChatWindowFactory.h"
-#include "Swiften/Queries/Requests/GetSecurityLabelsCatalogRequest.h"
-#include "Swiften/Avatars/AvatarManager.h"
+#include <Swiften/Base/String.h>
+#include <Swiften/Client/StanzaChannel.h>
+#include <Swiften/Elements/Delay.h>
+#include <Swiften/Elements/MUCInvitationPayload.h>
+#include <Swiften/Base/foreach.h>
+#include <Swift/Controllers/XMPPEvents/EventController.h>
+#include <Swiften/Disco/EntityCapsProvider.h>
+#include <Swift/Controllers/UIInterfaces/ChatWindow.h>
+#include <Swift/Controllers/UIInterfaces/ChatWindowFactory.h>
+#include <Swiften/Queries/Requests/GetSecurityLabelsCatalogRequest.h>
+#include <Swiften/Avatars/AvatarManager.h>
namespace Swift {
ChatControllerBase::ChatControllerBase(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &toJID, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool useDelayForLatency, UIEventStream* eventStream, EventController* eventController, TimerFactory* timerFactory, EntityCapsProvider* entityCapsProvider) : selfJID_(self), stanzaChannel_(stanzaChannel), iqRouter_(iqRouter), chatWindowFactory_(chatWindowFactory), toJID_(toJID), labelsEnabled_(false), presenceOracle_(presenceOracle), avatarManager_(avatarManager), useDelayForLatency_(useDelayForLatency), eventController_(eventController), timerFactory_(timerFactory), entityCapsProvider_(entityCapsProvider) {
chatWindow_ = chatWindowFactory_->createChatWindow(toJID, eventStream);
chatWindow_->onAllMessagesRead.connect(boost::bind(&ChatControllerBase::handleAllMessagesRead, this));
chatWindow_->onSendMessageRequest.connect(boost::bind(&ChatControllerBase::handleSendMessageRequest, this, _1, _2));
entityCapsProvider_->onCapsChanged.connect(boost::bind(&ChatControllerBase::handleCapsChanged, this, _1));
setOnline(stanzaChannel->isAvailable() && iqRouter->isAvailable());
@@ -170,18 +171,22 @@ void ChatControllerBase::handleIncomingMessage(boost::shared_ptr<MessageEvent> m
if (messageEvent->isReadable() && !messageEvent->getConcluded()) {
unreadMessages_.push_back(messageEvent);
}
boost::shared_ptr<Message> message = messageEvent->getStanza();
std::string body = message->getBody();
if (message->isError()) {
std::string errorMessage = str(format(QT_TRANSLATE_NOOP("", "Couldn't send message: %1%")) % getErrorMessage(message->getPayload<ErrorPayload>()));
chatWindow_->addErrorMessage(errorMessage);
}
+ else if (messageEvent->getStanza()->getPayload<MUCInvitationPayload>()) {
+ handleMUCInvitation(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()) {
@@ -250,10 +255,15 @@ std::string ChatControllerBase::getErrorMessage(boost::shared_ptr<ErrorPayload>
case ErrorPayload::ServiceUnavailable: return QT_TRANSLATE_NOOP("", "The service is unavailable"); break;
case ErrorPayload::SubscriptionRequired: return QT_TRANSLATE_NOOP("", "A subscription is required"); break;
case ErrorPayload::UndefinedCondition: return QT_TRANSLATE_NOOP("", "Undefined condition"); break;
case ErrorPayload::UnexpectedRequest: return QT_TRANSLATE_NOOP("", "Unexpected request"); break;
}
}
return defaultMessage;
}
+void ChatControllerBase::handleMUCInvitation(Message::ref message) {
+ MUCInvitationPayload::ref invite = message->getPayload<MUCInvitationPayload>();
+ chatWindow_->addMUCInvitation(invite->getJID(), invite->getReason(), invite->getPassword());
+}
+
}
diff --git a/Swift/Controllers/Chat/ChatControllerBase.h b/Swift/Controllers/Chat/ChatControllerBase.h
index 67bd74f..a857f3d 100644
--- a/Swift/Controllers/Chat/ChatControllerBase.h
+++ b/Swift/Controllers/Chat/ChatControllerBase.h
@@ -74,18 +74,19 @@ namespace Swift {
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);
protected:
JID selfJID_;
std::vector<boost::shared_ptr<MessageEvent> > unreadMessages_;
StanzaChannel* stanzaChannel_;
IQRouter* iqRouter_;
ChatWindowFactory* chatWindowFactory_;
ChatWindow* chatWindow_;
JID toJID_;
diff --git a/Swift/Controllers/Chat/ChatsManager.cpp b/Swift/Controllers/Chat/ChatsManager.cpp
index 47a65a8..c0b2a7d 100644
--- a/Swift/Controllers/Chat/ChatsManager.cpp
+++ b/Swift/Controllers/Chat/ChatsManager.cpp
@@ -27,18 +27,19 @@
#include <Swiften/Presence/PresenceSender.h>
#include <Swiften/Client/NickResolver.h>
#include <Swiften/MUC/MUCManager.h>
#include <Swiften/Elements/ChatState.h>
#include <Swiften/MUC/MUCBookmarkManager.h>
#include <Swift/Controllers/FileTransfer/FileTransferController.h>
#include <Swift/Controllers/FileTransfer/FileTransferOverview.h>
#include <Swift/Controllers/ProfileSettingsProvider.h>
#include <Swiften/Avatars/AvatarManager.h>
+#include <Swiften/Elements/MUCInvitationPayload.h>
namespace Swift {
typedef std::pair<JID, ChatController*> JIDChatControllerPair;
typedef std::pair<JID, MUCController*> JIDMUCControllerPair;
#define RECENT_CHATS "recent_chats"
ChatsManager::ChatsManager(
@@ -510,24 +511,25 @@ void ChatsManager::handleJoinMUCRequest(const JID &mucJID, const boost::optional
}
void ChatsManager::handleSearchMUCRequest() {
mucSearchController_->openSearchWindow();
}
void ChatsManager::handleIncomingMessage(boost::shared_ptr<Message> message) {
JID jid = message->getFrom();
boost::shared_ptr<MessageEvent> event(new MessageEvent(message));
- if (!event->isReadable() && !message->getPayload<ChatState>() && !message->hasSubject()) {
+ bool isInvite = message->getPayload<MUCInvitationPayload>();
+ if (!event->isReadable() && !message->getPayload<ChatState>() && !isInvite && !message->hasSubject()) {
return;
}
// Try to deliver it to a MUC
- if (message->getType() == Message::Groupchat || message->getType() == Message::Error) {
+ 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;
}
@@ -556,11 +558,10 @@ void ChatsManager::handleNewFileTransferController(FileTransferController* ftc)
void ChatsManager::handleRecentActivated(const ChatListWindow::Chat& chat) {
if (chat.isMUC) {
uiEventStream_->send(boost::make_shared<JoinMUCUIEvent>(chat.jid, chat.nick));
}
else {
uiEventStream_->send(boost::make_shared<RequestChatUIEvent>(chat.jid));
}
}
-
}
diff --git a/Swift/Controllers/Chat/MUCController.cpp b/Swift/Controllers/Chat/MUCController.cpp
index e1d02ae..87d5a16 100644
--- a/Swift/Controllers/Chat/MUCController.cpp
+++ b/Swift/Controllers/Chat/MUCController.cpp
@@ -68,18 +68,19 @@ MUCController::MUCController (
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));
chatWindow_->onChangeSubjectRequest.connect(boost::bind(&MUCController::handleChangeSubjectRequest, this, _1));
chatWindow_->onConfigureRequest.connect(boost::bind(&MUCController::handleConfigureRequest, this, _1));
chatWindow_->onDestroyRequest.connect(boost::bind(&MUCController::handleDestroyRoomRequest, this));
+ chatWindow_->onInvitePersonToThisMUCRequest.connect(boost::bind(&MUCController::handleInvitePersonToThisMUCRequest, this, _1, _2));
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_->onOccupantPresenceChange.connect(boost::bind(&MUCController::handleOccupantPresenceChange, this, _1));
muc_->onOccupantLeft.connect(boost::bind(&MUCController::handleOccupantLeft, this, _1, _2, _3));
muc_->onOccupantRoleChanged.connect(boost::bind(&MUCController::handleOccupantRoleChanged, this, _1, _2, _3));
muc_->onConfigurationFailed.connect(boost::bind(&MUCController::handleConfigurationFailed, this, _1));
muc_->onConfigurationFormReceived.connect(boost::bind(&MUCController::handleConfigurationFormReceived, this, _1));
if (timerFactory) {
@@ -597,10 +598,14 @@ void MUCController::handleConfigurationFailed(ErrorPayload::ref error) {
void MUCController::handleConfigurationFormReceived(Form::ref form) {
chatWindow_->showRoomConfigurationForm(form);
}
void MUCController::handleDestroyRoomRequest() {
muc_->destroyRoom();
}
+void MUCController::handleInvitePersonToThisMUCRequest(const JID& jid, const std::string& reason) {
+ muc_->invitePerson(jid, reason);
+}
+
}
diff --git a/Swift/Controllers/Chat/MUCController.h b/Swift/Controllers/Chat/MUCController.h
index 7a7461b..f83e2af 100644
--- a/Swift/Controllers/Chat/MUCController.h
+++ b/Swift/Controllers/Chat/MUCController.h
@@ -86,18 +86,19 @@ namespace Swift {
void updateJoinParts();
bool shouldUpdateJoinParts();
void dayTicked() {lastWasPresence_ = false;}
void processUserPart();
void handleBareJIDCapsChanged(const JID& jid);
void handleConfigureRequest(Form::ref);
void handleConfigurationFailed(ErrorPayload::ref);
void handleConfigurationFormReceived(Form::ref);
void handleDestroyRoomRequest();
+ void handleInvitePersonToThisMUCRequest(const JID& jid, const std::string& reason);
private:
MUC::ref muc_;
UIEventStream* events_;
std::string nick_;
std::string desiredNick_;
Roster* roster_;
TabComplete* completer_;
bool parting_;
diff --git a/Swift/Controllers/UIInterfaces/ChatWindow.h b/Swift/Controllers/UIInterfaces/ChatWindow.h
index df57d80..7977940 100644
--- a/Swift/Controllers/UIInterfaces/ChatWindow.h
+++ b/Swift/Controllers/UIInterfaces/ChatWindow.h
@@ -48,18 +48,19 @@ namespace Swift {
virtual void addSystemMessage(const std::string& message) = 0;
virtual void addPresenceMessage(const std::string& message) = 0;
virtual void addErrorMessage(const std::string& message) = 0;
virtual void replaceMessage(const std::string& message, const std::string& id, const boost::posix_time::ptime& time) = 0;
// File transfer related stuff
virtual std::string addFileTransfer(const std::string& senderName, bool senderIsSelf, const std::string& filename, const boost::uintmax_t sizeInBytes) = 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 JID& jid, const std::string& reason, const std::string& password) = 0;
virtual void setContactChatState(ChatState::ChatStateType state) = 0;
virtual void setName(const std::string& name) = 0;
virtual void show() = 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 setUnreadMessageCount(int count) = 0;
@@ -68,18 +69,19 @@ namespace Swift {
virtual void setSecurityLabelsError() = 0;
virtual SecurityLabelsCatalog::Item getSelectedSecurityLabel() = 0;
virtual void setInputEnabled(bool enabled) = 0;
virtual void setRosterModel(Roster* model) = 0;
virtual void setTabComplete(TabComplete* completer) = 0;
virtual void replaceLastMessage(const std::string& message) = 0;
virtual void setAckState(const std::string& id, AckState state) = 0;
virtual void flash() = 0;
virtual void setSubject(const std::string& subject) = 0;
+
/**
* 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).
*/
virtual void setAlert(const std::string& alertText, const std::string& buttonText = "") = 0;
/**
* Removes an alert.
*/
@@ -97,18 +99,19 @@ namespace Swift {
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 (Form::ref)> onConfigureRequest;
boost::signal<void ()> onDestroyRequest;
+ boost::signal<void (const JID&, const std::string& /*reason*/)> onInvitePersonToThisMUCRequest;
// 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;
};
}
#endif
diff --git a/Swift/Controllers/UnitTest/MockChatWindow.h b/Swift/Controllers/UnitTest/MockChatWindow.h
index ad8856b..58e8698 100644
--- a/Swift/Controllers/UnitTest/MockChatWindow.h
+++ b/Swift/Controllers/UnitTest/MockChatWindow.h
@@ -42,18 +42,19 @@ namespace Swift {
virtual void replaceMessage(const std::string&, const std::string&, const boost::posix_time::ptime&) {};
void setAckState(const std::string& /*id*/, AckState /*state*/) {};
virtual void flash() {};
virtual void setAlert(const std::string& /*alertText*/, const std::string& /*buttonText*/) {};
virtual void cancelAlert() {};
virtual void setCorrectionEnabled(Tristate /*enabled*/) {}
void setAvailableOccupantActions(const std::vector<OccupantAction>&/* actions*/) {}
void setSubject(const std::string& /*subject*/) {}
virtual void showRoomConfigurationForm(Form::ref) {}
+ virtual void addMUCInvitation(const JID& /*jid*/, const std::string& /*reason*/, const std::string& /*password*/) {};
boost::signal<void ()> onClosed;
boost::signal<void ()> onAllMessagesRead;
boost::signal<void (const std::string&, bool isCorrection)> onSendMessageRequest;
std::string name_;
std::string lastMessageBody_;
std::vector<SecurityLabelsCatalog::Item> labels_;
bool labelsEnabled_;