Mercurial > pidgin.yaz
annotate src/status.c @ 10343:ee4f477fc8cf
[gaim-migrate @ 11553]
Minor tweaks to the blist and status xml reading code. These functions
don't expect the filename to be called "blist.xml" and "status.xml"
anymore. Some guy wanted this because he wants to try to add some
sort of AIM buddy list importing, or something. I think.
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Fri, 10 Dec 2004 05:49:01 +0000 |
parents | 84d73473c019 |
children | 64bc206c7473 |
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" |
28 #include "debug.h" | |
10337 | 29 #include "notify.h" |
9949 | 30 #include "prefs.h" |
6065 | 31 #include "status.h" |
32 #include "util.h" | |
10337 | 33 #include "xmlnode.h" |
6065 | 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; | |
10006 | 72 time_t login_time; |
9949 | 73 |
74 unsigned int warning_level; | |
6065 | 75 |
9949 | 76 GList *statuses; |
77 GHashTable *status_table; | |
78 | |
79 GaimStatus *active_status; | |
6065 | 80 |
9949 | 81 union |
82 { | |
83 GaimAccount *account; | |
84 | |
85 struct | |
86 { | |
87 GaimConversation *conv; | |
88 char *user; | |
89 | |
90 } chat; | |
6065 | 91 |
9949 | 92 struct |
93 { | |
94 GaimAccount *account; | |
95 char *name; | |
96 size_t ref_count; | |
97 GList *buddies; | |
98 | |
99 } buddy; | |
100 | |
101 } u; | |
102 }; | |
103 | |
104 /** | |
105 * An active status. | |
106 */ | |
107 struct _GaimStatus | |
6065 | 108 { |
9949 | 109 GaimStatusType *type; |
110 GaimPresence *presence; | |
111 | |
112 const char *title; | |
6065 | 113 |
9949 | 114 gboolean active; |
6065 | 115 |
9949 | 116 GHashTable *attr_values; |
117 }; | |
6065 | 118 |
119 typedef struct | |
120 { | |
9949 | 121 GaimAccount *account; |
122 char *name; | |
123 } GaimStatusBuddyKey; | |
124 | |
10337 | 125 /** |
126 * The information of a snap-shot of the statuses of all | |
127 * your accounts. Basically these are your saved away messages. | |
128 * There is an overall status and message that applies to | |
129 * all your accounts, and then each individual account can | |
130 * optionally have a different custom status and message. | |
9949 | 131 * |
10337 | 132 * The changes to status.xml caused by the new status API |
133 * are fully backward compatible. The new status API just | |
134 * adds the optional sub-statuses to the XML file. | |
9949 | 135 */ |
10337 | 136 struct _GaimStatusSaved |
9949 | 137 { |
138 char *name; | |
10337 | 139 GaimStatusType *type; |
9949 | 140 char *message; |
141 | |
10337 | 142 GList *individual; /**< A list of GaimStatusSavedSub's. */ |
143 }; | |
9949 | 144 |
10337 | 145 struct _GaimStatusSavedSub |
146 { | |
147 GaimAccount *account; | |
148 GaimStatusType *type; | |
149 char *message; | |
150 }; | |
9949 | 151 |
152 static int primitive_scores[] = | |
153 { | |
154 0, /* unset */ | |
155 -500, /* offline */ | |
156 0, /* online */ | |
157 100, /* available */ | |
158 -75, /* unavailable */ | |
159 -50, /* hidden */ | |
160 -100, /* away */ | |
161 -200 /* extended away */ | |
162 -10, /* idle, special case. */ | |
163 -5 /* idle time, special case. */ | |
164 }; | |
165 | |
166 static GHashTable *buddy_presences = NULL; | |
10337 | 167 static GList *saved_statuses = NULL; |
9949 | 168 |
169 #define SCORE_IDLE 5 | |
170 #define SCORE_IDLE_TIME 6 | |
171 | |
172 /************************************************************************** | |
173 * GaimStatusType API | |
174 **************************************************************************/ | |
175 GaimStatusType * | |
176 gaim_status_type_new_full(GaimStatusPrimitive primitive, const char *id, | |
10009 | 177 const char *name, gboolean saveable, |
178 gboolean user_settable, gboolean independent) | |
9949 | 179 { |
180 GaimStatusType *status_type; | |
181 | |
182 g_return_val_if_fail(primitive != GAIM_STATUS_UNSET, NULL); | |
183 g_return_val_if_fail(id != NULL, NULL); | |
184 g_return_val_if_fail(name != NULL, NULL); | |
185 | |
186 status_type = g_new0(GaimStatusType, 1); | |
187 | |
188 status_type->primitive = primitive; | |
189 status_type->id = g_strdup(id); | |
190 status_type->name = g_strdup(name); | |
191 status_type->saveable = saveable; | |
192 status_type->user_settable = user_settable; | |
193 status_type->independent = independent; | |
194 | |
195 return status_type; | |
196 } | |
197 | |
198 GaimStatusType * | |
199 gaim_status_type_new(GaimStatusPrimitive primitive, const char *id, | |
10009 | 200 const char *name, gboolean user_settable) |
9949 | 201 { |
202 g_return_val_if_fail(primitive != GAIM_STATUS_UNSET, NULL); | |
203 g_return_val_if_fail(id != NULL, NULL); | |
204 g_return_val_if_fail(name != NULL, NULL); | |
205 | |
206 return gaim_status_type_new_full(primitive, id, name, FALSE, | |
207 user_settable, FALSE); | |
208 } | |
209 | |
210 GaimStatusType * | |
211 gaim_status_type_new_with_attrs(GaimStatusPrimitive primitive, | |
212 const char *id, const char *name, | |
213 gboolean saveable, gboolean user_settable, | |
214 gboolean independent, const char *attr_id, | |
215 const char *attr_name, GaimValue *attr_value, | |
216 ...) | |
217 { | |
218 GaimStatusType *status_type; | |
219 va_list args; | |
220 | |
221 g_return_val_if_fail(primitive != GAIM_STATUS_UNSET, NULL); | |
222 g_return_val_if_fail(id != NULL, NULL); | |
223 g_return_val_if_fail(name != NULL, NULL); | |
10012 | 224 g_return_val_if_fail(attr_id != NULL, NULL); |
9949 | 225 g_return_val_if_fail(attr_name != NULL, NULL); |
226 g_return_val_if_fail(attr_value != NULL, NULL); | |
227 | |
228 status_type = gaim_status_type_new_full(primitive, id, name, saveable, | |
229 user_settable, independent); | |
230 | |
10010 | 231 /* Add the first attribute */ |
9949 | 232 gaim_status_type_add_attr(status_type, attr_id, attr_name, attr_value); |
233 | |
234 va_start(args, attr_value); | |
235 gaim_status_type_add_attrs_vargs(status_type, args); | |
236 va_end(args); | |
237 | |
238 return status_type; | |
239 } | |
240 | |
241 void | |
242 gaim_status_type_destroy(GaimStatusType *status_type) | |
243 { | |
244 GList *l; | |
245 | |
246 g_return_if_fail(status_type != NULL); | |
247 | |
248 g_free(status_type->id); | |
249 g_free(status_type->name); | |
250 | |
251 if (status_type->primary_attr_id != NULL) | |
252 g_free(status_type->primary_attr_id); | |
253 | |
254 if (status_type->attrs != NULL) | |
255 { | |
256 for (l = status_type->attrs; l != NULL; l = l->next) | |
257 gaim_status_attr_destroy((GaimStatusAttr *)l->data); | |
258 | |
259 g_list_free(status_type->attrs); | |
260 } | |
261 | |
262 g_free(status_type); | |
263 } | |
264 | |
265 void | |
266 gaim_status_type_set_primary_attr(GaimStatusType *status_type, const char *id) | |
267 { | |
268 g_return_if_fail(status_type != NULL); | |
269 | |
270 if (status_type->primary_attr_id != NULL) | |
271 g_free(status_type->primary_attr_id); | |
272 | |
273 status_type->primary_attr_id = (id == NULL ? NULL : g_strdup(id)); | |
274 } | |
275 | |
276 void | |
10197 | 277 gaim_status_type_add_attr(GaimStatusType *status_type, const char *id, |
9949 | 278 const char *name, GaimValue *value) |
279 { | |
280 GaimStatusAttr *attr; | |
281 | |
282 g_return_if_fail(status_type != NULL); | |
283 g_return_if_fail(id != NULL); | |
284 g_return_if_fail(name != NULL); | |
285 g_return_if_fail(value != NULL); | |
286 | |
287 attr = gaim_status_attr_new(id, name, value); | |
288 | |
289 status_type->attrs = g_list_append(status_type->attrs, attr); | |
290 } | |
291 | |
292 void | |
293 gaim_status_type_add_attrs_vargs(GaimStatusType *status_type, va_list args) | |
294 { | |
295 const char *id, *name; | |
296 GaimValue *value; | |
297 | |
298 g_return_if_fail(status_type != NULL); | |
299 | |
300 while ((id = va_arg(args, const char *)) != NULL) | |
301 { | |
302 name = va_arg(args, const char *); | |
303 g_return_if_fail(name != NULL); | |
304 | |
305 value = va_arg(args, GaimValue *); | |
306 g_return_if_fail(value != NULL); | |
6065 | 307 |
9949 | 308 gaim_status_type_add_attr(status_type, id, name, value); |
309 } | |
310 } | |
311 | |
10010 | 312 void |
313 gaim_status_type_add_attrs(GaimStatusType *status_type, const char *id, | |
314 const char *name, GaimValue *value, ...) | |
315 { | |
316 va_list args; | |
317 | |
318 g_return_if_fail(status_type != NULL); | |
319 g_return_if_fail(id != NULL); | |
320 g_return_if_fail(name != NULL); | |
321 g_return_if_fail(value != NULL); | |
322 | |
323 /* Add the first attribute */ | |
324 gaim_status_type_add_attr(status_type, id, name, value); | |
325 | |
326 va_start(args, value); | |
327 gaim_status_type_add_attrs_vargs(status_type, args); | |
328 va_end(args); | |
329 } | |
330 | |
9949 | 331 GaimStatusPrimitive |
332 gaim_status_type_get_primitive(const GaimStatusType *status_type) | |
333 { | |
334 g_return_val_if_fail(status_type != NULL, GAIM_STATUS_UNSET); | |
335 | |
336 return status_type->primitive; | |
337 } | |
338 | |
339 const char * | |
340 gaim_status_type_get_id(const GaimStatusType *status_type) | |
341 { | |
342 g_return_val_if_fail(status_type != NULL, NULL); | |
343 | |
344 return status_type->id; | |
345 } | |
346 | |
347 const char * | |
348 gaim_status_type_get_name(const GaimStatusType *status_type) | |
349 { | |
350 g_return_val_if_fail(status_type != NULL, NULL); | |
351 | |
352 return status_type->name; | |
353 } | |
354 | |
355 gboolean | |
356 gaim_status_type_is_saveable(const GaimStatusType *status_type) | |
357 { | |
358 g_return_val_if_fail(status_type != NULL, FALSE); | |
359 | |
360 return status_type->saveable; | |
361 } | |
362 | |
363 gboolean | |
364 gaim_status_type_is_user_settable(const GaimStatusType *status_type) | |
365 { | |
366 g_return_val_if_fail(status_type != NULL, FALSE); | |
367 | |
368 return status_type->user_settable; | |
369 } | |
370 | |
371 gboolean | |
372 gaim_status_type_is_independent(const GaimStatusType *status_type) | |
373 { | |
374 g_return_val_if_fail(status_type != NULL, FALSE); | |
375 | |
376 return status_type->independent; | |
377 } | |
378 | |
379 gboolean | |
10067 | 380 gaim_status_type_is_exclusive(const GaimStatusType *status_type) |
381 { | |
382 g_return_val_if_fail(status_type != NULL, FALSE); | |
383 | |
384 return !status_type->independent; | |
385 } | |
386 | |
387 gboolean | |
9949 | 388 gaim_status_type_is_available(const GaimStatusType *status_type) |
389 { | |
390 GaimStatusPrimitive primitive; | |
391 | |
392 g_return_val_if_fail(status_type != NULL, FALSE); | |
393 | |
394 primitive = gaim_status_type_get_primitive(status_type); | |
395 | |
396 return (primitive == GAIM_STATUS_AVAILABLE || | |
397 primitive == GAIM_STATUS_HIDDEN); | |
398 } | |
399 | |
400 const char * | |
401 gaim_status_type_get_primary_attr(const GaimStatusType *status_type) | |
402 { | |
403 g_return_val_if_fail(status_type != NULL, NULL); | |
404 | |
405 return status_type->primary_attr_id; | |
406 } | |
407 | |
408 GaimStatusAttr * | |
409 gaim_status_type_get_attr(const GaimStatusType *status_type, const char *id) | |
410 { | |
411 GList *l; | |
412 | |
413 g_return_val_if_fail(status_type != NULL, NULL); | |
414 g_return_val_if_fail(id != NULL, NULL); | |
415 | |
416 for (l = status_type->attrs; l != NULL; l = l->next) | |
417 { | |
418 GaimStatusAttr *attr = (GaimStatusAttr *)l->data; | |
419 | |
420 if (!strcmp(gaim_status_attr_get_id(attr), id)) | |
421 return attr; | |
422 } | |
423 | |
424 return NULL; | |
425 } | |
426 | |
427 const GList * | |
428 gaim_status_type_get_attrs(const GaimStatusType *status_type) | |
429 { | |
430 g_return_val_if_fail(status_type != NULL, NULL); | |
431 | |
432 return status_type->attrs; | |
433 } | |
434 | |
435 | |
436 /************************************************************************** | |
437 * GaimStatusAttr API | |
438 **************************************************************************/ | |
439 GaimStatusAttr * | |
440 gaim_status_attr_new(const char *id, const char *name, GaimValue *value_type) | |
441 { | |
442 GaimStatusAttr *attr; | |
443 | |
444 g_return_val_if_fail(id != NULL, NULL); | |
445 g_return_val_if_fail(name != NULL, NULL); | |
446 g_return_val_if_fail(value_type != NULL, NULL); | |
447 | |
448 attr = g_new0(GaimStatusAttr, 1); | |
449 | |
450 attr->id = g_strdup(id); | |
451 attr->name = g_strdup(name); | |
452 attr->value_type = value_type; | |
453 | |
454 return attr; | |
455 } | |
456 | |
457 void | |
458 gaim_status_attr_destroy(GaimStatusAttr *attr) | |
459 { | |
460 g_return_if_fail(attr != NULL); | |
461 | |
462 g_free(attr->id); | |
463 g_free(attr->name); | |
464 | |
465 gaim_value_destroy(attr->value_type); | |
466 | |
467 g_free(attr); | |
468 } | |
469 | |
470 const char * | |
471 gaim_status_attr_get_id(const GaimStatusAttr *attr) | |
472 { | |
473 g_return_val_if_fail(attr != NULL, NULL); | |
474 | |
475 return attr->id; | |
476 } | |
477 | |
478 const char * | |
479 gaim_status_attr_get_name(const GaimStatusAttr *attr) | |
480 { | |
481 g_return_val_if_fail(attr != NULL, NULL); | |
482 | |
483 return attr->name; | |
484 } | |
485 | |
486 GaimValue * | |
487 gaim_status_attr_get_value_type(const GaimStatusAttr *attr) | |
488 { | |
489 g_return_val_if_fail(attr != NULL, NULL); | |
490 | |
491 return attr->value_type; | |
492 } | |
493 | |
494 | |
495 /************************************************************************** | |
496 * GaimStatus API | |
497 **************************************************************************/ | |
498 GaimStatus * | |
499 gaim_status_new(GaimStatusType *status_type, GaimPresence *presence) | |
500 { | |
501 GaimStatus *status; | |
502 const GList *l; | |
503 | |
504 g_return_val_if_fail(status_type != NULL, NULL); | |
505 g_return_val_if_fail(presence != NULL, NULL); | |
506 | |
507 status = g_new0(GaimStatus, 1); | |
508 | |
509 status->type = status_type; | |
510 status->presence = presence; | |
511 | |
512 status->attr_values = | |
513 g_hash_table_new_full(g_str_hash, g_str_equal, g_free, | |
514 (GDestroyNotify)gaim_value_destroy); | |
515 | |
516 for (l = gaim_status_type_get_attrs(status_type); l != NULL; l = l->next) | |
517 { | |
518 GaimStatusAttr *attr = (GaimStatusAttr *)l->data; | |
519 GaimValue *value = gaim_status_attr_get_value_type(attr); | |
520 GaimValue *new_value = gaim_value_dup(value); | |
521 | |
522 g_hash_table_insert(status->attr_values, | |
10197 | 523 g_strdup(gaim_status_attr_get_id(attr)), |
524 new_value); | |
9949 | 525 } |
526 | |
527 return status; | |
528 } | |
529 | |
530 void | |
531 gaim_status_destroy(GaimStatus *status) | |
532 { | |
533 g_return_if_fail(status != NULL); | |
534 | |
535 gaim_status_set_active(status, FALSE); | |
536 | |
537 g_hash_table_destroy(status->attr_values); | |
538 | |
539 g_free(status); | |
540 } | |
6065 | 541 |
542 static void | |
9949 | 543 notify_buddy_status_update(GaimBuddy *buddy, GaimPresence *presence, |
544 GaimStatus *old_status, GaimStatus *new_status) | |
545 { | |
546 GaimBlistUiOps *ops = gaim_blist_get_ui_ops(); | |
547 | |
548 if (gaim_prefs_get_bool("/core/logging/log_system") && | |
549 gaim_prefs_get_bool("/core/logging/log_away_state")) | |
550 { | |
551 time_t current_time = time(NULL); | |
552 const char *buddy_alias = gaim_buddy_get_alias(buddy); | |
553 char *tmp = NULL; | |
554 | |
555 if (!gaim_status_is_available(old_status) && | |
556 gaim_status_is_available(new_status)) | |
557 { | |
558 tmp = g_strdup_printf(_("%s came back"), buddy_alias); | |
559 } | |
560 else if (gaim_status_is_available(old_status) && | |
561 !gaim_status_is_available(new_status)) | |
562 { | |
563 tmp = g_strdup_printf(_("%s went away"), buddy_alias); | |
564 } | |
565 | |
566 if (tmp != NULL) | |
567 { | |
568 GaimLog *log = gaim_account_get_log(buddy->account); | |
569 | |
570 gaim_log_write(log, GAIM_MESSAGE_SYSTEM, buddy_alias, | |
571 current_time, tmp); | |
572 g_free(tmp); | |
573 } | |
574 } | |
575 | |
10012 | 576 |
577 | |
578 if (ops != NULL && ops->update != NULL) | |
579 ops->update(gaim_get_blist(), (GaimBlistNode*)buddy); | |
9949 | 580 } |
581 | |
582 static void | |
583 notify_status_update(GaimPresence *presence, GaimStatus *old_status, | |
10176
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
584 GaimStatus *new_status) |
6065 | 585 { |
9949 | 586 GaimPresenceContext context = gaim_presence_get_context(presence); |
587 | |
588 if (context == GAIM_PRESENCE_CONTEXT_ACCOUNT) | |
589 { | |
10176
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
590 GaimAccount *account = gaim_presence_get_account(presence); |
9949 | 591 GaimAccountUiOps *ops = gaim_accounts_get_ui_ops(); |
592 | |
10176
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
593 if (gaim_account_is_connected(account)) |
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
594 { |
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
595 GaimPluginProtocolInfo *prpl_info = NULL; |
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
596 GaimPlugin *prpl; |
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
597 |
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
598 prpl = gaim_find_prpl(gaim_account_get_protocol_id(account)); |
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
599 |
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
600 if (prpl != NULL) |
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
601 { |
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
602 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(prpl); |
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
603 |
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
604 if (prpl_info != NULL && prpl_info->set_status != NULL) |
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
605 prpl_info->set_status(account, new_status); |
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
606 } |
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
607 } |
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
608 |
9949 | 609 if (ops != NULL && ops->status_changed != NULL) |
610 { | |
10176
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
611 ops->status_changed(account, new_status); |
9949 | 612 } |
613 } | |
614 else if (context == GAIM_PRESENCE_CONTEXT_CONV) | |
615 { | |
616 /* TODO */ | |
617 #if 0 | |
618 GaimConversationUiOps *ops; | |
619 GaimConversation *conv; | |
620 | |
621 conv = gaim_status_get_conversation(new_status); | |
622 #endif | |
623 } | |
624 else if (context == GAIM_PRESENCE_CONTEXT_BUDDY) | |
625 { | |
626 const GList *l; | |
627 | |
628 for (l = gaim_presence_get_buddies(presence); l != NULL; l = l->next) | |
629 { | |
630 notify_buddy_status_update((GaimBuddy *)l->data, presence, | |
631 old_status, new_status); | |
632 } | |
633 } | |
634 } | |
635 | |
10204 | 636 static void |
637 status_has_changed(GaimStatus *status) | |
9949 | 638 { |
639 GaimPresence *presence; | |
640 GaimStatus *old_status; | |
641 | |
642 presence = gaim_status_get_presence(status); | |
643 old_status = gaim_presence_get_active_status(presence); | |
644 | |
10204 | 645 /* |
646 * If this status is exclusive, then we must be setting it to "active." | |
647 * Since we are setting it to active, we want to set the currently | |
648 * active status to "inactive." | |
649 */ | |
650 if (gaim_status_is_exclusive(status)) | |
9949 | 651 { |
652 const GList *l; | |
653 | |
10006 | 654 for (l = gaim_presence_get_statuses(presence); l != NULL; l = l->next) |
9949 | 655 { |
10056
b566449d45f8
[gaim-migrate @ 11021]
Luke Schierer <lschiere@pidgin.im>
parents:
10052
diff
changeset
|
656 GaimStatus *temp_status = l->data; |
9949 | 657 |
10204 | 658 if (temp_status == status) |
659 continue; | |
9949 | 660 |
10204 | 661 if (gaim_status_is_independent(temp_status)) |
9949 | 662 continue; |
663 | |
664 if (gaim_status_is_active(temp_status)) | |
665 { | |
666 /* | |
10204 | 667 * Since we don't want infinite recursion, we have to set |
668 * the active variable ourself instead of calling | |
669 * gaim_status_set_active(). | |
9949 | 670 */ |
671 temp_status->active = FALSE; | |
672 | |
673 notify_status_update(presence, old_status, temp_status); | |
674 | |
675 break; | |
676 } | |
677 } | |
678 } | |
679 | |
10204 | 680 notify_status_update(presence, old_status, status); |
681 } | |
682 | |
683 void | |
684 gaim_status_set_active(GaimStatus *status, gboolean active) | |
685 { | |
686 if (!active && gaim_status_is_exclusive(status)) | |
687 { | |
688 gaim_debug_error("status", | |
689 "Cannot deactivate an exclusive status (%s).\n", | |
690 gaim_status_get_id(status)); | |
691 return; | |
692 } | |
693 | |
694 g_return_if_fail(status != NULL); | |
695 | |
696 if (status->active == active) | |
697 return; | |
698 | |
699 status->active = active; | |
700 | |
701 status_has_changed(status); | |
702 } | |
703 | |
704 void | |
705 gaim_status_set_active_with_attrs(GaimStatus *status, gboolean active, va_list args) | |
706 { | |
707 gboolean changed = FALSE; | |
708 const gchar *id; | |
709 | |
710 if (!active && gaim_status_is_exclusive(status)) | |
711 { | |
712 gaim_debug_error("status", | |
713 "Cannot deactivate an exclusive status (%s).\n", | |
714 gaim_status_get_id(status)); | |
715 return; | |
716 } | |
717 | |
718 g_return_if_fail(status != NULL); | |
719 | |
720 if (status->active != active) | |
721 changed = TRUE; | |
722 | |
9949 | 723 status->active = active; |
6065 | 724 |
10204 | 725 /* Set any attributes */ |
726 while ((id = va_arg(args, const char *)) != NULL) | |
727 { | |
728 GaimValue *value; | |
729 value = gaim_status_get_attr_value(status, id); | |
730 if (value->type == GAIM_TYPE_STRING) | |
731 { | |
732 const gchar *string_data = va_arg(args, const char *); | |
733 if (((string_data == NULL) && (value->data.string_data == NULL)) || | |
734 ((string_data != NULL) && (value->data.string_data != NULL) && | |
735 !strcmp(string_data, value->data.string_data))) | |
736 { | |
737 continue; | |
738 } | |
739 gaim_status_set_attr_string(status, id, string_data); | |
740 changed = TRUE; | |
741 } | |
742 else if (value->type == GAIM_TYPE_INT) | |
743 { | |
744 int int_data = va_arg(args, int); | |
745 if (int_data == value->data.int_data) | |
746 continue; | |
747 gaim_status_set_attr_int(status, id, int_data); | |
748 changed = TRUE; | |
749 } | |
750 else if (value->type == GAIM_TYPE_BOOLEAN) | |
751 { | |
752 gboolean boolean_data = va_arg(args, gboolean); | |
753 if (boolean_data == value->data.boolean_data) | |
754 continue; | |
755 gaim_status_set_attr_int(status, id, boolean_data); | |
756 changed = TRUE; | |
757 } | |
758 else | |
759 { | |
760 /* We don't know what the data is--skip over it */ | |
761 va_arg(args, void *); | |
762 } | |
763 } | |
764 | |
765 if (!changed) | |
766 return; | |
767 | |
768 status_has_changed(status); | |
9949 | 769 } |
770 | |
771 void | |
772 gaim_status_set_attr_boolean(GaimStatus *status, const char *id, | |
773 gboolean value) | |
774 { | |
775 GaimStatusType *status_type; | |
776 GaimValue *attr_value; | |
777 | |
778 g_return_if_fail(status != NULL); | |
779 g_return_if_fail(id != NULL); | |
780 | |
781 status_type = gaim_status_get_type(status); | |
782 | |
10197 | 783 /* Make sure this attribute exists and is the correct type. */ |
784 attr_value = gaim_status_get_attr_value(status, id); | |
785 g_return_if_fail(attr_value != NULL); | |
9949 | 786 g_return_if_fail(gaim_value_get_type(attr_value) == GAIM_TYPE_BOOLEAN); |
787 | |
788 gaim_value_set_boolean(attr_value, value); | |
789 } | |
790 | |
791 void | |
792 gaim_status_set_attr_int(GaimStatus *status, const char *id, int value) | |
793 { | |
794 GaimStatusType *status_type; | |
795 GaimValue *attr_value; | |
796 | |
797 g_return_if_fail(status != NULL); | |
798 g_return_if_fail(id != NULL); | |
799 | |
800 status_type = gaim_status_get_type(status); | |
801 | |
10197 | 802 /* Make sure this attribute exists and is the correct type. */ |
803 attr_value = gaim_status_get_attr_value(status, id); | |
804 g_return_if_fail(attr_value != NULL); | |
9949 | 805 g_return_if_fail(gaim_value_get_type(attr_value) == GAIM_TYPE_INT); |
806 | |
807 gaim_value_set_int(attr_value, value); | |
6065 | 808 } |
809 | |
9949 | 810 void |
811 gaim_status_set_attr_string(GaimStatus *status, const char *id, | |
812 const char *value) | |
813 { | |
814 GaimStatusType *status_type; | |
815 GaimValue *attr_value; | |
816 | |
817 g_return_if_fail(status != NULL); | |
818 g_return_if_fail(id != NULL); | |
819 | |
820 status_type = gaim_status_get_type(status); | |
821 | |
10197 | 822 /* Make sure this attribute exists and is the correct type. */ |
10196 | 823 attr_value = gaim_status_get_attr_value(status, id); |
10197 | 824 g_return_if_fail(attr_value != NULL); |
9949 | 825 g_return_if_fail(gaim_value_get_type(attr_value) == GAIM_TYPE_STRING); |
826 | |
827 gaim_value_set_string(attr_value, value); | |
828 } | |
829 | |
830 GaimStatusType * | |
831 gaim_status_get_type(const GaimStatus *status) | |
832 { | |
833 g_return_val_if_fail(status != NULL, NULL); | |
834 | |
835 return status->type; | |
836 } | |
837 | |
838 GaimPresence * | |
839 gaim_status_get_presence(const GaimStatus *status) | |
6065 | 840 { |
9949 | 841 g_return_val_if_fail(status != NULL, NULL); |
842 | |
843 return status->presence; | |
844 } | |
845 | |
846 const char * | |
847 gaim_status_get_id(const GaimStatus *status) | |
848 { | |
849 g_return_val_if_fail(status != NULL, NULL); | |
850 | |
851 return gaim_status_type_get_id(gaim_status_get_type(status)); | |
852 } | |
853 | |
854 const char * | |
855 gaim_status_get_name(const GaimStatus *status) | |
856 { | |
857 g_return_val_if_fail(status != NULL, NULL); | |
858 | |
859 return gaim_status_type_get_name(gaim_status_get_type(status)); | |
860 } | |
861 | |
862 gboolean | |
863 gaim_status_is_independent(const GaimStatus *status) | |
864 { | |
865 g_return_val_if_fail(status != NULL, FALSE); | |
866 | |
867 return gaim_status_type_is_independent(gaim_status_get_type(status)); | |
868 } | |
869 | |
870 gboolean | |
10067 | 871 gaim_status_is_exclusive(const GaimStatus *status) |
872 { | |
873 g_return_val_if_fail(status != NULL, FALSE); | |
874 | |
875 return gaim_status_type_is_exclusive(gaim_status_get_type(status)); | |
876 } | |
877 | |
878 gboolean | |
9949 | 879 gaim_status_is_available(const GaimStatus *status) |
880 { | |
881 g_return_val_if_fail(status != NULL, FALSE); | |
882 | |
883 return gaim_status_type_is_available(gaim_status_get_type(status)); | |
884 } | |
6216 | 885 |
9949 | 886 gboolean |
887 gaim_status_is_active(const GaimStatus *status) | |
888 { | |
889 g_return_val_if_fail(status != NULL, FALSE); | |
890 | |
891 return status->active; | |
892 } | |
893 | |
10040
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
894 gboolean |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
895 gaim_status_is_online(const GaimStatus *status) |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
896 { |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
897 GaimStatusPrimitive primitive; |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
898 |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
899 g_return_val_if_fail( status != NULL, FALSE); |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
900 |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
901 primitive = gaim_status_type_get_primitive(gaim_status_get_type(status)); |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
902 |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
903 return (primitive != GAIM_STATUS_UNSET && |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
904 primitive != GAIM_STATUS_OFFLINE); |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
905 } |
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
906 |
9949 | 907 GaimValue * |
908 gaim_status_get_attr_value(const GaimStatus *status, const char *id) | |
909 { | |
910 GaimStatusType *status_type; | |
911 GaimStatusAttr *attr; | |
912 | |
913 g_return_val_if_fail(status != NULL, NULL); | |
914 g_return_val_if_fail(id != NULL, NULL); | |
915 | |
916 status_type = gaim_status_get_type(status); | |
917 | |
918 /* Make sure this attribute exists. */ | |
919 attr = gaim_status_type_get_attr(status_type, id); | |
920 g_return_val_if_fail(attr != NULL, NULL); | |
921 | |
922 return (GaimValue *)g_hash_table_lookup(status->attr_values, id); | |
923 } | |
924 | |
925 gboolean | |
926 gaim_status_get_attr_boolean(const GaimStatus *status, const char *id) | |
927 { | |
928 const GaimValue *value; | |
929 | |
930 g_return_val_if_fail(status != NULL, FALSE); | |
931 g_return_val_if_fail(id != NULL, FALSE); | |
932 | |
933 if ((value = gaim_status_get_attr_value(status, id)) == NULL) | |
934 return FALSE; | |
935 | |
10197 | 936 g_return_val_if_fail(gaim_value_get_type(value) == GAIM_TYPE_BOOLEAN, FALSE); |
9949 | 937 |
938 return gaim_value_get_boolean(value); | |
939 } | |
940 | |
941 int | |
942 gaim_status_get_attr_int(const GaimStatus *status, const char *id) | |
943 { | |
944 const GaimValue *value; | |
945 | |
946 g_return_val_if_fail(status != NULL, FALSE); | |
947 g_return_val_if_fail(id != NULL, FALSE); | |
948 | |
949 if ((value = gaim_status_get_attr_value(status, id)) == NULL) | |
950 return FALSE; | |
951 | |
952 g_return_val_if_fail(gaim_value_get_type(value) == GAIM_TYPE_INT, 0); | |
953 | |
954 return gaim_value_get_int(value); | |
955 } | |
956 | |
957 const char * | |
958 gaim_status_get_attr_string(const GaimStatus *status, const char *id) | |
959 { | |
960 const GaimValue *value; | |
961 | |
962 g_return_val_if_fail(status != NULL, FALSE); | |
963 g_return_val_if_fail(id != NULL, FALSE); | |
964 | |
965 if ((value = gaim_status_get_attr_value(status, id)) == NULL) | |
966 return FALSE; | |
967 | |
968 g_return_val_if_fail(gaim_value_get_type(value) == GAIM_TYPE_STRING, NULL); | |
969 | |
970 return gaim_value_get_string(value); | |
971 } | |
972 | |
973 gint | |
974 gaim_status_compare(const GaimStatus *status1, const GaimStatus *status2) | |
975 { | |
976 GaimStatusType *type1, *type2; | |
977 int score1 = 0, score2 = 0; | |
6065 | 978 |
9949 | 979 if ((status1 == NULL && status2 == NULL) || |
980 (status1 == status2)) | |
981 { | |
982 return 0; | |
983 } | |
984 else if (status1 == NULL) | |
985 return 1; | |
986 else if (status2 == NULL) | |
987 return -1; | |
988 | |
989 type1 = gaim_status_get_type(status1); | |
990 type2 = gaim_status_get_type(status2); | |
991 | |
992 if (gaim_status_is_active(status1)) | |
993 score1 = primitive_scores[gaim_status_type_get_primitive(type1)]; | |
994 | |
995 if (gaim_status_is_active(status2)) | |
996 score2 = primitive_scores[gaim_status_type_get_primitive(type2)]; | |
997 | |
998 if (score1 > score2) | |
999 return -1; | |
1000 else if (score1 < score2) | |
1001 return 1; | |
1002 | |
1003 return 0; | |
1004 } | |
1005 | |
1006 | |
1007 /************************************************************************** | |
1008 * GaimPresence API | |
1009 **************************************************************************/ | |
1010 GaimPresence * | |
1011 gaim_presence_new(GaimPresenceContext context) | |
1012 { | |
1013 GaimPresence *presence; | |
1014 | |
1015 g_return_val_if_fail(context != GAIM_PRESENCE_CONTEXT_UNSET, NULL); | |
1016 | |
1017 presence = g_new0(GaimPresence, 1); | |
1018 | |
1019 presence->context = context; | |
1020 | |
1021 presence->status_table = | |
10009 | 1022 g_hash_table_new_full(g_str_hash, g_str_equal, |
1023 g_free, (GFreeFunc)gaim_status_destroy); | |
9949 | 1024 |
1025 return presence; | |
1026 } | |
1027 | |
1028 GaimPresence * | |
1029 gaim_presence_new_for_account(GaimAccount *account) | |
1030 { | |
10012 | 1031 GaimPresence *presence = NULL; |
9949 | 1032 g_return_val_if_fail(account != NULL, NULL); |
1033 | |
1034 presence = gaim_presence_new(GAIM_PRESENCE_CONTEXT_ACCOUNT); | |
1035 presence->u.account = account; | |
10006 | 1036 presence->statuses = gaim_prpl_get_statuses(account, presence); |
9949 | 1037 |
1038 return presence; | |
1039 } | |
1040 | |
1041 GaimPresence * | |
1042 gaim_presence_new_for_conv(GaimConversation *conv) | |
1043 { | |
1044 GaimPresence *presence; | |
1045 | |
1046 g_return_val_if_fail(conv != NULL, NULL); | |
1047 | |
1048 presence = gaim_presence_new(GAIM_PRESENCE_CONTEXT_CONV); | |
1049 presence->u.chat.conv = conv; | |
10006 | 1050 /* presence->statuses = gaim_prpl_get_statuses(conv->account, presence); ? */ |
9949 | 1051 |
1052 return presence; | |
1053 } | |
6216 | 1054 |
9949 | 1055 GaimPresence * |
1056 gaim_presence_new_for_buddy(GaimBuddy *buddy) | |
1057 { | |
1058 GaimPresence *presence; | |
1059 GaimStatusBuddyKey *key; | |
10006 | 1060 GaimAccount *account; |
9949 | 1061 |
1062 g_return_val_if_fail(buddy != NULL, NULL); | |
10012 | 1063 account = buddy->account; |
9949 | 1064 |
10006 | 1065 account = buddy->account; |
1066 | |
9949 | 1067 key = g_new0(GaimStatusBuddyKey, 1); |
1068 key->account = buddy->account; | |
1069 key->name = g_strdup(buddy->name); | |
10006 | 1070 |
1071 presence = g_hash_table_lookup(buddy_presences, key); | |
1072 if (presence == NULL) | |
9949 | 1073 { |
1074 presence = gaim_presence_new(GAIM_PRESENCE_CONTEXT_BUDDY); | |
1075 | |
1076 presence->u.buddy.name = g_strdup(buddy->name); | |
1077 presence->u.buddy.account = buddy->account; | |
10006 | 1078 presence->statuses = gaim_prpl_get_statuses(buddy->account, presence); |
9949 | 1079 |
1080 g_hash_table_insert(buddy_presences, key, presence); | |
1081 } | |
1082 else | |
1083 { | |
1084 g_free(key->name); | |
1085 g_free(key); | |
1086 } | |
1087 | |
1088 presence->u.buddy.ref_count++; | |
1089 presence->u.buddy.buddies = g_list_append(presence->u.buddy.buddies, | |
1090 buddy); | |
1091 | |
1092 return presence; | |
1093 } | |
1094 | |
1095 void | |
1096 gaim_presence_destroy(GaimPresence *presence) | |
1097 { | |
1098 g_return_if_fail(presence != NULL); | |
6216 | 1099 |
9949 | 1100 if (gaim_presence_get_context(presence) == GAIM_PRESENCE_CONTEXT_BUDDY) |
1101 { | |
1102 GaimStatusBuddyKey key; | |
1103 | |
1104 presence->u.buddy.ref_count--; | |
1105 | |
10077 | 1106 if(presence->u.buddy.ref_count != 0) |
1107 return; | |
9949 | 1108 |
1109 key.account = presence->u.buddy.account; | |
1110 key.name = presence->u.buddy.name; | |
1111 | |
1112 g_hash_table_remove(buddy_presences, &key); | |
1113 | |
1114 if (presence->u.buddy.name != NULL) | |
1115 g_free(presence->u.buddy.name); | |
1116 } | |
1117 else if (gaim_presence_get_context(presence) == GAIM_PRESENCE_CONTEXT_CONV) | |
1118 { | |
1119 if (presence->u.chat.user != NULL) | |
1120 g_free(presence->u.chat.user); | |
1121 } | |
1122 | |
1123 if (presence->statuses != NULL) | |
1124 g_list_free(presence->statuses); | |
1125 | |
1126 g_hash_table_destroy(presence->status_table); | |
1127 | |
1128 g_free(presence); | |
1129 } | |
1130 | |
1131 void | |
1132 gaim_presence_remove_buddy(GaimPresence *presence, GaimBuddy *buddy) | |
1133 { | |
1134 g_return_if_fail(presence != NULL); | |
1135 g_return_if_fail(buddy != NULL); | |
1136 g_return_if_fail(gaim_presence_get_context(presence) == | |
1137 GAIM_PRESENCE_CONTEXT_BUDDY); | |
1138 | |
1139 if (g_list_find(presence->u.buddy.buddies, buddy) != NULL) | |
1140 { | |
1141 presence->u.buddy.buddies = g_list_remove(presence->u.buddy.buddies, | |
1142 buddy); | |
1143 presence->u.buddy.ref_count--; | |
1144 } | |
6065 | 1145 } |
1146 | |
9949 | 1147 void |
1148 gaim_presence_add_status(GaimPresence *presence, GaimStatus *status) | |
1149 { | |
1150 g_return_if_fail(presence != NULL); | |
1151 g_return_if_fail(status != NULL); | |
1152 | |
1153 presence->statuses = g_list_append(presence->statuses, status); | |
1154 | |
1155 g_hash_table_insert(presence->status_table, | |
1156 g_strdup(gaim_status_get_id(status)), status); | |
1157 } | |
1158 | |
1159 void | |
1160 gaim_presence_add_presence(GaimPresence *presence, const GList *source_list) | |
1161 { | |
1162 const GList *l; | |
1163 | |
1164 g_return_if_fail(presence != NULL); | |
1165 g_return_if_fail(source_list != NULL); | |
1166 | |
1167 for (l = source_list; l != NULL; l = l->next) | |
1168 gaim_presence_add_status(presence, (GaimStatus *)l->data); | |
1169 } | |
1170 | |
10153 | 1171 /* |
1172 * TODO: Should we g_return_if_fail(active == status_id->active); ? | |
1173 * | |
1174 * TODO: If a buddy signed on or off, should we do any of the following? | |
1175 * (Note: We definitely need to do some of this somewhere, I'm just | |
1176 * not sure if here is the correct place.) | |
1177 * | |
1178 * char *tmp = g_strdup_printf(_("%s logged in."), alias); | |
1179 * gaim_conversation_write(c, NULL, tmp, GAIM_MESSAGE_SYSTEM, time(NULL)); | |
1180 * g_free(tmp); | |
1181 * | |
1182 * GaimLog *log = gaim_account_get_log(account); | |
1183 * char *tmp = g_strdup_printf(_("%s signed on"), alias); | |
1184 * gaim_log_write(log, GAIM_MESSAGE_SYSTEM, (alias ? alias : name), current_time, tmp); | |
1185 * g_free(tmp); | |
1186 * | |
1187 * char *tmp = g_strdup_printf(_("%s logged out."), alias); | |
1188 * gaim_conversation_write(c, NULL, tmp, GAIM_MESSAGE_SYSTEM, time(NULL)); | |
1189 * g_free(tmp); | |
1190 * | |
1191 * char *tmp = g_strdup_printf(_("%s signed off"), alias); | |
1192 * gaim_log_write(log, GAIM_MESSAGE_SYSTEM, (alias ? alias : name), current_time, tmp); | |
1193 * g_free(tmp); | |
1194 * | |
1195 * serv_got_typing_stopped(gc, name); | |
1196 * | |
1197 * gaim_conversation_update(c, GAIM_CONV_UPDATE_AWAY); | |
1198 * | |
1199 */ | |
9949 | 1200 void |
1201 gaim_presence_set_status_active(GaimPresence *presence, const char *status_id, | |
1202 gboolean active) | |
1203 { | |
1204 GaimStatus *status; | |
1205 | |
1206 g_return_if_fail(presence != NULL); | |
1207 g_return_if_fail(status_id != NULL); | |
1208 | |
1209 status = gaim_presence_get_status(presence, status_id); | |
1210 | |
1211 g_return_if_fail(status != NULL); | |
1212 | |
10067 | 1213 if (gaim_status_is_exclusive(status)) |
9949 | 1214 { |
1215 if (!active) | |
1216 { | |
1217 gaim_debug_warning("status", | |
1218 "Attempted to set a non-independent status " | |
1219 "(%s) inactive. Only independent statuses " | |
1220 "can be specifically marked inactive.", | |
1221 status_id); | |
1222 | |
1223 return; | |
1224 } | |
1225 | |
10052 | 1226 } else if (presence->active_status != NULL) { |
1227 gaim_status_set_active(presence->active_status, FALSE); | |
9949 | 1228 |
1229 } | |
1230 | |
1231 gaim_status_set_active(status, active); | |
10052 | 1232 presence->active_status = status; |
9949 | 1233 } |
1234 | |
1235 void | |
1236 gaim_presence_switch_status(GaimPresence *presence, const char *status_id) | |
1237 { | |
1238 GaimStatus *status; | |
1239 | |
1240 g_return_if_fail(presence != NULL); | |
1241 g_return_if_fail(status_id != NULL); | |
1242 | |
1243 status = gaim_presence_get_status(presence, status_id); | |
1244 | |
1245 g_return_if_fail(status != NULL); | |
1246 | |
1247 if (gaim_status_is_independent(status)) | |
1248 return; | |
1249 | |
1250 if (presence->active_status != NULL) | |
1251 gaim_status_set_active(presence->active_status, FALSE); | |
1252 | |
1253 gaim_status_set_active(status, TRUE); | |
1254 } | |
1255 | |
1256 static void | |
1257 update_buddy_idle(GaimBuddy *buddy, GaimPresence *presence, | |
1258 time_t current_time, gboolean old_idle, gboolean idle) | |
1259 { | |
1260 GaimBlistUiOps *ops = gaim_get_blist()->ui_ops; | |
1261 | |
1262 if (!old_idle && idle) | |
1263 { | |
1264 gaim_signal_emit(gaim_blist_get_handle(), "buddy-idle", buddy); | |
1265 | |
1266 if (gaim_prefs_get_bool("/core/logging/log_system") && | |
1267 gaim_prefs_get_bool("/core/logging/log_idle_state")) | |
1268 { | |
1269 GaimLog *log = gaim_account_get_log(buddy->account); | |
1270 char *tmp = g_strdup_printf(_("%s became idle"), | |
1271 gaim_buddy_get_alias(buddy)); | |
1272 | |
1273 gaim_log_write(log, GAIM_MESSAGE_SYSTEM, | |
1274 gaim_buddy_get_alias(buddy), current_time, tmp); | |
1275 g_free(tmp); | |
1276 } | |
1277 } | |
1278 else if (old_idle && !idle) | |
1279 { | |
1280 gaim_signal_emit(gaim_blist_get_handle(), "buddy-unidle", buddy); | |
1281 | |
1282 if (gaim_prefs_get_bool("/core/logging/log_system") && | |
1283 gaim_prefs_get_bool("/core/logging/log_idle_state")) | |
1284 { | |
1285 GaimLog *log = gaim_account_get_log(buddy->account); | |
1286 char *tmp = g_strdup_printf(_("%s became unidle"), | |
1287 gaim_buddy_get_alias(buddy)); | |
1288 | |
1289 gaim_log_write(log, GAIM_MESSAGE_SYSTEM, | |
1290 gaim_buddy_get_alias(buddy), current_time, tmp); | |
1291 g_free(tmp); | |
1292 } | |
1293 } | |
1294 | |
1295 gaim_contact_compute_priority_buddy(gaim_buddy_get_contact(buddy)); | |
1296 | |
1297 if (ops != NULL && ops->update != NULL) | |
1298 ops->update(gaim_get_blist(), (GaimBlistNode *)buddy); | |
1299 } | |
1300 | |
1301 void | |
1302 gaim_presence_set_idle(GaimPresence *presence, gboolean idle, time_t idle_time) | |
1303 { | |
1304 gboolean old_idle; | |
1305 | |
1306 g_return_if_fail(presence != NULL); | |
1307 | |
1308 if (presence->idle == idle && presence->idle_time == idle_time) | |
1309 return; | |
1310 | |
1311 old_idle = presence->idle; | |
1312 presence->idle = idle; | |
1313 presence->idle_time = (idle ? idle_time : 0); | |
1314 | |
1315 if (gaim_presence_get_context(presence) == GAIM_PRESENCE_CONTEXT_BUDDY) | |
1316 { | |
1317 const GList *l; | |
1318 time_t current_time = time(NULL); | |
1319 | |
1320 for (l = gaim_presence_get_buddies(presence); l != NULL; l = l->next) | |
1321 { | |
1322 update_buddy_idle((GaimBuddy *)l->data, presence, current_time, | |
1323 old_idle, idle); | |
1324 } | |
1325 } | |
1326 } | |
1327 | |
1328 void | |
10006 | 1329 gaim_presence_set_login_time(GaimPresence *presence, time_t login_time) |
1330 { | |
1331 g_return_if_fail(presence != NULL); | |
1332 | |
1333 if (presence->login_time == login_time) | |
1334 return; | |
1335 | |
1336 presence->login_time = login_time; | |
1337 } | |
1338 | |
1339 void | |
9949 | 1340 gaim_presence_set_warning_level(GaimPresence *presence, unsigned int level) |
6065 | 1341 { |
9949 | 1342 g_return_if_fail(presence != NULL); |
1343 g_return_if_fail(level <= 100); | |
1344 | |
1345 if (presence->warning_level == level) | |
1346 return; | |
1347 | |
1348 presence->warning_level = level; | |
1349 | |
1350 if (gaim_presence_get_context(presence) == GAIM_PRESENCE_CONTEXT_BUDDY) | |
1351 { | |
1352 GaimBlistUiOps *ops = gaim_get_blist()->ui_ops; | |
1353 | |
1354 if (ops != NULL && ops->update != NULL) | |
1355 { | |
1356 const GList *l; | |
1357 | |
1358 for (l = gaim_presence_get_buddies(presence); | |
1359 l != NULL; | |
1360 l = l->next) | |
1361 { | |
1362 ops->update(gaim_get_blist(), (GaimBlistNode *)l->data); | |
1363 } | |
1364 } | |
1365 } | |
1366 } | |
1367 | |
1368 GaimPresenceContext | |
1369 gaim_presence_get_context(const GaimPresence *presence) | |
1370 { | |
1371 g_return_val_if_fail(presence != NULL, GAIM_PRESENCE_CONTEXT_UNSET); | |
1372 | |
1373 return presence->context; | |
1374 } | |
1375 | |
1376 GaimAccount * | |
1377 gaim_presence_get_account(const GaimPresence *presence) | |
1378 { | |
1379 GaimPresenceContext context; | |
1380 | |
1381 g_return_val_if_fail(presence != NULL, NULL); | |
1382 | |
1383 context = gaim_presence_get_context(presence); | |
1384 | |
1385 g_return_val_if_fail(context == GAIM_PRESENCE_CONTEXT_ACCOUNT || | |
1386 context == GAIM_PRESENCE_CONTEXT_BUDDY, NULL); | |
1387 | |
1388 return presence->u.account; | |
1389 } | |
1390 | |
1391 GaimConversation * | |
1392 gaim_presence_get_conversation(const GaimPresence *presence) | |
1393 { | |
1394 g_return_val_if_fail(presence != NULL, NULL); | |
1395 g_return_val_if_fail(gaim_presence_get_context(presence) == | |
1396 GAIM_PRESENCE_CONTEXT_CONV, NULL); | |
1397 | |
1398 return presence->u.chat.conv; | |
1399 } | |
1400 | |
1401 const char * | |
1402 gaim_presence_get_chat_user(const GaimPresence *presence) | |
1403 { | |
1404 g_return_val_if_fail(presence != NULL, NULL); | |
1405 g_return_val_if_fail(gaim_presence_get_context(presence) == | |
1406 GAIM_PRESENCE_CONTEXT_CONV, NULL); | |
1407 | |
1408 return presence->u.chat.user; | |
1409 } | |
1410 | |
1411 const GList * | |
1412 gaim_presence_get_buddies(const GaimPresence *presence) | |
1413 { | |
1414 g_return_val_if_fail(presence != NULL, NULL); | |
1415 g_return_val_if_fail(gaim_presence_get_context(presence) == | |
1416 GAIM_PRESENCE_CONTEXT_BUDDY, NULL); | |
1417 | |
1418 return presence->u.buddy.buddies; | |
1419 } | |
1420 | |
1421 const GList * | |
1422 gaim_presence_get_statuses(const GaimPresence *presence) | |
1423 { | |
1424 g_return_val_if_fail(presence != NULL, NULL); | |
1425 | |
1426 return presence->statuses; | |
1427 } | |
1428 | |
1429 GaimStatus * | |
1430 gaim_presence_get_status(const GaimPresence *presence, const char *status_id) | |
1431 { | |
1432 GaimStatus *status; | |
10006 | 1433 const GList *l = NULL; |
9949 | 1434 |
1435 g_return_val_if_fail(presence != NULL, NULL); | |
1436 g_return_val_if_fail(status_id != NULL, NULL); | |
1437 | |
10006 | 1438 /* What's the purpose of this hash table? */ |
10012 | 1439 status = (GaimStatus *)g_hash_table_lookup(presence->status_table, |
10006 | 1440 status_id); |
10012 | 1441 |
10006 | 1442 if (status == NULL) { |
10012 | 1443 for (l = gaim_presence_get_statuses(presence); |
10006 | 1444 l != NULL && status == NULL; l = l->next) |
1445 { | |
1446 GaimStatus *temp_status = l->data; | |
10012 | 1447 |
10006 | 1448 if (!strcmp(status_id, gaim_status_get_id(temp_status))) |
1449 status = temp_status; | |
1450 } | |
1451 | |
1452 if (status != NULL) | |
1453 g_hash_table_insert(presence->status_table, | |
1454 g_strdup(gaim_status_get_id(status)), status); | |
10012 | 1455 } |
9949 | 1456 |
1457 return status; | |
1458 } | |
1459 | |
1460 GaimStatus * | |
1461 gaim_presence_get_active_status(const GaimPresence *presence) | |
1462 { | |
1463 g_return_val_if_fail(presence != NULL, NULL); | |
1464 | |
1465 return presence->active_status; | |
1466 } | |
1467 | |
1468 gboolean | |
1469 gaim_presence_is_available(const GaimPresence *presence) | |
1470 { | |
1471 GaimStatus *status; | |
1472 | |
1473 g_return_val_if_fail(presence != NULL, FALSE); | |
1474 | |
1475 status = gaim_presence_get_active_status(presence); | |
1476 | |
1477 return ((status != NULL && gaim_status_is_available(status)) && | |
1478 !gaim_presence_is_idle(presence)); | |
1479 } | |
1480 | |
1481 gboolean | |
1482 gaim_presence_is_online(const GaimPresence *presence) | |
1483 { | |
1484 GaimStatus *status; | |
1485 | |
1486 g_return_val_if_fail(presence != NULL, FALSE); | |
1487 | |
1488 if ((status = gaim_presence_get_active_status(presence)) == NULL) | |
1489 return FALSE; | |
1490 | |
10040
81059dce3aed
[gaim-migrate @ 10999]
Luke Schierer <lschiere@pidgin.im>
parents:
10013
diff
changeset
|
1491 return gaim_status_is_online(status); |
9949 | 1492 } |
1493 | |
1494 gboolean | |
1495 gaim_presence_is_status_active(const GaimPresence *presence, | |
1496 const char *status_id) | |
1497 { | |
1498 GaimStatus *status; | |
1499 | |
1500 g_return_val_if_fail(presence != NULL, FALSE); | |
1501 g_return_val_if_fail(status_id != NULL, FALSE); | |
1502 | |
1503 status = gaim_presence_get_status(presence, status_id); | |
1504 | |
1505 return (status != NULL && gaim_status_is_active(status)); | |
1506 } | |
1507 | |
1508 gboolean | |
1509 gaim_presence_is_status_primitive_active(const GaimPresence *presence, | |
1510 GaimStatusPrimitive primitive) | |
1511 { | |
1512 GaimStatus *status; | |
1513 GaimStatusType *status_type; | |
1514 | |
1515 g_return_val_if_fail(presence != NULL, FALSE); | |
1516 g_return_val_if_fail(primitive != GAIM_STATUS_UNSET, FALSE); | |
1517 | |
1518 status = gaim_presence_get_active_status(presence); | |
1519 status_type = gaim_status_get_type(status); | |
1520 | |
1521 if (gaim_status_type_get_primitive(status_type) == primitive) | |
1522 return TRUE; | |
6065 | 1523 |
1524 return FALSE; | |
1525 } | |
1526 | |
9949 | 1527 gboolean |
1528 gaim_presence_is_idle(const GaimPresence *presence) | |
6065 | 1529 { |
9949 | 1530 g_return_val_if_fail(presence != NULL, FALSE); |
1531 | |
1532 return presence->idle; | |
6065 | 1533 } |
1534 | |
9949 | 1535 time_t |
1536 gaim_presence_get_idle_time(const GaimPresence *presence) | |
6065 | 1537 { |
9949 | 1538 g_return_val_if_fail(presence != NULL, 0); |
6065 | 1539 |
9949 | 1540 return presence->idle_time; |
1541 } | |
6065 | 1542 |
9949 | 1543 unsigned int |
1544 gaim_presence_get_warning_level(const GaimPresence *presence) | |
1545 { | |
1546 g_return_val_if_fail(presence != NULL, 0); | |
6216 | 1547 |
9949 | 1548 return presence->warning_level; |
6065 | 1549 } |
1550 | |
9949 | 1551 gint |
1552 gaim_presence_compare(const GaimPresence *presence1, | |
1553 const GaimPresence *presence2) | |
6065 | 1554 { |
9949 | 1555 gboolean idle1, idle2; |
1556 size_t idle_time_1, idle_time_2; | |
1557 int score1 = 0, score2 = 0; | |
1558 const GList *l; | |
6065 | 1559 |
9949 | 1560 if ((presence1 == NULL && presence2 == NULL) || (presence1 == presence2)) |
1561 return 0; | |
1562 else if (presence1 == NULL) | |
10151
d83e6f2125b1
[gaim-migrate @ 11228]
Christian Hammond <chipx86@chipx86.com>
parents:
10087
diff
changeset
|
1563 return 1; |
9949 | 1564 else if (presence2 == NULL) |
10151
d83e6f2125b1
[gaim-migrate @ 11228]
Christian Hammond <chipx86@chipx86.com>
parents:
10087
diff
changeset
|
1565 return -1; |
6065 | 1566 |
9949 | 1567 /* Compute the score of the first set of statuses. */ |
1568 for (l = gaim_presence_get_statuses(presence1); l != NULL; l = l->next) | |
1569 { | |
1570 GaimStatus *status = (GaimStatus *)l->data; | |
1571 GaimStatusType *type = gaim_status_get_type(status); | |
6065 | 1572 |
9949 | 1573 if (gaim_status_is_active(status)) |
1574 score1 += primitive_scores[gaim_status_type_get_primitive(type)]; | |
6065 | 1575 } |
1576 | |
9949 | 1577 /* Compute the score of the second set of statuses. */ |
10151
d83e6f2125b1
[gaim-migrate @ 11228]
Christian Hammond <chipx86@chipx86.com>
parents:
10087
diff
changeset
|
1578 for (l = gaim_presence_get_statuses(presence2); l != NULL; l = l->next) |
9949 | 1579 { |
1580 GaimStatus *status = (GaimStatus *)l->data; | |
1581 GaimStatusType *type = gaim_status_get_type(status); | |
6065 | 1582 |
9949 | 1583 if (gaim_status_is_active(status)) |
1584 score2 += primitive_scores[gaim_status_type_get_primitive(type)]; | |
6065 | 1585 } |
1586 | |
9949 | 1587 idle1 = gaim_presence_is_idle(presence1); |
1588 idle2 = gaim_presence_is_idle(presence2); | |
6065 | 1589 |
9949 | 1590 if (idle1) |
1591 score1 += primitive_scores[SCORE_IDLE]; | |
6065 | 1592 |
9949 | 1593 if (idle2) |
1594 score2 += primitive_scores[SCORE_IDLE]; | |
6065 | 1595 |
9949 | 1596 idle_time_1 = gaim_presence_get_idle_time(presence1); |
1597 idle_time_2 = gaim_presence_get_idle_time(presence2); | |
6065 | 1598 |
9949 | 1599 if (idle_time_1 > idle_time_2) |
1600 score1 += primitive_scores[SCORE_IDLE_TIME]; | |
1601 else if (idle_time_1 < idle_time_2) | |
1602 score2 += primitive_scores[SCORE_IDLE_TIME]; | |
6065 | 1603 |
9949 | 1604 if (score1 < score2) |
1605 return 1; | |
1606 else if (score1 > score2) | |
1607 return -1; | |
1608 | |
1609 return 0; | |
1610 } | |
1611 | |
6065 | 1612 |
9949 | 1613 /************************************************************************** |
1614 * Status subsystem | |
1615 **************************************************************************/ | |
1616 static void | |
1617 score_pref_changed_cb(const char *name, GaimPrefType type, gpointer value, | |
1618 gpointer data) | |
1619 { | |
1620 int index = GPOINTER_TO_INT(data); | |
6065 | 1621 |
9949 | 1622 primitive_scores[index] = GPOINTER_TO_INT(value); |
6065 | 1623 } |
1624 | |
10012 | 1625 guint |
10006 | 1626 gaim_buddy_presences_hash(gconstpointer key) |
1627 { | |
10012 | 1628 const GaimStatusBuddyKey *me = key; |
1629 guint ret; | |
1630 char *str; | |
1631 | |
1632 str = g_strdup_printf("%p%s", me->account, me->name); | |
1633 ret = g_str_hash(str); | |
1634 g_free(str); | |
1635 | |
1636 return ret; | |
10006 | 1637 } |
1638 | |
10012 | 1639 gboolean |
10006 | 1640 gaim_buddy_presences_equal(gconstpointer a, gconstpointer b) |
1641 { | |
1642 GaimStatusBuddyKey *key_a = (GaimStatusBuddyKey *)a; | |
1643 GaimStatusBuddyKey *key_b = (GaimStatusBuddyKey *)b; | |
1644 | |
10012 | 1645 if(key_a->account == key_b->account && |
1646 !strcmp(key_a->name, key_b->name)) | |
10006 | 1647 return TRUE; |
1648 else | |
1649 return FALSE; | |
1650 } | |
1651 | |
10176
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
1652 const GList * |
10337 | 1653 gaim_statuses_get_saved(void) |
1654 { | |
1655 return saved_statuses; | |
1656 } | |
1657 | |
1658 GaimStatusSaved * | |
10340 | 1659 gaim_statuses_find_saved(const char *name) |
10176
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
1660 { |
10340 | 1661 GList *l; |
1662 GaimStatusSaved *status; | |
1663 | |
1664 for (l = saved_statuses; l != NULL; l = g_list_next(l)) | |
1665 { | |
1666 status = (GaimStatusSaved *)l->data; | |
1667 if (!strcmp(status->name, name)) | |
1668 return status; | |
1669 } | |
1670 | |
10176
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
1671 return NULL; |
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
1672 } |
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
1673 |
10337 | 1674 const char * |
1675 gaim_statuses_saved_get_name(const GaimStatusSaved *saved_status) | |
10176
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
1676 { |
10337 | 1677 return saved_status->name; |
10176
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
1678 } |
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
1679 |
10340 | 1680 const GaimStatusType * |
1681 gaim_statuses_saved_get_type(const GaimStatusSaved *saved_status) | |
1682 { | |
1683 return saved_status->type; | |
1684 } | |
1685 | |
1686 const char * | |
1687 gaim_statuses_saved_get_message(const GaimStatusSaved *saved_status) | |
1688 { | |
1689 return saved_status->message; | |
1690 } | |
1691 | |
10087 | 1692 void * |
1693 gaim_statuses_get_handle() { | |
1694 static int handle; | |
1695 | |
1696 return &handle; | |
1697 } | |
1698 | |
9949 | 1699 void |
1700 gaim_statuses_init(void) | |
6065 | 1701 { |
10087 | 1702 void *handle = gaim_statuses_get_handle; |
1703 | |
9949 | 1704 gaim_prefs_add_none("/core/status"); |
1705 gaim_prefs_add_none("/core/status/scores"); | |
6065 | 1706 |
9949 | 1707 gaim_prefs_add_int("/core/status/scores/offline", |
1708 primitive_scores[GAIM_STATUS_OFFLINE]); | |
1709 gaim_prefs_add_int("/core/status/scores/available", | |
1710 primitive_scores[GAIM_STATUS_AVAILABLE]); | |
1711 gaim_prefs_add_int("/core/status/scores/hidden", | |
1712 primitive_scores[GAIM_STATUS_HIDDEN]); | |
1713 gaim_prefs_add_int("/core/status/scores/away", | |
1714 primitive_scores[GAIM_STATUS_AWAY]); | |
1715 gaim_prefs_add_int("/core/status/scores/extended_away", | |
1716 primitive_scores[GAIM_STATUS_EXTENDED_AWAY]); | |
1717 gaim_prefs_add_int("/core/status/scores/idle", | |
1718 primitive_scores[SCORE_IDLE]); | |
6065 | 1719 |
10087 | 1720 gaim_prefs_connect_callback(handle, "/core/status/scores/offline", |
9949 | 1721 score_pref_changed_cb, |
1722 GINT_TO_POINTER(GAIM_STATUS_OFFLINE)); | |
10087 | 1723 gaim_prefs_connect_callback(handle, "/core/status/scores/available", |
9949 | 1724 score_pref_changed_cb, |
1725 GINT_TO_POINTER(GAIM_STATUS_AVAILABLE)); | |
10087 | 1726 gaim_prefs_connect_callback(handle, "/core/status/scores/hidden", |
9949 | 1727 score_pref_changed_cb, |
1728 GINT_TO_POINTER(GAIM_STATUS_HIDDEN)); | |
10087 | 1729 gaim_prefs_connect_callback(handle, "/core/status/scores/away", |
9949 | 1730 score_pref_changed_cb, |
1731 GINT_TO_POINTER(GAIM_STATUS_AWAY)); | |
10087 | 1732 gaim_prefs_connect_callback(handle, "/core/status/scores/extended_away", |
9949 | 1733 score_pref_changed_cb, |
1734 GINT_TO_POINTER(GAIM_STATUS_EXTENDED_AWAY)); | |
10087 | 1735 gaim_prefs_connect_callback(handle, "/core/status/scores/idle", |
9949 | 1736 score_pref_changed_cb, |
1737 GINT_TO_POINTER(SCORE_IDLE)); | |
10006 | 1738 |
1739 buddy_presences = g_hash_table_new(gaim_buddy_presences_hash, | |
1740 gaim_buddy_presences_equal); | |
9949 | 1741 } |
6065 | 1742 |
9949 | 1743 void |
1744 gaim_statuses_uninit(void) | |
1745 { | |
10176
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
1746 if (buddy_presences != NULL) |
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
1747 { |
10077 | 1748 g_hash_table_destroy(buddy_presences); |
10176
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
1749 |
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
1750 buddy_presences = NULL; |
0109f3a518d2
[gaim-migrate @ 11291]
Christian Hammond <chipx86@chipx86.com>
parents:
10153
diff
changeset
|
1751 } |
9949 | 1752 } |
6065 | 1753 |
9949 | 1754 void |
1755 gaim_statuses_sync(void) | |
1756 { | |
10340 | 1757 /* TODO: Write me, baby. */ |
6065 | 1758 } |
9949 | 1759 |
10337 | 1760 /** |
1761 * Parse a saved status and add it to the saved_statuses linked list. | |
1762 * | |
1763 * Here's an example of the XML for a saved status: | |
1764 * <status name="Girls"> | |
1765 * <state>away</state> | |
1766 * <message>I like the way that they walk | |
1767 * And it's chill to hear them talk | |
1768 * And I can always make them smile | |
1769 * From White Castle to the Nile</message> | |
1770 * </status> | |
1771 * | |
1772 * I know. Moving, huh? | |
1773 */ | |
1774 static void | |
1775 gaim_statuses_read_parse_status(xmlnode *status) | |
1776 { | |
1777 xmlnode *node; | |
1778 const char *name, *state, *message; | |
1779 GaimStatusSaved *new; | |
10340 | 1780 int i; |
10337 | 1781 |
1782 name = xmlnode_get_attrib(status, "name"); | |
1783 if (name == NULL) | |
10340 | 1784 name = "No Title"; |
10337 | 1785 |
1786 node = xmlnode_get_child(status, "state"); | |
1787 if (node != NULL) { | |
1788 state = xmlnode_get_data(node); | |
1789 } | |
1790 | |
1791 node = xmlnode_get_child(status, "message"); | |
1792 if (node != NULL) { | |
1793 message = xmlnode_get_data(node); | |
1794 } | |
1795 | |
1796 /* TODO: Need to read in substatuses here */ | |
1797 | |
1798 new = g_new0(GaimStatusSaved, 1); | |
1799 | |
1800 new->name = g_strdup(name); | |
1801 /* TODO: Need to set type based on "state" */ | |
1802 new->type = NULL; | |
1803 if (message != NULL) | |
1804 new->message = g_strdup(message); | |
1805 | |
10340 | 1806 /* Ensure the title is unique */ |
1807 i = 2; | |
1808 while (gaim_statuses_find_saved(new->name) != NULL) { | |
1809 g_free(new->name); | |
1810 new->name = g_strdup_printf("%s %d", name, i); | |
1811 i++; | |
1812 } | |
1813 | |
10337 | 1814 saved_statuses = g_list_append(saved_statuses, new); |
1815 } | |
1816 | |
1817 /** | |
1818 * @return TRUE on success, FALSE on failure (if the file can not | |
1819 * be opened, or if it contains invalid XML). | |
1820 */ | |
1821 gboolean | |
1822 gaim_statuses_read(const char *filename) | |
1823 { | |
1824 GError *error; | |
1825 gchar *contents = NULL; | |
1826 gsize length; | |
1827 xmlnode *statuses, *status; | |
1828 | |
1829 gaim_debug_info("status", "Reading %s\n", filename); | |
1830 | |
1831 if (!g_file_get_contents(filename, &contents, &length, &error)) { | |
10343 | 1832 gaim_debug_error("status", "Error reading statuses: %s\n", |
10337 | 1833 error->message); |
1834 g_error_free(error); | |
1835 return FALSE; | |
1836 } | |
1837 | |
1838 statuses = xmlnode_from_str(contents, length); | |
1839 | |
1840 if (statuses == NULL) { | |
1841 FILE *backup; | |
1842 gchar *name; | |
10343 | 1843 gaim_debug_error("status", "Error parsing statuses\n"); |
1844 name = g_strdup_printf("%s~", filename); | |
10337 | 1845 if ((backup = fopen(name, "w"))) { |
1846 fwrite(contents, length, 1, backup); | |
1847 fclose(backup); | |
1848 chmod(name, S_IRUSR | S_IWUSR); | |
1849 } else { | |
1850 gaim_debug_error("status", "Unable to write backup %s\n", name); | |
1851 } | |
1852 g_free(name); | |
1853 g_free(contents); | |
1854 return FALSE; | |
1855 } | |
1856 | |
1857 g_free(contents); | |
1858 | |
1859 for (status = xmlnode_get_child(statuses, "status"); status != NULL; | |
1860 status = xmlnode_get_next_twin(status)) { | |
1861 gaim_statuses_read_parse_status(status); | |
1862 } | |
1863 | |
10343 | 1864 gaim_debug_info("status", "Finished reading statuses\n"); |
10337 | 1865 |
1866 xmlnode_free(statuses); | |
1867 | |
1868 return TRUE; | |
1869 } | |
1870 | |
9949 | 1871 void |
1872 gaim_statuses_load(void) | |
1873 { | |
10337 | 1874 const char *user_dir = gaim_user_dir(); |
1875 gchar *filename; | |
1876 gchar *msg; | |
1877 | |
1878 if (user_dir == NULL) | |
1879 return; | |
1880 | |
1881 filename = g_build_filename(user_dir, "status.xml", NULL); | |
1882 | |
1883 if (g_file_test(filename, G_FILE_TEST_EXISTS)) { | |
1884 if (!gaim_statuses_read(filename)) { | |
1885 msg = g_strdup_printf(_("An error was encountered parsing the " | |
1886 "file containing your saved statuses (%s). They " | |
1887 "have not been loaded, and the old file has been " | |
1888 "renamed to status.xml~."), filename); | |
1889 gaim_notify_error(NULL, NULL, _("Saved Statuses Error"), msg); | |
1890 g_free(msg); | |
1891 } | |
1892 } | |
1893 | |
1894 g_free(filename); | |
9949 | 1895 } |