summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swift/Controllers/Chat/ChatControllerBase.cpp')
-rw-r--r--Swift/Controllers/Chat/ChatControllerBase.cpp154
1 files changed, 154 insertions, 0 deletions
diff --git a/Swift/Controllers/Chat/ChatControllerBase.cpp b/Swift/Controllers/Chat/ChatControllerBase.cpp
new file mode 100644
index 0000000..5f78795
--- /dev/null
+++ b/Swift/Controllers/Chat/ChatControllerBase.cpp
@@ -0,0 +1,154 @@
+#include "Swift/Controllers/Chat/ChatControllerBase.h"
+
+#include <boost/bind.hpp>
+#include <boost/shared_ptr.hpp>
+
+#include "Swiften/Client/StanzaChannel.h"
+#include "Swiften/Base/foreach.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) : selfJID_(self), stanzaChannel_(stanzaChannel), iqRouter_(iqRouter), chatWindowFactory_(chatWindowFactory), toJID_(toJID), labelsEnabled_(false), presenceOracle_(presenceOracle), avatarManager_(avatarManager) {
+ chatWindow_ = chatWindowFactory_->createChatWindow(toJID);
+ chatWindow_->onAllMessagesRead.connect(boost::bind(&ChatControllerBase::handleAllMessagesRead, this));
+ chatWindow_->onSendMessageRequest.connect(boost::bind(&ChatControllerBase::handleSendMessageRequest, this, _1));
+ setEnabled(stanzaChannel->isAvailable() && iqRouter->isAvailable());
+}
+
+ChatControllerBase::~ChatControllerBase() {
+ delete chatWindow_;
+}
+
+void ChatControllerBase::setEnabled(bool enabled) {
+ chatWindow_->setInputEnabled(enabled);
+}
+
+void ChatControllerBase::setAvailableServerFeatures(boost::shared_ptr<DiscoInfo> info) {
+ if (iqRouter_->isAvailable() && info->hasFeature(DiscoInfo::SecurityLabels)) {
+ chatWindow_->setSecurityLabelsEnabled(true);
+ chatWindow_->setSecurityLabelsError();
+ boost::shared_ptr<GetSecurityLabelsCatalogRequest> request(new GetSecurityLabelsCatalogRequest(JID(toJID_.toBare()), iqRouter_));
+ request->onResponse.connect(boost::bind(&ChatControllerBase::handleSecurityLabelsCatalogResponse, this, _1, _2));
+ request->send();
+ labelsEnabled_ = true;
+ } else {
+ chatWindow_->setSecurityLabelsEnabled(false);
+ labelsEnabled_ = false;
+ }
+}
+
+void ChatControllerBase::handleAllMessagesRead() {
+ foreach (boost::shared_ptr<MessageEvent> messageEvent, unreadMessages_) {
+ messageEvent->read();
+ }
+ unreadMessages_.clear();
+ chatWindow_->setUnreadMessageCount(0);
+}
+
+void ChatControllerBase::handleSendMessageRequest(const String &body) {
+ if (!stanzaChannel_->isAvailable() || body.isEmpty()) {
+ return;
+ }
+ boost::shared_ptr<Message> message(new Message());
+ message->setTo(toJID_);
+ message->setType(Swift::Message::Chat);
+ message->setBody(body);
+ boost::optional<SecurityLabel> label;
+ if (labelsEnabled_) {
+ message->addPayload(boost::shared_ptr<SecurityLabel>(new SecurityLabel(chatWindow_->getSelectedSecurityLabel())));
+ label = boost::optional<SecurityLabel>(chatWindow_->getSelectedSecurityLabel());
+ }
+ preSendMessageRequest(message);
+ stanzaChannel_->sendMessage(message);
+ postSendMessage(message->getBody());
+}
+
+void ChatControllerBase::handleSecurityLabelsCatalogResponse(boost::shared_ptr<SecurityLabelsCatalog> catalog, const boost::optional<ErrorPayload>& error) {
+ if (!error) {
+ if (catalog->getLabels().size() == 0) {
+ chatWindow_->setSecurityLabelsEnabled(false);
+ labelsEnabled_ = false;
+ } else {
+ chatWindow_->setAvailableSecurityLabels(catalog->getLabels());
+ chatWindow_->setSecurityLabelsEnabled(true);
+ }
+ } else {
+ chatWindow_->setSecurityLabelsError();
+ }
+}
+
+void ChatControllerBase::showChatWindow() {
+ chatWindow_->show();
+}
+
+void ChatControllerBase::activateChatWindow() {
+ chatWindow_->activate();
+}
+
+void ChatControllerBase::addMessage(const String& message, const String& senderName, bool senderIsSelf, const boost::optional<SecurityLabel>& label, const String& avatarPath) {
+ if (message.beginsWith("/me ")) {
+ chatWindow_->addMessage(message, senderName, senderIsSelf, label, avatarPath);
+ } else {
+ chatWindow_->addAction(message, senderName, senderIsSelf, label, avatarPath);
+ }
+}
+
+void ChatControllerBase::handleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent) {
+ unreadMessages_.push_back(messageEvent);
+ chatWindow_->setUnreadMessageCount(unreadMessages_.size());
+
+ boost::shared_ptr<Message> message = messageEvent->getStanza();
+ preHandleIncomingMessage(message);
+ String body = message->getBody();
+ if (message->isError()) {
+ String errorMessage = getErrorMessage(message->getPayload<ErrorPayload>());
+ chatWindow_->addErrorMessage(errorMessage);
+ }
+ else {
+ showChatWindow();
+ boost::shared_ptr<SecurityLabel> label = message->getPayload<SecurityLabel>();
+ boost::optional<SecurityLabel> maybeLabel = label ? boost::optional<SecurityLabel>(*label) : boost::optional<SecurityLabel>();
+ JID from = message->getFrom();
+ addMessage(body, senderDisplayNameFromMessage(from), isIncomingMessageFromMe(message), maybeLabel, String(avatarManager_->getAvatarPath(from).string()));
+ }
+}
+
+String ChatControllerBase::getErrorMessage(boost::shared_ptr<ErrorPayload> error) {
+ String defaultMessage = "Error sending message";
+ if (!error->getText().isEmpty()) {
+ return error->getText();
+ }
+ else {
+ switch (error->getCondition()) {
+ case ErrorPayload::BadRequest: return defaultMessage; break;
+ case ErrorPayload::Conflict: return defaultMessage; break;
+ case ErrorPayload::FeatureNotImplemented: return defaultMessage; break;
+ case ErrorPayload::Forbidden: return defaultMessage; break;
+ case ErrorPayload::Gone: return "Recipient can no longer be contacted"; break;
+ case ErrorPayload::InternalServerError: return "Internal server error"; break;
+ case ErrorPayload::ItemNotFound: return defaultMessage; break;
+ case ErrorPayload::JIDMalformed: return defaultMessage; break;
+ case ErrorPayload::NotAcceptable: return "Message was rejected"; break;
+ case ErrorPayload::NotAllowed: return defaultMessage; break;
+ case ErrorPayload::NotAuthorized: return defaultMessage; break;
+ case ErrorPayload::PaymentRequired: return defaultMessage; break;
+ case ErrorPayload::RecipientUnavailable: return "Recipient is unavailable."; break;
+ case ErrorPayload::Redirect: return defaultMessage; break;
+ case ErrorPayload::RegistrationRequired: return defaultMessage; break;
+ case ErrorPayload::RemoteServerNotFound: return "Recipient's server not found."; break;
+ case ErrorPayload::RemoteServerTimeout: return defaultMessage; break;
+ case ErrorPayload::ResourceConstraint: return defaultMessage; break;
+ case ErrorPayload::ServiceUnavailable: return defaultMessage; break;
+ case ErrorPayload::SubscriptionRequired: return defaultMessage; break;
+ case ErrorPayload::UndefinedCondition: return defaultMessage; break;
+ case ErrorPayload::UnexpectedRequest: return defaultMessage; break;
+ }
+ }
+ return defaultMessage;
+}
+
+}