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
33class KMenu;
34class KAction;
35
36namespace Kopete
37{
38
39class Group;
40class MetaContact;
41class ChatSession;
42class OnlineStatus;
43class Plugin;
44class Protocol;
45class Account;
46class StatusMessage;
47
48typedef 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 */
58class 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
76public:
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 *> *customContextMenuActions();
247
248 /**
249 * @deprecated
250 */
251 virtual KDE_DEPRECATED QList<KAction *> *customContextMenuActions( 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 *popupMenu();
260
261 /**
262 * @deprecated
263 */
264 KDE_DEPRECATED KMenu *popupMenu( 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
418public 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 );
494private 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);
529signals:
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
568private:
569 class Private;
570 Private * const d;
571
572
573};
574
575
576} //END namespace Kopete
577
578#endif
579
580