3 * Purple is the legal property of its developers, whose names are too numerous
4 * to list here. Please refer to the COPYRIGHT file distributed with this
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
22 #include "glibcompat.h"
24 #include "dbus-maybe.h"
27 #define PURPLE_PRESENCE_GET_PRIVATE(obj) \
28 (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_PRESENCE, PurplePresencePrivate))
30 /** @copydoc _PurplePresencePrivate */
31 typedef struct _PurplePresencePrivate PurplePresencePrivate
;
33 #define PURPLE_ACCOUNT_PRESENCE_GET_PRIVATE(obj) \
34 (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_ACCOUNT_PRESENCE, PurpleAccountPresencePrivate))
36 /** @copydoc _PurpleAccountPresencePrivate */
37 typedef struct _PurpleAccountPresencePrivate PurpleAccountPresencePrivate
;
39 #define PURPLE_BUDDY_PRESENCE_GET_PRIVATE(obj) \
40 (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_BUDDY_PRESENCE, PurpleBuddyPresencePrivate))
42 /** @copydoc _PurpleBuddyPresencePrivate */
43 typedef struct _PurpleBuddyPresencePrivate PurpleBuddyPresencePrivate
;
45 /** Private data for a presence */
46 struct _PurplePresencePrivate
53 GHashTable
*status_table
;
55 PurpleStatus
*active_status
;
58 /* Presence property enums */
66 PRES_PROP_ACTIVE_STATUS
,
70 /** Private data for an account presence */
71 struct _PurpleAccountPresencePrivate
73 PurpleAccount
*account
;
76 /* Account presence property enums */
84 /** Private data for a buddy presence */
85 struct _PurpleBuddyPresencePrivate
90 /* Buddy presence property enums */
98 static GObjectClass
*parent_class
;
99 static PurplePresenceClass
*presence_class
;
101 static GParamSpec
*properties
[PRES_PROP_LAST
];
102 static GParamSpec
*ap_properties
[ACPRES_PROP_LAST
];
103 static GParamSpec
*bp_properties
[BUDPRES_PROP_LAST
];
105 /**************************************************************************
107 **************************************************************************/
110 purple_presence_set_status_active(PurplePresence
*presence
, const char *status_id
,
113 PurpleStatus
*status
;
115 g_return_if_fail(PURPLE_IS_PRESENCE(presence
));
116 g_return_if_fail(status_id
!= NULL
);
118 status
= purple_presence_get_status(presence
, status_id
);
120 g_return_if_fail(PURPLE_IS_STATUS(status
));
121 /* TODO: Should we do the following? */
122 /* g_return_if_fail(active == status->active); */
124 if (purple_status_is_exclusive(status
))
128 purple_debug_warning("presence",
129 "Attempted to set a non-independent status "
130 "(%s) inactive. Only independent statuses "
131 "can be specifically marked inactive.",
137 purple_status_set_active(status
, active
);
141 purple_presence_switch_status(PurplePresence
*presence
, const char *status_id
)
143 purple_presence_set_status_active(presence
, status_id
, TRUE
);
147 purple_presence_set_idle(PurplePresence
*presence
, gboolean idle
, time_t idle_time
)
150 PurplePresencePrivate
*priv
= PURPLE_PRESENCE_GET_PRIVATE(presence
);
151 PurplePresenceClass
*klass
= PURPLE_PRESENCE_GET_CLASS(presence
);
154 g_return_if_fail(priv
!= NULL
);
156 if (priv
->idle
== idle
&& priv
->idle_time
== idle_time
)
159 old_idle
= priv
->idle
;
161 priv
->idle_time
= (idle
? idle_time
: 0);
163 obj
= G_OBJECT(presence
);
164 g_object_freeze_notify(obj
);
165 g_object_notify_by_pspec(obj
, properties
[PRES_PROP_IDLE
]);
166 g_object_notify_by_pspec(obj
, properties
[PRES_PROP_IDLE_TIME
]);
167 g_object_thaw_notify(obj
);
169 if (klass
->update_idle
)
170 klass
->update_idle(presence
, old_idle
);
174 purple_presence_set_login_time(PurplePresence
*presence
, time_t login_time
)
176 PurplePresencePrivate
*priv
= PURPLE_PRESENCE_GET_PRIVATE(presence
);
178 g_return_if_fail(priv
!= NULL
);
180 if (priv
->login_time
== login_time
)
183 priv
->login_time
= login_time
;
185 g_object_notify_by_pspec(G_OBJECT(presence
),
186 properties
[PRES_PROP_LOGIN_TIME
]);
190 purple_presence_get_statuses(const PurplePresence
*presence
)
192 PurplePresencePrivate
*priv
= PURPLE_PRESENCE_GET_PRIVATE(presence
);
194 g_return_val_if_fail(priv
!= NULL
, NULL
);
196 return priv
->statuses
;
200 purple_presence_get_status(const PurplePresence
*presence
, const char *status_id
)
202 PurpleStatus
*status
;
203 PurplePresencePrivate
*priv
= PURPLE_PRESENCE_GET_PRIVATE(presence
);
206 g_return_val_if_fail(priv
!= NULL
, NULL
);
207 g_return_val_if_fail(status_id
!= NULL
, NULL
);
209 /* What's the purpose of this hash table? */
210 status
= (PurpleStatus
*)g_hash_table_lookup(priv
->status_table
,
213 if (status
== NULL
) {
214 for (l
= purple_presence_get_statuses(presence
);
215 l
!= NULL
&& status
== NULL
; l
= l
->next
)
217 PurpleStatus
*temp_status
= l
->data
;
219 if (purple_strequal(status_id
, purple_status_get_id(temp_status
)))
220 status
= temp_status
;
224 g_hash_table_insert(priv
->status_table
,
225 g_strdup(purple_status_get_id(status
)), status
);
232 purple_presence_get_active_status(const PurplePresence
*presence
)
234 PurplePresencePrivate
*priv
= PURPLE_PRESENCE_GET_PRIVATE(presence
);
236 g_return_val_if_fail(priv
!= NULL
, NULL
);
238 return priv
->active_status
;
242 purple_presence_is_available(const PurplePresence
*presence
)
244 PurpleStatus
*status
;
246 g_return_val_if_fail(PURPLE_IS_PRESENCE(presence
), FALSE
);
248 status
= purple_presence_get_active_status(presence
);
250 return ((status
!= NULL
&& purple_status_is_available(status
)) &&
251 !purple_presence_is_idle(presence
));
255 purple_presence_is_online(const PurplePresence
*presence
)
257 PurpleStatus
*status
;
259 g_return_val_if_fail(PURPLE_IS_PRESENCE(presence
), FALSE
);
261 if ((status
= purple_presence_get_active_status(presence
)) == NULL
)
264 return purple_status_is_online(status
);
268 purple_presence_is_status_active(const PurplePresence
*presence
,
269 const char *status_id
)
271 PurpleStatus
*status
;
273 g_return_val_if_fail(PURPLE_IS_PRESENCE(presence
), FALSE
);
274 g_return_val_if_fail(status_id
!= NULL
, FALSE
);
276 status
= purple_presence_get_status(presence
, status_id
);
278 return (status
!= NULL
&& purple_status_is_active(status
));
282 purple_presence_is_status_primitive_active(const PurplePresence
*presence
,
283 PurpleStatusPrimitive primitive
)
287 g_return_val_if_fail(PURPLE_IS_PRESENCE(presence
), FALSE
);
288 g_return_val_if_fail(primitive
!= PURPLE_STATUS_UNSET
, FALSE
);
290 for (l
= purple_presence_get_statuses(presence
);
291 l
!= NULL
; l
= l
->next
)
293 PurpleStatus
*temp_status
= l
->data
;
294 PurpleStatusType
*type
= purple_status_get_status_type(temp_status
);
296 if (purple_status_type_get_primitive(type
) == primitive
&&
297 purple_status_is_active(temp_status
))
304 purple_presence_is_idle(const PurplePresence
*presence
)
306 PurplePresencePrivate
*priv
= PURPLE_PRESENCE_GET_PRIVATE(presence
);
308 g_return_val_if_fail(priv
!= NULL
, FALSE
);
310 return purple_presence_is_online(presence
) && priv
->idle
;
314 purple_presence_get_idle_time(const PurplePresence
*presence
)
316 PurplePresencePrivate
*priv
= PURPLE_PRESENCE_GET_PRIVATE(presence
);
318 g_return_val_if_fail(priv
!= NULL
, 0);
320 return priv
->idle_time
;
324 purple_presence_get_login_time(const PurplePresence
*presence
)
326 PurplePresencePrivate
*priv
= PURPLE_PRESENCE_GET_PRIVATE(presence
);
328 g_return_val_if_fail(priv
!= NULL
, 0);
330 return purple_presence_is_online(presence
) ? priv
->login_time
: 0;
333 /**************************************************************************
334 * GObject code for PurplePresence
335 **************************************************************************/
337 /* Set method for GObject properties */
339 purple_presence_set_property(GObject
*obj
, guint param_id
, const GValue
*value
,
342 PurplePresence
*presence
= PURPLE_PRESENCE(obj
);
343 PurplePresencePrivate
*priv
= PURPLE_PRESENCE_GET_PRIVATE(presence
);
347 purple_presence_set_idle(presence
, g_value_get_boolean(value
), 0);
349 case PRES_PROP_IDLE_TIME
:
350 #if SIZEOF_TIME_T == 4
351 purple_presence_set_idle(presence
, TRUE
, g_value_get_int(value
));
352 #elif SIZEOF_TIME_T == 8
353 purple_presence_set_idle(presence
, TRUE
, g_value_get_int64(value
));
355 #error Unknown size of time_t
358 case PRES_PROP_LOGIN_TIME
:
359 #if SIZEOF_TIME_T == 4
360 purple_presence_set_login_time(presence
, g_value_get_int(value
));
361 #elif SIZEOF_TIME_T == 8
362 purple_presence_set_login_time(presence
, g_value_get_int64(value
));
364 #error Unknown size of time_t
367 case PRES_PROP_ACTIVE_STATUS
:
368 priv
->active_status
= g_value_get_object(value
);
371 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj
, param_id
, pspec
);
376 /* Get method for GObject properties */
378 purple_presence_get_property(GObject
*obj
, guint param_id
, GValue
*value
,
381 PurplePresence
*presence
= PURPLE_PRESENCE(obj
);
385 g_value_set_boolean(value
, purple_presence_is_idle(presence
));
387 case PRES_PROP_IDLE_TIME
:
388 #if SIZEOF_TIME_T == 4
389 g_value_set_int(value
, purple_presence_get_idle_time(presence
));
390 #elif SIZEOF_TIME_T == 8
391 g_value_set_int64(value
, purple_presence_get_idle_time(presence
));
393 #error Unknown size of time_t
396 case PRES_PROP_LOGIN_TIME
:
397 #if SIZEOF_TIME_T == 4
398 g_value_set_int(value
, purple_presence_get_login_time(presence
));
399 #elif SIZEOF_TIME_T == 8
400 g_value_set_int64(value
, purple_presence_get_login_time(presence
));
402 #error Unknown size of time_t
405 case PRES_PROP_STATUSES
:
406 g_value_set_pointer(value
, purple_presence_get_statuses(presence
));
408 case PRES_PROP_ACTIVE_STATUS
:
409 g_value_set_object(value
, purple_presence_get_active_status(presence
));
412 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj
, param_id
, pspec
);
417 /* GObject initialization function */
419 purple_presence_init(GTypeInstance
*instance
, gpointer klass
)
421 PURPLE_DBUS_REGISTER_POINTER(PURPLE_PRESENCE(instance
), PurplePresence
);
423 PURPLE_PRESENCE_GET_PRIVATE(instance
)->status_table
=
424 g_hash_table_new_full(g_str_hash
, g_str_equal
,
428 /* GObject dispose function */
430 purple_presence_dispose(GObject
*object
)
432 PurplePresencePrivate
*priv
= PURPLE_PRESENCE_GET_PRIVATE(object
);
434 if (priv
->statuses
) {
435 g_list_foreach(priv
->statuses
, (GFunc
)g_object_unref
, NULL
);
436 g_list_free(priv
->statuses
);
437 priv
->statuses
= NULL
;
440 parent_class
->dispose(object
);
443 /* GObject finalize function */
445 purple_presence_finalize(GObject
*object
)
447 PurplePresencePrivate
*priv
= PURPLE_PRESENCE_GET_PRIVATE(object
);
449 g_hash_table_destroy(priv
->status_table
);
451 PURPLE_DBUS_UNREGISTER_POINTER(object
);
453 parent_class
->finalize(object
);
456 /* Class initializer function */
457 static void purple_presence_class_init(PurplePresenceClass
*klass
)
459 GObjectClass
*obj_class
= G_OBJECT_CLASS(klass
);
461 parent_class
= g_type_class_peek_parent(klass
);
463 obj_class
->dispose
= purple_presence_dispose
;
464 obj_class
->finalize
= purple_presence_finalize
;
466 /* Setup properties */
467 obj_class
->get_property
= purple_presence_get_property
;
468 obj_class
->set_property
= purple_presence_set_property
;
470 g_type_class_add_private(klass
, sizeof(PurplePresencePrivate
));
472 properties
[PRES_PROP_IDLE
] = g_param_spec_boolean("idle", "Idle",
473 "Whether the presence is in idle state.", FALSE
,
474 G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS
);
476 properties
[PRES_PROP_IDLE_TIME
] =
477 #if SIZEOF_TIME_T == 4
479 #elif SIZEOF_TIME_T == 8
482 #error Unknown size of time_t
484 ("idle-time", "Idle time",
485 "The idle time of the presence",
486 #if SIZEOF_TIME_T == 4
487 G_MININT
, G_MAXINT
, 0,
488 #elif SIZEOF_TIME_T == 8
489 G_MININT64
, G_MAXINT64
, 0,
491 #error Unknown size of time_t
493 G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS
);
495 properties
[PRES_PROP_LOGIN_TIME
] =
496 #if SIZEOF_TIME_T == 4
498 #elif SIZEOF_TIME_T == 8
501 #error Unknown size of time_t
503 ("login-time", "Login time",
504 "The login time of the presence.",
505 #if SIZEOF_TIME_T == 4
506 G_MININT
, G_MAXINT
, 0,
507 #elif SIZEOF_TIME_T == 8
508 G_MININT64
, G_MAXINT64
, 0,
510 #error Unknown size of time_t
512 G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS
);
514 properties
[PRES_PROP_STATUSES
] = g_param_spec_pointer("statuses",
516 "The list of statuses in the presence.",
517 G_PARAM_READABLE
| G_PARAM_STATIC_STRINGS
);
519 properties
[PRES_PROP_ACTIVE_STATUS
] = g_param_spec_object("active-status",
521 "The active status for the presence.", PURPLE_TYPE_STATUS
,
522 G_PARAM_READWRITE
| G_PARAM_STATIC_STRINGS
);
524 g_object_class_install_properties(obj_class
, PRES_PROP_LAST
, properties
);
528 purple_presence_get_type(void)
530 static GType type
= 0;
533 static const GTypeInfo info
= {
534 sizeof(PurplePresenceClass
),
537 (GClassInitFunc
)purple_presence_class_init
,
540 sizeof(PurplePresence
),
542 (GInstanceInitFunc
)purple_presence_init
,
546 type
= g_type_register_static(G_TYPE_OBJECT
, "PurplePresence",
547 &info
, G_TYPE_FLAG_ABSTRACT
);
553 /**************************************************************************
554 * PurpleAccountPresence API
555 **************************************************************************/
557 purple_account_presence_update_idle(PurplePresence
*presence
, gboolean old_idle
)
559 PurpleAccount
*account
;
560 PurpleConnection
*gc
= NULL
;
561 PurpleProtocol
*protocol
= NULL
;
562 gboolean idle
= purple_presence_is_idle(presence
);
563 time_t idle_time
= purple_presence_get_idle_time(presence
);
564 time_t current_time
= time(NULL
);
566 account
= purple_account_presence_get_account(PURPLE_ACCOUNT_PRESENCE(presence
));
568 if (purple_prefs_get_bool("/purple/logging/log_system"))
570 PurpleLog
*log
= purple_account_get_log(account
, FALSE
);
578 tmp
= g_strdup_printf(_("+++ %s became idle"), purple_account_get_username(account
));
579 dt
= g_date_time_new_from_unix_local(idle_time
);
581 tmp
= g_strdup_printf(_("+++ %s became unidle"), purple_account_get_username(account
));
582 dt
= g_date_time_new_now_utc();
585 msg
= g_markup_escape_text(tmp
, -1);
587 purple_log_write(log
, PURPLE_MESSAGE_SYSTEM
,
588 purple_account_get_username(account
),
590 g_date_time_unref(dt
);
595 gc
= purple_account_get_connection(account
);
597 if(PURPLE_CONNECTION_IS_CONNECTED(gc
))
598 protocol
= purple_connection_get_protocol(gc
);
601 purple_protocol_server_iface_set_idle(protocol
, gc
, (idle
? (current_time
- idle_time
) : 0));
605 purple_account_presence_get_account(const PurpleAccountPresence
*presence
)
607 PurpleAccountPresencePrivate
*priv
= PURPLE_ACCOUNT_PRESENCE_GET_PRIVATE(presence
);
609 g_return_val_if_fail(priv
!= NULL
, NULL
);
611 return priv
->account
;
615 purple_buddy_presence_compute_score(const PurpleBuddyPresence
*buddy_presence
)
619 PurplePresence
*presence
= PURPLE_PRESENCE(buddy_presence
);
620 PurpleBuddy
*b
= purple_buddy_presence_get_buddy(buddy_presence
);
621 int *primitive_scores
= _purple_statuses_get_primitive_scores();
622 int offline_score
= purple_prefs_get_int("/purple/status/scores/offline_msg");
623 int idle_score
= purple_prefs_get_int("/purple/status/scores/idle");
625 for (l
= purple_presence_get_statuses(presence
); l
!= NULL
; l
= l
->next
) {
626 PurpleStatus
*status
= (PurpleStatus
*)l
->data
;
627 PurpleStatusType
*type
= purple_status_get_status_type(status
);
629 if (purple_status_is_active(status
)) {
630 score
+= primitive_scores
[purple_status_type_get_primitive(type
)];
631 if (!purple_status_is_online(status
)) {
632 if (b
&& purple_account_supports_offline_message(purple_buddy_get_account(b
), b
))
633 score
+= offline_score
;
637 score
+= purple_account_get_int(purple_buddy_get_account(b
), "score", 0);
638 if (purple_presence_is_idle(presence
))
644 purple_buddy_presence_compare(const PurpleBuddyPresence
*buddy_presence1
,
645 const PurpleBuddyPresence
*buddy_presence2
)
647 PurplePresence
*presence1
= PURPLE_PRESENCE(buddy_presence1
);
648 PurplePresence
*presence2
= PURPLE_PRESENCE(buddy_presence2
);
649 time_t idle_time_1
, idle_time_2
;
650 int score1
= 0, score2
= 0;
651 int idle_time_score
= purple_prefs_get_int("/purple/status/scores/idle_time");
653 if (presence1
== presence2
)
655 else if (presence1
== NULL
)
657 else if (presence2
== NULL
)
660 if (purple_presence_is_online(presence1
) &&
661 !purple_presence_is_online(presence2
))
663 else if (purple_presence_is_online(presence2
) &&
664 !purple_presence_is_online(presence1
))
667 /* Compute the score of the first set of statuses. */
668 score1
= purple_buddy_presence_compute_score(buddy_presence1
);
670 /* Compute the score of the second set of statuses. */
671 score2
= purple_buddy_presence_compute_score(buddy_presence2
);
673 idle_time_1
= time(NULL
) - purple_presence_get_idle_time(presence1
);
674 idle_time_2
= time(NULL
) - purple_presence_get_idle_time(presence2
);
676 if (idle_time_1
> idle_time_2
)
677 score1
+= idle_time_score
;
678 else if (idle_time_1
< idle_time_2
)
679 score2
+= idle_time_score
;
683 else if (score1
> score2
)
689 /**************************************************************************
690 * GObject code for PurpleAccountPresence
691 **************************************************************************/
693 /* Set method for GObject properties */
695 purple_account_presence_set_property(GObject
*obj
, guint param_id
, const GValue
*value
,
698 PurpleAccountPresence
*account_presence
= PURPLE_ACCOUNT_PRESENCE(obj
);
699 PurpleAccountPresencePrivate
*priv
=
700 PURPLE_ACCOUNT_PRESENCE_GET_PRIVATE(account_presence
);
703 case ACPRES_PROP_ACCOUNT
:
704 priv
->account
= g_value_get_object(value
);
707 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj
, param_id
, pspec
);
712 /* Get method for GObject properties */
714 purple_account_presence_get_property(GObject
*obj
, guint param_id
, GValue
*value
,
717 PurpleAccountPresence
*account_presence
= PURPLE_ACCOUNT_PRESENCE(obj
);
720 case ACPRES_PROP_ACCOUNT
:
721 g_value_set_object(value
,
722 purple_account_presence_get_account(account_presence
));
725 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj
, param_id
, pspec
);
730 /* Called when done constructing */
732 purple_account_presence_constructed(GObject
*object
)
734 PurplePresence
*presence
= PURPLE_PRESENCE(object
);
735 PurpleAccountPresencePrivate
*priv
= PURPLE_ACCOUNT_PRESENCE_GET_PRIVATE(presence
);
737 G_OBJECT_CLASS(presence_class
)->constructed(object
);
739 PURPLE_PRESENCE_GET_PRIVATE(presence
)->statuses
=
740 purple_protocol_get_statuses(priv
->account
, presence
);
743 /* Class initializer function */
744 static void purple_account_presence_class_init(PurpleAccountPresenceClass
*klass
)
746 GObjectClass
*obj_class
= G_OBJECT_CLASS(klass
);
748 PURPLE_PRESENCE_CLASS(klass
)->update_idle
= purple_account_presence_update_idle
;
750 presence_class
= g_type_class_peek_parent(klass
);
752 obj_class
->constructed
= purple_account_presence_constructed
;
754 /* Setup properties */
755 obj_class
->get_property
= purple_account_presence_get_property
;
756 obj_class
->set_property
= purple_account_presence_set_property
;
758 g_type_class_add_private(klass
, sizeof(PurpleAccountPresencePrivate
));
760 ap_properties
[ACPRES_PROP_ACCOUNT
] = g_param_spec_object("account",
762 "The account that this presence is of.", PURPLE_TYPE_ACCOUNT
,
763 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT_ONLY
|
764 G_PARAM_STATIC_STRINGS
);
766 g_object_class_install_properties(obj_class
, ACPRES_PROP_LAST
,
771 purple_account_presence_get_type(void)
773 static GType type
= 0;
776 static const GTypeInfo info
= {
777 sizeof(PurpleAccountPresenceClass
),
780 (GClassInitFunc
)purple_account_presence_class_init
,
783 sizeof(PurpleAccountPresence
),
789 type
= g_type_register_static(PURPLE_TYPE_PRESENCE
,
790 "PurpleAccountPresence",
797 PurpleAccountPresence
*
798 purple_account_presence_new(PurpleAccount
*account
)
800 g_return_val_if_fail(PURPLE_IS_ACCOUNT(account
), NULL
);
802 return g_object_new(PURPLE_TYPE_ACCOUNT_PRESENCE
,
807 /**************************************************************************
808 * PurpleBuddyPresence API
809 **************************************************************************/
811 purple_buddy_presence_update_idle(PurplePresence
*presence
, gboolean old_idle
)
813 PurpleBuddy
*buddy
= purple_buddy_presence_get_buddy(PURPLE_BUDDY_PRESENCE(presence
));
814 GDateTime
*current_time
= g_date_time_new_now_utc();
815 PurpleBlistUiOps
*ops
= purple_blist_get_ui_ops();
816 PurpleAccount
*account
= purple_buddy_get_account(buddy
);
817 gboolean idle
= purple_presence_is_idle(presence
);
819 if (!old_idle
&& idle
)
821 if (purple_prefs_get_bool("/purple/logging/log_system"))
823 PurpleLog
*log
= purple_account_get_log(account
, FALSE
);
828 tmp
= g_strdup_printf(_("%s became idle"),
829 purple_buddy_get_alias(buddy
));
830 tmp2
= g_markup_escape_text(tmp
, -1);
833 purple_log_write(log
, PURPLE_MESSAGE_SYSTEM
,
834 purple_buddy_get_alias(buddy
),
840 else if (old_idle
&& !idle
)
842 if (purple_prefs_get_bool("/purple/logging/log_system"))
844 PurpleLog
*log
= purple_account_get_log(account
, FALSE
);
849 tmp
= g_strdup_printf(_("%s became unidle"),
850 purple_buddy_get_alias(buddy
));
851 tmp2
= g_markup_escape_text(tmp
, -1);
854 purple_log_write(log
, PURPLE_MESSAGE_SYSTEM
,
855 purple_buddy_get_alias(buddy
),
862 if (old_idle
!= idle
)
863 purple_signal_emit(purple_blist_get_handle(), "buddy-idle-changed", buddy
,
866 purple_contact_invalidate_priority_buddy(purple_buddy_get_contact(buddy
));
868 /* Should this be done here? It'd perhaps make more sense to
869 * connect to buddy-[un]idle signals and update from there
872 if (ops
!= NULL
&& ops
->update
!= NULL
)
873 ops
->update(purple_blist_get_buddy_list(), (PurpleBlistNode
*)buddy
);
875 g_date_time_unref(current_time
);
879 purple_buddy_presence_get_buddy(const PurpleBuddyPresence
*presence
)
881 PurpleBuddyPresencePrivate
*priv
= PURPLE_BUDDY_PRESENCE_GET_PRIVATE(presence
);
883 g_return_val_if_fail(priv
!= NULL
, NULL
);
888 /**************************************************************************
889 * GObject code for PurpleBuddyPresence
890 **************************************************************************/
892 /* Set method for GObject properties */
894 purple_buddy_presence_set_property(GObject
*obj
, guint param_id
, const GValue
*value
,
897 PurpleBuddyPresence
*buddy_presence
= PURPLE_BUDDY_PRESENCE(obj
);
898 PurpleBuddyPresencePrivate
*priv
=
899 PURPLE_BUDDY_PRESENCE_GET_PRIVATE(buddy_presence
);
902 case BUDPRES_PROP_BUDDY
:
903 priv
->buddy
= g_value_get_object(value
);
906 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj
, param_id
, pspec
);
911 /* Get method for GObject properties */
913 purple_buddy_presence_get_property(GObject
*obj
, guint param_id
, GValue
*value
,
916 PurpleBuddyPresence
*buddy_presence
= PURPLE_BUDDY_PRESENCE(obj
);
919 case BUDPRES_PROP_BUDDY
:
920 g_value_set_object(value
,
921 purple_buddy_presence_get_buddy(buddy_presence
));
924 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj
, param_id
, pspec
);
929 /* Called when done constructing */
931 purple_buddy_presence_constructed(GObject
*object
)
933 PurplePresence
*presence
= PURPLE_PRESENCE(object
);
934 PurpleBuddyPresencePrivate
*priv
= PURPLE_BUDDY_PRESENCE_GET_PRIVATE(presence
);
935 PurpleAccount
*account
;
937 G_OBJECT_CLASS(presence_class
)->constructed(object
);
939 account
= purple_buddy_get_account(priv
->buddy
);
940 PURPLE_PRESENCE_GET_PRIVATE(presence
)->statuses
=
941 purple_protocol_get_statuses(account
, presence
);
944 /* Class initializer function */
945 static void purple_buddy_presence_class_init(PurpleBuddyPresenceClass
*klass
)
947 GObjectClass
*obj_class
= G_OBJECT_CLASS(klass
);
949 PURPLE_PRESENCE_CLASS(klass
)->update_idle
= purple_buddy_presence_update_idle
;
951 presence_class
= g_type_class_peek_parent(klass
);
953 obj_class
->constructed
= purple_buddy_presence_constructed
;
955 /* Setup properties */
956 obj_class
->get_property
= purple_buddy_presence_get_property
;
957 obj_class
->set_property
= purple_buddy_presence_set_property
;
959 g_type_class_add_private(klass
, sizeof(PurpleBuddyPresencePrivate
));
961 bp_properties
[BUDPRES_PROP_BUDDY
] = g_param_spec_object("buddy", "Buddy",
962 "The buddy that this presence is of.", PURPLE_TYPE_BUDDY
,
963 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT_ONLY
|
964 G_PARAM_STATIC_STRINGS
);
966 g_object_class_install_properties(obj_class
, BUDPRES_PROP_LAST
,
971 purple_buddy_presence_get_type(void)
973 static GType type
= 0;
976 static const GTypeInfo info
= {
977 sizeof(PurpleBuddyPresenceClass
),
980 (GClassInitFunc
)purple_buddy_presence_class_init
,
983 sizeof(PurpleBuddyPresence
),
989 type
= g_type_register_static(PURPLE_TYPE_PRESENCE
,
990 "PurpleBuddyPresence",
997 PurpleBuddyPresence
*
998 purple_buddy_presence_new(PurpleBuddy
*buddy
)
1000 g_return_val_if_fail(PURPLE_IS_BUDDY(buddy
), NULL
);
1002 return g_object_new(PURPLE_TYPE_BUDDY_PRESENCE
,