1 | /* |
2 | kopetemetacontact.h - Kopete Meta Contact |
3 | |
4 | Copyright (c) 2002-2003 by Martijn Klingens <klingens@kde.org> |
5 | Copyright (c) 2002-2005 by Duncan Mac-Vicar Prett <duncan@kde.org> |
6 | Copyright (c) 2002-2005 by Olivier Goffart <ogoffart@kde.org> |
7 | Copyright (c) 2003 by Will Stephenson <will@stevello.free-online.co.uk> |
8 | |
9 | Kopete (c) 2002-2005 by the Kopete developers <kopete-devel@kde.org> |
10 | |
11 | ************************************************************************* |
12 | * * |
13 | * This library is free software; you can redistribute it and/or * |
14 | * modify it under the terms of the GNU Lesser General Public * |
15 | * License as published by the Free Software Foundation; either * |
16 | * version 2 of the License, or (at your option) any later version. * |
17 | * * |
18 | ************************************************************************* |
19 | */ |
20 | |
21 | #ifndef kopetemetacontact_h__ |
22 | #define kopetemetacontact_h__ |
23 | |
24 | #include "kopetecontactlistelement.h" |
25 | |
26 | #include <QtCore/QList> |
27 | #include <QtCore/QUuid> |
28 | |
29 | #include <kdemacros.h> |
30 | #include <kurl.h> |
31 | #include "kopete_export.h" |
32 | |
33 | #include "kopeteonlinestatus.h" |
34 | #include "kopetestatusmessage.h" |
35 | |
36 | namespace Kopete { |
37 | |
38 | |
39 | class Plugin; |
40 | class Group; |
41 | class Picture; |
42 | |
43 | /** |
44 | * @author Will Stephenson <will@stevello.free-online.co.uk> |
45 | * @author Martijn Klingens <klingens@kde.org> |
46 | * @author Duncan Mac-Vicar Prett <duncan@kde.org> |
47 | * @author Olivier Goffart <ogoffart@kde.org> |
48 | * |
49 | * A metacontact represent a person. This is a kind of entry to |
50 | * the contact list. All information of a contact is contained in |
51 | * the metacontact. Plugins can store data in it with all |
52 | * @ref ContactListElement methods |
53 | */ |
54 | class KOPETE_EXPORT MetaContact : public ContactListElement |
55 | { |
56 | Q_OBJECT |
57 | |
58 | Q_PROPERTY( QString displayName READ displayName WRITE setDisplayName ) |
59 | Q_PROPERTY( QString statusString READ statusString ) |
60 | Q_PROPERTY( QString statusIcon READ statusIcon ) |
61 | Q_PROPERTY( bool isOnline READ isOnline ) |
62 | Q_PROPERTY( bool isReachable READ isReachable ) |
63 | Q_PROPERTY( bool isTemporary READ isTemporary ) |
64 | Q_PROPERTY( bool canAcceptFiles READ canAcceptFiles ) |
65 | //Q_PROPERTY( ulong idleTime READ idleTime ) |
66 | Q_PROPERTY( QUuid metaContactId READ metaContactId WRITE setMetaContactId ) |
67 | Q_PROPERTY( bool photoSyncedWithKABC READ isPhotoSyncedWithKABC WRITE setPhotoSyncedWithKABC ) |
68 | |
69 | public: |
70 | typedef QList<MetaContact *> List; |
71 | /** |
72 | * Enumeration of possible sources for a property (which may be |
73 | * photos, see setPhotoSource() for instance). |
74 | */ |
75 | enum PropertySource { |
76 | SourceContact /**< Data comes from the contact itself. */, |
77 | SourceKABC /**< Data comes from KABC (addressbook). */, |
78 | SourceCustom /**< Data comes from somewhere else. */ |
79 | }; |
80 | |
81 | /** |
82 | * constructor |
83 | */ |
84 | MetaContact(); |
85 | /** |
86 | * destructor |
87 | */ |
88 | ~MetaContact(); |
89 | |
90 | /** |
91 | * @brief Returns this metacontact's ID. |
92 | * |
93 | * Every metacontact has a unique id, set when creating the contact, |
94 | * or reading the contactlist |
95 | */ |
96 | QUuid metaContactId() const; |
97 | |
98 | /** |
99 | * @internal |
100 | * Set the meta contact id for this meta contact to use. It should only |
101 | * be used by the contact list loading mechanism |
102 | */ |
103 | void setMetaContactId( const QUuid& newMetaContactId ); |
104 | |
105 | /** |
106 | * @brief Get the KABC id for this metacontact |
107 | */ |
108 | QString kabcId() const; |
109 | |
110 | /** |
111 | * @brief Set the KABC id for this metacontact |
112 | * Use with care! You could create a one to many relationship |
113 | */ |
114 | void setKabcId( const QString& newKabcId ); |
115 | |
116 | /** |
117 | * @brief Retrieve the list of contacts that are part of the meta contact |
118 | */ |
119 | QList<Contact *> contacts() const; |
120 | |
121 | /** |
122 | * @brief The groups the contact is stored in |
123 | */ |
124 | QList<Group *> groups() const; |
125 | |
126 | /** |
127 | * Find the Contact to a given contact. If contact |
128 | * is not found, a null pointer is returned. |
129 | * if @p protocolId or @p accountId are null, it is searched over all protocols/accounts |
130 | */ |
131 | Contact *findContact( const QString &protocolId, const QString &accountId, const QString &contactId ); |
132 | |
133 | /** |
134 | * @brief Set the source of metacontact displayName |
135 | * |
136 | * This method selects the display name source for one |
137 | * of the sources defined in @ref PropertySource |
138 | * |
139 | * @see PropertySource |
140 | */ |
141 | void setDisplayNameSource(PropertySource source); |
142 | |
143 | void setDisplayNameSource( const QString &nameSourcePID, const QString &nameSourceAID, const QString &nameSourceCID ); |
144 | |
145 | /** |
146 | * @brief get the source of metacontact display name |
147 | * |
148 | * This method obtains the current name source for one |
149 | * of the sources defined in @ref PropertySource |
150 | * |
151 | * @see PropertySource |
152 | */ |
153 | PropertySource displayNameSource() const; |
154 | |
155 | /** |
156 | * @brief Set the source of metacontact photo |
157 | * |
158 | * This method selects the photo source for one |
159 | * of the sources defined in @ref PropertySource |
160 | * |
161 | * @see PropertySource |
162 | */ |
163 | void setPhotoSource(PropertySource source); |
164 | |
165 | void setPhotoSource( const QString &photoSourcePID, const QString &photoSourceAID, const QString &photoSourceCID ); |
166 | |
167 | /** |
168 | * @brief get the source of metacontact photo |
169 | * |
170 | * This method obtains the current photo source for one |
171 | * of the sources defined in @ref PropertySource |
172 | * |
173 | * @see PropertySource |
174 | */ |
175 | PropertySource photoSource() const; |
176 | |
177 | /** |
178 | * @brief the display name showed in the contact list window |
179 | * |
180 | * The displayname is the name which should be shown almost everywere to |
181 | * represent the metacontact. (in the contact list, in the chatwindow, ...) |
182 | * |
183 | * This is a kind of alias, set by the kopete user, as opposed to a nickname |
184 | * set by the contact itself. |
185 | * |
186 | * If the protocol support alias serverside, the metacontact displayname |
187 | * should probably be synchronized with the alias on the server. |
188 | * |
189 | * This displayName is obtained from the source set with @ref setDisplayNameSource |
190 | */ |
191 | QString displayName() const; |
192 | |
193 | /** |
194 | * @brief the photo showed in the contact list window |
195 | * |
196 | * Returns a image for the metacontact. If the metacontact photo source is |
197 | * the KDE addressbook. it will return the picture stored in the addressbook |
198 | * It can also use a subcontact as the photo source. |
199 | * |
200 | * This photo is obtained from the source set with @ref setPhotoSource |
201 | * @deprecated Use picture().image() instead. |
202 | */ |
203 | KDE_DEPRECATED QImage photo() const; |
204 | |
205 | /** |
206 | * Return the correct Kopete::Picture object depending of the metacontact photo source. |
207 | * |
208 | * This photo is obtained from the source set with @ref setPhotoSource |
209 | * |
210 | * KDE4 TODO: Rename this to photo() and use the new object. |
211 | */ |
212 | Picture &picture() const; |
213 | |
214 | /** |
215 | * @brief Set the custom displayName. |
216 | * |
217 | * This display name is used when name source is Custom |
218 | * this metohd may emit @ref displayNameChanged signal. |
219 | * And will call @ref Kopete::Contact::sync |
220 | * |
221 | * @see displayName() |
222 | * @see displayNameSource() |
223 | */ |
224 | void setDisplayName( const QString &name ); |
225 | |
226 | /** |
227 | * @brief Returns the custom display name |
228 | * |
229 | * @see displayName() |
230 | * @see displayNameSource() |
231 | */ |
232 | QString customDisplayName() const; |
233 | |
234 | /** |
235 | * @brief Returns the custom display photo |
236 | * |
237 | * @see photo() |
238 | * @see photoSource() |
239 | */ |
240 | KUrl customPhoto() const; |
241 | |
242 | |
243 | /** |
244 | * @brief Set the custom photo. |
245 | * |
246 | * This photo is used when photo source is set toCustom |
247 | * this metohd may emit @ref photoChanged signal. |
248 | * |
249 | * @see photo() |
250 | * @see photoSource() |
251 | */ |
252 | void setPhoto( const KUrl &url ); |
253 | |
254 | /** |
255 | * @brief get the subcontact being tracked for its displayname (null if not set) |
256 | * |
257 | * The MetaContact will adjust its displayName() every time the |
258 | * "nameSource" changes its nickname property. |
259 | */ |
260 | Contact *displayNameSourceContact() const; |
261 | |
262 | /** |
263 | * @brief set the subcontact whose name is to be tracked (set to null to disable tracking) |
264 | * @see nameSource |
265 | */ |
266 | void setDisplayNameSourceContact( Contact* contact ); |
267 | |
268 | /** |
269 | * @brief get the subcontact being tracked for its photo |
270 | */ |
271 | Contact *photoSourceContact() const; |
272 | |
273 | /** |
274 | * @brief set the subcontact to use for SourceContact source |
275 | */ |
276 | void setPhotoSourceContact( Contact* contact ); |
277 | |
278 | /** |
279 | * @return true if when a subcontact change his photo, the photo will be set to the kabc contact. |
280 | */ |
281 | bool isPhotoSyncedWithKABC() const; |
282 | |
283 | /** |
284 | * Set if the photo should be synced with the adressbook when the photosource change his photo |
285 | * |
286 | * If \p b is true, the photo will be synced immediately if possible |
287 | */ |
288 | void setPhotoSyncedWithKABC(bool b); |
289 | |
290 | |
291 | /** |
292 | * Temporary contacts will not be serialized. |
293 | * If they are added to the contact list, they appears in a special "Not in your contact list" group. |
294 | * (the @ref Group::temporary group) |
295 | */ |
296 | bool isTemporary() const; |
297 | |
298 | /** |
299 | * @brief Add a contact which has just been deserialised to the meta contact |
300 | * @param c The Contact being added |
301 | */ |
302 | void addContact( Contact *c ); |
303 | |
304 | /** |
305 | * @brief remove the contact from this metacontact |
306 | * |
307 | * set 'deleted' to true if the Contact is already deleted |
308 | * |
309 | * @param c is the contact to remove |
310 | * @param deleted : if it is false, it will disconnect the old contact, and call some method. |
311 | */ |
312 | void removeContact( Contact *c , bool deleted = false ); |
313 | |
314 | /** |
315 | * @return the preferred child Contact for communication, or 0 if none is suitable (all unreachable). |
316 | */ |
317 | Contact *preferredContact(); |
318 | |
319 | /** |
320 | * @brief The name of the icon associated with the contact's status |
321 | * @todo improve with OnlineStatus |
322 | */ |
323 | QString statusIcon() const; |
324 | |
325 | /** |
326 | * @brief The status string of the contact |
327 | * |
328 | * @see @ref status() |
329 | * @todo improve with OnlineStatus |
330 | */ |
331 | QString statusString() const; |
332 | |
333 | /** |
334 | * Returns whether this contact can be reached online for at least one |
335 | * FIXME: Make that an enum, because status can be unknown for certain |
336 | * protocols |
337 | */ |
338 | bool isOnline() const; |
339 | |
340 | /** |
341 | * Returns whether this contact is visible even if offline |
342 | */ |
343 | bool isAlwaysVisible() const; |
344 | |
345 | /** |
346 | * Returns whether this contact can accept files |
347 | * @return True if the user is online with a file capable protocol, false otherwise |
348 | */ |
349 | bool canAcceptFiles() const; |
350 | |
351 | /** |
352 | * Return a more fine-grained status. |
353 | * Online means at least one sub-contact is online, away means at least |
354 | * one is away, but nobody is online and offline speaks for itself |
355 | */ |
356 | OnlineStatus::StatusType status() const; |
357 | |
358 | /** |
359 | * Like isOnline, but returns true even if the contact is not online, but |
360 | * can be reached trough offline-messages. |
361 | * it it return false, you are unable to open a chatwindow |
362 | * @todo : Here too, use preference order, not append order! |
363 | * @todo : Here too an enum. |
364 | */ |
365 | bool isReachable() const; |
366 | |
367 | /** |
368 | * return the time in second the contact is idle. |
369 | */ |
370 | quint32 idleTime() const; |
371 | |
372 | /** |
373 | * Get or set a field for the KDE address book backend. Fields not |
374 | * registered during the call to Plugin::addressBookFields() |
375 | * cannot be altered! |
376 | * |
377 | * @param p The Plugin by which uses this field |
378 | * @param app refers to the application id in the libkabc database. |
379 | * This should be a standardized format to make sense in the address |
380 | * book in the first place - if you could use "" as application |
381 | * then probably you should use the plugin data API instead of the |
382 | * address book fields. |
383 | * @param key The name of the address book field to get or set |
384 | * |
385 | * @todo: In the code the requirement that fields are registered first |
386 | * is already lifted, but the API needs some review before we |
387 | * can remove it here too. |
388 | * Probably it requires once more some rewrites to get it working |
389 | * properly :( - Martijn |
390 | */ |
391 | QString addressBookField( Plugin *p, const QString &app, const QString &key ) const; |
392 | |
393 | /** |
394 | * @brief set an address book field |
395 | * |
396 | * @see also @ref addressBookField() |
397 | * @param p The Plugin by which uses this field |
398 | * @param app The application ID in the KABC database |
399 | * @param key The name of the address book field to set |
400 | * @param value The value of the address book field to set |
401 | */ |
402 | void setAddressBookField( Plugin *p, const QString &app, const QString &key, const QString &value ); |
403 | |
404 | /** |
405 | * @brief The status message of metacontact |
406 | */ |
407 | StatusMessage statusMessage() const; |
408 | |
409 | public slots: |
410 | |
411 | /** |
412 | * @brief Send a file to this metacontact |
413 | * |
414 | * This is the MetaContact level slot for sending files. It may be called through the |
415 | * "Send File" entry in the GUI, or over DCOP. If the function is called through the GUI, |
416 | * no parameters are sent and they assume default values. This slot calls the slotSendFile |
417 | * with identical params of the highest ranked contact capable of sending files (if any) |
418 | * |
419 | * @param sourceURL The actual KUrl of the file you are sending |
420 | * @param altFileName (Optional) An alternate name for the file - what the receiver will see |
421 | * @param fileSize (Optional) Size of the file being sent. Used when sending a nondeterminate |
422 | * file size (such as over a socket) |
423 | * |
424 | */ |
425 | void sendFile( const KUrl &sourceURL, const QString &altFileName = QString(), |
426 | unsigned long fileSize = 0L ); |
427 | |
428 | /** |
429 | * Serialize this metaContact |
430 | * This causes each Kopete::Protocol subclass to serialise its contacts' data into the metacontact's plugin data |
431 | */ |
432 | void serialize(); |
433 | |
434 | signals: |
435 | /** |
436 | * One of the subcontacts' idle status has changed. As with online status, |
437 | * this can occur without the metacontact changing idle state |
438 | */ |
439 | void contactIdleStateChanged( Kopete::Contact *contact ); |
440 | |
441 | /** |
442 | * Status title or message has changed |
443 | */ |
444 | void statusMessageChanged( Kopete::MetaContact *metaContact ); |
445 | |
446 | public slots: |
447 | |
448 | /** |
449 | * @brief Move a contact from one group to another. |
450 | */ |
451 | void moveToGroup( Kopete::Group *from, Kopete::Group *to ); |
452 | |
453 | /** |
454 | * @brief Remove a contact from one group |
455 | */ |
456 | void removeFromGroup( Kopete::Group *from ); |
457 | |
458 | /** |
459 | * @brief Add a contact to another group. |
460 | */ |
461 | void addToGroup( Kopete::Group *to ); |
462 | |
463 | /** |
464 | * @brief Set if this is a temporary contact. (see @ref isTemporary) |
465 | * |
466 | * @param b if the contact is or not temporary |
467 | * @param group if the contact was temporary and b is false, then the contact will be moved to this group. |
468 | * if group is null, it will be moved to top-level |
469 | */ |
470 | void setTemporary( bool b = true, Kopete::Group *group = 0L ); |
471 | |
472 | /** |
473 | * @brief Contact another user. |
474 | * |
475 | * Depending on the config settings, call sendMessage() or |
476 | * startChat() |
477 | * |
478 | * returns the Contact that was chosen as the preferred |
479 | */ |
480 | Contact *execute(); |
481 | |
482 | /** |
483 | * @brief Send a single message, classic ICQ style. |
484 | * |
485 | * The actual sending is done by the Contact, but the meta contact |
486 | * does the GUI side of things. |
487 | * This is a slot to allow being called easily from e.g. a GUI. |
488 | * |
489 | * returns the Contact that was chosen as the preferred |
490 | */ |
491 | Contact *sendMessage(); |
492 | |
493 | /** |
494 | * @brief Start a chat in a persistent chat window |
495 | * |
496 | * Like sendMessage, but this time a full-blown chat will be opened. |
497 | * Most protocols can't distinguish between the two and are either |
498 | * completely session based like MSN or completely message based like |
499 | * ICQ the only true difference is the GUI shown to the user. |
500 | * |
501 | * returns the Contact that was chosen as the preferred |
502 | */ |
503 | Contact *startChat(); |
504 | |
505 | /** |
506 | * When all the plugins are loaded, set the Contact Source. |
507 | */ |
508 | void slotAllPluginsLoaded(); |
509 | |
510 | /** |
511 | * If a plugin is loaded, maybe data about this plugin are already cached in the metacontact |
512 | */ |
513 | void slotPluginLoaded( Kopete::Plugin *plugin ); |
514 | |
515 | /** |
516 | * If a protocol is loaded, deserialize cached data |
517 | */ |
518 | void slotProtocolLoaded( Kopete::Protocol *p ); |
519 | |
520 | signals: |
521 | /** |
522 | * @brief The MetaContact online status changed |
523 | */ |
524 | void onlineStatusChanged( Kopete::MetaContact *contact, Kopete::OnlineStatus::StatusType status ); |
525 | |
526 | /** |
527 | * @brief A contact's online status changed |
528 | * |
529 | * this signal differs from @ref onlineStatusChanged because a contact can |
530 | * change his status without changing MetaContact status. It is mainly used to update the small icons |
531 | * in the contact list |
532 | */ |
533 | void contactStatusChanged( Kopete::Contact *contact, const Kopete::OnlineStatus &status ); |
534 | |
535 | /** |
536 | * @brief The meta contact's display name changed |
537 | */ |
538 | void displayNameChanged( const QString &oldName, const QString &newName ); |
539 | |
540 | /** |
541 | * @brief The meta contact's photo changed |
542 | */ |
543 | void photoChanged(); |
544 | |
545 | /** |
546 | * @brief The contact was moved |
547 | */ |
548 | void movedToGroup( Kopete::MetaContact *contact, Kopete::Group *from, Kopete::Group *to ); |
549 | |
550 | /** |
551 | * @brief The contact was removed from group |
552 | */ |
553 | void removedFromGroup( Kopete::MetaContact *contact, Kopete::Group *group ); |
554 | |
555 | /** |
556 | * @brief The contact was added to another group |
557 | */ |
558 | void addedToGroup( Kopete::MetaContact *contact, Kopete::Group *to ); |
559 | |
560 | /** |
561 | * @brief a contact has been added into this metacontact |
562 | * |
563 | * This signal is emitted when a contact is added to this metacontact |
564 | */ |
565 | void contactAdded( Kopete::Contact *c ); |
566 | |
567 | /** |
568 | * @brief a contact has been removed from this metacontact |
569 | * |
570 | * This signal is emitted when a contact is removed from this metacontact |
571 | */ |
572 | void contactRemoved( Kopete::Contact *c ); |
573 | |
574 | /** |
575 | * Some part of this object's persistent data (as returned by toXML) has changed. |
576 | */ |
577 | void persistentDataChanged( ); |
578 | |
579 | private slots: |
580 | /** |
581 | * Update the contact's online status and emit onlineStatusChanged |
582 | * when appropriate |
583 | */ |
584 | void updateOnlineStatus(); |
585 | |
586 | /** |
587 | * One of the child contact's online status changed |
588 | */ |
589 | void slotContactStatusChanged( Kopete::Contact *c, const Kopete::OnlineStatus &status, const Kopete::OnlineStatus &oldStatus ); |
590 | |
591 | /** |
592 | * One of the child contact's property changed |
593 | */ |
594 | void slotPropertyChanged( Kopete::PropertyContainer *contact, const QString &key, const QVariant &oldValue, const QVariant &newValue ); |
595 | |
596 | void slotContactDisplayNameChanged( const QString &oldName, const QString &newName ); |
597 | |
598 | /** |
599 | * A child contact was deleted, remove it from the list, if it's still |
600 | * there |
601 | */ |
602 | void slotContactDestroyed( Kopete::Contact* ); |
603 | |
604 | /** |
605 | * Update the KABC Picture when the addressbook is changed. |
606 | */ |
607 | void slotUpdateAddressBookPicture(); |
608 | |
609 | protected: |
610 | //QImage photoFromContact( Kopete::Contact *c) const; |
611 | //QImage photoFromKABC( const QString &id ) const; |
612 | QImage photoFromCustom() const; |
613 | //QString nameFromContact( Kopete::Contact *c) const; |
614 | //QString nameFromKABC( const QString &id ) const; |
615 | |
616 | void onlineStatusNotification( Kopete::Contact * c ); |
617 | |
618 | private: |
619 | class Private; |
620 | Private * const d; |
621 | }; |
622 | |
623 | // util functions shared with metacontact property dialog |
624 | KOPETE_EXPORT QImage photoFromContact( Kopete::Contact *c) /*const*/; |
625 | KOPETE_EXPORT QImage photoFromKABC( const QString &id ) /*const*/; |
626 | KOPETE_EXPORT QString nameFromContact( Kopete::Contact *c) /*const*/; |
627 | KOPETE_EXPORT QString nameFromKABC( const QString &id ) /*const*/; |
628 | |
629 | } //END namespace Kopete |
630 | |
631 | |
632 | #endif |
633 | |
634 | // vim: set noet ts=4 sts=4 sw=4: |
635 | |
636 | |