Mercurial > pidgin.yaz
annotate src/status.c @ 12692:4da7062a06c2
[gaim-migrate @ 15035]
SF Patch #1277888 from Douglas Thrift
I modified this a bit, but the end result is: This patch adds a logging preference that defaults to off. When enabled, the date is included in messages' timestamps in logs (in addition to the time).
This can be useful if you leave conversations open for days (for me, that's chats). The original patch had this affect timestamps in the conversation window as well, but I didn't like that. I figured it probably wasn't necessary, and I was dreading adding another conversation pref. I welcome feedback on this issue.
committer: Tailor Script <tailor@pidgin.im>
author | Richard Laager <rlaager@wiktel.com> |
---|---|
date | Tue, 03 Jan 2006 06:33:00 +0000 |
parents | 57462d6542ea |
children | eda1572c788b |
rev | line source |
---|---|
9944 | 1 /** |
10067 | 2 * @file status.c Status API |
9944 | 3 * @ingroup core |
4 * | |
6065 | 5 * gaim |
6 * | |
8046 | 7 * Gaim is the legal property of its developers, whose names are too numerous |
8 * to list here. Please refer to the COPYRIGHT file distributed with this | |
9 * source distribution. | |
9944 | 10 * |
6065 | 11 * This program is free software; you can redistribute it and/or modify |
12 * it under the terms of the GNU General Public License as published by | |
13 * the Free Software Foundation; either version 2 of the License, or | |
14 * (at your option) any later version. | |
15 * | |
16 * This program is distributed in the hope that it will be useful, | |
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 * GNU General Public License for more details. | |
20 * | |
21 * You should have received a copy of the GNU General Public License | |
22 * along with this program; if not, write to the Free Software | |
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
24 */ | |
9949 | 25 #include "internal.h" |
6065 | 26 |
9949 | 27 #include "blist.h" |
10400 | 28 #include "core.h" |
11187 | 29 #include "dbus-maybe.h" |
9949 | 30 #include "debug.h" |
10337 | 31 #include "notify.h" |
9949 | 32 #include "prefs.h" |
6065 | 33 #include "status.h" |
34 | |
9949 | 35 /** |
36 * A type of status. | |
37 */ | |
38 struct _GaimStatusType | |
39 { | |
40 GaimStatusPrimitive primitive; | |
6371
8f94cce8faa5
[gaim-migrate @ 6876]
Christian Hammond <chipx86@chipx86.com>
parents:
6321
diff
changeset
|
41 |
9949 | 42 char *id; |
43 char *name; | |
44 char *primary_attr_id; | |
45 | |
46 gboolean saveable; | |
47 gboolean user_settable; | |
48 gboolean independent; | |
49 | |
50 GList *attrs; | |
51 }; | |
6371
8f94cce8faa5
[gaim-migrate @ 6876]
Christian Hammond <chipx86@chipx86.com>
parents:
6321
diff
changeset
|
52 |
9949 | 53 /** |
54 * A status attribute. | |
55 */ | |
56 struct _GaimStatusAttr | |
57 { | |
58 char *id; | |
59 char *name; | |
60 GaimValue *value_type; | |
61 }; | |
6065 | 62 |
9949 | 63 /** |
64 * A list of statuses. | |
65 */ | |
66 struct _GaimPresence | |
67 { | |
68 GaimPresenceContext context; | |
69 | |
70 gboolean idle; | |
71 time_t idle_time; | |
11249 | 72 time_t login_time; |
9949 | 73 |
74 GList *statuses; | |
75 GHashTable *status_table; | |
76 | |
77 GaimStatus *active_status; | |
6065 | 78 |
9949 | 79 union |
80 { | |
81 GaimAccount *account; | |
82 | |
83 struct | |
84 { | |
85 GaimConversation *conv; | |
86 char *user; | |
87 | |
88 } chat; | |
6065 | 89 |
9949 | 90 struct |
91 { | |
92 GaimAccount *account; | |
93 char *name; | |
94 size_t ref_count; | |
95 GList *buddies; | |
96 | |
97 } buddy; | |
98 | |
99 } u; | |
100 }; | |
101 | |
102 /** | |
103 * An active status. | |
104 */ | |
105 struct _GaimStatus | |
6065 | 106 { |
9949 | 107 GaimStatusType *type; |
108 GaimPresence *presence; | |
109 | |
110 const char *title; | |
6065 | 111 |
9949 | 112 gboolean active; |
6065 | 113 |
9949 | 114 GHashTable *attr_values; |
115 }; | |
6065 | 116 |
117 typedef struct | |
118 { | |
9949 | 119 GaimAccount *account; |
120 char *name; | |
121 } GaimStatusBuddyKey; | |
122 | |
123 static int primitive_scores[] = | |
124 { | |
125 0, /* unset */ | |
126 -500, /* offline */ | |
127 100, /* available */ | |
128 -75, /* unavailable */ | |
12595
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
129 -50, /* invisible */ |
9949 | 130 -100, /* away */ |
10860 | 131 -200, /* extended away */ |
12595
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
132 -400, /* mobile */ |
9949 | 133 -10, /* idle, special case. */ |
134 -5 /* idle time, special case. */ | |
135 }; | |
136 | |
137 static GHashTable *buddy_presences = NULL; | |
138 | |
12164
281ab2ecc08c
[gaim-migrate @ 14465]
Richard Laager <rlaager@wiktel.com>
parents:
12145
diff
changeset
|
139 #define SCORE_IDLE 7 |
281ab2ecc08c
[gaim-migrate @ 14465]
Richard Laager <rlaager@wiktel.com>
parents:
12145
diff
changeset
|
140 #define SCORE_IDLE_TIME 8 |
9949 | 141 |
142 /************************************************************************** | |
10419 | 143 * GaimStatusPrimitive API |
144 **************************************************************************/ | |
145 static struct GaimStatusPrimitiveMap | |
146 { | |
147 GaimStatusPrimitive type; | |
148 const char *id; | |
149 const char *name; | |
150 | |
151 } const status_primitive_map[] = | |
152 { | |
153 { GAIM_STATUS_UNSET, "unset", N_("Unset") }, | |
154 { GAIM_STATUS_OFFLINE, "offline", N_("Offline") }, | |
155 { GAIM_STATUS_AVAILABLE, "available", N_("Available") }, | |
156 { GAIM_STATUS_UNAVAILABLE, "unavailable", N_("Unavailable") }, | |
12595
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
157 { GAIM_STATUS_INVISIBLE, "invisible", N_("Invisible") }, |
10419 | 158 { GAIM_STATUS_AWAY, "away", N_("Away") }, |
12595
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
159 { GAIM_STATUS_EXTENDED_AWAY, "extended_away", N_("Extended Away") }, |
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
160 { GAIM_STATUS_MOBILE, "mobile", N_("Mobile") } |
10419 | 161 }; |
162 | |
163 const char * | |
164 gaim_primitive_get_id_from_type(GaimStatusPrimitive type) | |
165 { | |
166 int i; | |
167 | |
168 for (i = 0; i < GAIM_STATUS_NUM_PRIMITIVES; i++) | |
169 { | |
170 if (type == status_primitive_map[i].type) | |
171 return status_primitive_map[i].id; | |
172 } | |
173 | |
174 return status_primitive_map[0].id; | |
175 } | |
176 | |
177 const char * | |
178 gaim_primitive_get_name_from_type(GaimStatusPrimitive type) | |
179 { | |
180 int i; | |
181 | |
182 for (i = 0; i < GAIM_STATUS_NUM_PRIMITIVES; i++) | |
183 { | |
12595
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
184 if (type == status_primitive_map[i].type) |
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
185 return status_primitive_map[i].name; |
10419 | 186 } |
187 | |
188 return status_primitive_map[0].name; | |
189 } | |
190 | |
191 GaimStatusPrimitive | |
192 gaim_primitive_get_type_from_id(const char *id) | |
193 { | |
194 int i; | |
195 | |
196 g_return_val_if_fail(id != NULL, GAIM_STATUS_UNSET); | |
197 | |
198 for (i = 0; i < GAIM_STATUS_NUM_PRIMITIVES; i++) | |
199 { | |
200 if (!strcmp(id, status_primitive_map[i].id)) | |
201 return status_primitive_map[i].type; | |
202 } | |
203 | |
204 return status_primitive_map[0].type; | |
205 } | |
206 | |
207 | |
208 /************************************************************************** | |
9949 | 209 * GaimStatusType API |
210 **************************************************************************/ | |
211 GaimStatusType * | |
212 gaim_status_type_new_full(GaimStatusPrimitive primitive, const char *id, | |
10009 | 213 const char *name, gboolean saveable, |
214 gboolean user_settable, gboolean independent) | |
9949 | 215 { |
216 GaimStatusType *status_type; | |
217 | |
218 g_return_val_if_fail(primitive != GAIM_STATUS_UNSET, NULL); | |
219 | |
220 status_type = g_new0(GaimStatusType, 1); | |
11187 | 221 GAIM_DBUS_REGISTER_POINTER(status_type, GaimStatusType); |
9949 | 222 |
223 status_type->primitive = primitive; | |
224 status_type->saveable = saveable; | |
225 status_type->user_settable = user_settable; | |
226 status_type->independent = independent; | |
227 | |
12595
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
228 if (id != NULL) |
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
229 status_type->id = g_strdup(id); |
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
230 else |
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
231 status_type->id = g_strdup(gaim_primitive_get_id_from_type(primitive)); |
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
232 |
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
233 if (name != NULL) |
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
234 status_type->name = g_strdup(name); |
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
235 else |
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
236 status_type->name = g_strdup(_(gaim_primitive_get_name_from_type(primitive))); |
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
237 |
9949 | 238 return status_type; |
239 } | |
240 | |
241 GaimStatusType * | |
242 gaim_status_type_new(GaimStatusPrimitive primitive, const char *id, | |
10009 | 243 const char *name, gboolean user_settable) |
9949 | 244 { |
245 g_return_val_if_fail(primitive != GAIM_STATUS_UNSET, NULL); | |
246 | |
247 return gaim_status_type_new_full(primitive, id, name, FALSE, | |
248 user_settable, FALSE); | |
249 } | |
250 | |
251 GaimStatusType * | |
252 gaim_status_type_new_with_attrs(GaimStatusPrimitive primitive, | |
253 const char *id, const char *name, | |
254 gboolean saveable, gboolean user_settable, | |
255 gboolean independent, const char *attr_id, | |
256 const char *attr_name, GaimValue *attr_value, | |
257 ...) | |
258 { | |
259 GaimStatusType *status_type; | |
260 va_list args; | |
261 | |
262 g_return_val_if_fail(primitive != GAIM_STATUS_UNSET, NULL); | |
10012 | 263 g_return_val_if_fail(attr_id != NULL, NULL); |
9949 | 264 g_return_val_if_fail(attr_name != NULL, NULL); |
265 g_return_val_if_fail(attr_value != NULL, NULL); | |
266 | |
267 status_type = gaim_status_type_new_full(primitive, id, name, saveable, | |
268 user_settable, independent); | |
269 | |
10010 | 270 /* Add the first attribute */ |
9949 | 271 gaim_status_type_add_attr(status_type, attr_id, attr_name, attr_value); |
272 | |
273 va_start(args, attr_value); | |
274 gaim_status_type_add_attrs_vargs(status_type, args); | |
275 va_end(args); | |
276 | |
277 return status_type; | |
278 } | |
279 | |
280 void | |
281 gaim_status_type_destroy(GaimStatusType *status_type) | |
282 { | |
283 GList *l; | |
284 | |
285 g_return_if_fail(status_type != NULL); | |
286 | |
287 g_free(status_type->id); | |
288 g_free(status_type->name); | |
289 | |
290 if (status_type->primary_attr_id != NULL) | |
291 g_free(status_type->primary_attr_id); | |
292 | |
293 if (status_type->attrs != NULL) | |
294 { | |
295 for (l = status_type->attrs; l != NULL; l = l->next) | |
296 gaim_status_attr_destroy((GaimStatusAttr *)l->data); | |
297 | |
298 g_list_free(status_type->attrs); | |
299 } | |
300 | |
11187 | 301 GAIM_DBUS_UNREGISTER_POINTER(status_type); |
9949 | 302 g_free(status_type); |
303 } | |
304 | |
305 void | |
306 gaim_status_type_set_primary_attr(GaimStatusType *status_type, const char *id) | |
307 { | |
308 g_return_if_fail(status_type != NULL); | |
309 | |
310 if (status_type->primary_attr_id != NULL) | |
311 g_free(status_type->primary_attr_id); | |
312 | |
313 status_type->primary_attr_id = (id == NULL ? NULL : g_strdup(id)); | |
314 } | |
315 | |
316 void | |
10197 | 317 gaim_status_type_add_attr(GaimStatusType *status_type, const char *id, |
9949 | 318 const char *name, GaimValue *value) |
319 { | |
320 GaimStatusAttr *attr; | |
321 | |
322 g_return_if_fail(status_type != NULL); | |
323 g_return_if_fail(id != NULL); | |
324 g_return_if_fail(name != NULL); | |
325 g_return_if_fail(value != NULL); | |
326 | |
327 attr = gaim_status_attr_new(id, name, value); | |
328 | |
329 status_type->attrs = g_list_append(status_type->attrs, attr); | |
330 } | |
331 | |
332 void | |
333 gaim_status_type_add_attrs_vargs(GaimStatusType *status_type, va_list args) | |
334 { | |
335 const char *id, *name; | |
336 GaimValue *value; | |
337 | |
338 g_return_if_fail(status_type != NULL); | |
339 | |
340 while ((id = va_arg(args, const char *)) != NULL) | |
341 { | |
342 name = va_arg(args, const char *); | |
343 g_return_if_fail(name != NULL); | |
344 | |
345 value = va_arg(args, GaimValue *); | |
346 g_return_if_fail(value != NULL); | |
6065 | 347 |
9949 | 348 gaim_status_type_add_attr(status_type, id, name, value); |
349 } | |
350 } | |
351 | |
10010 | 352 void |
353 gaim_status_type_add_attrs(GaimStatusType *status_type, const char *id, | |
354 const char *name, GaimValue *value, ...) | |
355 { | |
356 va_list args; | |
357 | |
358 g_return_if_fail(status_type != NULL); | |
359 g_return_if_fail(id != NULL); | |
360 g_return_if_fail(name != NULL); | |
361 g_return_if_fail(value != NULL); | |
362 | |
363 /* Add the first attribute */ | |
364 gaim_status_type_add_attr(status_type, id, name, value); | |
365 | |
366 va_start(args, value); | |
367 gaim_status_type_add_attrs_vargs(status_type, args); | |
368 va_end(args); | |
369 } | |
370 | |
9949 | 371 GaimStatusPrimitive |
372 gaim_status_type_get_primitive(const GaimStatusType *status_type) | |
373 { | |
374 g_return_val_if_fail(status_type != NULL, GAIM_STATUS_UNSET); | |
375 | |
376 return status_type->primitive; | |
377 } | |
378 | |
379 const char * | |
380 gaim_status_type_get_id(const GaimStatusType *status_type) | |
381 { | |
382 g_return_val_if_fail(status_type != NULL, NULL); | |
383 | |
384 return status_type->id; | |
385 } | |
386 | |
387 const char * | |
388 gaim_status_type_get_name(const GaimStatusType *status_type) | |
389 { | |
390 g_return_val_if_fail(status_type != NULL, NULL); | |
391 | |
392 return status_type->name; | |
393 } | |
394 | |
395 gboolean | |
396 gaim_status_type_is_saveable(const GaimStatusType *status_type) | |
397 { | |
398 g_return_val_if_fail(status_type != NULL, FALSE); | |
399 | |
400 return status_type->saveable; | |
401 } | |
402 | |
403 gboolean | |
404 gaim_status_type_is_user_settable(const GaimStatusType *status_type) | |
405 { | |
406 g_return_val_if_fail(status_type != NULL, FALSE); | |
407 | |
408 return status_type->user_settable; | |
409 } | |
410 | |
411 gboolean | |
412 gaim_status_type_is_independent(const GaimStatusType *status_type) | |
413 { | |
414 g_return_val_if_fail(status_type != NULL, FALSE); | |
415 | |
416 return status_type->independent; | |
417 } | |
418 | |
419 gboolean | |
10067 | 420 gaim_status_type_is_exclusive(const GaimStatusType *status_type) |
421 { | |
422 g_return_val_if_fail(status_type != NULL, FALSE); | |
423 | |
424 return !status_type->independent; | |
425 } | |
426 | |
427 gboolean | |
9949 | 428 gaim_status_type_is_available(const GaimStatusType *status_type) |
429 { | |
430 GaimStatusPrimitive primitive; | |
431 | |
432 g_return_val_if_fail(status_type != NULL, FALSE); | |
433 | |
434 primitive = gaim_status_type_get_primitive(status_type); | |
435 | |
12587 | 436 return (primitive == GAIM_STATUS_AVAILABLE); |
9949 | 437 } |
438 | |
439 const char * | |
440 gaim_status_type_get_primary_attr(const GaimStatusType *status_type) | |
441 { | |
442 g_return_val_if_fail(status_type != NULL, NULL); | |
443 | |
444 return status_type->primary_attr_id; | |
445 } | |
446 | |
447 GaimStatusAttr * | |
448 gaim_status_type_get_attr(const GaimStatusType *status_type, const char *id) | |
449 { | |
450 GList *l; | |
451 | |
452 g_return_val_if_fail(status_type != NULL, NULL); | |
453 g_return_val_if_fail(id != NULL, NULL); | |
454 | |
455 for (l = status_type->attrs; l != NULL; l = l->next) | |
456 { | |
457 GaimStatusAttr *attr = (GaimStatusAttr *)l->data; | |
458 | |
459 if (!strcmp(gaim_status_attr_get_id(attr), id)) | |
460 return attr; | |
461 } | |
462 | |
463 return NULL; | |
464 } | |
465 | |
466 const GList * | |
467 gaim_status_type_get_attrs(const GaimStatusType *status_type) | |
468 { | |
469 g_return_val_if_fail(status_type != NULL, NULL); | |
470 | |
471 return status_type->attrs; | |
472 } | |
473 | |
10348 | 474 const GaimStatusType * |
475 gaim_status_type_find_with_id(GList *status_types, const char *id) | |
476 { | |
477 GaimStatusType *status_type; | |
478 | |
479 g_return_val_if_fail(id != NULL, NULL); | |
480 | |
481 while (status_types != NULL) | |
482 { | |
483 status_type = status_types->data; | |
484 | |
485 if (!strcmp(id, status_type->id)) | |
486 return status_type; | |
10895 | 487 |
488 status_types = status_types->next; | |
10348 | 489 } |
490 | |
491 return NULL; | |
492 } | |
493 | |
9949 | 494 |
495 /************************************************************************** | |
496 * GaimStatusAttr API | |
497 **************************************************************************/ | |
498 GaimStatusAttr * | |
499 gaim_status_attr_new(const char *id, const char *name, GaimValue *value_type) | |
500 { | |
501 GaimStatusAttr *attr; | |
502 | |
503 g_return_val_if_fail(id != NULL, NULL); | |
504 g_return_val_if_fail(name != NULL, NULL); | |
505 g_return_val_if_fail(value_type != NULL, NULL); | |
506 | |
507 attr = g_new0(GaimStatusAttr, 1); | |
11187 | 508 GAIM_DBUS_REGISTER_POINTER(attr, GaimStatusAttr); |
9949 | 509 |
510 attr->id = g_strdup(id); | |
511 attr->name = g_strdup(name); | |
512 attr->value_type = value_type; | |
513 | |
514 return attr; | |
515 } | |
516 | |
517 void | |
518 gaim_status_attr_destroy(GaimStatusAttr *attr) | |
519 { | |
520 g_return_if_fail(attr != NULL); | |
521 | |
522 g_free(attr->id); | |
523 g_free(attr->name); | |
524 | |
525 gaim_value_destroy(attr->value_type); | |
526 | |
11187 | 527 GAIM_DBUS_UNREGISTER_POINTER(attr); |
9949 | 528 g_free(attr); |
529 } | |
530 | |
531 const char * | |
532 gaim_status_attr_get_id(const GaimStatusAttr *attr) | |
533 { | |
534 g_return_val_if_fail(attr != NULL, NULL); | |
535 | |
536 return attr->id; | |
537 } | |
538 | |
539 const char * | |
540 gaim_status_attr_get_name(const GaimStatusAttr *attr) | |
541 { | |
542 g_return_val_if_fail(attr != NULL, NULL); | |
543 | |
544 return attr->name; | |
545 } | |
546 | |
547 GaimValue * | |
11249 | 548 gaim_status_attr_get_value(const GaimStatusAttr *attr) |
9949 | 549 { |
550 g_return_val_if_fail(attr != NULL, NULL); | |
551 | |
552 return attr->value_type; | |
553 } | |
554 | |
555 | |
556 /************************************************************************** | |
557 * GaimStatus API | |
558 **************************************************************************/ | |
559 GaimStatus * | |
560 gaim_status_new(GaimStatusType *status_type, GaimPresence *presence) | |
561 { | |
562 GaimStatus *status; | |
563 const GList *l; | |
564 | |
565 g_return_val_if_fail(status_type != NULL, NULL); | |
566 g_return_val_if_fail(presence != NULL, NULL); | |
567 | |
568 status = g_new0(GaimStatus, 1); | |
11187 | 569 GAIM_DBUS_REGISTER_POINTER(status, GaimStatus); |
9949 | 570 |
571 status->type = status_type; | |
572 status->presence = presence; | |
573 | |
574 status->attr_values = | |
575 g_hash_table_new_full(g_str_hash, g_str_equal, g_free, | |
576 (GDestroyNotify)gaim_value_destroy); | |
577 | |
578 for (l = gaim_status_type_get_attrs(status_type); l != NULL; l = l->next) | |
579 { | |
580 GaimStatusAttr *attr = (GaimStatusAttr *)l->data; | |
11249 | 581 GaimValue *value = gaim_status_attr_get_value(attr); |
9949 | 582 GaimValue *new_value = gaim_value_dup(value); |
583 | |
584 g_hash_table_insert(status->attr_values, | |
10197 | 585 g_strdup(gaim_status_attr_get_id(attr)), |
586 new_value); | |
9949 | 587 } |
588 | |
589 return status; | |
590 } | |
591 | |
10754 | 592 /* |
593 * TODO: If the GaimStatus is in a GaimPresence, then | |
594 * remove it from the GaimPresence? | |
595 */ | |
9949 | 596 void |
597 gaim_status_destroy(GaimStatus *status) | |
598 { | |
599 g_return_if_fail(status != NULL); | |
600 | |
601 g_hash_table_destroy(status->attr_values); | |
602 | |
11187 | 603 GAIM_DBUS_UNREGISTER_POINTER(status); |
9949 | 604 g_free(status); |
605 } | |
6065 | 606 |
607 static void | |
9949 | 608 notify_buddy_status_update(GaimBuddy *buddy, GaimPresence *presence, |
609 GaimStatus *old_status, GaimStatus *new_status) | |
610 { | |
611 GaimBlistUiOps *ops = gaim_blist_get_ui_ops(); | |
612 | |
11698 | 613 if (gaim_prefs_get_bool("/core/logging/log_system")) |
9949 | 614 { |
615 time_t current_time = time(NULL); | |
616 const char *buddy_alias = gaim_buddy_get_alias(buddy); | |
617 char *tmp = NULL; | |
618 | |
12668
57462d6542ea
[gaim-migrate @ 15011]
Richard Laager <rlaager@wiktel.com>
parents:
12595
diff
changeset
|
619 if (gaim_status_is_available(new_status)) |
9949 | 620 { |
12668
57462d6542ea
[gaim-migrate @ 15011]
Richard Laager <rlaager@wiktel.com>
parents:
12595
diff
changeset
|
621 if (((old_status == NULL) || !gaim_status_is_online(old_status))) |
57462d6542ea
[gaim-migrate @ 15011]
Richard Laager <rlaager@wiktel.com>
parents:
12595
diff
changeset
|
622 { |
57462d6542ea
[gaim-migrate @ 15011]
Richard Laager <rlaager@wiktel.com>
parents:
12595
diff
changeset
|
623 tmp = g_strdup_printf(_("%s signed on"), buddy_alias); |
57462d6542ea
[gaim-migrate @ 15011]
Richard Laager <rlaager@wiktel.com>
parents:
12595
diff
changeset
|
624 } |
57462d6542ea
[gaim-migrate @ 15011]
Richard Laager <rlaager@wiktel.com>
parents:
12595
diff
changeset
|
625 else if (!gaim_status_is_available(old_status)) |
57462d6542ea
[gaim-migrate @ 15011]
Richard Laager <rlaager@wiktel.com>
parents:
12595
diff
changeset
|
626 { |
57462d6542ea
[gaim-migrate @ 15011]
Richard Laager <rlaager@wiktel.com>
parents:
12595
diff
changeset
|
627 tmp = g_strdup_printf(_("%s came back"), buddy_alias); |
57462d6542ea
[gaim-migrate @ 15011]
Richard Laager <rlaager@wiktel.com>
parents:
12595
diff
changeset
|
628 } |
9949 | 629 } |
12668
57462d6542ea
[gaim-migrate @ 15011]
Richard Laager <rlaager@wiktel.com>
parents:
12595
diff
changeset
|
630 else if ((old_status != NULL) && gaim_status_is_available(old_status)) |
9949 | 631 { |
12668
57462d6542ea
[gaim-migrate @ 15011]
Richard Laager <rlaager@wiktel.com>
parents:
12595
diff
changeset
|
632 if (!gaim_status_is_online(new_status)) |
57462d6542ea
[gaim-migrate @ 15011]
Richard Laager <rlaager@wiktel.com>
parents:
12595
diff
changeset
|
633 { |
57462d6542ea
[gaim-migrate @ 15011]
Richard Laager <rlaager@wiktel.com>
parents:
12595
diff
changeset
|
634 tmp = g_strdup_printf(_("%s signed off"), buddy_alias); |
57462d6542ea
[gaim-migrate @ 15011]
Richard Laager <rlaager@wiktel.com>
parents:
12595
diff
changeset
|
635 } |
57462d6542ea
[gaim-migrate @ 15011]
Richard Laager <rlaager@wiktel.com>
parents:
12595
diff
changeset
|
636 else if (!gaim_status_is_available(new_status)) |
57462d6542ea
[gaim-migrate @ 15011]
Richard Laager <rlaager@wiktel.com>
parents:
12595
diff
changeset
|
637 { |
57462d6542ea
[gaim-migrate @ 15011]
Richard Laager <rlaager@wiktel.com>
parents:
12595
diff
changeset
|
638 tmp = g_strdup_printf(_("%s went away"), buddy_alias); |
57462d6542ea
[gaim-migrate @ 15011]
Richard Laager <rlaager@wiktel.com>
parents:
12595
diff
changeset
|
639 } |
9949 | 640 } |
641 | |
642 if (tmp != NULL) | |
643 { | |
644 GaimLog *log = gaim_account_get_log(buddy->account); | |
645 | |
646 gaim_log_write(log, GAIM_MESSAGE_SYSTEM, buddy_alias, | |
647 current_time, tmp); | |
648 g_free(tmp); | |
649 } | |
650 } | |
651 | |
10012 | 652 if (ops != NULL && ops->update != NULL) |
653 ops->update(gaim_get_blist(), (GaimBlistNode*)buddy); | |
9949 | 654 } |
655 | |
656 static void | |
657 notify_status_update(GaimPresence *presence, GaimStatus *old_status, | |
10176
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
658 GaimStatus *new_status) |
6065 | 659 { |
9949 | 660 GaimPresenceContext context = gaim_presence_get_context(presence); |
661 | |
662 if (context == GAIM_PRESENCE_CONTEXT_ACCOUNT) | |
663 { | |
10176
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
664 GaimAccount *account = gaim_presence_get_account(presence); |
9949 | 665 GaimAccountUiOps *ops = gaim_accounts_get_ui_ops(); |
666 | |
10400 | 667 if (gaim_account_get_enabled(account, gaim_core_get_ui())) |
10447 | 668 gaim_prpl_change_account_status(account, old_status, new_status); |
10176
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
669 |
9949 | 670 if (ops != NULL && ops->status_changed != NULL) |
671 { | |
10176
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
672 ops->status_changed(account, new_status); |
9949 | 673 } |
674 } | |
675 else if (context == GAIM_PRESENCE_CONTEXT_BUDDY) | |
676 { | |
677 const GList *l; | |
678 | |
679 for (l = gaim_presence_get_buddies(presence); l != NULL; l = l->next) | |
680 { | |
681 notify_buddy_status_update((GaimBuddy *)l->data, presence, | |
682 old_status, new_status); | |
683 } | |
684 } | |
685 } | |
686 | |
10204 | 687 static void |
688 status_has_changed(GaimStatus *status) | |
9949 | 689 { |
690 GaimPresence *presence; | |
691 GaimStatus *old_status; | |
692 | |
693 presence = gaim_status_get_presence(status); | |
694 | |
10204 | 695 /* |
696 * If this status is exclusive, then we must be setting it to "active." | |
697 * Since we are setting it to active, we want to set the currently | |
698 * active status to "inactive." | |
699 */ | |
700 if (gaim_status_is_exclusive(status)) | |
9949 | 701 { |
10754 | 702 old_status = gaim_presence_get_active_status(presence); |
10760 | 703 if (old_status != NULL && (old_status != status)) |
10754 | 704 old_status->active = FALSE; |
705 presence->active_status = status; | |
9949 | 706 } |
10754 | 707 else |
708 old_status = NULL; | |
9949 | 709 |
10204 | 710 notify_status_update(presence, old_status, status); |
711 } | |
712 | |
713 void | |
714 gaim_status_set_active(GaimStatus *status, gboolean active) | |
715 { | |
10754 | 716 gaim_status_set_active_with_attrs(status, active, NULL); |
10204 | 717 } |
718 | |
11249 | 719 /* |
720 * This used to parse the va_list directly, but now it creates a GList | |
721 * and passes it to gaim_status_set_active_with_attrs_list(). That | |
722 * function was created because accounts.c needs to pass a GList of | |
723 * attributes to the status API. | |
724 */ | |
10204 | 725 void |
726 gaim_status_set_active_with_attrs(GaimStatus *status, gboolean active, va_list args) | |
727 { | |
11249 | 728 GList *attrs = NULL; |
729 const gchar *id; | |
730 gpointer data; | |
731 | |
732 if (args != NULL) | |
733 { | |
734 while ((id = va_arg(args, const char *)) != NULL) | |
735 { | |
736 attrs = g_list_append(attrs, (char *)id); | |
737 data = va_arg(args, void *); | |
738 attrs = g_list_append(attrs, data); | |
739 } | |
740 } | |
741 gaim_status_set_active_with_attrs_list(status, active, attrs); | |
742 g_list_free(attrs); | |
743 } | |
744 | |
745 void | |
746 gaim_status_set_active_with_attrs_list(GaimStatus *status, gboolean active, | |
747 const GList *attrs) | |
748 { | |
10204 | 749 gboolean changed = FALSE; |
750 const gchar *id; | |
751 | |
10714 | 752 g_return_if_fail(status != NULL); |
753 | |
10204 | 754 if (!active && gaim_status_is_exclusive(status)) |
755 { | |
756 gaim_debug_error("status", | |
757 "Cannot deactivate an exclusive status (%s).\n", | |
758 gaim_status_get_id(status)); | |
759 return; | |
760 } | |
761 | |
762 if (status->active != active) | |
10738 | 763 { |
10204 | 764 changed = TRUE; |
10738 | 765 } |
10204 | 766 |
9949 | 767 status->active = active; |
6065 | 768 |
10204 | 769 /* Set any attributes */ |
11249 | 770 while (attrs) |
10204 | 771 { |
772 GaimValue *value; | |
11249 | 773 |
774 id = attrs->data; | |
775 attrs = attrs->next; | |
10204 | 776 value = gaim_status_get_attr_value(status, id); |
10713 | 777 if (value == NULL) |
778 { | |
779 gaim_debug_warning("status", "The attribute \"%s\" on the status \"%s\" is " | |
10714 | 780 "not supported.\n", id, status->type->name); |
10713 | 781 /* Skip over the data and move on to the next attribute */ |
11249 | 782 attrs = attrs->next; |
10713 | 783 continue; |
784 } | |
785 | |
10204 | 786 if (value->type == GAIM_TYPE_STRING) |
787 { | |
11249 | 788 const gchar *string_data = attrs->data; |
789 attrs = attrs->next; | |
10204 | 790 if (((string_data == NULL) && (value->data.string_data == NULL)) || |
791 ((string_data != NULL) && (value->data.string_data != NULL) && | |
792 !strcmp(string_data, value->data.string_data))) | |
793 { | |
794 continue; | |
795 } | |
796 gaim_status_set_attr_string(status, id, string_data); | |
797 changed = TRUE; | |
798 } | |
799 else if (value->type == GAIM_TYPE_INT) | |
800 { | |
11586 | 801 int int_data = GPOINTER_TO_INT(attrs->data); |
11249 | 802 attrs = attrs->next; |
10204 | 803 if (int_data == value->data.int_data) |
804 continue; | |
805 gaim_status_set_attr_int(status, id, int_data); | |
806 changed = TRUE; | |
807 } | |
808 else if (value->type == GAIM_TYPE_BOOLEAN) | |
809 { | |
11586 | 810 gboolean boolean_data = GPOINTER_TO_INT(attrs->data); |
11249 | 811 attrs = attrs->next; |
10204 | 812 if (boolean_data == value->data.boolean_data) |
813 continue; | |
814 gaim_status_set_attr_int(status, id, boolean_data); | |
815 changed = TRUE; | |
816 } | |
817 else | |
818 { | |
819 /* We don't know what the data is--skip over it */ | |
11249 | 820 attrs = attrs->next; |
10204 | 821 } |
822 } | |
823 | |
824 if (!changed) | |
825 return; | |
826 status_has_changed(status); | |
9949 | 827 } |
828 | |
829 void | |
830 gaim_status_set_attr_boolean(GaimStatus *status, const char *id, | |
831 gboolean value) | |
832 { | |
833 GaimStatusType *status_type; | |
834 GaimValue *attr_value; | |
835 | |
836 g_return_if_fail(status != NULL); | |
837 g_return_if_fail(id != NULL); | |
838 | |
839 status_type = gaim_status_get_type(status); | |
840 | |
10197 | 841 /* Make sure this attribute exists and is the correct type. */ |
842 attr_value = gaim_status_get_attr_value(status, id); | |
843 g_return_if_fail(attr_value != NULL); | |
9949 | 844 g_return_if_fail(gaim_value_get_type(attr_value) == GAIM_TYPE_BOOLEAN); |
845 | |
846 gaim_value_set_boolean(attr_value, value); | |
847 } | |
848 | |
849 void | |
850 gaim_status_set_attr_int(GaimStatus *status, const char *id, int value) | |
851 { | |
852 GaimStatusType *status_type; | |
853 GaimValue *attr_value; | |
854 | |
855 g_return_if_fail(status != NULL); | |
856 g_return_if_fail(id != NULL); | |
857 | |
858 status_type = gaim_status_get_type(status); | |
859 | |
10197 | 860 /* Make sure this attribute exists and is the correct type. */ |
861 attr_value = gaim_status_get_attr_value(status, id); | |
862 g_return_if_fail(attr_value != NULL); | |
9949 | 863 g_return_if_fail(gaim_value_get_type(attr_value) == GAIM_TYPE_INT); |
864 | |
865 gaim_value_set_int(attr_value, value); | |
6065 | 866 } |
867 | |
9949 | 868 void |
869 gaim_status_set_attr_string(GaimStatus *status, const char *id, | |
870 const char *value) | |
871 { | |
872 GaimStatusType *status_type; | |
873 GaimValue *attr_value; | |
874 | |
875 g_return_if_fail(status != NULL); | |
876 g_return_if_fail(id != NULL); | |
877 | |
878 status_type = gaim_status_get_type(status); | |
879 | |
10197 | 880 /* Make sure this attribute exists and is the correct type. */ |
10196 | 881 attr_value = gaim_status_get_attr_value(status, id); |
12434 | 882 /* This used to be g_return_if_fail, but it's failing a LOT, so |
883 * let's generate a log error for now. */ | |
884 /* g_return_if_fail(attr_value != NULL); */ | |
885 if (attr_value == NULL) { | |
886 gaim_debug_error("status", | |
887 "Attempted to set status attribute '%s' for " | |
888 "status '%s', which is not legal. Fix " | |
889 "this!\n", id, | |
890 gaim_status_type_get_name(gaim_status_get_type(status))); | |
891 return; | |
892 | |
893 } | |
9949 | 894 g_return_if_fail(gaim_value_get_type(attr_value) == GAIM_TYPE_STRING); |
895 | |
896 gaim_value_set_string(attr_value, value); | |
897 } | |
898 | |
899 GaimStatusType * | |
900 gaim_status_get_type(const GaimStatus *status) | |
901 { | |
902 g_return_val_if_fail(status != NULL, NULL); | |
903 | |
904 return status->type; | |
905 } | |
906 | |
907 GaimPresence * | |
908 gaim_status_get_presence(const GaimStatus *status) | |
6065 | 909 { |
9949 | 910 g_return_val_if_fail(status != NULL, NULL); |
911 | |
912 return status->presence; | |
913 } | |
914 | |
915 const char * | |
916 gaim_status_get_id(const GaimStatus *status) | |
917 { | |
918 g_return_val_if_fail(status != NULL, NULL); | |
919 | |
920 return gaim_status_type_get_id(gaim_status_get_type(status)); | |
921 } | |
922 | |
923 const char * | |
924 gaim_status_get_name(const GaimStatus *status) | |
925 { | |
926 g_return_val_if_fail(status != NULL, NULL); | |
927 | |
928 return gaim_status_type_get_name(gaim_status_get_type(status)); | |
929 } | |
930 | |
931 gboolean | |
932 gaim_status_is_independent(const GaimStatus *status) | |
933 { | |
934 g_return_val_if_fail(status != NULL, FALSE); | |
935 | |
936 return gaim_status_type_is_independent(gaim_status_get_type(status)); | |
937 } | |
938 | |
939 gboolean | |
10067 | 940 gaim_status_is_exclusive(const GaimStatus *status) |
941 { | |
942 g_return_val_if_fail(status != NULL, FALSE); | |
943 | |
944 return gaim_status_type_is_exclusive(gaim_status_get_type(status)); | |
945 } | |
946 | |
947 gboolean | |
9949 | 948 gaim_status_is_available(const GaimStatus *status) |
949 { | |
950 g_return_val_if_fail(status != NULL, FALSE); | |
951 | |
952 return gaim_status_type_is_available(gaim_status_get_type(status)); | |
953 } | |
6216 | 954 |
9949 | 955 gboolean |
956 gaim_status_is_active(const GaimStatus *status) | |
957 { | |
958 g_return_val_if_fail(status != NULL, FALSE); | |
959 | |
960 return status->active; | |
961 } | |
962 | |
10040
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
963 gboolean |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
964 gaim_status_is_online(const GaimStatus *status) |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
965 { |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
966 GaimStatusPrimitive primitive; |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
967 |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
968 g_return_val_if_fail( status != NULL, FALSE); |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
969 |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
970 primitive = gaim_status_type_get_primitive(gaim_status_get_type(status)); |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
971 |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
972 return (primitive != GAIM_STATUS_UNSET && |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
973 primitive != GAIM_STATUS_OFFLINE); |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
974 } |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
975 |
9949 | 976 GaimValue * |
977 gaim_status_get_attr_value(const GaimStatus *status, const char *id) | |
978 { | |
979 g_return_val_if_fail(status != NULL, NULL); | |
980 g_return_val_if_fail(id != NULL, NULL); | |
981 | |
982 return (GaimValue *)g_hash_table_lookup(status->attr_values, id); | |
983 } | |
984 | |
985 gboolean | |
986 gaim_status_get_attr_boolean(const GaimStatus *status, const char *id) | |
987 { | |
988 const GaimValue *value; | |
989 | |
990 g_return_val_if_fail(status != NULL, FALSE); | |
991 g_return_val_if_fail(id != NULL, FALSE); | |
992 | |
993 if ((value = gaim_status_get_attr_value(status, id)) == NULL) | |
994 return FALSE; | |
995 | |
10197 | 996 g_return_val_if_fail(gaim_value_get_type(value) == GAIM_TYPE_BOOLEAN, FALSE); |
9949 | 997 |
998 return gaim_value_get_boolean(value); | |
999 } | |
1000 | |
1001 int | |
1002 gaim_status_get_attr_int(const GaimStatus *status, const char *id) | |
1003 { | |
1004 const GaimValue *value; | |
1005 | |
10507 | 1006 g_return_val_if_fail(status != NULL, 0); |
1007 g_return_val_if_fail(id != NULL, 0); | |
9949 | 1008 |
1009 if ((value = gaim_status_get_attr_value(status, id)) == NULL) | |
10507 | 1010 return 0; |
9949 | 1011 |
1012 g_return_val_if_fail(gaim_value_get_type(value) == GAIM_TYPE_INT, 0); | |
1013 | |
1014 return gaim_value_get_int(value); | |
1015 } | |
1016 | |
1017 const char * | |
1018 gaim_status_get_attr_string(const GaimStatus *status, const char *id) | |
1019 { | |
1020 const GaimValue *value; | |
1021 | |
10507 | 1022 g_return_val_if_fail(status != NULL, NULL); |
1023 g_return_val_if_fail(id != NULL, NULL); | |
9949 | 1024 |
1025 if ((value = gaim_status_get_attr_value(status, id)) == NULL) | |
10504 | 1026 return NULL; |
9949 | 1027 |
1028 g_return_val_if_fail(gaim_value_get_type(value) == GAIM_TYPE_STRING, NULL); | |
1029 | |
1030 return gaim_value_get_string(value); | |
1031 } | |
1032 | |
1033 gint | |
1034 gaim_status_compare(const GaimStatus *status1, const GaimStatus *status2) | |
1035 { | |
1036 GaimStatusType *type1, *type2; | |
1037 int score1 = 0, score2 = 0; | |
6065 | 1038 |
9949 | 1039 if ((status1 == NULL && status2 == NULL) || |
1040 (status1 == status2)) | |
1041 { | |
1042 return 0; | |
1043 } | |
1044 else if (status1 == NULL) | |
1045 return 1; | |
1046 else if (status2 == NULL) | |
1047 return -1; | |
1048 | |
1049 type1 = gaim_status_get_type(status1); | |
1050 type2 = gaim_status_get_type(status2); | |
1051 | |
1052 if (gaim_status_is_active(status1)) | |
1053 score1 = primitive_scores[gaim_status_type_get_primitive(type1)]; | |
1054 | |
1055 if (gaim_status_is_active(status2)) | |
1056 score2 = primitive_scores[gaim_status_type_get_primitive(type2)]; | |
1057 | |
1058 if (score1 > score2) | |
1059 return -1; | |
1060 else if (score1 < score2) | |
1061 return 1; | |
1062 | |
1063 return 0; | |
1064 } | |
1065 | |
1066 | |
1067 /************************************************************************** | |
1068 * GaimPresence API | |
1069 **************************************************************************/ | |
1070 GaimPresence * | |
1071 gaim_presence_new(GaimPresenceContext context) | |
1072 { | |
1073 GaimPresence *presence; | |
1074 | |
1075 g_return_val_if_fail(context != GAIM_PRESENCE_CONTEXT_UNSET, NULL); | |
1076 | |
1077 presence = g_new0(GaimPresence, 1); | |
11187 | 1078 GAIM_DBUS_REGISTER_POINTER(presence, GaimPresence); |
9949 | 1079 |
1080 presence->context = context; | |
1081 | |
1082 presence->status_table = | |
10009 | 1083 g_hash_table_new_full(g_str_hash, g_str_equal, |
11638 | 1084 g_free, NULL); |
9949 | 1085 |
1086 return presence; | |
1087 } | |
1088 | |
1089 GaimPresence * | |
1090 gaim_presence_new_for_account(GaimAccount *account) | |
1091 { | |
10012 | 1092 GaimPresence *presence = NULL; |
9949 | 1093 g_return_val_if_fail(account != NULL, NULL); |
1094 | |
1095 presence = gaim_presence_new(GAIM_PRESENCE_CONTEXT_ACCOUNT); | |
1096 presence->u.account = account; | |
10006 | 1097 presence->statuses = gaim_prpl_get_statuses(account, presence); |
9949 | 1098 |
1099 return presence; | |
1100 } | |
1101 | |
1102 GaimPresence * | |
1103 gaim_presence_new_for_conv(GaimConversation *conv) | |
1104 { | |
1105 GaimPresence *presence; | |
1106 | |
1107 g_return_val_if_fail(conv != NULL, NULL); | |
1108 | |
1109 presence = gaim_presence_new(GAIM_PRESENCE_CONTEXT_CONV); | |
1110 presence->u.chat.conv = conv; | |
10006 | 1111 /* presence->statuses = gaim_prpl_get_statuses(conv->account, presence); ? */ |
9949 | 1112 |
1113 return presence; | |
1114 } | |
6216 | 1115 |
9949 | 1116 GaimPresence * |
1117 gaim_presence_new_for_buddy(GaimBuddy *buddy) | |
1118 { | |
1119 GaimPresence *presence; | |
1120 GaimStatusBuddyKey *key; | |
10006 | 1121 GaimAccount *account; |
9949 | 1122 |
1123 g_return_val_if_fail(buddy != NULL, NULL); | |
10012 | 1124 account = buddy->account; |
9949 | 1125 |
1126 key = g_new0(GaimStatusBuddyKey, 1); | |
1127 key->account = buddy->account; | |
1128 key->name = g_strdup(buddy->name); | |
10006 | 1129 |
1130 presence = g_hash_table_lookup(buddy_presences, key); | |
1131 if (presence == NULL) | |
9949 | 1132 { |
1133 presence = gaim_presence_new(GAIM_PRESENCE_CONTEXT_BUDDY); | |
1134 | |
1135 presence->u.buddy.name = g_strdup(buddy->name); | |
1136 presence->u.buddy.account = buddy->account; | |
10006 | 1137 presence->statuses = gaim_prpl_get_statuses(buddy->account, presence); |
9949 | 1138 |
1139 g_hash_table_insert(buddy_presences, key, presence); | |
1140 } | |
1141 else | |
1142 { | |
1143 g_free(key->name); | |
1144 g_free(key); | |
1145 } | |
1146 | |
1147 presence->u.buddy.ref_count++; | |
1148 presence->u.buddy.buddies = g_list_append(presence->u.buddy.buddies, | |
1149 buddy); | |
1150 | |
1151 return presence; | |
1152 } | |
1153 | |
1154 void | |
1155 gaim_presence_destroy(GaimPresence *presence) | |
1156 { | |
1157 g_return_if_fail(presence != NULL); | |
6216 | 1158 |
9949 | 1159 if (gaim_presence_get_context(presence) == GAIM_PRESENCE_CONTEXT_BUDDY) |
1160 { | |
1161 GaimStatusBuddyKey key; | |
1162 | |
10077 | 1163 if(presence->u.buddy.ref_count != 0) |
1164 return; | |
9949 | 1165 |
1166 key.account = presence->u.buddy.account; | |
1167 key.name = presence->u.buddy.name; | |
1168 | |
1169 g_hash_table_remove(buddy_presences, &key); | |
1170 | |
1171 if (presence->u.buddy.name != NULL) | |
1172 g_free(presence->u.buddy.name); | |
1173 } | |
1174 else if (gaim_presence_get_context(presence) == GAIM_PRESENCE_CONTEXT_CONV) | |
1175 { | |
1176 if (presence->u.chat.user != NULL) | |
1177 g_free(presence->u.chat.user); | |
1178 } | |
1179 | |
11638 | 1180 if (presence->statuses != NULL) { |
1181 g_list_foreach(presence->statuses, (GFunc)gaim_status_destroy, NULL); | |
9949 | 1182 g_list_free(presence->statuses); |
11638 | 1183 } |
9949 | 1184 |
1185 g_hash_table_destroy(presence->status_table); | |
1186 | |
11187 | 1187 GAIM_DBUS_UNREGISTER_POINTER(presence); |
9949 | 1188 g_free(presence); |
1189 } | |
1190 | |
10580 | 1191 /* |
1192 * TODO: Maybe we should cal gaim_presence_destroy() after we | |
1193 * decrement the ref count? I don't see why we should | |
1194 * make other places do it manually when we can do it here. | |
1195 */ | |
9949 | 1196 void |
1197 gaim_presence_remove_buddy(GaimPresence *presence, GaimBuddy *buddy) | |
1198 { | |
1199 g_return_if_fail(presence != NULL); | |
1200 g_return_if_fail(buddy != NULL); | |
1201 g_return_if_fail(gaim_presence_get_context(presence) == | |
1202 GAIM_PRESENCE_CONTEXT_BUDDY); | |
1203 | |
1204 if (g_list_find(presence->u.buddy.buddies, buddy) != NULL) | |
1205 { | |
1206 presence->u.buddy.buddies = g_list_remove(presence->u.buddy.buddies, | |
1207 buddy); | |
1208 presence->u.buddy.ref_count--; | |
1209 } | |
6065 | 1210 } |
1211 | |
9949 | 1212 void |
1213 gaim_presence_add_status(GaimPresence *presence, GaimStatus *status) | |
1214 { | |
1215 g_return_if_fail(presence != NULL); | |
1216 g_return_if_fail(status != NULL); | |
1217 | |
1218 presence->statuses = g_list_append(presence->statuses, status); | |
1219 | |
1220 g_hash_table_insert(presence->status_table, | |
1221 g_strdup(gaim_status_get_id(status)), status); | |
1222 } | |
1223 | |
1224 void | |
11318 | 1225 gaim_presence_add_list(GaimPresence *presence, const GList *source_list) |
9949 | 1226 { |
1227 const GList *l; | |
1228 | |
1229 g_return_if_fail(presence != NULL); | |
1230 g_return_if_fail(source_list != NULL); | |
1231 | |
1232 for (l = source_list; l != NULL; l = l->next) | |
1233 gaim_presence_add_status(presence, (GaimStatus *)l->data); | |
1234 } | |
1235 | |
1236 void | |
1237 gaim_presence_set_status_active(GaimPresence *presence, const char *status_id, | |
1238 gboolean active) | |
1239 { | |
1240 GaimStatus *status; | |
1241 | |
1242 g_return_if_fail(presence != NULL); | |
1243 g_return_if_fail(status_id != NULL); | |
1244 | |
1245 status = gaim_presence_get_status(presence, status_id); | |
1246 | |
1247 g_return_if_fail(status != NULL); | |
10348 | 1248 /* TODO: Should we do the following? */ |
1249 /* g_return_if_fail(active == status->active); */ | |
9949 | 1250 |
10067 | 1251 if (gaim_status_is_exclusive(status)) |
9949 | 1252 { |
1253 if (!active) | |
1254 { | |
1255 gaim_debug_warning("status", | |
1256 "Attempted to set a non-independent status " | |
1257 "(%s) inactive. Only independent statuses " | |
1258 "can be specifically marked inactive.", | |
1259 status_id); | |
1260 return; | |
1261 } | |
1262 } | |
1263 | |
1264 gaim_status_set_active(status, active); | |
1265 } | |
1266 | |
1267 void | |
1268 gaim_presence_switch_status(GaimPresence *presence, const char *status_id) | |
1269 { | |
10754 | 1270 gaim_presence_set_status_active(presence, status_id, TRUE); |
9949 | 1271 } |
1272 | |
1273 static void | |
1274 update_buddy_idle(GaimBuddy *buddy, GaimPresence *presence, | |
1275 time_t current_time, gboolean old_idle, gboolean idle) | |
1276 { | |
1277 GaimBlistUiOps *ops = gaim_get_blist()->ui_ops; | |
12015
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1278 GaimConversation *conv; |
9949 | 1279 |
1280 if (!old_idle && idle) | |
1281 { | |
11698 | 1282 if (gaim_prefs_get_bool("/core/logging/log_system")) |
9949 | 1283 { |
1284 GaimLog *log = gaim_account_get_log(buddy->account); | |
1285 char *tmp = g_strdup_printf(_("%s became idle"), | |
1286 gaim_buddy_get_alias(buddy)); | |
1287 | |
1288 gaim_log_write(log, GAIM_MESSAGE_SYSTEM, | |
1289 gaim_buddy_get_alias(buddy), current_time, tmp); | |
1290 g_free(tmp); | |
1291 } | |
1292 } | |
1293 else if (old_idle && !idle) | |
1294 { | |
11698 | 1295 if (gaim_prefs_get_bool("/core/logging/log_system")) |
9949 | 1296 { |
1297 GaimLog *log = gaim_account_get_log(buddy->account); | |
1298 char *tmp = g_strdup_printf(_("%s became unidle"), | |
1299 gaim_buddy_get_alias(buddy)); | |
1300 | |
1301 gaim_log_write(log, GAIM_MESSAGE_SYSTEM, | |
1302 gaim_buddy_get_alias(buddy), current_time, tmp); | |
1303 g_free(tmp); | |
1304 } | |
1305 } | |
1306 | |
11935
cb73483c9f63
[gaim-migrate @ 14226]
Etan Reisner <pidgin@unreliablesource.net>
parents:
11905
diff
changeset
|
1307 if (old_idle != idle) |
cb73483c9f63
[gaim-migrate @ 14226]
Etan Reisner <pidgin@unreliablesource.net>
parents:
11905
diff
changeset
|
1308 gaim_signal_emit(gaim_blist_get_handle(), "buddy-idle-changed", buddy, |
cb73483c9f63
[gaim-migrate @ 14226]
Etan Reisner <pidgin@unreliablesource.net>
parents:
11905
diff
changeset
|
1309 old_idle, idle); |
cb73483c9f63
[gaim-migrate @ 14226]
Etan Reisner <pidgin@unreliablesource.net>
parents:
11905
diff
changeset
|
1310 |
10378 | 1311 gaim_contact_invalidate_priority_buddy(gaim_buddy_get_contact(buddy)); |
9949 | 1312 |
12015
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1313 /* Should this be done here? It'd perhaps make more sense to |
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1314 * connect to buddy-[un]idle signals and update from there |
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1315 */ |
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1316 |
9949 | 1317 if (ops != NULL && ops->update != NULL) |
1318 ops->update(gaim_get_blist(), (GaimBlistNode *)buddy); | |
12015
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1319 |
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1320 conv = gaim_find_conversation_with_account(GAIM_CONV_TYPE_IM, |
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1321 gaim_buddy_get_name(buddy), |
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1322 gaim_buddy_get_account(buddy)); |
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1323 if (conv) |
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1324 { |
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1325 GaimConversationUiOps *conv_ops; |
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1326 conv_ops = gaim_conversation_get_ui_ops(conv); |
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1327 if (conv_ops && conv_ops->updated) |
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1328 conv_ops->updated(conv, GAIM_CONV_UPDATE_AWAY); |
5a63ea24ac83
[gaim-migrate @ 14308]
Daniel Atallah <daniel.atallah@gmail.com>
parents:
11975
diff
changeset
|
1329 } |
9949 | 1330 } |
1331 | |
1332 void | |
1333 gaim_presence_set_idle(GaimPresence *presence, gboolean idle, time_t idle_time) | |
1334 { | |
1335 gboolean old_idle; | |
1336 | |
1337 g_return_if_fail(presence != NULL); | |
1338 | |
1339 if (presence->idle == idle && presence->idle_time == idle_time) | |
1340 return; | |
1341 | |
1342 old_idle = presence->idle; | |
1343 presence->idle = idle; | |
1344 presence->idle_time = (idle ? idle_time : 0); | |
1345 | |
1346 if (gaim_presence_get_context(presence) == GAIM_PRESENCE_CONTEXT_BUDDY) | |
1347 { | |
1348 const GList *l; | |
1349 time_t current_time = time(NULL); | |
1350 | |
1351 for (l = gaim_presence_get_buddies(presence); l != NULL; l = l->next) | |
1352 { | |
1353 update_buddy_idle((GaimBuddy *)l->data, presence, current_time, | |
1354 old_idle, idle); | |
1355 } | |
1356 } | |
11551
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1357 else if(gaim_presence_get_context(presence) == GAIM_PRESENCE_CONTEXT_ACCOUNT) |
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1358 { |
11975 | 1359 GaimAccount *account; |
1360 GaimConnection *gc; | |
11551
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1361 GaimPluginProtocolInfo *prpl_info = NULL; |
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1362 |
11975 | 1363 account = gaim_presence_get_account(presence); |
12145
5bda6a03d43b
[gaim-migrate @ 14446]
Richard Laager <rlaager@wiktel.com>
parents:
12123
diff
changeset
|
1364 |
5bda6a03d43b
[gaim-migrate @ 14446]
Richard Laager <rlaager@wiktel.com>
parents:
12123
diff
changeset
|
1365 if (gaim_prefs_get_bool("/core/logging/log_system")) |
5bda6a03d43b
[gaim-migrate @ 14446]
Richard Laager <rlaager@wiktel.com>
parents:
12123
diff
changeset
|
1366 { |
5bda6a03d43b
[gaim-migrate @ 14446]
Richard Laager <rlaager@wiktel.com>
parents:
12123
diff
changeset
|
1367 GaimLog *log = gaim_account_get_log(account); |
5bda6a03d43b
[gaim-migrate @ 14446]
Richard Laager <rlaager@wiktel.com>
parents:
12123
diff
changeset
|
1368 char *msg; |
11975 | 1369 |
12145
5bda6a03d43b
[gaim-migrate @ 14446]
Richard Laager <rlaager@wiktel.com>
parents:
12123
diff
changeset
|
1370 if (idle) |
5bda6a03d43b
[gaim-migrate @ 14446]
Richard Laager <rlaager@wiktel.com>
parents:
12123
diff
changeset
|
1371 msg = g_strdup_printf(_("+++ %s became idle"), gaim_account_get_username(account)); |
5bda6a03d43b
[gaim-migrate @ 14446]
Richard Laager <rlaager@wiktel.com>
parents:
12123
diff
changeset
|
1372 else |
5bda6a03d43b
[gaim-migrate @ 14446]
Richard Laager <rlaager@wiktel.com>
parents:
12123
diff
changeset
|
1373 msg = g_strdup_printf(_("+++ %s became unidle"), gaim_account_get_username(account)); |
5bda6a03d43b
[gaim-migrate @ 14446]
Richard Laager <rlaager@wiktel.com>
parents:
12123
diff
changeset
|
1374 gaim_log_write(log, GAIM_MESSAGE_SYSTEM, |
5bda6a03d43b
[gaim-migrate @ 14446]
Richard Laager <rlaager@wiktel.com>
parents:
12123
diff
changeset
|
1375 gaim_account_get_username(account), |
5bda6a03d43b
[gaim-migrate @ 14446]
Richard Laager <rlaager@wiktel.com>
parents:
12123
diff
changeset
|
1376 idle_time, msg); |
5bda6a03d43b
[gaim-migrate @ 14446]
Richard Laager <rlaager@wiktel.com>
parents:
12123
diff
changeset
|
1377 g_free(msg); |
5bda6a03d43b
[gaim-migrate @ 14446]
Richard Laager <rlaager@wiktel.com>
parents:
12123
diff
changeset
|
1378 } |
11975 | 1379 |
1380 gc = gaim_account_get_connection(account); | |
1381 | |
11551
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1382 if (gc != NULL && gc->prpl != NULL) |
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1383 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl); |
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1384 |
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1385 if (prpl_info && g_list_find(gaim_connections_get_all(), gc) && |
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1386 prpl_info->set_idle) |
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1387 prpl_info->set_idle(gc, time(NULL) - idle_time); |
78aad676fdb2
[gaim-migrate @ 13806]
Luke Schierer <lschiere@pidgin.im>
parents:
11522
diff
changeset
|
1388 } |
9949 | 1389 } |
1390 | |
1391 void | |
10006 | 1392 gaim_presence_set_login_time(GaimPresence *presence, time_t login_time) |
1393 { | |
1394 g_return_if_fail(presence != NULL); | |
1395 | |
1396 if (presence->login_time == login_time) | |
1397 return; | |
1398 | |
1399 presence->login_time = login_time; | |
1400 } | |
1401 | |
9949 | 1402 GaimPresenceContext |
1403 gaim_presence_get_context(const GaimPresence *presence) | |
1404 { | |
1405 g_return_val_if_fail(presence != NULL, GAIM_PRESENCE_CONTEXT_UNSET); | |
1406 | |
1407 return presence->context; | |
1408 } | |
1409 | |
1410 GaimAccount * | |
1411 gaim_presence_get_account(const GaimPresence *presence) | |
1412 { | |
1413 GaimPresenceContext context; | |
1414 | |
1415 g_return_val_if_fail(presence != NULL, NULL); | |
1416 | |
1417 context = gaim_presence_get_context(presence); | |
1418 | |
1419 g_return_val_if_fail(context == GAIM_PRESENCE_CONTEXT_ACCOUNT || | |
1420 context == GAIM_PRESENCE_CONTEXT_BUDDY, NULL); | |
1421 | |
1422 return presence->u.account; | |
1423 } | |
1424 | |
1425 GaimConversation * | |
1426 gaim_presence_get_conversation(const GaimPresence *presence) | |
1427 { | |
1428 g_return_val_if_fail(presence != NULL, NULL); | |
1429 g_return_val_if_fail(gaim_presence_get_context(presence) == | |
1430 GAIM_PRESENCE_CONTEXT_CONV, NULL); | |
1431 | |
1432 return presence->u.chat.conv; | |
1433 } | |
1434 | |
1435 const char * | |
1436 gaim_presence_get_chat_user(const GaimPresence *presence) | |
1437 { | |
1438 g_return_val_if_fail(presence != NULL, NULL); | |
1439 g_return_val_if_fail(gaim_presence_get_context(presence) == | |
1440 GAIM_PRESENCE_CONTEXT_CONV, NULL); | |
1441 | |
1442 return presence->u.chat.user; | |
1443 } | |
1444 | |
1445 const GList * | |
1446 gaim_presence_get_buddies(const GaimPresence *presence) | |
1447 { | |
1448 g_return_val_if_fail(presence != NULL, NULL); | |
1449 g_return_val_if_fail(gaim_presence_get_context(presence) == | |
1450 GAIM_PRESENCE_CONTEXT_BUDDY, NULL); | |
1451 | |
1452 return presence->u.buddy.buddies; | |
1453 } | |
1454 | |
1455 const GList * | |
1456 gaim_presence_get_statuses(const GaimPresence *presence) | |
1457 { | |
1458 g_return_val_if_fail(presence != NULL, NULL); | |
1459 | |
1460 return presence->statuses; | |
1461 } | |
1462 | |
1463 GaimStatus * | |
1464 gaim_presence_get_status(const GaimPresence *presence, const char *status_id) | |
1465 { | |
1466 GaimStatus *status; | |
10006 | 1467 const GList *l = NULL; |
9949 | 1468 |
1469 g_return_val_if_fail(presence != NULL, NULL); | |
1470 g_return_val_if_fail(status_id != NULL, NULL); | |
1471 | |
10006 | 1472 /* What's the purpose of this hash table? */ |
10012 | 1473 status = (GaimStatus *)g_hash_table_lookup(presence->status_table, |
10006 | 1474 status_id); |
10012 | 1475 |
10006 | 1476 if (status == NULL) { |
10012 | 1477 for (l = gaim_presence_get_statuses(presence); |
10006 | 1478 l != NULL && status == NULL; l = l->next) |
1479 { | |
1480 GaimStatus *temp_status = l->data; | |
10012 | 1481 |
10006 | 1482 if (!strcmp(status_id, gaim_status_get_id(temp_status))) |
1483 status = temp_status; | |
1484 } | |
1485 | |
1486 if (status != NULL) | |
1487 g_hash_table_insert(presence->status_table, | |
1488 g_strdup(gaim_status_get_id(status)), status); | |
10012 | 1489 } |
9949 | 1490 |
1491 return status; | |
1492 } | |
1493 | |
1494 GaimStatus * | |
1495 gaim_presence_get_active_status(const GaimPresence *presence) | |
1496 { | |
1497 g_return_val_if_fail(presence != NULL, NULL); | |
1498 | |
1499 return presence->active_status; | |
1500 } | |
1501 | |
1502 gboolean | |
1503 gaim_presence_is_available(const GaimPresence *presence) | |
1504 { | |
1505 GaimStatus *status; | |
1506 | |
1507 g_return_val_if_fail(presence != NULL, FALSE); | |
1508 | |
1509 status = gaim_presence_get_active_status(presence); | |
1510 | |
1511 return ((status != NULL && gaim_status_is_available(status)) && | |
1512 !gaim_presence_is_idle(presence)); | |
1513 } | |
1514 | |
1515 gboolean | |
1516 gaim_presence_is_online(const GaimPresence *presence) | |
1517 { | |
1518 GaimStatus *status; | |
1519 | |
1520 g_return_val_if_fail(presence != NULL, FALSE); | |
1521 | |
1522 if ((status = gaim_presence_get_active_status(presence)) == NULL) | |
1523 return FALSE; | |
1524 | |
10040
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
1525 return gaim_status_is_online(status); |
9949 | 1526 } |
1527 | |
1528 gboolean | |
1529 gaim_presence_is_status_active(const GaimPresence *presence, | |
1530 const char *status_id) | |
1531 { | |
1532 GaimStatus *status; | |
1533 | |
1534 g_return_val_if_fail(presence != NULL, FALSE); | |
1535 g_return_val_if_fail(status_id != NULL, FALSE); | |
1536 | |
1537 status = gaim_presence_get_status(presence, status_id); | |
1538 | |
1539 return (status != NULL && gaim_status_is_active(status)); | |
1540 } | |
1541 | |
1542 gboolean | |
1543 gaim_presence_is_status_primitive_active(const GaimPresence *presence, | |
1544 GaimStatusPrimitive primitive) | |
1545 { | |
1546 GaimStatus *status; | |
1547 GaimStatusType *status_type; | |
1548 | |
1549 g_return_val_if_fail(presence != NULL, FALSE); | |
1550 g_return_val_if_fail(primitive != GAIM_STATUS_UNSET, FALSE); | |
1551 | |
1552 status = gaim_presence_get_active_status(presence); | |
1553 status_type = gaim_status_get_type(status); | |
1554 | |
1555 if (gaim_status_type_get_primitive(status_type) == primitive) | |
1556 return TRUE; | |
6065 | 1557 |
1558 return FALSE; | |
1559 } | |
1560 | |
9949 | 1561 gboolean |
1562 gaim_presence_is_idle(const GaimPresence *presence) | |
6065 | 1563 { |
9949 | 1564 g_return_val_if_fail(presence != NULL, FALSE); |
1565 | |
11634 | 1566 return gaim_presence_is_online(presence) && presence->idle; |
6065 | 1567 } |
1568 | |
9949 | 1569 time_t |
1570 gaim_presence_get_idle_time(const GaimPresence *presence) | |
6065 | 1571 { |
9949 | 1572 g_return_val_if_fail(presence != NULL, 0); |
6065 | 1573 |
9949 | 1574 return presence->idle_time; |
1575 } | |
6065 | 1576 |
10567 | 1577 time_t |
1578 gaim_presence_get_login_time(const GaimPresence *presence) | |
1579 { | |
1580 g_return_val_if_fail(presence != NULL, 0); | |
1581 | |
11973 | 1582 return gaim_presence_is_online(presence) ? presence->login_time : 0; |
10567 | 1583 } |
1584 | |
9949 | 1585 gint |
1586 gaim_presence_compare(const GaimPresence *presence1, | |
1587 const GaimPresence *presence2) | |
6065 | 1588 { |
9949 | 1589 gboolean idle1, idle2; |
10860 | 1590 time_t idle_time_1, idle_time_2; |
9949 | 1591 int score1 = 0, score2 = 0; |
1592 const GList *l; | |
6065 | 1593 |
12164
281ab2ecc08c
[gaim-migrate @ 14465]
Richard Laager <rlaager@wiktel.com>
parents:
12145
diff
changeset
|
1594 if (presence1 == presence2) |
9949 | 1595 return 0; |
1596 else if (presence1 == NULL) | |
10151
d83e6f2125b1
[gaim-migrate @ 11228]
Christian Hammond <chipx86@chipx86.com>
parents:
10087
diff
changeset
|
1597 return 1; |
9949 | 1598 else if (presence2 == NULL) |
10151
d83e6f2125b1
[gaim-migrate @ 11228]
Christian Hammond <chipx86@chipx86.com>
parents:
10087
diff
changeset
|
1599 return -1; |
6065 | 1600 |
9949 | 1601 /* Compute the score of the first set of statuses. */ |
1602 for (l = gaim_presence_get_statuses(presence1); l != NULL; l = l->next) | |
1603 { | |
1604 GaimStatus *status = (GaimStatus *)l->data; | |
1605 GaimStatusType *type = gaim_status_get_type(status); | |
6065 | 1606 |
9949 | 1607 if (gaim_status_is_active(status)) |
1608 score1 += primitive_scores[gaim_status_type_get_primitive(type)]; | |
6065 | 1609 } |
12164
281ab2ecc08c
[gaim-migrate @ 14465]
Richard Laager <rlaager@wiktel.com>
parents:
12145
diff
changeset
|
1610 score1 += gaim_account_get_int(gaim_presence_get_account(presence1), "score", 0); |
6065 | 1611 |
9949 | 1612 /* Compute the score of the second set of statuses. */ |
10151
d83e6f2125b1
[gaim-migrate @ 11228]
Christian Hammond <chipx86@chipx86.com>
parents:
10087
diff
changeset
|
1613 for (l = gaim_presence_get_statuses(presence2); l != NULL; l = l->next) |
9949 | 1614 { |
1615 GaimStatus *status = (GaimStatus *)l->data; | |
1616 GaimStatusType *type = gaim_status_get_type(status); | |
6065 | 1617 |
9949 | 1618 if (gaim_status_is_active(status)) |
1619 score2 += primitive_scores[gaim_status_type_get_primitive(type)]; | |
6065 | 1620 } |
12164
281ab2ecc08c
[gaim-migrate @ 14465]
Richard Laager <rlaager@wiktel.com>
parents:
12145
diff
changeset
|
1621 score2 += gaim_account_get_int(gaim_presence_get_account(presence2), "score", 0); |
6065 | 1622 |
9949 | 1623 idle1 = gaim_presence_is_idle(presence1); |
1624 idle2 = gaim_presence_is_idle(presence2); | |
6065 | 1625 |
9949 | 1626 if (idle1) |
1627 score1 += primitive_scores[SCORE_IDLE]; | |
6065 | 1628 |
9949 | 1629 if (idle2) |
1630 score2 += primitive_scores[SCORE_IDLE]; | |
6065 | 1631 |
10860 | 1632 idle_time_1 = time(NULL) - gaim_presence_get_idle_time(presence1); |
1633 idle_time_2 = time(NULL) - gaim_presence_get_idle_time(presence2); | |
6065 | 1634 |
9949 | 1635 if (idle_time_1 > idle_time_2) |
1636 score1 += primitive_scores[SCORE_IDLE_TIME]; | |
1637 else if (idle_time_1 < idle_time_2) | |
1638 score2 += primitive_scores[SCORE_IDLE_TIME]; | |
6065 | 1639 |
9949 | 1640 if (score1 < score2) |
1641 return 1; | |
1642 else if (score1 > score2) | |
1643 return -1; | |
1644 | |
1645 return 0; | |
1646 } | |
1647 | |
6065 | 1648 |
9949 | 1649 /************************************************************************** |
1650 * Status subsystem | |
1651 **************************************************************************/ | |
1652 static void | |
1653 score_pref_changed_cb(const char *name, GaimPrefType type, gpointer value, | |
1654 gpointer data) | |
1655 { | |
1656 int index = GPOINTER_TO_INT(data); | |
6065 | 1657 |
9949 | 1658 primitive_scores[index] = GPOINTER_TO_INT(value); |
6065 | 1659 } |
1660 | |
10519 | 1661 static guint |
10006 | 1662 gaim_buddy_presences_hash(gconstpointer key) |
1663 { | |
10012 | 1664 const GaimStatusBuddyKey *me = key; |
1665 guint ret; | |
1666 char *str; | |
1667 | |
1668 str = g_strdup_printf("%p%s", me->account, me->name); | |
1669 ret = g_str_hash(str); | |
1670 g_free(str); | |
1671 | |
1672 return ret; | |
10006 | 1673 } |
1674 | |
10519 | 1675 static gboolean |
10006 | 1676 gaim_buddy_presences_equal(gconstpointer a, gconstpointer b) |
1677 { | |
1678 GaimStatusBuddyKey *key_a = (GaimStatusBuddyKey *)a; | |
1679 GaimStatusBuddyKey *key_b = (GaimStatusBuddyKey *)b; | |
1680 | |
10012 | 1681 if(key_a->account == key_b->account && |
1682 !strcmp(key_a->name, key_b->name)) | |
10006 | 1683 return TRUE; |
1684 else | |
1685 return FALSE; | |
1686 } | |
1687 | |
10519 | 1688 static void |
1689 gaim_buddy_presences_key_free(gpointer a) | |
1690 { | |
1691 GaimStatusBuddyKey *key = (GaimStatusBuddyKey *)a; | |
1692 g_free(key->name); | |
1693 g_free(key); | |
1694 } | |
1695 | |
10087 | 1696 void * |
10418 | 1697 gaim_status_get_handle(void) { |
10087 | 1698 static int handle; |
1699 | |
1700 return &handle; | |
1701 } | |
1702 | |
9949 | 1703 void |
10418 | 1704 gaim_status_init(void) |
6065 | 1705 { |
10418 | 1706 void *handle = gaim_status_get_handle; |
10087 | 1707 |
9949 | 1708 gaim_prefs_add_none("/core/status"); |
1709 gaim_prefs_add_none("/core/status/scores"); | |
6065 | 1710 |
9949 | 1711 gaim_prefs_add_int("/core/status/scores/offline", |
1712 primitive_scores[GAIM_STATUS_OFFLINE]); | |
1713 gaim_prefs_add_int("/core/status/scores/available", | |
1714 primitive_scores[GAIM_STATUS_AVAILABLE]); | |
12595
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
1715 gaim_prefs_add_int("/core/status/scores/invisible", |
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
1716 primitive_scores[GAIM_STATUS_INVISIBLE]); |
9949 | 1717 gaim_prefs_add_int("/core/status/scores/away", |
1718 primitive_scores[GAIM_STATUS_AWAY]); | |
1719 gaim_prefs_add_int("/core/status/scores/extended_away", | |
1720 primitive_scores[GAIM_STATUS_EXTENDED_AWAY]); | |
1721 gaim_prefs_add_int("/core/status/scores/idle", | |
1722 primitive_scores[SCORE_IDLE]); | |
6065 | 1723 |
10087 | 1724 gaim_prefs_connect_callback(handle, "/core/status/scores/offline", |
9949 | 1725 score_pref_changed_cb, |
1726 GINT_TO_POINTER(GAIM_STATUS_OFFLINE)); | |
10087 | 1727 gaim_prefs_connect_callback(handle, "/core/status/scores/available", |
9949 | 1728 score_pref_changed_cb, |
1729 GINT_TO_POINTER(GAIM_STATUS_AVAILABLE)); | |
12595
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
1730 gaim_prefs_connect_callback(handle, "/core/status/scores/invisible", |
9949 | 1731 score_pref_changed_cb, |
12595
3169cd6727ad
[gaim-migrate @ 14925]
Richard Laager <rlaager@wiktel.com>
parents:
12587
diff
changeset
|
1732 GINT_TO_POINTER(GAIM_STATUS_INVISIBLE)); |
10087 | 1733 gaim_prefs_connect_callback(handle, "/core/status/scores/away", |
9949 | 1734 score_pref_changed_cb, |
1735 GINT_TO_POINTER(GAIM_STATUS_AWAY)); | |
10087 | 1736 gaim_prefs_connect_callback(handle, "/core/status/scores/extended_away", |
9949 | 1737 score_pref_changed_cb, |
1738 GINT_TO_POINTER(GAIM_STATUS_EXTENDED_AWAY)); | |
10087 | 1739 gaim_prefs_connect_callback(handle, "/core/status/scores/idle", |
9949 | 1740 score_pref_changed_cb, |
1741 GINT_TO_POINTER(SCORE_IDLE)); | |
10006 | 1742 |
10519 | 1743 buddy_presences = g_hash_table_new_full(gaim_buddy_presences_hash, |
1744 gaim_buddy_presences_equal, | |
1745 gaim_buddy_presences_key_free, NULL); | |
9949 | 1746 } |
6065 | 1747 |
9949 | 1748 void |
10418 | 1749 gaim_status_uninit(void) |
9949 | 1750 { |
10176
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
1751 if (buddy_presences != NULL) |
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
1752 { |
10077 | 1753 g_hash_table_destroy(buddy_presences); |
10176
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
1754 |
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
1755 buddy_presences = NULL; |
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
1756 } |
9949 | 1757 } |