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 "skypeaccount.h"
22 #include "skypeprotocol.h"
23 #include "skypecontact.h"
25 #include "skypecalldialog.h"
26 #include "skypechatsession.h"
27 #include "skypeconference.h"
30 #include <kopetemetacontact.h>
31 #include <kopeteonlinestatus.h>
32 #include <kopetecontactlist.h>
33 #include <kopetecontact.h>
34 #include <kopetegroup.h>
36 #include <kmessagebox.h>
38 #include <kconfigbase.h>
40 #include <kopetemessage.h>
43 class SkypeAccountPrivate
{
45 ///The skype protocol pointer
46 SkypeProtocol
*protocol
;
47 ///ID of this account (means my skype name)
51 ///The hitchhike mode of incoming messages
53 ///The mark read messages mode
55 ///Search for unread messages on login?
57 ///Do we show call control window?
59 ///Metacontact for all users that aren't in the list
60 Kopete::MetaContact notInListUsers
;
62 SkypeAccountPrivate(SkypeAccount
&account
) : skype(account
) {};//just an empty constructor
63 ///Automatic close of call window when the call finishes (in seconds, 0 -> disabled)
64 int callWindowTimeout
;
65 ///Are the pings enabled?
67 ///What bus are we using, session (0) or system (1)?
69 ///How long can I keep trying connect to newly started skype, before I give up (seconds)
71 ///By what command is the skype started?
73 ///What is my name, by the way?
75 ///Do we wait before connecting?
76 int waitBeforeConnect
;
77 ///List of chat all chat sessions
78 Q3Dict
<SkypeChatSession
> sessions
;
79 ///Last used chat session
80 SkypeChatSession
*lastSession
;
81 ///List of the conference calls
82 Q3Dict
<SkypeConference
> conferences
;
83 ///List of existing calls
84 Q3Dict
<SkypeCallDialog
> calls
;
85 ///Shall chat window leave the chat whenit is closed
87 ///Executed before making the call
88 QString startCallCommand
;
89 ///Executed after finished the call
90 QString endCallCommand
;
91 ///Wait for the start call command to finitsh?
92 bool waitForStartCallCommand
;
93 ///Execute the end call command only if no other calls exists?
94 bool endCallCommandOnlyLats
;
95 ///How many calls are opened now?
97 ///Command executed on incoming call
98 QString incommingCommand
;
101 SkypeAccount::SkypeAccount(SkypeProtocol
*protocol
, const QString
& accountID
) : Kopete::Account(protocol
, accountID
) {
102 kDebug() << k_funcinfo
<< endl
;//some debug info
104 //keep track of what accounts the protocol has
105 protocol
->registerAccount(this);
108 d
= new SkypeAccountPrivate(*this);
109 d
->calls
.setAutoDelete(false);
110 d
->conferences
.setAutoDelete(false);
111 //remember the protocol, it will be needed
112 d
->protocol
= protocol
;
114 //load the properties
115 KConfigGroup
*config
= configGroup();
116 author
= config
->readEntry("Authorization");//get the name how to authorize myself
117 launchType
= config
->readEntry("Launch", 0);//launch the skype?
118 setScanForUnread(config
->readEntry("ScanForUnread", true));
119 setCallControl(config
->readEntry("CallControl", false));
120 setPings(config
->readEntry("Pings", true));
121 setBus(config
->readEntry("Bus", 1));
122 setLaunchTimeout(config
->readEntry("LaunchTimeout", 30));
123 d
->myName
= config
->readEntry("MyselfName", "Skype");
124 setSkypeCommand(config
->readEntry("SkypeCommand", "skype"));
125 setWaitBeforeConnect(config
->readEntry("WaitBeforeConnect", 0));
126 setLeaveOnExit(config
->readEntry("LeaveOnExit", false));
127 setStartCallCommand(config
->readEntry("StartCallCommand", ""));
128 setEndCallCommand(config
->readEntry("EndCallCommand", ""));
129 setWaitForStartCallCommand(config
->readEntry("WaitForStartCallCommand", false));
130 setEndCallCommandOnlyForLast(config
->readEntry("EndCallCommandOnlyLast", false));
131 setIncomingCommand(config
->readEntry("IncomingCall", ""));
133 //create myself contact
134 SkypeContact
*_myself
= new SkypeContact(this, "Skype", Kopete::ContactList::self()->myself(), false);
136 //and set default online status (means offline)
137 myself()->setOnlineStatus(protocol
->Offline
);
139 //Now, connect the signals
140 QObject::connect(&d
->skype
, SIGNAL(wentOnline()), this, SLOT(wentOnline()));
141 QObject::connect(&d
->skype
, SIGNAL(wentOffline()), this, SLOT(wentOffline()));
142 QObject::connect(&d
->skype
, SIGNAL(wentAway()), this, SLOT(wentAway()));
143 QObject::connect(&d
->skype
, SIGNAL(wentNotAvailable()), this, SLOT(wentNotAvailable()));
144 QObject::connect(&d
->skype
, SIGNAL(wentDND()), this, SLOT(wentDND()));
145 QObject::connect(&d
->skype
, SIGNAL(wentInvisible()), this, SLOT(wentInvisible()));
146 QObject::connect(&d
->skype
, SIGNAL(wentSkypeMe()), this, SLOT(wentSkypeMe()));
147 QObject::connect(&d
->skype
, SIGNAL(statusConnecting()), this, SLOT(statusConnecting()));
148 QObject::connect(&d
->skype
, SIGNAL(newUser(const QString
&, int)), this, SLOT(newUser(const QString
&, int)));
149 QObject::connect(&d
->skype
, SIGNAL(contactInfo(const QString
&, const QString
& )), this, SLOT(updateContactInfo(const QString
&, const QString
& )));
150 QObject::connect(&d
->skype
, SIGNAL(receivedIM(const QString
&, const QString
&, const QString
& )), this, SLOT(receivedIm(const QString
&, const QString
&, const QString
& )));
151 QObject::connect(&d
->skype
, SIGNAL(gotMessageId(const QString
& )), this, SLOT(gotMessageId(const QString
& )));//every time some ID is known inform the contacts
152 QObject::connect(&d
->skype
, SIGNAL(newCall(const QString
&, const QString
&)), this, SLOT(newCall(const QString
&, const QString
&)));
153 QObject::connect(&d
->skype
, SIGNAL(setMyselfName(const QString
&)), this, SLOT(setMyselfName(const QString
& )));
154 QObject::connect(&d
->skype
, SIGNAL(receivedMultiIM(const QString
&, const QString
&, const QString
&, const QString
& )), this, SLOT(receiveMultiIm(const QString
&, const QString
&, const QString
&, const QString
& )));
155 QObject::connect(&d
->skype
, SIGNAL(outgoingMessage(const QString
&, const QString
&)), this, SLOT(sentMessage(const QString
&, const QString
& )));
156 QObject::connect(&d
->skype
, SIGNAL(groupCall(const QString
&, const QString
& )), this, SLOT(groupCall(const QString
&, const QString
& )));
157 QObject::connect(Kopete::ContactList::self(), SIGNAL(groupRemoved (Kopete::Group
*)), this, SLOT(deleteGroup (Kopete::Group
*) ) );
158 QObject::connect(Kopete::ContactList::self(), SIGNAL(groupRenamed (Kopete::Group
*, const QString
& )), this, SLOT(renameGroup (Kopete::Group
*, const QString
& )) );
160 //set values for the connection (should be updated if changed)
161 d
->skype
.setValues(launchType
, author
);
162 setHitchHike(config
->readEntry("Hitch", true));
163 setMarkRead(config
->readEntry("MarkRead", true));//read the modes of account
164 d
->callWindowTimeout
= config
->readEntry("CloseWindowTimeout", 4);
165 setPings(config
->readEntry("Pings", true));
166 d
->sessions
.setAutoDelete(false);
172 SkypeAccount::~SkypeAccount() {
173 kDebug() << k_funcinfo
<< endl
;//some debug info
177 d
->protocol
->unregisterAccount();//This account no longer exists
183 bool SkypeAccount::createContact(const QString
&contactID
, Kopete::MetaContact
*parentContact
) {
184 kDebug() << k_funcinfo
<< endl
;//some debug info
186 if (!contact(contactID
)) {//check weather it is not used already
187 SkypeContact
*newContact
= new SkypeContact(this, contactID
, parentContact
);//create the contact
189 return newContact
!= 0L;//test weather it was created
191 kDebug() << k_funcinfo
<< "Contact already exists:" << contactID
<< endl
;//Tell that it is not OK
197 void SkypeAccount::setAway(bool away
, const QString
&reason
) {
198 kDebug() << k_funcinfo
<< endl
;//some debug info
201 setOnlineStatus(d
->protocol
->Away
, reason
);
203 setOnlineStatus(d
->protocol
->Online
, reason
);
206 void SkypeAccount::setOnlineStatus(const Kopete::OnlineStatus
&status
, const Kopete::StatusMessage
&reason
, const OnlineStatusOptions
& options
) {
207 kDebug() << k_funcinfo
<< endl
;//some debug info
209 if (status
== d
->protocol
->Online
)
210 d
->skype
.setOnline();//Go online
211 else if (status
== d
->protocol
->Offline
)
212 d
->skype
.setOffline();//Go offline
213 else if (status
== d
->protocol
->Away
)
215 else if (status
== d
->protocol
->NotAvailable
)
216 d
->skype
.setNotAvailable();
217 else if (status
== d
->protocol
->DoNotDisturb
)
219 else if (status
== d
->protocol
->Invisible
)
220 d
->skype
.setInvisible();
221 else if (status
== d
->protocol
->SkypeMe
)
222 d
->skype
.setSkypeMe();
224 kDebug() << "Unknown online status" << endl
;//Just a warning that I do not know that status
226 ///TODO: Port to kde4
231 void SkypeAccount::setStatusMessage(const Kopete::StatusMessage
&statusMessage
)
233 ///TODO: Port to kde4
234 Q_UNUSED(statusMessage
);
237 void SkypeAccount::disconnect() {
238 kDebug() << k_funcinfo
<< endl
;//some debug info
240 setOnlineStatus(d
->protocol
->Offline
, Kopete::StatusMessage());
243 SkypeContact
*SkypeAccount::contact(const QString
&id
) {
244 kDebug() << k_funcinfo
<< endl
;//some debug info
246 return static_cast<SkypeContact
*>(contacts()[id
]);//get the contact and convert it into the skype contact, there are no other contacts anyway
249 void SkypeAccount::connect(const Kopete::OnlineStatus
&Status
) {
250 kDebug() << k_funcinfo
<< endl
;//some debug info
252 if ((Status
!= d
->protocol
->Online
) && (Status
!= d
->protocol
->Away
) &&
253 (Status
!= d
->protocol
->NotAvailable
) && (Status
!= d
->protocol
->DoNotDisturb
) &&
254 (Status
!= d
->protocol
->SkypeMe
))//some strange online status, taje a default one
255 setOnlineStatus(d
->protocol
->Online
, Kopete::StatusMessage());
257 setOnlineStatus(Status
, Kopete::StatusMessage());//just change the status
261 void SkypeAccount::save() {
262 kDebug() << k_funcinfo
<< endl
;//some debug info
264 KConfigGroup
*config
= configGroup();//get the config
265 config
->writeEntry("Authorization", author
);//write the authorization name
266 config
->writeEntry("Launch", launchType
);//and the launch type
267 config
->writeEntry("Hitch", getHitchHike());//save the hitch hike messages mode
268 config
->writeEntry("MarkRead", getMarkRead());//save the Mark read messages mode
269 config
->writeEntry("ScanForUnread", getScanForUnread());
270 config
->writeEntry("CallControl", getCallControl());
271 config
->writeEntry("CloseWindowTimeout", d
->callWindowTimeout
);
272 config
->writeEntry("Pings", getPings());
273 config
->writeEntry("Bus", getBus());
274 config
->writeEntry("LaunchTimeout", getLaunchTimeout());
275 config
->writeEntry("SkypeCommand", getSkypeCommand());
276 config
->writeEntry("MyselfName", d
->myName
);
277 config
->writeEntry("WaitBeforeConnect", getWaitBeforeConnect());
278 config
->writeEntry("LeaveOnExit", leaveOnExit());
279 config
->writeEntry("StartCallCommand", startCallCommand());
280 config
->writeEntry("EndCallCommand", endCallCommand());
281 config
->writeEntry("WaitForStartCallCommand", waitForStartCallCommand());
282 config
->writeEntry("EndCallCommandOnlyLast", endCallCommandOnlyLast());
283 config
->writeEntry("IncomingCall", incomingCommand());
285 //save it into the skype connection as well
286 d
->skype
.setValues(launchType
, author
);
289 void SkypeAccount::wentOnline() {
290 kDebug() << k_funcinfo
<< endl
;//some debug info
292 myself()->setOnlineStatus(d
->protocol
->Online
);//just set the icon
293 d
->skype
.enablePings(d
->pings
);
294 emit
connectionStatus(true);
297 void SkypeAccount::wentOffline() {
298 kDebug() << k_funcinfo
<< endl
;//some debug info
300 myself()->setOnlineStatus(d
->protocol
->Offline
);//just change the icon
301 emit
connectionStatus(false);
304 void SkypeAccount::wentAway() {
305 kDebug() << k_funcinfo
<< endl
;//some debug info
307 myself()->setOnlineStatus(d
->protocol
->Away
);//just change the icon
308 emit
connectionStatus(true);
311 void SkypeAccount::wentNotAvailable() {
312 kDebug() << k_funcinfo
<< endl
;//some debug info
314 myself()->setOnlineStatus(d
->protocol
->NotAvailable
);
315 emit
connectionStatus(true);
318 void SkypeAccount::wentDND() {
319 kDebug() << k_funcinfo
<< endl
;//some debug info
321 myself()->setOnlineStatus(d
->protocol
->DoNotDisturb
);
322 emit
connectionStatus(true);
325 void SkypeAccount::wentInvisible() {
326 kDebug() << k_funcinfo
<< endl
;//some debug info
328 myself()->setOnlineStatus(d
->protocol
->Invisible
);
329 emit
connectionStatus(true);
332 void SkypeAccount::wentSkypeMe() {
333 kDebug() << k_funcinfo
<< endl
;//some debug info
335 myself()->setOnlineStatus(d
->protocol
->SkypeMe
);
336 emit
connectionStatus(true);
339 void SkypeAccount::statusConnecting() {
340 kDebug() << k_funcinfo
<< endl
;//some debug info
342 myself()->setOnlineStatus(d
->protocol
->Connecting
);
343 emit
connectionStatus(false);
346 void SkypeAccount::newUser(const QString
&name
, int groupID
) {
347 kDebug() << k_funcinfo
<< QString("name = %1").arg(name
) << QString("groupID = %1").arg(groupID
) << endl
;//some debug info
349 if (name
== "echo123")// echo123 - Make Test Call has moved to Skype protocol toolbar
352 QString group
= d
->skype
.getGroupName(groupID
);
354 Kopete::Group
* skypeGroup
;
356 if (group
.isEmpty() || groupID
== -1) // If skype group hasnt name, in kopete will be in top
357 skypeGroup
= Kopete::Group::topLevel();
359 skypeGroup
= Kopete::ContactList::self()->findGroup(group
); //get kopete group by skype group name. If skype group in kopete doesnt exist, create it automatically
360 if ( skypeGroup
== Kopete::Group::topLevel() ){ //if group in skype has name i18n("Top Level") kopete get top level group, but in skype top level group is group without name
361 QList
<Kopete::Group
*> groups
= Kopete::ContactList::self()->groups(); //get all groups
363 for (QList
<Kopete::Group
*>::iterator it
= groups
.begin(); it
!= groups
.end(); ++it
){ //search all groups, if one isnt top level and has skype group name
364 if ( (*it
)->displayName() == group
&& (*it
) != Kopete::Group::topLevel() ){
366 found
= true; //if found skip creating new
370 skypeGroup
= new Kopete::Group(group
); //create new group with name
371 Kopete::ContactList::self()->addGroup(skypeGroup
); //add this new group to contact list
376 if (contacts().contains(name
)){
377 Kopete::Contact
* contact
= contacts().value(name
); //get metacontact of skype contact name
378 if (skypeGroup
!= contact
->metaContact()->groups().first()){ // if skype Group is different like kopete group, move metacontact to skype group
379 kDebug() << "Moving contact" << name
<< "to group" << group
<< endl
;
380 contact
->metaContact()->moveToGroup(contact
->metaContact()->groups().first(), skypeGroup
);
385 addContact(name
, d
->skype
.getDisplayName(name
), skypeGroup
, ChangeKABC
);
388 void SkypeAccount::prepareContact(SkypeContact
*contact
) {
389 kDebug() << k_funcinfo
<< endl
;//some debug info
391 QObject::connect(&d
->skype
, SIGNAL(updateAllContacts()), contact
, SLOT(requestInfo()));//all contacts will know that
392 QObject::connect(contact
, SIGNAL(infoRequest(const QString
& )), &d
->skype
, SLOT(getContactInfo(const QString
& )));//How do we ask for info?
393 QObject::connect(this, SIGNAL(connectionStatus(bool )), contact
, SLOT(connectionStatus(bool )));
394 QObject::connect(contact
, SIGNAL(setActionsPossible(bool )), d
->protocol
, SLOT(updateCallActionStatus()));
397 void SkypeAccount::updateContactInfo(const QString
&contact
, const QString
&change
) {
398 kDebug() << k_funcinfo
<< endl
;//some debug info
400 SkypeContact
*cont
= static_cast<SkypeContact
*> (contacts().value(contact
));//get the contact
402 cont
->setInfo(change
);//give it the message
403 else {//it does not yet exist, create it if it is in skype contact list (can be got by buddystatus)
404 const QString
&type
= change
.section(' ', 0, 0).trimmed().toUpper();//get the first part of the message, it should be BUDDYSTATUS
405 const QString
&value
= change
.section(' ', 1, 1).trimmed();//get the second part if it is some reasonable value
406 if ((type
== "BUDDYSTATUS") && ((value
== "2") || (value
== "3"))) {//the user is in skype contact list
407 newUser(contact
, d
->skype
.getContactGroupID(contact
));
408 } else if (type
!= "BUDDYSTATUS")//this is some other info
409 d
->skype
.getContactBuddy(contact
);//get the buddy status for the account and check, if it is in contact list or not
413 bool SkypeAccount::canComunicate() {
414 return d
->skype
.canComunicate();
417 SkypeProtocol
* SkypeAccount::protocol() {
421 void SkypeAccount::sendMessage(Kopete::Message
&message
, const QString
&chat
) {
422 kDebug() << k_funcinfo
<< endl
;//some debug info
424 if (chat
.isEmpty()) {
425 const QString
&user
= message
.to().at(0)->contactId();//get id of the first contact, messages to multiple people are not yet possible
426 const QString
&body
= message
.plainBody().trimmed();//get the text of the message
428 d
->skype
.send(user
, body
);//send it by skype
430 const QString
&body
= message
.plainBody().trimmed();
432 d
->skype
.sendToChat(chat
, body
);
436 bool SkypeAccount::getHitchHike() const {
440 bool SkypeAccount::getMarkRead() const {
444 void SkypeAccount::setHitchHike(bool value
) {
445 d
->hitch
= value
;//save it
446 d
->skype
.setHitchMode(value
);//set it in the skype
449 void SkypeAccount::setMarkRead(bool value
) {
450 d
->markRead
= value
;//remember it
451 d
->skype
.setMarkMode(value
);
454 bool SkypeAccount::userHasChat(const QString
&userId
) {
455 SkypeContact
*cont
= static_cast<SkypeContact
*> (contacts().value(userId
));//get the contact
458 return cont
->hasChat();//so ask it
460 return false;//if it does not exist it can not have a chat opened
463 void SkypeAccount::receivedIm(const QString
&user
, const QString
&message
, const QString
&messageId
) {
464 kDebug() << k_funcinfo
<< "User: " << user
<< ", message: " << message
<< endl
;//some debug info
465 getContact(user
)->receiveIm(message
, getMessageChat(messageId
));//let the contact show the message
468 void SkypeAccount::setScanForUnread(bool value
) {
469 d
->searchForUnread
= value
;
470 d
->skype
.setScanForUnread(value
);
473 bool SkypeAccount::getScanForUnread() const {
474 return d
->searchForUnread
;
477 void SkypeAccount::makeCall(SkypeContact
*user
) {
478 makeCall(user
->contactId());
481 void SkypeAccount::makeCall(const QString
&users
) {
483 d
->skype
.makeCall(users
);
486 void SkypeAccount::makeTestCall() {
488 d
->skype
.makeCall("echo123");
491 bool SkypeAccount::getCallControl() const {
492 return d
->callControl
;
495 void SkypeAccount::setCallControl(bool value
) {
496 d
->callControl
= value
;
499 void SkypeAccount::newCall(const QString
&callId
, const QString
&userId
) {
500 kDebug() << k_funcinfo
<< endl
;//some debug info
502 if (d
->callControl
) {//Show the skype call control window
503 SkypeCallDialog
*dialog
= new SkypeCallDialog(callId
, userId
, this);//It should free itself when it is closed
505 QObject::connect(&d
->skype
, SIGNAL(callStatus(const QString
&, const QString
& )), dialog
, SLOT(updateStatus(const QString
&, const QString
& )));
506 QObject::connect(dialog
, SIGNAL(acceptTheCall(const QString
& )), &d
->skype
, SLOT(acceptCall(const QString
& )));
507 QObject::connect(dialog
, SIGNAL(hangTheCall(const QString
& )), &d
->skype
, SLOT(hangUp(const QString
& )));
508 QObject::connect(dialog
, SIGNAL(toggleHoldCall(const QString
& )), &d
->skype
, SLOT(toggleHoldCall(const QString
& )));
509 QObject::connect(&d
->skype
, SIGNAL(callError(const QString
&, const QString
& )), dialog
, SLOT(updateError(const QString
&, const QString
& )));
510 QObject::connect(&d
->skype
, SIGNAL(skypeOutInfo(int, const QString
& )), dialog
, SLOT(skypeOutInfo(int, const QString
& )));
511 QObject::connect(dialog
, SIGNAL(updateSkypeOut()), &d
->skype
, SLOT(getSkypeOut()));
512 QObject::connect(dialog
, SIGNAL(callFinished(const QString
& )), this, SLOT(removeCall(const QString
& )));
514 dialog
->show();//Show Call dialog
516 d
->skype
.getSkypeOut();
517 d
->calls
.insert(callId
, dialog
);
520 if ((!d
->incommingCommand
.isEmpty()) && (d
->skype
.isCallIncoming(callId
))) {
521 kDebug() << "Running ring command" << endl
;
522 QProcess
*proc
= new QProcess();
523 QStringList args
= d
->incommingCommand
.split(' ');
524 QString bin
= args
.takeFirst();
525 proc
->start(bin
, args
);
529 bool SkypeAccount::isCallIncoming(const QString
&callId
) {
530 kDebug() << k_funcinfo
<< endl
;//some debug info
532 return d
->skype
.isCallIncoming(callId
);
535 void SkypeAccount::setCloseWindowTimeout(int timeout
) {
536 d
->callWindowTimeout
= timeout
;
539 int SkypeAccount::closeCallWindowTimeout() const {
540 return d
->callWindowTimeout
;
543 QString
SkypeAccount::getUserLabel(const QString
&userId
) {
544 kDebug() << k_funcinfo
<< endl
;//some debug info
546 if (userId
.indexOf(' ') != -1) {//there are more people than just one
547 QStringList users
= userId
.split(' ');
548 for (QStringList::iterator it
= users
.begin(); it
!= users
.end(); ++it
) {
549 (*it
) = getUserLabel((*it
).trimmed());
551 return users
.join("\n");
554 Kopete::Contact
*cont
= contact(userId
);
557 addContact(userId
, QString::null
, 0L, Temporary
);//create a temporary contact
559 cont
= (contacts().value(userId
));//It should be there now
561 return userId
;//something odd,.but better do nothing than crash
564 return QString("%1 (%2)").arg(cont
->nickName()).arg(userId
);
567 void SkypeAccount::setPings(bool enabled
) {
568 d
->skype
.enablePings(enabled
);
572 bool SkypeAccount::getPings() const {
576 int SkypeAccount::getBus() const {
580 void SkypeAccount::setBus(int bus
) {
582 d
->skype
.setBus(bus
);
585 void SkypeAccount::setLaunchTimeout(int seconds
) {
586 d
->launchTimeout
= seconds
;
587 d
->skype
.setLaunchTimeout(seconds
);
590 int SkypeAccount::getLaunchTimeout() const {
591 return d
->launchTimeout
;
594 void SkypeAccount::setSkypeCommand(const QString
&command
) {
595 d
->skypeCommand
= command
;
596 d
->skype
.setSkypeCommand(command
);
599 const QString
&SkypeAccount::getSkypeCommand() const {
600 return d
->skypeCommand
;
603 void SkypeAccount::setMyselfName(const QString
&name
) {
605 myself()->setNickName(name
);
608 void SkypeAccount::setWaitBeforeConnect(int value
) {
609 d
->waitBeforeConnect
= value
;
610 d
->skype
.setWaitConnect(value
);
613 int SkypeAccount::getWaitBeforeConnect() const {
614 return d
->waitBeforeConnect
;
617 SkypeContact
*SkypeAccount::getContact(const QString
&userId
) {
618 SkypeContact
*cont
= static_cast<SkypeContact
*> (contacts().value(userId
));//get the contact
619 if (!cont
) {//We do not know such contact
620 addContact(userId
, QString::null
, 0L, Temporary
);//create a temporary contact
622 cont
= static_cast<SkypeContact
*> (contacts().value(userId
));//It should be there now
627 void SkypeAccount::prepareChatSession(SkypeChatSession
*session
) {
628 QObject::connect(session
, SIGNAL(updateChatId(const QString
&, const QString
&, SkypeChatSession
* )), this, SLOT(setChatId(const QString
&, const QString
&, SkypeChatSession
* )));
629 QObject::connect(session
, SIGNAL(wantTopic(const QString
& )), &d
->skype
, SLOT(getTopic(const QString
& )));
630 QObject::connect(&d
->skype
, SIGNAL(joinUser(const QString
&, const QString
& )), session
, SLOT(joinUser(const QString
&, const QString
& )));
631 QObject::connect(&d
->skype
, SIGNAL(leftUser(const QString
&, const QString
&, const QString
& )), session
, SLOT(leftUser(const QString
&, const QString
&, const QString
& )));
632 QObject::connect(&d
->skype
, SIGNAL(setTopic(const QString
&, const QString
& )), session
, SLOT(setTopic(const QString
&, const QString
& )));
633 QObject::connect(session
, SIGNAL(inviteUserToChat(const QString
&, const QString
& )), &d
->skype
, SLOT(inviteUser(const QString
&, const QString
& )));
634 QObject::connect(session
, SIGNAL(leaveChat(const QString
& )), &d
->skype
, SLOT(leaveChat(const QString
& )));
637 void SkypeAccount::setChatId(const QString
&oldId
, const QString
&newId
, SkypeChatSession
*sender
) {
638 d
->sessions
.remove(oldId
);//remove the old one
639 if (!newId
.isEmpty()) {
640 d
->sessions
.insert(newId
, sender
);
644 bool SkypeAccount::chatExists(const QString
&chat
) {
645 return d
->sessions
.find(chat
);
648 void SkypeAccount::receiveMultiIm(const QString
&chatId
, const QString
&body
, const QString
&messageId
, const QString
&user
) {
649 SkypeChatSession
*session
= d
->sessions
.find(chatId
);
652 QStringList users
= d
->skype
.getChatUsers(chatId
);
653 Kopete::ContactPtrList list
;
654 for (QStringList::iterator it
= users
.begin(); it
!= users
.end(); ++it
) {
655 list
.append(getContact(*it
));
658 session
= new SkypeChatSession(this, chatId
, list
);
661 Kopete::Message
mes(getContact(user
), myself());
662 mes
.setDirection(Kopete::Message::Inbound
);
663 mes
.setPlainBody(body
);
664 session
->appendMessage(mes
);
669 QString
SkypeAccount::getMessageChat(const QString
&messageId
) {
670 return d
->skype
.getMessageChat(messageId
);
673 void SkypeAccount::registerLastSession(SkypeChatSession
*lastSession
) {
674 d
->lastSession
= lastSession
;
677 void SkypeAccount::gotMessageId(const QString
&messageId
) {
678 if ((d
->lastSession
) && (!messageId
.isEmpty())) {
679 d
->lastSession
->setChatId(d
->skype
.getMessageChat(messageId
));
685 void SkypeAccount::sentMessage(const QString
&body
, const QString
&chat
) {
686 kDebug() << k_funcinfo
<< "chat: " << chat
<< endl
;//some debug info
688 SkypeChatSession
*session
= d
->sessions
.find(chat
);
689 const QStringList
&users
= d
->skype
.getChatUsers(chat
);
690 QList
<Kopete::Contact
*> *recv
= 0L;
694 recv
= constructContactList(users
);
695 if (recv
->count() == 1) {
696 SkypeContact
*cont
= static_cast<SkypeContact
*> (recv
->at(0));
698 session
= cont
->getChatSession();
699 session
->setChatId(chat
);
701 session
= new SkypeChatSession(this, chat
, *recv
);
709 recv
= constructContactList(users
);
711 session
->sentMessage(recv
, body
);
715 QList
<Kopete::Contact
*> *SkypeAccount::constructContactList(const QStringList
&users
) {
716 QList
<Kopete::Contact
*> *list
= new QList
<Kopete::Contact
*> ();
717 for (QStringList::const_iterator it
= users
.begin(); it
!= users
.end(); ++it
) {
718 list
->append(getContact(*it
));
724 void SkypeAccount::groupCall(const QString
&callId
, const QString
&groupId
) {
725 kDebug() << k_funcinfo
<< endl
;
727 //TODO: Find out a way to embet qdialog into another one after creation
733 SkypeConference
*conf
;
734 if (!(conf
= d
->conferences
[groupId
])) {//does it already exist?
735 conf
= new SkypeConference(groupId
);//no, create one then..
736 d
->conferences
.insert(groupId
, conf
);
738 QObject::connect(conf
, SIGNAL(removeConference(const QString
& )), this, SLOT(removeCallGroup(const QString
& )));
741 conf
->embedCall(d
->calls
[callId
]);
744 void SkypeAccount::removeCall(const QString
&callId
) {
745 kDebug() << k_funcinfo
<< endl
;
746 d
->calls
.remove(callId
);
749 void SkypeAccount::removeCallGroup(const QString
&groupId
) {
750 kDebug() << k_funcinfo
<< endl
;
751 d
->conferences
.remove(groupId
);
754 QString
SkypeAccount::createChat(const QString
&users
) {
755 return d
->skype
.createChat(users
);
758 bool SkypeAccount::leaveOnExit() const {
759 return d
->leaveOnExit
;
762 void SkypeAccount::setLeaveOnExit(bool value
) {
763 d
->leaveOnExit
= value
;
766 void SkypeAccount::chatUser(const QString
&userId
) {
767 SkypeContact
*contact
= getContact(userId
);
772 void SkypeAccount::setStartCallCommand(const QString
&value
) {
773 d
->startCallCommand
= value
;
776 void SkypeAccount::setEndCallCommand(const QString
&value
) {
777 d
->endCallCommand
= value
;
780 void SkypeAccount::setWaitForStartCallCommand(bool value
) {
781 d
->waitForStartCallCommand
= value
;
783 void SkypeAccount::setEndCallCommandOnlyForLast(bool value
) {
784 d
->endCallCommandOnlyLats
= value
;
787 QString
SkypeAccount::startCallCommand() const {
788 return d
->startCallCommand
;
791 QString
SkypeAccount::endCallCommand() const {
792 return d
->endCallCommand
;
795 bool SkypeAccount::waitForStartCallCommand() const {
796 return d
->waitForStartCallCommand
;
799 bool SkypeAccount::endCallCommandOnlyLast() const {
800 return d
->endCallCommandOnlyLats
;
803 void SkypeAccount::startCall() {
804 kDebug() << k_funcinfo
<< endl
;
806 QProcess
*proc
= new QProcess();
807 QStringList args
= d
->startCallCommand
.split(' ');
808 QString bin
= args
.takeFirst();
809 if (d
->waitForStartCallCommand
)
810 proc
->execute(bin
, args
);
812 proc
->start(bin
, args
);
816 void SkypeAccount::endCall() {
817 kDebug() << k_funcinfo
<< endl
;
819 if ((--d
->callCount
== 0) || (!d
->endCallCommandOnlyLats
)) {
820 QProcess
*proc
= new QProcess();
821 QStringList args
= d
->endCallCommand
.split(' ');
822 QString bin
= args
.takeFirst();
823 proc
->start(bin
, args
);
825 if (d
->callCount
< 0)
829 void SkypeAccount::setIncomingCommand(const QString
&command
) {
830 d
->incommingCommand
= command
;
833 QString
SkypeAccount::incomingCommand() const {
834 return d
->incommingCommand
;
837 void SkypeAccount::registerContact(const QString
&contactId
) {
838 kDebug() << k_funcinfo
<< endl
;
839 d
-> skype
.addContact(contactId
);
842 void SkypeAccount::removeContact(const QString
&contactId
) {
843 d
-> skype
.removeContact(contactId
);
846 bool SkypeAccount::ableMultiCall() {
847 return (d
->skype
.ableConference());
850 bool SkypeAccount::canAlterAuth() {
851 return (d
->skype
.canComunicate());
854 void SkypeAccount::authorizeUser(const QString
&userId
) {
855 d
->skype
.setAuthor(userId
, Skype::Author
);
858 void SkypeAccount::disAuthorUser(const QString
&userId
) {
859 d
->skype
.setAuthor(userId
, Skype::Deny
);
862 void SkypeAccount::blockUser(const QString
&userId
) {
863 d
->skype
.setAuthor(userId
, Skype::Block
);
866 int SkypeAccount::getAuthor(const QString
&contactId
) {
867 switch (d
->skype
.getAuthor(contactId
)) {
878 bool SkypeAccount::hasCustomStatusMenu() const {
879 kDebug() << k_funcinfo
<< endl
;//some debug info
883 void SkypeAccount::fillActionMenu( KActionMenu
*actionMenu
) {
884 kDebug() << k_funcinfo
<< endl
;//some debug info
886 actionMenu
->setIcon( myself()->onlineStatus().iconFor(this) );
887 actionMenu
->menu()->addTitle( QIcon(myself()->onlineStatus().iconFor(this)), i18n("Skype (%1)", accountId()));
891 KAction
*setOnline
= new KAction( KIcon(QIcon(d
->protocol
->Online
.iconFor(this))), i18n("Online"), this );
892 QObject::connect( setOnline
, SIGNAL(triggered(bool)), &d
->skype
, SLOT(setOnline()) );
893 actionMenu
->addAction(setOnline
);
895 KAction
*setOffline
= new KAction( KIcon(QIcon(d
->protocol
->Offline
.iconFor(this))), i18n("Offline"), this );
896 QObject::connect( setOffline
, SIGNAL(triggered(bool)), &d
->skype
, SLOT(setOffline()) );
897 actionMenu
->addAction(setOffline
);
899 KAction
*setAway
= new KAction( KIcon(QIcon(d
->protocol
->Away
.iconFor(this))), i18n("Away"), this );
900 QObject::connect( setAway
, SIGNAL(triggered(bool)), &d
->skype
, SLOT(setAway()) );
901 actionMenu
->addAction(setAway
);
903 KAction
*setNotAvailable
= new KAction( KIcon(QIcon(d
->protocol
->NotAvailable
.iconFor(this))), i18n("Not Available"), this );
904 QObject::connect( setNotAvailable
, SIGNAL(triggered(bool)), &d
->skype
, SLOT(setNotAvailable()) );
905 actionMenu
->addAction(setNotAvailable
);
907 KAction
*setDND
= new KAction( KIcon(QIcon(d
->protocol
->DoNotDisturb
.iconFor(this))), i18n("Do Not Disturb"), this );
908 QObject::connect( setDND
, SIGNAL(triggered(bool)), &d
->skype
, SLOT(setDND()) );
909 actionMenu
->addAction(setDND
);
911 KAction
*setInvisible
= new KAction( KIcon(QIcon(d
->protocol
->Invisible
.iconFor(this))), i18n("Invisible"), this );
912 QObject::connect( setInvisible
, SIGNAL(triggered(bool)), &d
->skype
, SLOT(setInvisible()) );
913 actionMenu
->addAction(setInvisible
);
915 KAction
*setSkypeMe
= new KAction( KIcon(QIcon(d
->protocol
->SkypeMe
.iconFor(this))), i18n("Skype Me"), this );
916 QObject::connect( setSkypeMe
, SIGNAL(triggered(bool)), &d
->skype
, SLOT(setSkypeMe()) );
917 actionMenu
->addAction(setSkypeMe
);
919 actionMenu
->addSeparator();
921 KAction
*makeTestCall
= new KAction( KIcon("skype_call"), i18n("Make Test Call"), this );
922 QObject::connect( makeTestCall
, SIGNAL(triggered(bool)), this, SLOT(makeTestCall()) );
924 const Kopete::OnlineStatus
&myStatus
= (myself()) ? myself()->onlineStatus() : protocol()->Offline
;
925 if (myStatus
== protocol()->Offline
|| myStatus
== protocol()->Connecting
){
926 makeTestCall
->setEnabled(false);
929 actionMenu
->addAction(makeTestCall
);
931 actionMenu
->addSeparator();
933 KAction
*properties
= new KAction( i18n("Properties"), this );
934 QObject::connect( properties
, SIGNAL(triggered(bool)), this, SLOT(editAccount()) );
935 actionMenu
->addAction(properties
);
939 QString
SkypeAccount::getMyselfSkypeName() {
940 kDebug() << k_funcinfo
<< endl
;//some debug info
941 return d
->skype
.getMyself();
944 void SkypeAccount::MovedBetweenGroup(SkypeContact
*contact
) {
945 kDebug() << k_funcinfo
<< endl
;//some debug info
947 int newGroup
= d
->skype
.getGroupID(contact
->metaContact()->groups().first()->displayName());
948 int oldGroup
= d
->skype
.getContactGroupID(contact
->contactId());
950 kDebug() << "oldGroup:" << oldGroup
<< "newGroup:" << newGroup
<< endl
;
952 if ( oldGroup
!= -1 ){
953 kDebug() << "Removing contact" << contact
->contactId() << "from group" << d
->skype
.getContactGroupID(contact
->contactId()) << endl
;
954 d
->skype
.removeFromGroup(contact
->contactId(), oldGroup
);
957 if ( newGroup
== -1 ){
958 if ( contact
->metaContact()->groups().first() != Kopete::Group::topLevel() ){
959 d
->skype
.createGroup(contact
->metaContact()->groups().first()->displayName());
960 newGroup
= d
->skype
.getGroupID(contact
->metaContact()->groups().first()->displayName());
962 kDebug() << "Contact is in top level, so in no skype group, skipping" << endl
;
967 if ( newGroup
!= -1 ){
968 kDebug() << "Adding contact" << contact
->contactId() << "to group" << d
->skype
.getGroupID(contact
->metaContact()->groups().first()->displayName()) << endl
;
969 d
->skype
.addToGroup(contact
->contactId(), newGroup
);
971 kDebug() << "Error: Cant create new skype group" << contact
->metaContact()->groups().first()->displayName() << endl
;
974 void SkypeAccount::deleteGroup (Kopete::Group
* group
){
975 kDebug() << k_funcinfo
<< group
->displayName() << endl
;//some debug info
976 int groupID
= d
->skype
.getGroupID( group
->displayName() );
978 d
->skype
.deleteGroup(groupID
);
980 kDebug() << "Group" << group
->displayName() << "in skype doesnt exist, skipping" << endl
;
983 void SkypeAccount::renameGroup (Kopete::Group
* group
, const QString
&oldname
){
984 kDebug() << k_funcinfo
<< "Renaming skype group" << oldname
<< "to" << group
->displayName() << endl
;//some debug info
985 int groupID
= d
->skype
.getGroupID( oldname
);
987 d
->skype
.renameGroup( groupID
, group
->displayName() );
989 kDebug() << "Old group" << oldname
<< "in skype doesnt exist, skipping" << endl
;
992 void SkypeAccount::openFileTransfer(const QString
&user
, const QString
&url
) {
993 kDebug() << k_funcinfo
<< user
<< url
<< endl
;
994 d
->skype
.openFileTransfer(user
, url
);
997 #include "skypeaccount.moc"