summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swift/Controllers/Chat/ChatController.cpp')
-rw-r--r--Swift/Controllers/Chat/ChatController.cpp110
1 files changed, 90 insertions, 20 deletions
diff --git a/Swift/Controllers/Chat/ChatController.cpp b/Swift/Controllers/Chat/ChatController.cpp
index 22ef68d..a3d9fb5 100644
--- a/Swift/Controllers/Chat/ChatController.cpp
+++ b/Swift/Controllers/Chat/ChatController.cpp
@@ -11,16 +11,22 @@
#include <Swift/Controllers/Intl.h>
#include <Swiften/Base/format.h>
-#include "Swiften/Avatars/AvatarManager.h"
-#include "Swiften/Chat/ChatStateNotifier.h"
-#include "Swiften/Chat/ChatStateTracker.h"
-#include "Swiften/Client/StanzaChannel.h"
-#include "Swiften/Disco/EntityCapsProvider.h"
-#include "Swift/Controllers/UIInterfaces/ChatWindow.h"
-#include "Swift/Controllers/UIInterfaces/ChatWindowFactory.h"
-#include "Swiften/Client/NickResolver.h"
-#include "Swift/Controllers/XMPPEvents/EventController.h"
+#include <Swiften/Base/Algorithm.h>
+#include <Swiften/Avatars/AvatarManager.h>
+#include <Swiften/Chat/ChatStateNotifier.h>
+#include <Swiften/Chat/ChatStateTracker.h>
+#include <Swiften/Client/StanzaChannel.h>
+#include <Swift/Controllers/UIInterfaces/ChatWindow.h>
+#include <Swift/Controllers/UIInterfaces/ChatWindowFactory.h>
+#include <Swiften/Client/NickResolver.h>
+#include <Swift/Controllers/XMPPEvents/EventController.h>
+#include <Swift/Controllers/FileTransfer/FileTransferController.h>
#include <Swift/Controllers/StatusUtil.h>
+#include <Swiften/Disco/EntityCapsProvider.h>
+#include <Swiften/Base/foreach.h>
+#include <Swift/Controllers/UIEvents/UIEventStream.h>
+#include <Swift/Controllers/UIEvents/SendFileUIEvent.h>
+
namespace Swift {
@@ -28,7 +34,7 @@ namespace Swift {
* The controller does not gain ownership of the stanzaChannel, nor the factory.
*/
ChatController::ChatController(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &contact, NickResolver* nickResolver, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool isInMUC, bool useDelayForLatency, UIEventStream* eventStream, EventController* eventController, TimerFactory* timerFactory, EntityCapsProvider* entityCapsProvider)
- : ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, contact, presenceOracle, avatarManager, useDelayForLatency, eventStream, eventController, timerFactory) {
+ : ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, contact, presenceOracle, avatarManager, useDelayForLatency, eventStream, eventController, timerFactory, entityCapsProvider), eventStream_(eventStream) {
isInMUC_ = isInMUC;
lastWasPresence_ = false;
chatStateNotifier_ = new ChatStateNotifier(stanzaChannel, contact, entityCapsProvider);
@@ -59,6 +65,11 @@ ChatController::ChatController(const JID& self, StanzaChannel* stanzaChannel, IQ
chatWindow_->addSystemMessage(startMessage);
chatWindow_->onUserTyping.connect(boost::bind(&ChatStateNotifier::setUserIsTyping, chatStateNotifier_));
chatWindow_->onUserCancelsTyping.connect(boost::bind(&ChatStateNotifier::userCancelledNewMessage, chatStateNotifier_));
+ chatWindow_->onFileTransferStart.connect(boost::bind(&ChatController::handleFileTransferStart, this, _1, _2));
+ chatWindow_->onFileTransferAccept.connect(boost::bind(&ChatController::handleFileTransferAccept, this, _1, _2));
+ chatWindow_->onFileTransferCancel.connect(boost::bind(&ChatController::handleFileTransferCancel, this, _1));
+ chatWindow_->onSendFileRequest.connect(boost::bind(&ChatController::handleSendFileRequest, this, _1));
+ handleBareJIDCapsChanged(toJID_);
}
@@ -74,6 +85,19 @@ ChatController::~ChatController() {
delete chatStateTracker_;
}
+void ChatController::handleBareJIDCapsChanged(const JID& /*jid*/) {
+ DiscoInfo::ref disco = entityCapsProvider_->getCaps(toJID_);
+ if (disco) {
+ if (disco->hasFeature(DiscoInfo::MessageCorrectionFeature)) {
+ chatWindow_->setCorrectionEnabled(ChatWindow::Yes);
+ } else {
+ chatWindow_->setCorrectionEnabled(ChatWindow::No);
+ }
+ } else {
+ chatWindow_->setCorrectionEnabled(ChatWindow::Maybe);
+ }
+}
+
void ChatController::setToJID(const JID& jid) {
chatStateNotifier_->setContact(jid);
ChatControllerBase::setToJID(jid);
@@ -84,6 +108,7 @@ void ChatController::setToJID(const JID& jid) {
presence = jid.isBare() ? presenceOracle_->getHighestPriorityPresence(jid.toBare()) : presenceOracle_->getLastPresence(jid);
}
chatStateNotifier_->setContactIsOnline(presence && presence->getType() == Presence::Available);
+ handleBareJIDCapsChanged(toJID_);
}
bool ChatController::isIncomingMessageFromMe(boost::shared_ptr<Message>) {
@@ -102,8 +127,8 @@ void ChatController::preHandleIncomingMessage(boost::shared_ptr<MessageEvent> me
setToJID(from);
}
}
- chatStateNotifier_->receivedMessageFromContact(message->getPayload<ChatState>());
chatStateTracker_->handleMessageReceived(message);
+ chatStateNotifier_->receivedMessageFromContact(message->getPayload<ChatState>());
}
void ChatController::postHandleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent) {
@@ -116,27 +141,33 @@ void ChatController::preSendMessageRequest(boost::shared_ptr<Message> message) {
}
void ChatController::postSendMessage(const std::string& body, boost::shared_ptr<Stanza> sentStanza) {
- std::string id = addMessage(body, QT_TRANSLATE_NOOP("", "me"), true, labelsEnabled_ ? chatWindow_->getSelectedSecurityLabel().getLabel() : boost::shared_ptr<SecurityLabel>(), std::string(avatarManager_->getAvatarPath(selfJID_).string()), boost::posix_time::microsec_clock::universal_time());
- if (stanzaChannel_->getStreamManagementEnabled()) {
- chatWindow_->setAckState(id, ChatWindow::Pending);
- unackedStanzas_[sentStanza] = id;
+ boost::shared_ptr<Replace> replace = sentStanza->getPayload<Replace>();
+ if (replace) {
+ eraseIf(unackedStanzas_, PairSecondEquals<boost::shared_ptr<Stanza>, std::string>(myLastMessageUIID_));
+ chatWindow_->replaceMessage(body, myLastMessageUIID_, boost::posix_time::microsec_clock::universal_time());
+ } else {
+ myLastMessageUIID_ = addMessage(body, QT_TRANSLATE_NOOP("", "me"), true, labelsEnabled_ ? chatWindow_->getSelectedSecurityLabel().getLabel() : boost::shared_ptr<SecurityLabel>(), std::string(avatarManager_->getAvatarPath(selfJID_).string()), boost::posix_time::microsec_clock::universal_time());
+ }
+ if (stanzaChannel_->getStreamManagementEnabled() && !myLastMessageUIID_.empty() ) {
+ chatWindow_->setAckState(myLastMessageUIID_, ChatWindow::Pending);
+ unackedStanzas_[sentStanza] = myLastMessageUIID_;
}
lastWasPresence_ = false;
chatStateNotifier_->userSentMessage();
}
void ChatController::handleStanzaAcked(boost::shared_ptr<Stanza> stanza) {
- std::string id = unackedStanzas_[stanza];
- if (id != "") {
- chatWindow_->setAckState(id, ChatWindow::Received);
+ std::map<boost::shared_ptr<Stanza>, std::string>::iterator unackedStanza = unackedStanzas_.find(stanza);
+ if (unackedStanza != unackedStanzas_.end()) {
+ chatWindow_->setAckState(unackedStanza->second, ChatWindow::Received);
+ unackedStanzas_.erase(unackedStanza);
}
- unackedStanzas_.erase(unackedStanzas_.find(stanza));
}
void ChatController::setOnline(bool online) {
if (!online) {
std::map<boost::shared_ptr<Stanza>, std::string>::iterator it = unackedStanzas_.begin();
- for ( ; it != unackedStanzas_.end(); it++) {
+ for ( ; it != unackedStanzas_.end(); ++it) {
chatWindow_->setAckState(it->second, ChatWindow::Failed);
}
unackedStanzas_.clear();
@@ -149,6 +180,45 @@ void ChatController::setOnline(bool online) {
ChatControllerBase::setOnline(online);
}
+void ChatController::handleNewFileTransferController(FileTransferController* ftc) {
+ std::string nick = senderDisplayNameFromMessage(ftc->getOtherParty());
+ std::string ftID = ftc->setChatWindow(chatWindow_, nick);
+
+ ftControllers[ftID] = ftc;
+}
+
+void ChatController::handleFileTransferCancel(std::string id) {
+ std::cout << "handleFileTransferCancel(" << id << ")" << std::endl;
+ if (ftControllers.find(id) != ftControllers.end()) {
+ ftControllers[id]->cancel();
+ } else {
+ std::cerr << "unknown file transfer UI id" << std::endl;
+ }
+}
+
+void ChatController::handleFileTransferStart(std::string id, std::string description) {
+ std::cout << "handleFileTransferStart(" << id << ", " << description << ")" << std::endl;
+ if (ftControllers.find(id) != ftControllers.end()) {
+ ftControllers[id]->start(description);
+ } else {
+ std::cerr << "unknown file transfer UI id" << std::endl;
+ }
+}
+
+void ChatController::handleFileTransferAccept(std::string id, std::string filename) {
+ std::cout << "handleFileTransferAccept(" << id << ", " << filename << ")" << std::endl;
+ if (ftControllers.find(id) != ftControllers.end()) {
+ ftControllers[id]->accept(filename);
+ } else {
+ std::cerr << "unknown file transfer UI id" << std::endl;
+ }
+}
+
+void ChatController::handleSendFileRequest(std::string filename) {
+ std::cout << "ChatController::handleSendFileRequest(" << filename << ")" << std::endl;
+ eventStream_->send(boost::make_shared<SendFileUIEvent>(getToJID(), filename));
+}
+
std::string ChatController::senderDisplayNameFromMessage(const JID& from) {
return nickResolver_->jidToNick(from);
}