1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
/*
* Copyright (c) 2010 Kevin Smith
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#include "Swift/Controllers/Chat/ChatController.h"
#include <boost/bind.hpp>
#include "Swiften/Avatars/AvatarManager.h"
#include "Swiften/Chat/ChatStateNotifier.h"
#include "Swiften/Chat/ChatStateMessageSender.h"
#include "Swiften/Chat/ChatStateTracker.h"
#include "Swift/Controllers/UIInterfaces/ChatWindow.h"
#include "Swift/Controllers/UIInterfaces/ChatWindowFactory.h"
#include "Swift/Controllers/NickResolver.h"
#include "Swift/Controllers/EventController.h"
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)
: ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, contact, presenceOracle, avatarManager, useDelayForLatency, eventStream, eventController) {
isInMUC_ = isInMUC;
chatStateNotifier_ = new ChatStateNotifier();
chatStateMessageSender_ = new ChatStateMessageSender(chatStateNotifier_, stanzaChannel, contact);
chatStateTracker_ = new ChatStateTracker();
nickResolver_ = nickResolver;
presenceOracle_->onPresenceChange.connect(boost::bind(&ChatController::handlePresenceChange, this, _1, _2));
chatStateTracker_->onChatStateChange.connect(boost::bind(&ChatWindow::setContactChatState, chatWindow_, _1));
String nick = nickResolver_->jidToNick(toJID_);
chatWindow_->setName(nick);
String startMessage("Starting chat with " + nick);
if (isInMUC) {
startMessage += " in chatroom " + contact.toBare().toString() + ".";
} else {
startMessage += " (" + contact.toBare().toString() + ").";
}
chatWindow_->addSystemMessage(startMessage);
chatWindow_->onUserTyping.connect(boost::bind(&ChatStateNotifier::setUserIsTyping, chatStateNotifier_));
chatWindow_->onUserCancelsTyping.connect(boost::bind(&ChatStateNotifier::userCancelledNewMessage, chatStateNotifier_));
}
ChatController::~ChatController() {
delete chatStateNotifier_;
delete chatStateMessageSender_;
delete chatStateTracker_;
}
void ChatController::setToJID(const JID& jid) {
chatStateMessageSender_->setContact(jid);
ChatControllerBase::setToJID(jid);
}
bool ChatController::isIncomingMessageFromMe(boost::shared_ptr<Message>) {
return false;
}
void ChatController::preHandleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent) {
eventController_->handleIncomingEvent(messageEvent);
boost::shared_ptr<Message> message = messageEvent->getStanza();
JID from = message->getFrom();
if (!from.equals(toJID_, JID::WithResource)) {
if (toJID_.equals(from, JID::WithoutResource) && toJID_.isBare()){
toJID_ = from;
}
}
chatStateNotifier_->receivedMessageFromContact(message->getPayload<ChatState>());
chatStateTracker_->handleMessageReceived(message);
}
void ChatController::preSendMessageRequest(boost::shared_ptr<Message> message) {
if (chatStateNotifier_->contactShouldReceiveStates()) {
message->addPayload(boost::shared_ptr<Payload>(new ChatState(ChatState::Active)));
}
}
void ChatController::postSendMessage(const String& body) {
addMessage(body, "me", true, labelsEnabled_ ? chatWindow_->getSelectedSecurityLabel() : boost::optional<SecurityLabel>(), String(avatarManager_->getAvatarPath(selfJID_).string()), boost::posix_time::microsec_clock::universal_time());
chatStateNotifier_->userSentMessage();
}
String ChatController::senderDisplayNameFromMessage(const JID& from) {
return nickResolver_->jidToNick(from);
}
String ChatController::getStatusChangeString(boost::shared_ptr<Presence> presence) {
String nick = senderDisplayNameFromMessage(presence->getFrom());
if (presence->getType() == Presence::Unavailable) {
return nick + " has gone offline.";
} else if (presence->getType() == Presence::Available) {
StatusShow::Type show = presence->getShow();
if (show == StatusShow::Online || show == StatusShow::FFC) {
return nick + " has become available.";
} else if (show == StatusShow::Away || show == StatusShow::XA) {
return nick + " has gone away.";
} else if (show == StatusShow::DND) {
return nick + " is now busy.";
}
}
return "";
}
void ChatController::handlePresenceChange(boost::shared_ptr<Presence> newPresence, boost::shared_ptr<Presence> previousPresence) {
if (!toJID_.equals(newPresence->getFrom(), toJID_.isBare() ? JID::WithoutResource : JID::WithResource)) {
return;
}
chatStateTracker_->handlePresenceChange(newPresence, previousPresence);
String newStatusChangeString = getStatusChangeString(newPresence);
if (!previousPresence || newStatusChangeString != getStatusChangeString(previousPresence)) {
chatWindow_->addPresenceMessage(newStatusChangeString);
}
}
boost::optional<boost::posix_time::ptime> ChatController::getMessageTimestamp(boost::shared_ptr<Message> message) const {
return message->getTimestamp();
}
}
|