1 /* This file is part of the KDE project
2 Copyright (C) 2005 Michal Vaner <michal.vaner@kdemail.net>
3 Copyright (C) 2008-2009 Pali Rohár <pali.rohar@gmail.com>
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License version 2 as published by the Free Software Foundation.
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA.
21 #include "skypechatsession.h"
22 #include "skypeaccount.h"
23 #include "skypeprotocol.h"
24 #include "skypecontact.h"
27 #include <kopetechatsessionmanager.h>
28 #include <kopetemetacontact.h>
29 #include <kopetecontactaction.h>
32 #include <kactionmenu.h>
33 #include <kactioncollection.h>
35 #include <kgenericfactory.h>
37 static Kopete::MetaContact
*dummyContacts
= new Kopete::MetaContact();
39 class ChatDummyContact
: public Kopete::Contact
{
41 ChatDummyContact(SkypeAccount
*account
, const QString
&name
) : Kopete::Contact(account
, name
, dummyContacts
) {};
42 virtual Kopete::ChatSession
*manager (CanCreateFlags canCreate
) {return 0L;};
45 class SkypeChatSessionPrivate
{
47 ///Dummy contact representing this chat
48 Kopete::Contact
*dummyContact
;
50 ///Referenco to the protocol
51 SkypeProtocol
*protocol
;
52 ///Reference to the account
53 SkypeAccount
*account
;
54 ///Am I connected to the messageSent signal?
56 ///ID of this chat session
60 * @param _protocol Reference to the Skype protocol
61 * @param _account Reference to the account this chat belongs to
63 SkypeChatSessionPrivate(SkypeProtocol
*_protocol
, SkypeAccount
*_account
) {
64 kDebug() << k_funcinfo
<< endl
;//some debug info
69 connectedSent
= false;
73 ///Is it multi-user chat?
75 ///Please give me a contact that stands for the whole chat so I can send it to it
76 Kopete::Contact
*getDummyContact() {
80 return dummyContact
= new ChatDummyContact(account
, chatId
);
83 ///The action to call the user(s)
85 ///The action to invite the user
86 KActionMenu
*inviteAction
;
87 ///The contact if any (and one)
88 SkypeContact
*contact
;
91 static Kopete::ContactPtrList
constructList(SkypeContact
*contact
) {
92 Kopete::ContactPtrList list
;//create the contact
93 list
.append(contact
);//add there the contact
95 return list
;//and return the list
98 SkypeChatSession::SkypeChatSession(SkypeAccount
*account
, SkypeContact
*contact
) :
99 Kopete::ChatSession(account
->myself(), constructList(contact
), account
->protocol(), Kopete::ChatSession::Form()) {
100 kDebug() << k_funcinfo
<< endl
;//some debug info
102 setComponentData(account
->protocol()->componentData());
104 //create the D-pointer
105 d
= new SkypeChatSessionPrivate(account
->protocol(), account
);
106 Kopete::ChatSessionManager::self()->registerChatSession( this );
107 connect(this, SIGNAL(messageSent(Kopete::Message
&, Kopete::ChatSession
*)), this, SLOT(message(Kopete::Message
& )));//this will send the messages from this user going out
108 account
->prepareChatSession(this);
111 d
->callAction
= new KAction(this);
112 d
->callAction
->setText(i18n("Call"));
113 d
->callAction
->setIcon(KIcon("skype_call"));
114 connect(d
->callAction
, SIGNAL(triggered()), SLOT(callChatSession()));
116 connect(contact
, SIGNAL(setActionsPossible(bool )), d
->callAction
, SLOT(setEnabled(bool )));
117 connect(this, SIGNAL(becameMultiChat(const QString
&, SkypeChatSession
* )), this, SLOT(disallowCall()));
119 actionCollection()->addAction("callSkypeContactFromChat", d
->callAction
);
121 d
->contact
= contact
;
123 d
->inviteAction
= new KActionMenu (KIcon("system-users"), i18n ("&Invite"), this);
124 d
->inviteAction
->setDelayed(false);
125 connect( d
->inviteAction
->menu(), SIGNAL(aboutToShow()), this, SLOT(showInviteMenu()) );
126 connect( d
->inviteAction
->menu(), SIGNAL(aboutToHide()), this, SLOT(hideInviteMenu()) );
127 actionCollection()->addAction("skypeInvite", d
->inviteAction
);
129 setMayInvite(true);//It is possible to invite people to chat with Skype
130 setXMLFile("skypechatui.rc");
133 SkypeChatSession::SkypeChatSession(SkypeAccount
*account
, const QString
&session
, const Kopete::ContactPtrList
&users
) :
134 Kopete::ChatSession(account
->myself(), users
, account
->protocol(), Kopete::ChatSession::Form()) {
135 kDebug() << k_funcinfo
<< endl
;//some debug info
137 setComponentData(account
->protocol()->componentData());
139 //create the D-pointer
140 d
= new SkypeChatSessionPrivate(account
->protocol(), account
);
141 Kopete::ChatSessionManager::self()->registerChatSession(this);
142 connect(this, SIGNAL(messageSent(Kopete::Message
&, Kopete::ChatSession
*)), this, SLOT(message(Kopete::Message
& )));
143 account
->prepareChatSession(this);
146 emit
updateChatId("", session
, this);
148 d
->callAction
= new KAction(this);
149 d
->callAction
->setText(i18n("Call"));
150 d
->callAction
->setIcon(KIcon("skype_call"));
151 connect(d
->callAction
, SIGNAL(triggered()), SLOT(callChatSession()));
153 actionCollection()->addAction("callSkypeContactFromChat", d
->callAction
);
155 disallowCall();//TODO I hope it will not be needed in future
157 d
->inviteAction
= new KActionMenu (KIcon("system-users"), i18n ("&Invite"), this);
158 d
->inviteAction
->setDelayed(false);
159 connect( d
->inviteAction
->menu(), SIGNAL(aboutToShow()), this, SLOT(showInviteMenu()) );
160 connect( d
->inviteAction
->menu(), SIGNAL(aboutToHide()), this, SLOT(hideInviteMenu()) );
161 actionCollection()->addAction("skypeInvite", d
->inviteAction
);
163 setMayInvite(true);//It is possible to invite people to chat with Skype
164 setXMLFile("skypechatui.rc");
167 SkypeChatSession::~SkypeChatSession() {
168 kDebug() << k_funcinfo
<< endl
;//some debug info
170 if (d
->account
->leaveOnExit() && (d
->isMulti
))
171 emit
leaveChat(d
->chatId
);
172 emit
updateChatId(d
->chatId
, "", this);
173 delete d
->inviteAction
;//remove invite action menu
174 delete d
;//remove the D pointer
177 void SkypeChatSession::message(Kopete::Message
&message
) {
178 kDebug() << k_funcinfo
<< endl
;//some debug info
180 d
->account
->registerLastSession(this);
181 d
->account
->sendMessage(message
, (d
->isMulti
) ? (d
->chatId
) : "");//send it
185 void SkypeChatSession::setTopic(const QString
&chat
, const QString
&topic
) {
191 void SkypeChatSession::joinUser(const QString
&chat
, const QString
&userId
) {
192 kDebug() << k_funcinfo
<< "Chat: " << chat
<< endl
;//some debug info
194 if (chat
== d
->chatId
) {
195 addContact(d
->account
->getContact(userId
));
197 emit
becameMultiChat(d
->chatId
, this);
201 void SkypeChatSession::leftUser(const QString
&chat
, const QString
&userId
, const QString
&reason
) {
202 kDebug() << "User: " << userId
<< k_funcinfo
<< endl
;//some debug info
204 if (chat
== d
->chatId
) {
205 removeContact(d
->account
->getContact(userId
), reason
);
209 void SkypeChatSession::setChatId(const QString
&chatId
) {
210 kDebug() << k_funcinfo
<< "ID: " << chatId
<< endl
;//some debug info
212 if (d
->chatId
!= chatId
) {
213 emit
updateChatId(d
->chatId
, chatId
, this);
215 emit
wantTopic(chatId
);
219 void SkypeChatSession::sentMessage(const QList
<Kopete::Contact
*> *recv
, const QString
&body
) {
220 Kopete::Message
*mes
;
221 if (recv
->count() == 1) {
222 mes
= new Kopete::Message(d
->account
->myself(), *recv
->begin());
223 mes
->setDirection(Kopete::Message::Outbound
);
224 mes
->setPlainBody(body
);
226 mes
= new Kopete::Message(d
->account
->myself(), d
->account
->myself());
227 mes
->setDirection(Kopete::Message::Outbound
);
228 mes
->setPlainBody(body
);
230 mes
= new Kopete::Message(d
->account
->myself(), *recv
);
231 mes
->setDirection(Kopete::Message::Outbound
);
232 mes
->setPlainBody(body
);
237 void SkypeChatSession::disallowCall() {
238 d
->callAction
->setEnabled(false);
241 disconnect(d->contact, SIGNAL(setActionsPossible(bool )), d->callAction, SLOT(setEnabled(bool )));
246 void SkypeChatSession::callChatSession() {
247 if (d
->contact
)///@todo find a better way to do it later to allow multiple people to call
251 void SkypeChatSession::inviteContact(const QString
&contactId
) {
252 if (d
->chatId
.isEmpty()) {
253 d
->chatId
= d
->account
->createChat(d
->contact
->contactId());
254 emit
updateChatId("", d
->chatId
, this);
257 emit
inviteUserToChat(d
->chatId
, contactId
);
260 void SkypeChatSession::inviteContact(Kopete::Contact
* contact
) {
261 inviteContact(contact
->contactId());
264 void SkypeChatSession::showInviteMenu() {
267 QHash
<QString
, Kopete::Contact
*> contactList
= account()->contacts();
268 for ( QHash
<QString
, Kopete::Contact
*>::Iterator it
= contactList
.begin(); it
!= contactList
.end(); ++it
) {
269 if ( ! members().contains(it
.value()) && it
.value()->isOnline() && it
.value()->onlineStatus().status() != Kopete::OnlineStatus::Offline
&& it
.value() != myself() ) {
270 KAction
*a
= new Kopete::UI::ContactAction(it
.value(), actionCollection());
271 connect( a
, SIGNAL(triggered(Kopete::Contact
*, bool)), this, SLOT(inviteContact(Kopete::Contact
*)) );
272 d
->inviteAction
->addAction(a
);
277 void SkypeChatSession::hideInviteMenu() {
280 //Detele all invite actions for all contacts
281 //QList <QAction *> actions = d->inviteAction->menu()->actions();
282 //for ( QList <QAction *>::Iterator it = actions.begin(); it != actions.end(); ++it )
286 d
->inviteAction
->menu()->clear();
289 #include "skypechatsession.moc"