1 /*
2 * %kadu copyright begin%
3 * Copyright 2014 Rafał Przemysław Malinowski (rafal.przemyslaw.malinowski@gmail.com)
4 * %kadu copyright end%
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of
9 * the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "jabber-room-chat-service.h"
21
22 #include "services/jabber-presence-service.h"
23 #include "jabber-room-chat.h"
24 #include "jabber-protocol.h"
25 #include "jid.h"
26
27 #include "buddies/buddy-manager.h"
28 #include "chat/chat-details-room.h"
29 #include "chat/chat-manager.h"
30 #include "chat/chat.h"
31 #include "contacts/contact-manager.h"
32 #include "message/message-storage.h"
33
34 #include <qxmpp/QXmppClient.h>
35 #include <qxmpp/QXmppMessage.h>
36 #include <qxmpp/QXmppMucManager.h>
37
JabberRoomChatService(QXmppClient * client,QXmppMucManager * muc,Account account,QObject * parent)38 JabberRoomChatService::JabberRoomChatService(QXmppClient *client, QXmppMucManager *muc, Account account, QObject *parent) :
39 AccountService{account, parent},
40 m_client{client},
41 m_muc{muc}
42 {
43 connect(m_client, SIGNAL(connected()), this, SLOT(connected()));
44 }
45
~JabberRoomChatService()46 JabberRoomChatService::~JabberRoomChatService()
47 {
48 }
49
setBuddyManager(BuddyManager * buddyManager)50 void JabberRoomChatService::setBuddyManager(BuddyManager *buddyManager)
51 {
52 m_buddyManager = buddyManager;
53 }
54
setChatManager(ChatManager * chatManager)55 void JabberRoomChatService::setChatManager(ChatManager *chatManager)
56 {
57 m_chatManager = chatManager;
58 connect(m_chatManager, SIGNAL(chatOpened(Chat)), this, SLOT(chatOpened(Chat)));
59 connect(m_chatManager, SIGNAL(chatClosed(Chat)), this, SLOT(chatClosed(Chat)));
60 }
61
setContactManager(ContactManager * contactManager)62 void JabberRoomChatService::setContactManager(ContactManager *contactManager)
63 {
64 m_contactManager = contactManager;
65 }
66
setMessageStorage(MessageStorage * messageStorage)67 void JabberRoomChatService::setMessageStorage(MessageStorage *messageStorage)
68 {
69 m_messageStorage = messageStorage;
70 }
71
setPresenceService(JabberPresenceService * presenceService)72 void JabberRoomChatService::setPresenceService(JabberPresenceService *presenceService)
73 {
74 m_presenceService = presenceService;
75 }
76
init()77 void JabberRoomChatService::init()
78 {
79 for (auto &&chat : m_chatManager->chats(account()))
80 if (chat.isOpen() && myRoomChatDetails(chat))
81 getOrCreateRoomChat(chat);
82 }
83
myRoomChatDetails(const Chat & chat) const84 ChatDetailsRoom * JabberRoomChatService::myRoomChatDetails(const Chat &chat) const
85 {
86 if (chat.chatAccount() != account())
87 return nullptr;
88
89 return qobject_cast<ChatDetailsRoom *>(chat.details());
90 }
91
connected()92 void JabberRoomChatService::connected()
93 {
94 for (auto &&roomChat : m_chats)
95 roomChat->join();
96 }
97
getRoomChat(const QString & id) const98 JabberRoomChat * JabberRoomChatService::getRoomChat(const QString &id) const
99 {
100 for (auto &&roomChat : m_chats)
101 {
102 auto details = myRoomChatDetails(roomChat->chat());
103 if (details && details->room() == id)
104 return roomChat;
105 }
106
107 return nullptr;
108 }
109
getRoomChat(const Chat & chat) const110 JabberRoomChat * JabberRoomChatService::getRoomChat(const Chat &chat) const
111 {
112 if (chat.chatAccount() != account())
113 return nullptr;
114
115 if (m_chats.contains(chat))
116 return m_chats[chat];
117 else
118 return nullptr;
119 }
120
getOrCreateRoomChat(const Chat & chat)121 JabberRoomChat * JabberRoomChatService::getOrCreateRoomChat(const Chat &chat)
122 {
123 if (chat.chatAccount() != account())
124 return nullptr;
125
126 if (m_chats.contains(chat))
127 return m_chats[chat];
128
129 auto details = qobject_cast<ChatDetailsRoom *>(chat.details());
130 if (!details)
131 return nullptr;
132
133 auto room = m_muc->addRoom(details->room());
134 auto roomChat = new JabberRoomChat{room, chat, this};
135 roomChat->setBuddyManager(m_buddyManager);
136 roomChat->setContactManager(m_contactManager);
137 roomChat->setPresenceService(m_presenceService);
138
139 m_chats[chat] = roomChat;
140 return roomChat;
141 }
142
chatOpened(const Chat & chat)143 void JabberRoomChatService::chatOpened(const Chat &chat)
144 {
145 auto roomChat = getOrCreateRoomChat(chat);
146 if (!roomChat)
147 return;
148
149 if (m_client->isConnected())
150 roomChat->join();
151 }
152
chatClosed(const Chat & chat)153 void JabberRoomChatService::chatClosed(const Chat &chat)
154 {
155 auto roomChat = getRoomChat(chat);
156 if (!roomChat)
157 return;
158
159 if (!roomChat->stayInRoomAfterClosingWindow())
160 leaveChat(chat);
161 }
162
leaveChat(const Chat & chat)163 void JabberRoomChatService::leaveChat(const Chat &chat)
164 {
165 auto roomChat = getRoomChat(chat);
166 if (!roomChat)
167 return;
168
169 roomChat->leave();
170 m_chats[chat]->deleteLater();
171 m_chats.remove(chat);
172 }
173
isRoomChat(const Chat & chat) const174 bool JabberRoomChatService::isRoomChat(const Chat &chat) const
175 {
176 return myRoomChatDetails(chat) != nullptr;
177 }
178
handleReceivedMessage(const QXmppMessage & xmppMessage) const179 Message JabberRoomChatService::handleReceivedMessage(const QXmppMessage &xmppMessage) const
180 {
181 auto jid = Jid::parse(xmppMessage.from());
182 auto roomChat = getRoomChat(jid.bare());
183 if (!roomChat)
184 return Message::null;
185
186 if (jid.resource() == roomChat->nick()) // message from myself
187 return Message::null;
188
189 auto contact = m_contactManager->byId(account(), jid.full(), ActionCreateAndAdd);
190 auto buddy = m_buddyManager->byContact(contact, ActionCreateAndAdd);
191 buddy.setDisplay(jid.resource());
192 buddy.setTemporary(true);
193
194 auto result = m_messageStorage->create();
195 result.setMessageChat(roomChat->chat());
196 result.setMessageSender(contact);
197
198 return result;
199 }
200
201 #include "moc_jabber-room-chat-service.cpp"
202