1 /*
2 kopetedbusinterface.h - Kopete D-Bus interface
3
4 Copyright (c) 2007 by Michaël Larouche <larouche@kde.org>
5 Copyright (c) 2007 Will Stephenson <wstephenson@kde.org>
6
7 Kopete (c) 2002-2007 by the Kopete developers <kopete-devel@kde.org>
8
9 *************************************************************************
10 * *
11 * This library is free software; you can redistribute it and/or *
12 * modify it under the terms of the GNU Lesser General Public *
13 * License as published by the Free Software Foundation; either *
14 * version 2 of the License, or (at your option) any later version. *
15 * *
16 *************************************************************************
17 */
18 #include "kopetedbusinterface.h"
19 #include "kopetedbusinterface_p.h"
20
21 // Qt includes
22 #include <QStringList>
23 #include <QList>
24
25 // KDE includes
26 #include <QUrl>
27 #include <kplugininfo.h>
28
29 // Kopete includes
30 #include <kopetecontactlist.h>
31 #include <kopetemetacontact.h>
32 #include <kopetecontact.h>
33 #include <kopeteidentity.h>
34 #include <kopeteidentitymanager.h>
35 #include <kopeteavatarmanager.h>
36 #include <kopeteaccount.h>
37 #include <kopeteaccountmanager.h>
38 #include <kopeteonlinestatus.h>
39 #include <kopetemessage.h>
40 #include <kopetechatsession.h>
41 #include <kopetegroup.h>
42 #include <kopetepluginmanager.h>
43 #include <kopetepicture.h>
44 #include <kopeteviewmanager.h>
45 #include <kopetemessageevent.h>
46
47 // Local includes
48 #include "kopeteadaptor.h"
49
KopeteDBusInterface(QObject * parent)50 KopeteDBusInterface::KopeteDBusInterface(QObject *parent)
51 : QObject(parent)
52 , d(new KopeteDBusInterfacePrivate())
53 {
54 setObjectName(QStringLiteral("KopeteDBusInterface"));
55 new KopeteAdaptor(this);
56 QDBusConnection::sessionBus().registerObject(QStringLiteral("/Kopete"), this);
57
58 QObject::connect(d, SIGNAL(contactChanged(QString)), this, SIGNAL(contactChanged(QString)));
59 }
60
~KopeteDBusInterface()61 KopeteDBusInterface::~KopeteDBusInterface()
62 {
63 }
64
protocols() const65 QStringList KopeteDBusInterface::protocols() const
66 {
67 QStringList list;
68 foreach (KPluginInfo p, Kopete::PluginManager::self()->availablePlugins("Protocols")) {
69 list << p.name();
70 }
71 return list;
72 }
73
contacts() const74 QStringList KopeteDBusInterface::contacts() const
75 {
76 return d->listContact(Kopete::ContactList::self()->metaContacts());
77 }
78
contactsByFilter(const QString & filter) const79 QStringList KopeteDBusInterface::contactsByFilter(const QString &filter) const
80 {
81 QList<Kopete::MetaContact *> completeList
82 = Kopete::ContactList::self()->metaContacts();
83 QList<Kopete::MetaContact *> filteredList;
84
85 Kopete::MetaContact *contact;
86
87 if (filter.toLower() == QLatin1String("online")) {
88 // "online" returns contacts that are not offline, which means that
89 // those being away, busy etc. are included as well.
90 foreach (contact, completeList) {
91 if (contact->isOnline()) {
92 filteredList << contact;
93 }
94 }
95 } else if (filter.toLower() == QLatin1String("reachable")) {
96 foreach (contact, completeList) {
97 if (contact->isReachable()) {
98 filteredList << contact;
99 }
100 }
101 } else if (filter.toLower() == QLatin1String("filecapable")) {
102 foreach (contact, completeList) {
103 if (contact->canAcceptFiles()) {
104 filteredList << contact;
105 }
106 }
107 } else if (filter.toLower() == QLatin1String("away")) {
108 foreach (contact, completeList) {
109 if (contact->status() == Kopete::OnlineStatus::Away) {
110 filteredList << contact;
111 }
112 }
113 } else if (filter.toLower() == QLatin1String("busy")) {
114 foreach (contact, completeList) {
115 if (contact->status() == Kopete::OnlineStatus::Busy) {
116 filteredList << contact;
117 }
118 }
119 }
120
121 return d->listContact(filteredList);
122 }
123
setIdentityNickName(const QString & nickName,const QString & identityId)124 void KopeteDBusInterface::setIdentityNickName(const QString &nickName, const QString &identityId)
125 {
126 Kopete::Identity *identity = 0;
127
128 if (identityId.isEmpty()) {
129 identity = Kopete::IdentityManager::self()->defaultIdentity();
130 } else {
131 identity = Kopete::IdentityManager::self()->findIdentity(identityId);
132 }
133
134 if (identity) {
135 identity->setProperty(Kopete::Global::Properties::self()->nickName(),
136 nickName);
137 }
138 }
139
setIdentityAvatar(const QString & avatarUrl,const QString & identityId)140 void KopeteDBusInterface::setIdentityAvatar(const QString &avatarUrl, const QString &identityId)
141 {
142 Kopete::Identity *identity = 0;
143
144 if (identityId.isEmpty()) {
145 identity = Kopete::IdentityManager::self()->defaultIdentity();
146 } else {
147 identity = Kopete::IdentityManager::self()->findIdentity(identityId);
148 }
149
150 if (identity) {
151 // Add the avatar using AvatarManager
152 Kopete::AvatarManager::AvatarEntry avatarEntry;
153 avatarEntry.name = QStringLiteral("D-Bus Avatar");
154 avatarEntry.path = QUrl(avatarUrl).path();
155 avatarEntry.category = Kopete::AvatarManager::User;
156
157 avatarEntry = Kopete::AvatarManager::self()->add(avatarEntry);
158
159 identity->setProperty(Kopete::Global::Properties::self()->photo(),
160 avatarEntry.path);
161 }
162 }
163
setIdentityOnlineStatus(const QString & status,const QString & message,const QString & identityId)164 void KopeteDBusInterface::setIdentityOnlineStatus(const QString &status, const QString &message, const QString &identityId)
165 {
166 Kopete::Identity *identity = 0;
167
168 if (identityId.isEmpty()) {
169 identity = Kopete::IdentityManager::self()->defaultIdentity();
170 } else {
171 identity = Kopete::IdentityManager::self()->findIdentity(identityId);
172 }
173
174 if (identity) {
175 identity->setOnlineStatus(d->status2Value(status), message);
176 }
177 }
178
identities() const179 QStringList KopeteDBusInterface::identities() const
180 {
181 QStringList result;
182
183 foreach (Kopete::Identity *identity, Kopete::IdentityManager::self()->identities()) {
184 result << identity->id();
185 }
186
187 return result;
188 }
189
labelForIdentity(const QString & id) const190 QString KopeteDBusInterface::labelForIdentity(const QString &id) const
191 {
192 Kopete::Identity *identity
193 = Kopete::IdentityManager::self()->findIdentity(id);
194 if (identity) {
195 return identity->label();
196 } else {
197 return QString();
198 }
199 }
200
accounts() const201 QStringList KopeteDBusInterface::accounts() const
202 {
203 QStringList result;
204
205 foreach (Kopete::Account *account, Kopete::AccountManager::self()->accounts()) {
206 result << account->accountId();
207 }
208
209 return result;
210 }
211
connectAll()212 void KopeteDBusInterface::connectAll()
213 {
214 Kopete::AccountManager::self()->setOnlineStatus(
215 Kopete::OnlineStatusManager::Online, QString(),
216 Kopete::AccountManager::ConnectIfOffline);
217 }
218
disconnectAll()219 void KopeteDBusInterface::disconnectAll()
220 {
221 Kopete::AccountManager::self()->setOnlineStatus(
222 Kopete::OnlineStatusManager::Offline);
223 }
224
suspend()225 void KopeteDBusInterface::suspend()
226 {
227 Kopete::AccountManager::self()->suspend();
228 }
229
resume()230 void KopeteDBusInterface::resume()
231 {
232 Kopete::AccountManager::self()->resume();
233 }
234
setOnlineStatus(const QString & status,const QString & message)235 void KopeteDBusInterface::setOnlineStatus(const QString &status, const QString &message)
236 {
237 Kopete::AccountManager::self()->setOnlineStatus(d->status2Value(status),
238 message);
239 }
240
setStatusMessage(const QString & message)241 void KopeteDBusInterface::setStatusMessage(const QString &message)
242 {
243 Kopete::AccountManager::self()->setStatusMessage(message);
244 }
245
sendMessage(const QString & contactId,const QString & message)246 void KopeteDBusInterface::sendMessage(const QString &contactId, const QString &message)
247 {
248 Kopete::MetaContact *destMetaContact = d->findContact(contactId);
249 if (destMetaContact && destMetaContact->isReachable()) {
250 Kopete::Contact *destContact = destMetaContact->execute();
251 if (destContact) {
252 Kopete::Message newMessage(destContact->account()->myself(),
253 destContact);
254 newMessage.setPlainBody(message);
255 newMessage.setDirection(Kopete::Message::Outbound);
256
257 destContact->manager(Kopete::Contact::CanCreate)->sendMessage(
258 newMessage);
259 }
260 }
261 }
262
openChat(const QString & contactId)263 void KopeteDBusInterface::openChat(const QString &contactId)
264 {
265 Kopete::MetaContact *contact = d->findContact(contactId);
266 if (contact && contact->isReachable()) {
267 Kopete::Contact *preferredContact = contact->preferredContact();
268 if (preferredContact && preferredContact->account()
269 && preferredContact != preferredContact->account()->myself()) {
270 contact->execute();
271 }
272 }
273 }
274
getDisplayName(const QString & contactId)275 QString KopeteDBusInterface::getDisplayName(const QString &contactId)
276 {
277 Kopete::MetaContact *contact = d->findContact(contactId);
278 if (contact) {
279 return contact->displayName();
280 } else {
281 return QLatin1String("");
282 }
283 }
284
isContactOnline(const QString & contactId)285 bool KopeteDBusInterface::isContactOnline(const QString &contactId)
286 {
287 Kopete::MetaContact *contact = d->findContact(contactId);
288 if (contact) {
289 return contact->isOnline();
290 } else {
291 return false;
292 }
293 }
294
addContact(const QString & protocolName,const QString & accountId,const QString & contactId,const QString & displayName,const QString & groupName)295 bool KopeteDBusInterface::addContact(const QString &protocolName, const QString &accountId, const QString &contactId, const QString &displayName, const QString &groupName)
296 {
297 QString protocolId = protocolName;
298 if (!protocolName.contains(QLatin1String("Protocol"))) {
299 protocolId += QLatin1String("Protocol");
300 }
301
302 // Find the account using the given parameters on D-Bus
303 Kopete::Account *account = Kopete::AccountManager::self()->findAccount(
304 protocolId, accountId);
305
306 if (account) {
307 QString contactName;
308 Kopete::Group *realGroup = 0;
309
310 if (displayName.isEmpty()) {
311 contactName = contactId;
312 } else {
313 contactName = displayName;
314 }
315
316 if (!groupName.isEmpty()) {
317 realGroup = Kopete::ContactList::self()->findGroup(groupName);
318 }
319
320 account->addContact(contactId, contactName, realGroup,
321 Kopete::Account::DontChangeKABC);
322
323 return true;
324 }
325
326 return false;
327 }
328
sendFile(const QString & contactId,const QString & fileUrl)329 void KopeteDBusInterface::sendFile(const QString &contactId, const QString &fileUrl)
330 {
331 Kopete::MetaContact *destMetaContact = d->findContact(contactId);
332 if (destMetaContact && destMetaContact->isReachable()) {
333 Kopete::Contact *destContact = destMetaContact->execute();
334 if (destContact && destContact->isFileCapable()) {
335 destContact->sendFile(QUrl::fromLocalFile(fileUrl));
336 }
337 }
338 }
339
isConnected(const QString & protocolName,const QString & accountId)340 bool KopeteDBusInterface::isConnected(const QString &protocolName, const QString &accountId)
341 {
342 QString protocolId = protocolName;
343 if (!protocolName.contains(QLatin1String("Protocol"))) {
344 protocolId += QLatin1String("Protocol");
345 }
346
347 Kopete::Account *account = Kopete::AccountManager::self()->findAccount(
348 protocolId, accountId);
349 return account ? account->isConnected() : false;
350 }
351
connect(const QString & protocolName,const QString & accountId)352 void KopeteDBusInterface::connect(const QString &protocolName, const QString &accountId)
353 {
354 QString protocolId = protocolName;
355 if (!protocolName.contains(QLatin1String("Protocol"))) {
356 protocolId += QLatin1String("Protocol");
357 }
358
359 Kopete::Account *account = Kopete::AccountManager::self()->findAccount(
360 protocolId, accountId);
361 if (account) {
362 account->connect();
363 }
364 }
365
disconnect(const QString & protocolName,const QString & accountId)366 void KopeteDBusInterface::disconnect(const QString &protocolName, const QString &accountId)
367 {
368 QString protocolId = protocolName;
369 if (!protocolName.contains(QLatin1String("Protocol"))) {
370 protocolId += QLatin1String("Protocol");
371 }
372
373 Kopete::Account *account = Kopete::AccountManager::self()->findAccount(
374 protocolId, accountId);
375 if (account) {
376 account->disconnect();
377 }
378 }
379
contactProperties(const QString & contactId)380 QVariantMap KopeteDBusInterface::contactProperties(const QString &contactId)
381 {
382 QVariantMap properties;
383 Kopete::MetaContact *contact = d->findContact(contactId);
384
385 if (contact) {
386 properties[QStringLiteral("status")] = Kopete::OnlineStatus::statusTypeToString(
387 contact->status());
388 properties[QStringLiteral("message_reachable")] = contact->isReachable();
389 properties[QStringLiteral("file_reachable")] = contact->canAcceptFiles();
390 properties[QStringLiteral("display_name")] = contact->displayName();
391 properties[QStringLiteral("id")] = contact->metaContactId().toString();
392 if (contact->photoSource() == Kopete::MetaContact::SourceCustom) {
393 properties[QStringLiteral("picture")] = contact->customPhoto().toDisplayString();
394 } else {
395 properties[QStringLiteral("picture")] = contact->picture().path();
396 }
397 properties[QStringLiteral("idle_time")] = qulonglong(contact->idleTime());
398 if (contact->preferredContact()) {
399 /** @todo: export status message title as well or merge both? */
400 properties[QStringLiteral("status_message")]
401 = contact->preferredContact()->statusMessage().message();
402 }
403
404 QStringList messages;
405 foreach (Kopete::Contact *subContact, contact->contacts()) {
406 QList<Kopete::MessageEvent *> pendingMessages = KopeteViewManager::viewManager()->pendingMessages(subContact);
407 foreach (Kopete::MessageEvent *event, pendingMessages) {
408 messages << event->message().parsedBody();
409 }
410 }
411 properties[QStringLiteral("pending_messages")] = messages;
412 }
413
414 return properties;
415 }
416