comparison libpurple/status.c @ 32692:0f94ec89f0bc

merged from im.pidgin.pidgin
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Mon, 26 Sep 2011 14:57:21 +0900
parents ac6353ffa129 d2fe5f01635b
children 4a34689eeb33
comparison
equal deleted inserted replaced
32438:55e678325bda 32692:0f94ec89f0bc
255 255
256 return purple_status_type_new_full(primitive, id, name, TRUE, 256 return purple_status_type_new_full(primitive, id, name, TRUE,
257 user_settable, FALSE); 257 user_settable, FALSE);
258 } 258 }
259 259
260 static void
261 status_type_add_attr(PurpleStatusType *status_type, const char *id,
262 const char *name, PurpleValue *value)
263 {
264 PurpleStatusAttr *attr;
265
266 g_return_if_fail(status_type != NULL);
267 g_return_if_fail(id != NULL);
268 g_return_if_fail(name != NULL);
269 g_return_if_fail(value != NULL);
270
271 attr = purple_status_attr_new(id, name, value);
272
273 status_type->attrs = g_list_append(status_type->attrs, attr);
274 }
275
276 static void
277 status_type_add_attrs_vargs(PurpleStatusType *status_type, va_list args)
278 {
279 const char *id, *name;
280 PurpleValue *value;
281
282 g_return_if_fail(status_type != NULL);
283
284 while ((id = va_arg(args, const char *)) != NULL)
285 {
286 name = va_arg(args, const char *);
287 g_return_if_fail(name != NULL);
288
289 value = va_arg(args, PurpleValue *);
290 g_return_if_fail(value != NULL);
291
292 status_type_add_attr(status_type, id, name, value);
293 }
294 }
295
260 PurpleStatusType * 296 PurpleStatusType *
261 purple_status_type_new_with_attrs(PurpleStatusPrimitive primitive, 297 purple_status_type_new_with_attrs(PurpleStatusPrimitive primitive,
262 const char *id, const char *name, 298 const char *id, const char *name,
263 gboolean saveable, gboolean user_settable, 299 gboolean saveable, gboolean user_settable,
264 gboolean independent, const char *attr_id, 300 gboolean independent, const char *attr_id,
275 311
276 status_type = purple_status_type_new_full(primitive, id, name, saveable, 312 status_type = purple_status_type_new_full(primitive, id, name, saveable,
277 user_settable, independent); 313 user_settable, independent);
278 314
279 /* Add the first attribute */ 315 /* Add the first attribute */
280 purple_status_type_add_attr(status_type, attr_id, attr_name, attr_value); 316 status_type_add_attr(status_type, attr_id, attr_name, attr_value);
281 317
282 va_start(args, attr_value); 318 va_start(args, attr_value);
283 purple_status_type_add_attrs_vargs(status_type, args); 319 status_type_add_attrs_vargs(status_type, args);
284 va_end(args); 320 va_end(args);
285 321
286 return status_type; 322 return status_type;
287 } 323 }
288 324
297 g_list_foreach(status_type->attrs, (GFunc)purple_status_attr_destroy, NULL); 333 g_list_foreach(status_type->attrs, (GFunc)purple_status_attr_destroy, NULL);
298 g_list_free(status_type->attrs); 334 g_list_free(status_type->attrs);
299 335
300 PURPLE_DBUS_UNREGISTER_POINTER(status_type); 336 PURPLE_DBUS_UNREGISTER_POINTER(status_type);
301 g_free(status_type); 337 g_free(status_type);
302 }
303
304 void
305 purple_status_type_add_attr(PurpleStatusType *status_type, const char *id,
306 const char *name, PurpleValue *value)
307 {
308 PurpleStatusAttr *attr;
309
310 g_return_if_fail(status_type != NULL);
311 g_return_if_fail(id != NULL);
312 g_return_if_fail(name != NULL);
313 g_return_if_fail(value != NULL);
314
315 attr = purple_status_attr_new(id, name, value);
316
317 status_type->attrs = g_list_append(status_type->attrs, attr);
318 }
319
320 void
321 purple_status_type_add_attrs_vargs(PurpleStatusType *status_type, va_list args)
322 {
323 const char *id, *name;
324 PurpleValue *value;
325
326 g_return_if_fail(status_type != NULL);
327
328 while ((id = va_arg(args, const char *)) != NULL)
329 {
330 name = va_arg(args, const char *);
331 g_return_if_fail(name != NULL);
332
333 value = va_arg(args, PurpleValue *);
334 g_return_if_fail(value != NULL);
335
336 purple_status_type_add_attr(status_type, id, name, value);
337 }
338 }
339
340 void
341 purple_status_type_add_attrs(PurpleStatusType *status_type, const char *id,
342 const char *name, PurpleValue *value, ...)
343 {
344 va_list args;
345
346 g_return_if_fail(status_type != NULL);
347 g_return_if_fail(id != NULL);
348 g_return_if_fail(name != NULL);
349 g_return_if_fail(value != NULL);
350
351 /* Add the first attribute */
352 purple_status_type_add_attr(status_type, id, name, value);
353
354 va_start(args, value);
355 purple_status_type_add_attrs_vargs(status_type, args);
356 va_end(args);
357 } 338 }
358 339
359 PurpleStatusPrimitive 340 PurpleStatusPrimitive
360 purple_status_type_get_primitive(const PurpleStatusType *status_type) 341 purple_status_type_get_primitive(const PurpleStatusType *status_type)
361 { 342 {
685 old_status = NULL; 666 old_status = NULL;
686 667
687 notify_status_update(presence, old_status, status); 668 notify_status_update(presence, old_status, status);
688 } 669 }
689 670
690 void 671 static void
691 purple_status_set_active(PurpleStatus *status, gboolean active) 672 status_set_attr_boolean(PurpleStatus *status, const char *id,
692 {
693 purple_status_set_active_with_attrs_list(status, active, NULL);
694 }
695
696 /*
697 * This used to parse the va_list directly, but now it creates a GList
698 * and passes it to purple_status_set_active_with_attrs_list(). That
699 * function was created because accounts.c needs to pass a GList of
700 * attributes to the status API.
701 */
702 void
703 purple_status_set_active_with_attrs(PurpleStatus *status, gboolean active, va_list args)
704 {
705 GList *attrs = NULL;
706 const gchar *id;
707 gpointer data;
708
709 while ((id = va_arg(args, const char *)) != NULL)
710 {
711 attrs = g_list_append(attrs, (char *)id);
712 data = va_arg(args, void *);
713 attrs = g_list_append(attrs, data);
714 }
715 purple_status_set_active_with_attrs_list(status, active, attrs);
716 g_list_free(attrs);
717 }
718
719 void
720 purple_status_set_active_with_attrs_list(PurpleStatus *status, gboolean active,
721 GList *attrs)
722 {
723 gboolean changed = FALSE;
724 GList *l;
725 GList *specified_attr_ids = NULL;
726 PurpleStatusType *status_type;
727
728 g_return_if_fail(status != NULL);
729
730 if (!active && purple_status_is_exclusive(status))
731 {
732 purple_debug_error("status",
733 "Cannot deactivate an exclusive status (%s).\n",
734 purple_status_get_id(status));
735 return;
736 }
737
738 if (status->active != active)
739 {
740 changed = TRUE;
741 }
742
743 status->active = active;
744
745 /* Set any attributes */
746 l = attrs;
747 while (l != NULL)
748 {
749 const gchar *id;
750 PurpleValue *value;
751
752 id = l->data;
753 l = l->next;
754 value = purple_status_get_attr_value(status, id);
755 if (value == NULL)
756 {
757 purple_debug_warning("status", "The attribute \"%s\" on the status \"%s\" is "
758 "not supported.\n", id, status->type->name);
759 /* Skip over the data and move on to the next attribute */
760 l = l->next;
761 continue;
762 }
763
764 specified_attr_ids = g_list_prepend(specified_attr_ids, (gpointer)id);
765
766 if (purple_value_get_type(value) == PURPLE_TYPE_STRING)
767 {
768 const gchar *string_data = l->data;
769 l = l->next;
770 if (purple_strequal(string_data, purple_value_get_string(value)))
771 continue;
772 purple_status_set_attr_string(status, id, string_data);
773 changed = TRUE;
774 }
775 else if (purple_value_get_type(value) == PURPLE_TYPE_INT)
776 {
777 int int_data = GPOINTER_TO_INT(l->data);
778 l = l->next;
779 if (int_data == purple_value_get_int(value))
780 continue;
781 purple_status_set_attr_int(status, id, int_data);
782 changed = TRUE;
783 }
784 else if (purple_value_get_type(value) == PURPLE_TYPE_BOOLEAN)
785 {
786 gboolean boolean_data = GPOINTER_TO_INT(l->data);
787 l = l->next;
788 if (boolean_data == purple_value_get_boolean(value))
789 continue;
790 purple_status_set_attr_boolean(status, id, boolean_data);
791 changed = TRUE;
792 }
793 else
794 {
795 /* We don't know what the data is--skip over it */
796 l = l->next;
797 }
798 }
799
800 /* Reset any unspecified attributes to their default value */
801 status_type = purple_status_get_type(status);
802 l = purple_status_type_get_attrs(status_type);
803 while (l != NULL) {
804 PurpleStatusAttr *attr;
805
806 attr = l->data;
807 l = l->next;
808
809 if (!g_list_find_custom(specified_attr_ids, attr->id, (GCompareFunc)strcmp)) {
810 PurpleValue *default_value;
811 default_value = purple_status_attr_get_value(attr);
812 if (purple_value_get_type(default_value) == PURPLE_TYPE_STRING) {
813 const char *cur = purple_status_get_attr_string(status, attr->id);
814 const char *def = purple_value_get_string(default_value);
815 if ((cur == NULL && def == NULL)
816 || (cur != NULL && def != NULL
817 && !strcmp(cur, def))) {
818 continue;
819 }
820
821 purple_status_set_attr_string(status, attr->id, def);
822 } else if (purple_value_get_type(default_value) == PURPLE_TYPE_INT) {
823 int cur = purple_status_get_attr_int(status, attr->id);
824 int def = purple_value_get_int(default_value);
825 if (cur == def)
826 continue;
827
828 purple_status_set_attr_int(status, attr->id, def);
829 } else if (purple_value_get_type(default_value) == PURPLE_TYPE_BOOLEAN) {
830 gboolean cur = purple_status_get_attr_boolean(status, attr->id);
831 gboolean def = purple_value_get_boolean(default_value);
832 if (cur == def)
833 continue;
834
835 purple_status_set_attr_boolean(status, attr->id, def);
836 }
837 changed = TRUE;
838 }
839 }
840 g_list_free(specified_attr_ids);
841
842 if (!changed)
843 return;
844 status_has_changed(status);
845 }
846
847 void
848 purple_status_set_attr_boolean(PurpleStatus *status, const char *id,
849 gboolean value) 673 gboolean value)
850 { 674 {
851 PurpleValue *attr_value; 675 PurpleValue *attr_value;
852 676
853 g_return_if_fail(status != NULL); 677 g_return_if_fail(status != NULL);
859 g_return_if_fail(purple_value_get_type(attr_value) == PURPLE_TYPE_BOOLEAN); 683 g_return_if_fail(purple_value_get_type(attr_value) == PURPLE_TYPE_BOOLEAN);
860 684
861 purple_value_set_boolean(attr_value, value); 685 purple_value_set_boolean(attr_value, value);
862 } 686 }
863 687
864 void 688 static void
865 purple_status_set_attr_int(PurpleStatus *status, const char *id, int value) 689 status_set_attr_int(PurpleStatus *status, const char *id, int value)
866 { 690 {
867 PurpleValue *attr_value; 691 PurpleValue *attr_value;
868 692
869 g_return_if_fail(status != NULL); 693 g_return_if_fail(status != NULL);
870 g_return_if_fail(id != NULL); 694 g_return_if_fail(id != NULL);
875 g_return_if_fail(purple_value_get_type(attr_value) == PURPLE_TYPE_INT); 699 g_return_if_fail(purple_value_get_type(attr_value) == PURPLE_TYPE_INT);
876 700
877 purple_value_set_int(attr_value, value); 701 purple_value_set_int(attr_value, value);
878 } 702 }
879 703
880 void 704 static void
881 purple_status_set_attr_string(PurpleStatus *status, const char *id, 705 status_set_attr_string(PurpleStatus *status, const char *id,
882 const char *value) 706 const char *value)
883 { 707 {
884 PurpleValue *attr_value; 708 PurpleValue *attr_value;
885 709
886 g_return_if_fail(status != NULL); 710 g_return_if_fail(status != NULL);
904 /* XXX: Check if the value has actually changed. If it has, and the status 728 /* XXX: Check if the value has actually changed. If it has, and the status
905 * is active, should this trigger 'status_has_changed'? */ 729 * is active, should this trigger 'status_has_changed'? */
906 purple_value_set_string(attr_value, value); 730 purple_value_set_string(attr_value, value);
907 } 731 }
908 732
733 void
734 purple_status_set_active(PurpleStatus *status, gboolean active)
735 {
736 purple_status_set_active_with_attrs_list(status, active, NULL);
737 }
738
739 /*
740 * This used to parse the va_list directly, but now it creates a GList
741 * and passes it to purple_status_set_active_with_attrs_list(). That
742 * function was created because accounts.c needs to pass a GList of
743 * attributes to the status API.
744 */
745 void
746 purple_status_set_active_with_attrs(PurpleStatus *status, gboolean active, va_list args)
747 {
748 GList *attrs = NULL;
749 const gchar *id;
750 gpointer data;
751
752 while ((id = va_arg(args, const char *)) != NULL)
753 {
754 attrs = g_list_append(attrs, (char *)id);
755 data = va_arg(args, void *);
756 attrs = g_list_append(attrs, data);
757 }
758 purple_status_set_active_with_attrs_list(status, active, attrs);
759 g_list_free(attrs);
760 }
761
762 void
763 purple_status_set_active_with_attrs_list(PurpleStatus *status, gboolean active,
764 GList *attrs)
765 {
766 gboolean changed = FALSE;
767 GList *l;
768 GList *specified_attr_ids = NULL;
769 PurpleStatusType *status_type;
770
771 g_return_if_fail(status != NULL);
772
773 if (!active && purple_status_is_exclusive(status))
774 {
775 purple_debug_error("status",
776 "Cannot deactivate an exclusive status (%s).\n",
777 purple_status_get_id(status));
778 return;
779 }
780
781 if (status->active != active)
782 {
783 changed = TRUE;
784 }
785
786 status->active = active;
787
788 /* Set any attributes */
789 l = attrs;
790 while (l != NULL)
791 {
792 const gchar *id;
793 PurpleValue *value;
794
795 id = l->data;
796 l = l->next;
797 value = purple_status_get_attr_value(status, id);
798 if (value == NULL)
799 {
800 purple_debug_warning("status", "The attribute \"%s\" on the status \"%s\" is "
801 "not supported.\n", id, status->type->name);
802 /* Skip over the data and move on to the next attribute */
803 l = l->next;
804 continue;
805 }
806
807 specified_attr_ids = g_list_prepend(specified_attr_ids, (gpointer)id);
808
809 if (purple_value_get_type(value) == PURPLE_TYPE_STRING)
810 {
811 const gchar *string_data = l->data;
812 l = l->next;
813 if (purple_strequal(string_data, purple_value_get_string(value)))
814 continue;
815 status_set_attr_string(status, id, string_data);
816 changed = TRUE;
817 }
818 else if (purple_value_get_type(value) == PURPLE_TYPE_INT)
819 {
820 int int_data = GPOINTER_TO_INT(l->data);
821 l = l->next;
822 if (int_data == purple_value_get_int(value))
823 continue;
824 status_set_attr_int(status, id, int_data);
825 changed = TRUE;
826 }
827 else if (purple_value_get_type(value) == PURPLE_TYPE_BOOLEAN)
828 {
829 gboolean boolean_data = GPOINTER_TO_INT(l->data);
830 l = l->next;
831 if (boolean_data == purple_value_get_boolean(value))
832 continue;
833 status_set_attr_boolean(status, id, boolean_data);
834 changed = TRUE;
835 }
836 else
837 {
838 /* We don't know what the data is--skip over it */
839 l = l->next;
840 }
841 }
842
843 /* Reset any unspecified attributes to their default value */
844 status_type = purple_status_get_type(status);
845 l = purple_status_type_get_attrs(status_type);
846 while (l != NULL) {
847 PurpleStatusAttr *attr;
848
849 attr = l->data;
850 l = l->next;
851
852 if (!g_list_find_custom(specified_attr_ids, attr->id, (GCompareFunc)strcmp)) {
853 PurpleValue *default_value;
854 default_value = purple_status_attr_get_value(attr);
855 if (purple_value_get_type(default_value) == PURPLE_TYPE_STRING) {
856 const char *cur = purple_status_get_attr_string(status, attr->id);
857 const char *def = purple_value_get_string(default_value);
858 if ((cur == NULL && def == NULL)
859 || (cur != NULL && def != NULL
860 && !strcmp(cur, def))) {
861 continue;
862 }
863
864 status_set_attr_string(status, attr->id, def);
865 } else if (purple_value_get_type(default_value) == PURPLE_TYPE_INT) {
866 int cur = purple_status_get_attr_int(status, attr->id);
867 int def = purple_value_get_int(default_value);
868 if (cur == def)
869 continue;
870
871 status_set_attr_int(status, attr->id, def);
872 } else if (purple_value_get_type(default_value) == PURPLE_TYPE_BOOLEAN) {
873 gboolean cur = purple_status_get_attr_boolean(status, attr->id);
874 gboolean def = purple_value_get_boolean(default_value);
875 if (cur == def)
876 continue;
877
878 status_set_attr_boolean(status, attr->id, def);
879 }
880 changed = TRUE;
881 }
882 }
883 g_list_free(specified_attr_ids);
884
885 if (!changed)
886 return;
887 status_has_changed(status);
888 }
889
909 PurpleStatusType * 890 PurpleStatusType *
910 purple_status_get_type(const PurpleStatus *status) 891 purple_status_get_type(const PurpleStatus *status)
911 { 892 {
912 g_return_val_if_fail(status != NULL, NULL); 893 g_return_val_if_fail(status != NULL, NULL);
913 894
1162 1143
1163 g_hash_table_destroy(presence->status_table); 1144 g_hash_table_destroy(presence->status_table);
1164 1145
1165 PURPLE_DBUS_UNREGISTER_POINTER(presence); 1146 PURPLE_DBUS_UNREGISTER_POINTER(presence);
1166 g_free(presence); 1147 g_free(presence);
1167 }
1168
1169 void
1170 purple_presence_add_status(PurplePresence *presence, PurpleStatus *status)
1171 {
1172 g_return_if_fail(presence != NULL);
1173 g_return_if_fail(status != NULL);
1174
1175 presence->statuses = g_list_append(presence->statuses, status);
1176
1177 g_hash_table_insert(presence->status_table,
1178 g_strdup(purple_status_get_id(status)), status);
1179 }
1180
1181 void
1182 purple_presence_add_list(PurplePresence *presence, GList *source_list)
1183 {
1184 GList *l;
1185
1186 g_return_if_fail(presence != NULL);
1187 g_return_if_fail(source_list != NULL);
1188
1189 for (l = source_list; l != NULL; l = l->next)
1190 purple_presence_add_status(presence, (PurpleStatus *)l->data);
1191 } 1148 }
1192 1149
1193 void 1150 void
1194 purple_presence_set_status_active(PurplePresence *presence, const char *status_id, 1151 purple_presence_set_status_active(PurplePresence *presence, const char *status_id,
1195 gboolean active) 1152 gboolean active)