Show invite menu in wlm chat window immediately
[kdenetwork.git] / kopete / protocols / skype / skypeaccount.cpp
blob9cc823141af8be99cc991122fcce4b4c64dcac08
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"
24 #include "skype.h"
25 #include "skypecalldialog.h"
26 #include "skypechatsession.h"
27 #include "skypeconference.h"
29 #include <qstring.h>
30 #include <kopetemetacontact.h>
31 #include <kopeteonlinestatus.h>
32 #include <kopetecontactlist.h>
33 #include <kopetecontact.h>
34 #include <kopetegroup.h>
35 #include <kdebug.h>
36 #include <kmessagebox.h>
37 #include <klocale.h>
38 #include <kconfigbase.h>
39 #include <Q3Dict>
40 #include <kopetemessage.h>
41 #include <qprocess.h>
43 class SkypeAccountPrivate {
44 public:
45 ///The skype protocol pointer
46 SkypeProtocol *protocol;
47 ///ID of this account (means my skype name)
48 QString ID;
49 ///The skype back-end
50 Skype skype;
51 ///The hitchhike mode of incoming messages
52 bool hitch;
53 ///The mark read messages mode
54 bool markRead;
55 ///Search for unread messages on login?
56 bool searchForUnread;
57 ///Do we show call control window?
58 bool callControl;
59 ///Metacontact for all users that aren't in the list
60 Kopete::MetaContact notInListUsers;
61 ///Constructor
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?
66 bool pings;
67 ///What bus are we using, session (0) or system (1)?
68 int bus;
69 ///How long can I keep trying connect to newly started skype, before I give up (seconds)
70 int launchTimeout;
71 ///By what command is the skype started?
72 QString skypeCommand;
73 ///What is my name, by the way?
74 QString myName;
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
86 bool leaveOnExit;
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?
96 int callCount;
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);
107 //the d pointer
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);
135 setMyself(_myself);
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);
167 d->lastSession = 0L;
168 d->callCount = 0;
172 SkypeAccount::~SkypeAccount() {
173 kDebug() << k_funcinfo << endl;//some debug info
175 save();
177 d->protocol->unregisterAccount();//This account no longer exists
179 //free memory
180 delete d;
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
190 } else {
191 kDebug() << k_funcinfo << "Contact already exists:" << contactID << endl;//Tell that it is not OK
193 return false;
197 void SkypeAccount::setAway(bool away, const QString &reason) {
198 kDebug() << k_funcinfo << endl;//some debug info
200 if (away)
201 setOnlineStatus(d->protocol->Away, reason);
202 else
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)
214 d->skype.setAway();
215 else if (status == d->protocol->NotAvailable)
216 d->skype.setNotAvailable();
217 else if (status == d->protocol->DoNotDisturb)
218 d->skype.setDND();
219 else if (status == d->protocol->Invisible)
220 d->skype.setInvisible();
221 else if (status == d->protocol->SkypeMe)
222 d->skype.setSkypeMe();
223 else
224 kDebug() << "Unknown online status" << endl;//Just a warning that I do not know that status
226 ///TODO: Port to kde4
227 Q_UNUSED(reason);
228 Q_UNUSED(options);
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());
256 else
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
350 return;
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();
358 else {
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
362 bool found = false;
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() ){
365 skypeGroup = (*it);
366 found = true; //if found skip creating new
369 if ( !found ){
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);
382 return;
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
401 if (cont)
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() {
418 return d->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
429 } else {
430 const QString &body = message.plainBody().trimmed();
432 d->skype.sendToChat(chat, body);
436 bool SkypeAccount::getHitchHike() const {
437 return d->hitch;
440 bool SkypeAccount::getMarkRead() const {
441 return d->markRead;
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
457 if (cont)//it exists
458 return cont->hasChat();//so ask it
459 else
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) {
482 startCall();
483 d->skype.makeCall(users);
486 void SkypeAccount::makeTestCall() {
487 startCall();
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);
556 if (!cont) {
557 addContact(userId, QString::null, 0L, Temporary);//create a temporary contact
559 cont = (contacts().value(userId));//It should be there now
560 if (!cont)
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);
569 d->pings = enabled;
572 bool SkypeAccount::getPings() const {
573 return d->pings;
576 int SkypeAccount::getBus() const {
577 return d->bus;
580 void SkypeAccount::setBus(int bus) {
581 d->bus = 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) {
604 d->myName = 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
624 return cont;
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);
651 if (!session) {
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);
666 Q_UNUSED(messageId);
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));
682 d->lastSession = 0L;
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;
692 if (!session) {
693 if (d->hitch) {
694 recv = constructContactList(users);
695 if (recv->count() == 1) {
696 SkypeContact *cont = static_cast<SkypeContact *> (recv->at(0));
697 cont->startChat();
698 session = cont->getChatSession();
699 session->setChatId(chat);
700 } else {
701 session = new SkypeChatSession(this, chat, *recv);
703 } else {
704 return;
708 if (!recv)
709 recv = constructContactList(users);
711 session->sentMessage(recv, body);
712 delete recv;
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));
721 return list;
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
728 return;
730 if (!d->callControl)
731 return;
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);
769 contact->execute();
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);
811 else
812 proc->start(bin, args);
813 ++d->callCount;
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)
826 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)) {
868 case Skype::Author:
869 return 0;
870 case Skype::Deny:
871 return 1;
872 case Skype::Block:
873 return 2;
875 return 0;
878 bool SkypeAccount::hasCustomStatusMenu() const {
879 kDebug() << k_funcinfo << endl;//some debug info
880 return true;
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()));
889 if (d->protocol)
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());
961 } else {
962 kDebug() << "Contact is in top level, so in no skype group, skipping" << endl;
963 return;
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);
970 } else
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() );
977 if ( groupID != -1 )
978 d->skype.deleteGroup(groupID);
979 else
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 );
986 if ( groupID != -1 )
987 d->skype.renameGroup( groupID, group->displayName() );
988 else
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"