summaryrefslogtreecommitdiffstats
path: root/kopete/libkopete/kopetecontact.h
blob: 8f02bfc2f30f2be225999659b7b0e0f66bba2598 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
/*
    kopetecontact.h - Kopete Contact

    Copyright (c) 2002-2004 by Duncan Mac-Vicar Prett <[email protected]>
    Copyright (c) 2002-2003 by Martijn Klingens       <[email protected]>
    Copyright (c) 2002-2004 by Olivier Goffart        <ogoffart @ tiscalinet.be>

    Kopete    (c) 2002-2004 by the Kopete developers  <[email protected]>

    *************************************************************************
    *                                                                       *
    * This library is free software; you can redistribute it and/or         *
    * modify it under the terms of the GNU Lesser General Public            *
    * License as published by the Free Software Foundation; either          *
    * version 2 of the License, or (at your option) any later version.      *
    *                                                                       *
    *************************************************************************
*/

#ifndef __KOPETECONTACT_H__
#define __KOPETECONTACT_H__

#include <qobject.h>
#include <kurl.h>
#include <kdemacros.h>
#include "kopeteglobal.h"

#include "kopete_export.h"

class QImage;
class KPopupMenu;
class KAction;

namespace Kopete
{

class Group;
class MetaContact;
class ChatSession;
class OnlineStatus;
class Plugin;
class Protocol;
class Account;
typedef QPtrList<Group> GroupList;

/**
 * @author Duncan Mac-Vicar P. <[email protected]>
 * @author Martijn Klingens <[email protected]>
 * @author Olivier Goffart <ogoffart@ tiscalinet.be>
 *
 * This class abstracts a generic contact
 * Use it for inserting contacts in the contact list for example.
 */
class KOPETE_EXPORT Contact : public QObject
{
	Q_OBJECT

	Q_ENUMS( CanCreateFlags )
	Q_PROPERTY( QString formattedName READ formattedName )
	Q_PROPERTY( QString formattedIdleTime READ formattedIdleTime )
	Q_PROPERTY( bool isOnline READ isOnline )
	Q_PROPERTY( bool fileCapable READ isFileCapable WRITE setFileCapable )
	Q_PROPERTY( bool canAcceptFiles READ canAcceptFiles )
	//Q_PROPERTY( bool isReachable READ isReachable )
	Q_PROPERTY( QString contactId READ contactId )
	Q_PROPERTY( QString icon READ icon WRITE setIcon )
	Q_PROPERTY( QString toolTip READ toolTip )
	Q_PROPERTY( QString nickName READ nickName WRITE setNickName )
	//Q_PROPERTY( unsigned long idleTime READ idleTime WRITE setIdleTime )

public:
	/**
	 * \brief Create new contact.
	 *
	 * <b>The parent MetaContact must not be NULL</b>
	 *
	 * \note id is required to be unique per protocol and per account.
	 * Across those boundaries ids may occur multiple times.
	 * The id is solely for comparing items safely (using pointers is
	 * more crash-prone). DO NOT assume anything regarding the id's
	 * value! Even if it may look like an ICQ UIN or an MSN passport,
	 * this is undefined and may change at any time!
	 *
	 * @param account is the parent account. this constructor automatically register the contact to the account
	 * @param id is the Contact's unique Id (mostly the user's login)
	 * @param parent is the parent @ref MetaContact this Contact is part of
	 * @param icon is an optional icon
	 */
	Contact( Account *account, const QString &id, MetaContact *parent,
		const QString &icon = QString::null );

	~Contact();

	/**
	 * \brief Get the metacontact for this contact
	 * @return The MetaContact object for this contact
	 */
	MetaContact *metaContact() const;


	/**
	 * \brief Get the unique id that identifies a contact.
	 *
	 * \note Id is required to be unique per protocol and per account.
	 * Across those boundaries ids may occur multiple times.
	 * The id is solely for comparing items safely (using pointers is
	 * more crash-prone). DO NOT assume anything regarding the id's
	 * value! Even if it may look like an ICQ UIN or an MSN passport,
	 * this is undefined and may change at any time!
	 *
	 * @return The unique id of the contact
	 */
	QString contactId() const;

	/**
	 * \brief Get the protocol that the contact belongs to.
	 *
	 * simply return account()->protocol()
	 *
	 * @return the contact's protocol
	 */
	Protocol* protocol() const;

	/**
	 * \brief Get the account that this contact belongs to
	 *
	 * @return the Account object for this contact
	 */
	Account* account() const;

	/**
	 * \brief Move this contact to a new MetaContact.
	 * This basically reparents the contact and updates the internal
	 * data structures.
	 * If the old contact is going to be empty, a question may ask to the user if it wants to delete the old contact.
	 *
	 * @param m The new MetaContact to move this contact to
	 */
	void setMetaContact(MetaContact *m);


	/**
	 * @brief Get whether this contact is online.
	 * @return @c true if the contact is online, @c false otherwise.
	 */
	bool isOnline() const;

	/**
	 * \brief Get whether this contact can receive messages
	 *
	 * Used in determining if the contact is able to
	 * receive messages.  This function must be defined by child classes
	 *
	 * @return true if the contact can be reached
	 * @return false if the contact can not be reached
	 */
	// FIXME: After KDE 3.2 we should split this into a public, NON-virtual
	//        isReachable() accessor that checks for account->isConnected()
	//        and then calls a new virtual method that does the
	//        protocol-specific work, like 'doIsUnreachable' or so - Martijn
	//
	//FIXME: Can this be made const please? - JK
	virtual bool isReachable();

	/**
	 * @brief Serialize the contact for storage in the contact list.
	 *
	 * The provided serializedData contain the contact id in the field
	 * "contactId". If you don't like this, or don't want to
	 * store these fields at all,
	 * you are free to remove them from the list.
	 *
	 * Most plugins don't need more than these fields, so they only need
	 * to set the address book fields themselves. If you have nothing to
	 * save at all you can clear the QMap, an empty map is treated as
	 * 'nothing to save'.
	 *
	 * The provided addressBookFields QMap contains the index field as
	 * marked with @ref Plugin::addAddressBookField() with the
	 * contact id as value. If no index field is available the QMap is
	 * simply passed as an empty map.
	 *
	 * @sa Protocol::deserializeContact
	 */
	virtual void serialize( QMap<QString, QString> &serializedData, QMap<QString, QString> &addressBookData );

	/**
	 * @brief Serialize the contacts persistent properties for storage in the contact list.
	 *
	 * Does the same as @ref serialize() does but for KopeteContactProperties
	 * set in this contact with their persistency flag turned on.
	 * In contrary to @ref serialize() this does not need to be reimplemented.
	 *
	 */
	void serializeProperties(QMap<QString, QString> &serializedData);

	/**
	 * @brief Deserialize the contacts persistent properties
	 */
	void deserializeProperties(QMap<QString, QString> &serializedData);

	/**
	 * @brief Get the online status of the contact
	 * @return the online status of the contact
	 */
	OnlineStatus onlineStatus() const;

	/**
	 * \brief Set the contact's online status
	 */
	void setOnlineStatus(const OnlineStatus &status);

	/**
	 * \brief Get the set of custom menu items for this contact
	 *
	 * Returns a set of custom menu items for the context menu
	 * which is displayed in showContextMenu (private).  Protocols
	 * should use this to add protocol-specific actions to the
	 * popup menu. Kopete take care of the deletion of the action collection.
	 * Actions should have the collection as parent.
	 *
	 * @return Collection of menu items to be show on the context menu
	 * @todo if possible, try to use KXMLGUI
	 */
	virtual QPtrList<KAction> *customContextMenuActions();

	/**
	 * @todo  What is this function for ?
	 */
	virtual QPtrList<KAction> *customContextMenuActions( ChatSession *manager );

	/**
	 * @brief Get the Context Menu for this contact
	 *
	 * This menu includes generic actions common to each protocol, and action defined in
	 * @ref customContextMenuActions()
	 */
	KPopupMenu *popupMenu( ChatSession *manager = 0L );

	/**
	 * \brief Get whether or not this contact is capable of file transfers
	 *
	 *
	 * \see setFileCapable()
	 * \return true if the protocol for this contact is capable of file transfers
	 * \return false if the protocol for this contact is not capable of file transfers
	 *
	 * @todo have a capabilioties. or move to protocol capabilities
	 */
	bool isFileCapable() const;

	/**
	 * \brief Set the file transfer capability of this contact
	 *
	 * \param filecap The new file transfer capability setting
	 * @todo have a capabilioties. or move to protocol capabilities
	 */
	void setFileCapable( bool filecap );

	/**
	 * \brief Get whether or not this contact can accept file transfers
	 *
	 * This function checks to make sure that the contact is online as well as
	 * capable of sending files.
	 * \see isReachable()
	 * @return true if this contact is online and is capable of receiving files
	 * @todo have a capabilioties. or move to protocol capabilities
	 */
	bool canAcceptFiles() const;

	enum CanCreateFlags {  CannotCreate=false , CanCreate=true  };

	/**
	 * Returns the primary message manager affiliated with this contact
	 * Although a contact can have more than one active message manager
	 * (as is the case with MSN at least), only one message manager will
	 * ever be the contacts "primary" message manager.. aka the 1 on 1 chat.
	 * This function should always return that instance.
	 *
	 * @param canCreate If a new message manager can be created in addition
	 * to any existing managers. Currently, this is only set to true when
	 * a chat is initiated by the user by clicking the contact list.
	 */
	virtual ChatSession * manager( CanCreateFlags canCreate = CannotCreate ) =0;

	/**
	 * Returns the name of the icon to use for this contact
	 *  If null, the protocol icon need to be used.
	 * The icon is not colored, nor has the status icon overloaded
	 */
	QString& icon() const;

	/**
	 * @brief Change the icon to use for this contact
	 * If you don't want to have the protocol icon as icon for this contact, you may set
	 * another icon.  The icon doesn't need to be colored with the account icon as this operation
	 * will be performed later.
	 *
	 * if you want to go back to the protocol icon, set a null string.
	 */
	void setIcon( const QString& icon );

	/**
	 * \brief Get the time (in seconds) this contact has been idle
	 * It will return the time set in @ref setIdleTime() with an addition of the time
	 * since you set this last time
	 * @return time this contact has been idle for, in seconds
	 //
         // FIXME: Can we make this just 'unsigned long' ? QT Properties can't handle
         // 'unsigned long int'
	 */
	virtual unsigned long int idleTime() const;

	/**
	 * \brief Set the current idle time in seconds.
	 * Kopete will automatically calculate the time in @ref idleTime
	 * except if you set 0.
	 //
	 // FIXME: Can we make this just 'unsigned long' ? QT Properties can't handle
	 // 'unsigned long int'
	 */
	void setIdleTime(unsigned long int);

	/**
	 * @return A QStringList containing all property keys
	 **/
	QStringList properties() const;

	/**
	 * Check for existance of a certain property stored
	 * using "key".
	 * \param key the property to check for
	 **/
	bool hasProperty(const QString &key) const;

	/**
	 * \brief Get the value of a property with key "key".
	 *
	 * If you don't know the type of the returned QVariant, you will need
	 * to check for it.
	 * \return the value of the property
	 **/
	const Kopete::ContactProperty &property(const QString &key) const;
	const Kopete::ContactProperty &property(const Kopete::ContactPropertyTmpl &tmpl) const;

	/**
	 * \brief Add or Set a property for this contact.
	 *
	 * @param tmpl The template this property is based on, key, label etc. are
	 * taken from this one
	 * @param value The value to store
	 *
	 * \note Setting a NULL value or an empty QString castable value
	 * removes the property if it already existed.
	 * <b>Don't</b> abuse this for property-removal, instead use
	 * @ref removeProperty() if you want to remove on purpose.
	 * The Removal is done to clean up the list of properties and to purge them
	 * from UI.
	 **/
	void setProperty(const Kopete::ContactPropertyTmpl &tmpl, const QVariant &value);

        /**
	 * \brief Convenience method to set the nickName property to the specified value
	 * @param name The nickname to set
	 */
	void setNickName( const QString &name );

	/**
	 * \brief Convenience method to retrieve the nickName property.
	 *
	 * This method will return the contactId if there has been no nickName property set
	 */
	QString nickName() const;

	/**
	 * \brief Remove a property if it exists
	 *
	 * @param tmpl the template this property is based on
	 **/
	void removeProperty(const Kopete::ContactPropertyTmpl &tmpl);

	/**
	 * \brief Get the tooltip for this contact
	 * Makes use of formattedName() and formattedIdleTime().
	 * \return an RTF tooltip depending on KopetePrefs settings
	 **/
	QString toolTip() const;

	/**
	 * Returns a formatted string of "firstName" and/or "lastName" properties
	 * if present.
	 * Suitable for GUI display
	 **/
	QString formattedName() const;

	/**
	 * Returns a formatted string of idleTime().
	 * Suitable for GUI display
	 **/
	QString formattedIdleTime() const;

	/**
	 * used in @ref sync()
	 */
	enum Changed{ MovedBetweenGroup = 0x01, ///< the contact has been moved between groups
		      DisplayNameChanged = 0x02 ///< the displayname of the contact changed
	};


public slots:
	/**
	 * This should typically pop up a KopeteChatWindow
	 */
	void startChat();

	/**
	 * Pops up an email type window
	 */
	void sendMessage();

	/**
	 * The user clicked on the contact, do the default action
	 */
	void execute();

	/**
	 * Changes the MetaContact that this contact is a part of.  This function
	 * is called by the KAction changeMetaContact that is part of the context
	 * menu.
	 */
	void changeMetaContact();

	/**
	 * Method to retrieve user information.  Should be implemented by
	 * the protocols, and popup some sort of dialog box
	 *
	 * reimplement it to show the informlation
	 * @todo rename and make it pure virtual
	 */
	virtual void slotUserInfo() {};

	/**
	 * @brief Syncronise the server and the metacontact.
	 * Protocols with server-side contact lists can implement this to
	 * sync the server groups with the metaContact groups. Or the server alias if any.
	 *
	 * This method is called every time the metacontact has been moved or renamed.
	 *
	 * default implementation does nothing
	 *
	 * @param changed is a bitmask of the @ref Changed enum which say why the call to this funtion is done.
	 */
	virtual void sync(unsigned int changed = 0xFF);

	/**
	 * Method to delete a contact from the contact list,
	 * should be implemented by protocol plugin to handle
	 * protocol-specific actions required to delete a contact
	 * (ie. messages to the server, etc)
	 * the default implementation simply call deleteLater()
	 */
	virtual void deleteContact();

	/**
	 * This is the Contact level slot for sending files. It should be
	 * implemented by all contacts which have the setFileCapable() flag set to
	 * true. If the function is called through the GUI, no parameters are sent
	 * and they take on default values (the file is chosen with a file open dialog)
	 *
	 * @param sourceURL The actual KURL of the file you are sending
	 * @param fileName (Optional) An alternate name for the file - what the
	 * receiver will see
	 * @param fileSize (Optional) Size of the file being sent. Used when sending
	 * a nondeterminate
	 *                file size (such as over  asocket
	 */
	virtual void sendFile( const KURL &sourceURL = KURL(),
			       const QString &fileName = QString::null, uint fileSize = 0L );

private slots:

	/**
	 * This add the contact totally in the list if it was a temporary contact
	 */
	void slotAddContact();

	/**
	 * slot called when the action "delete" is called.
	 */
	void slotDelete();

	/**
	 * slot called when the action "block" is called.
	 */
	void slotBlock();

	/**
	 * slot called when the action "unblock" is called.
	 */
	void slotUnblock();

	/**
	 * The account's isConnected has changed.
	 */
	void slotAccountIsConnectedChanged();

signals:
	/**
	 * The contact's online status changed
	 */
	void onlineStatusChanged( Kopete::Contact *contact,
		const Kopete::OnlineStatus &status, const Kopete::OnlineStatus &oldStatus );

	/**
	 * The contact is about to be destroyed.
	 * Called when entering the destructor. Useful for cleanup, since
	 * metaContact() is still accessible at this point.
	 *
	 * @warning this signal is emit in the Contact destructor, so all
	 * virtual method are not available
	 */
	void contactDestroyed( Kopete::Contact *contact );

	/**
	 * The contact's idle state changed.
	 * You need to emit this signal to update the view.
	 * That mean when activity has been noticed
	 */
	void idleStateChanged( Kopete::Contact *contact );

	/**
	 * One of the contact's properties has changed.
	 * @param contact this contact, useful for listening to signals from more than one contact
	 * @param key the key whose value has changed
	 * @param oldValue the value before the change, or an invalid QVariant if the property is new
	 * @param newValue the value after the change, or an invalid QVariant if the property was removed
	 */
	void propertyChanged( Kopete::Contact *contact, const QString &key,
		const QVariant &oldValue, const QVariant &newValue );

protected:
	virtual void virtual_hook(uint id, void *data);

private:
	class Private;
	Private *d;


};


} //END namespace Kopete

#endif

// vim: set noet ts=4 sts=4 sw=4: