1 | /* |
2 | kopetecontact.h - Kopete Contact |
3 | |
4 | Copyright (c) 2002-2004 by Duncan Mac-Vicar Prett <duncan@kde.org> |
5 | Copyright (c) 2002-2003 by Martijn Klingens <klingens@kde.org> |
6 | Copyright (c) 2002-2004 by Olivier Goffart <ogoffart@kde.org> |
7 | |
8 | Kopete (c) 2002-2004 by the Kopete developers <kopete-devel@kde.org> |
9 | |
10 | ************************************************************************* |
11 | * * |
12 | * This library is free software; you can redistribute it and/or * |
13 | * modify it under the terms of the GNU Lesser General Public * |
14 | * License as published by the Free Software Foundation; either * |
15 | * version 2 of the License, or (at your option) any later version. * |
16 | * * |
17 | ************************************************************************* |
18 | */ |
19 | |
20 | #ifndef KOPETECONTACT_H |
21 | #define KOPETECONTACT_H |
22 | |
23 | #include "kopetecontactlistelement.h" |
24 | #include "kopetepropertycontainer.h" |
25 | |
26 | #include <kurl.h> |
27 | #include <kdemacros.h> |
28 | #include <ktoggleaction.h> |
29 | #include "kopeteglobal.h" |
30 | |
31 | #include "kopete_export.h" |
32 | |
33 | class ; |
34 | class KAction; |
35 | |
36 | namespace Kopete |
37 | { |
38 | |
39 | class Group; |
40 | class MetaContact; |
41 | class ChatSession; |
42 | class OnlineStatus; |
43 | class Plugin; |
44 | class Protocol; |
45 | class Account; |
46 | class StatusMessage; |
47 | |
48 | typedef QList<Group *> GroupList; |
49 | |
50 | /** |
51 | * @author Duncan Mac-Vicar P. <duncan@kde.org> |
52 | * @author Martijn Klingens <klingens@kde.org> |
53 | * @author Olivier Goffart <ogoffart@kde.org> |
54 | * |
55 | * This class abstracts a generic contact |
56 | * Use it for inserting contacts in the contact list for example. |
57 | */ |
58 | class KOPETE_EXPORT Contact |
59 | : public ContactListElement |
60 | { |
61 | Q_OBJECT |
62 | |
63 | Q_ENUMS( CanCreateFlags ) |
64 | Q_PROPERTY( QString formattedName READ formattedName ) |
65 | Q_PROPERTY( QString formattedIdleTime READ formattedIdleTime ) |
66 | Q_PROPERTY( bool isOnline READ isOnline ) |
67 | Q_PROPERTY( bool fileCapable READ isFileCapable WRITE setFileCapable ) |
68 | Q_PROPERTY( bool canAcceptFiles READ canAcceptFiles ) |
69 | //Q_PROPERTY( bool isReachable READ isReachable ) |
70 | Q_PROPERTY( QString contactId READ contactId ) |
71 | Q_PROPERTY( QString icon READ icon WRITE setIcon ) |
72 | Q_PROPERTY( QString toolTip READ toolTip ) |
73 | Q_PROPERTY( QString nickName READ nickName WRITE setNickName ) |
74 | //Q_PROPERTY( unsigned long idleTime READ idleTime WRITE setIdleTime ) |
75 | |
76 | public: |
77 | /** |
78 | * used in @ref sync() |
79 | */ |
80 | enum Changed{ MovedBetweenGroup = 0x01, ///< the contact has been moved between groups |
81 | DisplayNameChanged = 0x02 ///< the displayname of the contact changed |
82 | }; |
83 | |
84 | enum NameType { |
85 | NickName, ///< Nick name, comes from contact |
86 | CustomName, ///< Custom name set by user and stored on server contact list, can be changed |
87 | FormattedName, ///< Formatted name (first and/or last name) |
88 | ContactId, ///< Contact id, will never change |
89 | }; |
90 | |
91 | /** |
92 | * These functions do conversion between enum NameType and QString |
93 | * Usefull for protocol serialize/deserialize funcions |
94 | */ |
95 | static NameType nameTypeFromString(const QString &nameType); |
96 | static const QString nameTypeToString(NameType nameType); |
97 | |
98 | /** |
99 | * \brief Create new contact. |
100 | * |
101 | * <b>The parent MetaContact must not be NULL</b> |
102 | * |
103 | * \note id is required to be unique per protocol and per account. |
104 | * Across those boundaries ids may occur multiple times. |
105 | * The id is solely for comparing items safely (using pointers is |
106 | * more crash-prone). DO NOT assume anything regarding the id's |
107 | * value! Even if it may look like an ICQ UIN or an MSN passport, |
108 | * this is undefined and may change at any time! |
109 | * |
110 | * @param account is the parent account. this constructor automatically register the contact to the account |
111 | * @param id is the Contact's unique Id (mostly the user's login) |
112 | * @param parent is the parent @ref MetaContact this Contact is part of |
113 | * @param icon is an optional icon |
114 | */ |
115 | Contact( Account *account, const QString &id, MetaContact *parent, |
116 | const QString &icon = QString() ); |
117 | |
118 | ~Contact(); |
119 | |
120 | /** |
121 | * \brief Get the metacontact for this contact |
122 | * @return The MetaContact object for this contact |
123 | */ |
124 | MetaContact *metaContact() const; |
125 | |
126 | |
127 | /** |
128 | * \brief Get the unique id that identifies a contact. |
129 | * |
130 | * \note Id is required to be unique per protocol and per account. |
131 | * Across those boundaries ids may occur multiple times. |
132 | * The id is solely for comparing items safely (using pointers is |
133 | * more crash-prone). DO NOT assume anything regarding the id's |
134 | * value! Even if it may look like an ICQ UIN or an MSN passport, |
135 | * this is undefined and may change at any time! |
136 | * |
137 | * @return The unique id of the contact |
138 | */ |
139 | QString contactId() const; |
140 | |
141 | /** |
142 | * \brief Get the protocol that the contact belongs to. |
143 | * |
144 | * simply return account()->protocol() |
145 | * |
146 | * @return the contact's protocol |
147 | */ |
148 | Protocol* protocol() const; |
149 | |
150 | /** |
151 | * \brief Get the account that this contact belongs to |
152 | * |
153 | * @return the Account object for this contact |
154 | */ |
155 | Account* account() const; |
156 | |
157 | /** |
158 | * \brief Move this contact to a new MetaContact. |
159 | * This basically reparents the contact and updates the internal |
160 | * data structures. |
161 | * If the old contact is going to be empty, the old contact will be removed. |
162 | * |
163 | * @param m The new MetaContact to move this contact to |
164 | */ |
165 | void setMetaContact(MetaContact *m); |
166 | |
167 | /** |
168 | * @brief Get whether this contact is online. |
169 | * @return @c true if the contact is online, @c false otherwise. |
170 | */ |
171 | bool isOnline() const; |
172 | |
173 | /** |
174 | * \brief Get whether this contact can receive messages |
175 | * |
176 | * Used in determining if the contact is able to |
177 | * receive messages. This function must be defined by child classes |
178 | * |
179 | * @return true if the contact can be reached |
180 | * @return false if the contact cannot be reached |
181 | */ |
182 | // FIXME: After KDE 3.2 we should split this into a public, NON-virtual |
183 | // isReachable() accessor that checks for account->isConnected() |
184 | // and then calls a new virtual method that does the |
185 | // protocol-specific work, like 'doIsUnreachable' or so - Martijn |
186 | // |
187 | //FIXME: Can this be made const please? - JK |
188 | virtual bool isReachable(); |
189 | |
190 | /** |
191 | * @brief Serialize the contact for storage in the contact list. |
192 | * |
193 | * The provided serializedData contain the contact id in the field |
194 | * "contactId". If you don't like this, or don't want to |
195 | * store these fields at all, |
196 | * you are free to remove them from the list. |
197 | * |
198 | * Most plugins don't need more than these fields, so they only need |
199 | * to set the address book fields themselves. If you have nothing to |
200 | * save at all you can clear the QMap, an empty map is treated as |
201 | * 'nothing to save'. |
202 | * |
203 | * The provided addressBookFields QMap contains the index field as |
204 | * marked with @ref Plugin::addAddressBookField() with the |
205 | * contact id as value. If no index field is available the QMap is |
206 | * simply passed as an empty map. |
207 | * |
208 | * @sa Protocol::deserializeContact |
209 | */ |
210 | virtual void serialize( QMap<QString, QString> &serializedData, QMap<QString, QString> &addressBookData ); |
211 | |
212 | /** |
213 | * @brief Get the online status of the contact |
214 | * @return the online status of the contact |
215 | */ |
216 | OnlineStatus onlineStatus() const; |
217 | |
218 | /** |
219 | * \brief Set the contact's online status |
220 | */ |
221 | void setOnlineStatus(const OnlineStatus &status); |
222 | |
223 | /** |
224 | * @brief Get the current status message of the contact. |
225 | * @return the status in a Kopete::StatusMessage. |
226 | */ |
227 | Kopete::StatusMessage statusMessage() const; |
228 | /** |
229 | * @brief Set the contact's status message. |
230 | * It sets also the "awayMessage" property so you don't need to do it. |
231 | */ |
232 | void setStatusMessage(const Kopete::StatusMessage &statusMessage); |
233 | |
234 | /** |
235 | * \brief Get the set of custom menu items for this contact |
236 | * |
237 | * Returns a set of custom menu items for the context menu |
238 | * which is displayed in showContextMenu (private). Protocols |
239 | * should use this to add protocol-specific actions to the |
240 | * popup menu. Kopete take care of the deletion of the action collection. |
241 | * Actions should have the collection as parent. |
242 | * |
243 | * @return Collection of menu items to be show on the context menu |
244 | * @todo if possible, try to use KXMLGUI |
245 | */ |
246 | virtual QList<KAction *> *(); |
247 | |
248 | /** |
249 | * @deprecated |
250 | */ |
251 | virtual KDE_DEPRECATED QList<KAction *> *( ChatSession *manager ); |
252 | |
253 | /** |
254 | * @brief Get the Context Menu for this contact |
255 | * |
256 | * This menu includes generic actions common to each protocol, and action defined in |
257 | * @ref customContextMenuActions() |
258 | */ |
259 | KMenu *(); |
260 | |
261 | /** |
262 | * @deprecated |
263 | */ |
264 | KDE_DEPRECATED KMenu *( ChatSession *manager ); |
265 | |
266 | /** |
267 | * \brief Get whether or not this contact is capable of file transfers |
268 | * |
269 | * |
270 | * \see setFileCapable() |
271 | * \return true if the protocol for this contact is capable of file transfers |
272 | * \return false if the protocol for this contact is not capable of file transfers |
273 | * |
274 | * @todo have a capabilioties. or move to protocol capabilities |
275 | */ |
276 | bool isFileCapable() const; |
277 | |
278 | /** |
279 | * \brief Set the file transfer capability of this contact |
280 | * |
281 | * \param filecap The new file transfer capability setting |
282 | * @todo have a capabilioties. or move to protocol capabilities |
283 | */ |
284 | void setFileCapable( bool filecap ); |
285 | |
286 | /** |
287 | * \brief Get whether or not this contact can accept file transfers |
288 | * |
289 | * This function checks to make sure that the contact is online as well as |
290 | * capable of sending files. |
291 | * \see isReachable() |
292 | * @return true if this contact is online and is capable of receiving files |
293 | * @todo have a capabilioties. or move to protocol capabilities |
294 | */ |
295 | bool canAcceptFiles() const; |
296 | |
297 | enum CanCreateFlags { CannotCreate=false , CanCreate=true }; |
298 | |
299 | /** |
300 | * Returns the primary message manager affiliated with this contact |
301 | * Although a contact can have more than one active message manager |
302 | * (as is the case with MSN at least), only one message manager will |
303 | * ever be the contacts "primary" message manager.. aka the 1 on 1 chat. |
304 | * This function should always return that instance. |
305 | * |
306 | * @param canCreate If a new message manager can be created in addition |
307 | * to any existing managers. Currently, this is only set to true when |
308 | * a chat is initiated by the user by clicking the contact list. |
309 | */ |
310 | virtual ChatSession * manager( CanCreateFlags canCreate = CannotCreate ) =0; |
311 | |
312 | /** |
313 | * Returns the name of the icon to use for this contact |
314 | * If null, the protocol icon need to be used. |
315 | * The icon is not colored, nor has the status icon overloaded |
316 | */ |
317 | QString& icon() const; |
318 | |
319 | /** |
320 | * @brief Change the icon to use for this contact |
321 | * If you don't want to have the protocol icon as icon for this contact, you may set |
322 | * another icon. The icon doesn't need to be colored with the account icon as this operation |
323 | * will be performed later. |
324 | * |
325 | * if you want to go back to the protocol icon, set a null string. |
326 | */ |
327 | void setIcon( const QString& icon ); |
328 | |
329 | /** |
330 | * \brief Get the time (in seconds) this contact has been idle |
331 | * It will return the time set in @ref setIdleTime() with an addition of the time |
332 | * since you set this last time |
333 | * @return time this contact has been idle for, in seconds |
334 | // |
335 | // FIXME: Can we make this just 'unsigned long' ? QT Properties can't handle |
336 | // 'unsigned long int' |
337 | */ |
338 | virtual unsigned long int idleTime() const; |
339 | |
340 | /** |
341 | * \brief Set the current idle time in seconds. |
342 | * Kopete will automatically calculate the time in @ref idleTime |
343 | * except if you set 0. |
344 | // |
345 | // FIXME: Can we make this just 'unsigned long' ? QT Properties can't handle |
346 | // 'unsigned long int' |
347 | */ |
348 | void setIdleTime(unsigned long int); |
349 | |
350 | /** |
351 | * \brief Convenience method to set the nickName property to the specified value |
352 | * @param name The nickname to set |
353 | */ |
354 | void setNickName( const QString &name ); |
355 | |
356 | /** |
357 | * \brief Convenience method to retrieve the nickName property. |
358 | * Property nickName comes from contact and cannot be changed by user custom name |
359 | * This method will return the contactId if there has been no nickName property set |
360 | */ |
361 | QString nickName() const; |
362 | |
363 | /** |
364 | * \brief Convenience method to set the customkName property to the specified value |
365 | * @param name The name to set |
366 | */ |
367 | void setCustomName( const QString &name ); |
368 | |
369 | /** |
370 | * \brief Convenience method to retrieve the customName property. |
371 | * Property customName is name set by user and stored on server contact list |
372 | * This method will return nickName if there has been no customName property set |
373 | */ |
374 | QString customName() const; |
375 | |
376 | /** |
377 | * Set preferred name type, used by displayName function |
378 | */ |
379 | void setPreferredNameType(NameType type); |
380 | |
381 | /** |
382 | * Returns prefered name type, used by displayName function |
383 | * Default is CustomName |
384 | */ |
385 | NameType preferredNameType() const; |
386 | |
387 | /** |
388 | * Returns display name of contact. Suitable for GUI display. |
389 | * Call formattedName or nickName or customName or contactId depending on preferredNameType. |
390 | * This method will return contactId if preferredNameType property is empty string. |
391 | */ |
392 | QString displayName() const; |
393 | |
394 | /** |
395 | * \brief Get the tooltip for this contact |
396 | * Makes use of formattedName() and formattedIdleTime(). |
397 | * \return an RTF tooltip depending on Kopete::AppearanceSettings settings |
398 | **/ |
399 | QString toolTip() const; |
400 | |
401 | /** |
402 | * Returns a formatted string of "firstName" and/or "lastName" properties if present. |
403 | **/ |
404 | QString formattedName() const; |
405 | |
406 | /** |
407 | * Returns a formatted string of idleTime(). |
408 | * Suitable for GUI display |
409 | **/ |
410 | QString formattedIdleTime() const; |
411 | |
412 | /** |
413 | * @brief Convience method to set the photo property |
414 | * @param photoPath Local path to the photo |
415 | */ |
416 | void setPhoto(const QString &photoPath); |
417 | |
418 | public slots: |
419 | /** |
420 | * This should typically pop up a KopeteChatWindow |
421 | */ |
422 | void startChat(); |
423 | |
424 | /** |
425 | * Pops up an email type window |
426 | */ |
427 | void sendMessage(); |
428 | |
429 | /** |
430 | * The user clicked on the contact, do the default action |
431 | */ |
432 | void execute(); |
433 | |
434 | /** |
435 | * Toggle the visibility of this contact even if offline. This function |
436 | * is called by the KAction toggleAlwaysVisible that is part of the context |
437 | * menu. |
438 | */ |
439 | void toggleAlwaysVisible(); |
440 | |
441 | /** |
442 | * Changes the MetaContact that this contact is a part of. This function |
443 | * is called by the KAction changeMetaContact that is part of the context |
444 | * menu. |
445 | */ |
446 | void changeMetaContact(); |
447 | /** |
448 | * Method to retrieve user information. Should be implemented by |
449 | * the protocols, and popup some sort of dialog box |
450 | * |
451 | * reimplement it to show the informlation |
452 | * @todo rename and make it pure virtual |
453 | */ |
454 | virtual void slotUserInfo() {} |
455 | |
456 | /** |
457 | * @brief Syncronise the server and the metacontact. |
458 | * Protocols with server-side contact lists can implement this to |
459 | * sync the server groups with the metaContact groups. Or the server alias if any. |
460 | * |
461 | * This method is called every time the metacontact has been moved or renamed. |
462 | * |
463 | * default implementation does nothing |
464 | * |
465 | * @param changed is a bitmask of the @ref Changed enum which say why the call to this function is done. |
466 | */ |
467 | virtual void sync(unsigned int changed = 0xFF); |
468 | |
469 | /** |
470 | * @deprecated Use DeleteContactTask instead. |
471 | * Method to delete a contact from the contact list, |
472 | * should be implemented by protocol plugin to handle |
473 | * protocol-specific actions required to delete a contact |
474 | * (ie. messages to the server, etc) |
475 | * the default implementation simply call deleteLater() |
476 | */ |
477 | virtual KDE_DEPRECATED void deleteContact(); |
478 | |
479 | /** |
480 | * This is the Contact level slot for sending files. It should be |
481 | * implemented by all contacts which have the setFileCapable() flag set to |
482 | * true. If the function is called through the GUI, no parameters are sent |
483 | * and they take on default values (the file is chosen with a file open dialog) |
484 | * |
485 | * @param sourceURL The actual KUrl of the file you are sending |
486 | * @param fileName (Optional) An alternate name for the file - what the |
487 | * receiver will see |
488 | * @param fileSize (Optional) Size of the file being sent. Used when sending |
489 | * a nondeterminate |
490 | * file size (such as over asocket |
491 | */ |
492 | virtual void sendFile( const KUrl &sourceURL = KUrl(), |
493 | const QString &fileName = QString(), uint fileSize = 0L ); |
494 | private slots: |
495 | /** |
496 | * This add the contact totally in the list if it was a temporary contact |
497 | */ |
498 | void slotAddContact(); |
499 | |
500 | /** |
501 | * slot called when the action "delete" is called. |
502 | */ |
503 | void slotDelete(); |
504 | |
505 | /** |
506 | * slot called when the action "block" is called. |
507 | */ |
508 | void slotBlock(); |
509 | |
510 | /** |
511 | * slot called when the action "unblock" is called. |
512 | */ |
513 | void slotUnblock(); |
514 | |
515 | /** |
516 | * The account's isConnected has changed. |
517 | */ |
518 | void slotAccountIsConnectedChanged(); |
519 | |
520 | /** |
521 | * slot called when the metaContact was deleted. |
522 | */ |
523 | void slotMetaContactDestroyed( QObject* mc ); |
524 | |
525 | /** |
526 | * slot to handle changing display name |
527 | */ |
528 | void slotPropertyChanged(Kopete::PropertyContainer *, const QString &key, const QVariant &oldValue, const QVariant &newValue); |
529 | signals: |
530 | /** |
531 | * The contact's online status changed |
532 | */ |
533 | void onlineStatusChanged( Kopete::Contact *contact, |
534 | const Kopete::OnlineStatus &status, const Kopete::OnlineStatus &oldStatus ); |
535 | |
536 | /** |
537 | * The contact's status message changed |
538 | */ |
539 | void statusMessageChanged( Kopete::Contact *contact ); |
540 | |
541 | /** |
542 | * The contact is about to be destroyed. |
543 | * Called when entering the destructor. Useful for cleanup, since |
544 | * metaContact() is still accessible at this point. |
545 | * |
546 | * @warning this signal is emit in the Contact destructor, so all |
547 | * virtual method are not available |
548 | */ |
549 | void contactDestroyed( Kopete::Contact *contact ); |
550 | |
551 | /** |
552 | * The contact's idle state changed. |
553 | * You need to emit this signal to update the view. |
554 | * That mean when activity has been noticed |
555 | */ |
556 | void idleStateChanged( Kopete::Contact *contact ); |
557 | |
558 | /** |
559 | * \brief Emitted when the file transfer capability of this contact has changed |
560 | */ |
561 | void canAcceptFilesChanged(); |
562 | |
563 | /** |
564 | * Emitted when displayName has changed |
565 | */ |
566 | void displayNameChanged(const QString &oldName, const QString &newName); |
567 | |
568 | private: |
569 | class Private; |
570 | Private * const d; |
571 | |
572 | |
573 | }; |
574 | |
575 | |
576 | } //END namespace Kopete |
577 | |
578 | #endif |
579 | |
580 | |