Mercurial > pidgin
comparison libpurple/buddyicon.c @ 23116:944059cb7807
Add the purple_buddy_icons_node_has_custom_icon,
purple_buddy_icons_node_find_custom_icon, and
purple_buddy_icons_node_set_custom_icon functions.
Deprecate the purple_buddy_icons_has_custom_icon,
purple_buddy_icons_find_custom_icon, and purple_buddy_icons_set_custom_icon
functions.
This allows custom icons to be set for PurpleChat:s and PurpleGroup:s as well
as PurpleBuddy:s. The UI bits of this coming soon.
author | Etan Reisner <pidgin@unreliablesource.net> |
---|---|
date | Tue, 13 May 2008 04:36:07 +0000 |
parents | eccdd341dc6e |
children | 4044655e5615 |
comparison
equal
deleted
inserted
replaced
23115:d11c993700e6 | 23116:944059cb7807 |
---|---|
90 * will be six. When this reference count reaches 0 the icon will | 90 * will be six. When this reference count reaches 0 the icon will |
91 * be deleted from disk. | 91 * be deleted from disk. |
92 */ | 92 */ |
93 static GHashTable *icon_file_cache = NULL; | 93 static GHashTable *icon_file_cache = NULL; |
94 | 94 |
95 /* This one is used for both custom buddy icons | 95 /** |
96 * on PurpleContacts and account icons. */ | 96 * This hash table is used for both custom buddy icons on PurpleBlistNodes and |
97 * account icons. | |
98 */ | |
97 static GHashTable *pointer_icon_cache = NULL; | 99 static GHashTable *pointer_icon_cache = NULL; |
98 | 100 |
99 static char *cache_dir = NULL; | 101 static char *cache_dir = NULL; |
100 | 102 |
101 /** "Should icons be cached to disk?" */ | 103 /** "Should icons be cached to disk?" */ |
682 } | 684 } |
683 | 685 |
684 return (icon ? purple_buddy_icon_ref(icon) : NULL); | 686 return (icon ? purple_buddy_icon_ref(icon) : NULL); |
685 } | 687 } |
686 | 688 |
687 gboolean | |
688 purple_buddy_icons_has_custom_icon(PurpleContact *contact) | |
689 { | |
690 g_return_val_if_fail(contact != NULL, FALSE); | |
691 | |
692 return (purple_blist_node_get_string((PurpleBlistNode*)contact, "custom_buddy_icon") != NULL); | |
693 } | |
694 | |
695 PurpleStoredImage * | 689 PurpleStoredImage * |
696 purple_buddy_icons_find_account_icon(PurpleAccount *account) | 690 purple_buddy_icons_find_account_icon(PurpleAccount *account) |
697 { | 691 { |
698 PurpleStoredImage *img; | 692 PurpleStoredImage *img; |
699 const char *account_icon_file; | 693 const char *account_icon_file; |
805 } | 799 } |
806 | 800 |
807 return ret; | 801 return ret; |
808 } | 802 } |
809 | 803 |
804 gboolean | |
805 purple_buddy_icons_node_has_custom_icon(PurpleBlistNode *node) | |
806 { | |
807 g_return_val_if_fail(node != NULL, FALSE); | |
808 | |
809 return (purple_blist_node_get_string(node, "custom_buddy_icon") != NULL); | |
810 } | |
811 | |
810 PurpleStoredImage * | 812 PurpleStoredImage * |
811 purple_buddy_icons_find_custom_icon(PurpleContact *contact) | 813 purple_buddy_icons_node_find_custom_icon(PurpleBlistNode *node) |
812 { | 814 { |
815 char *path; | |
816 size_t len; | |
817 guchar *data; | |
813 PurpleStoredImage *img; | 818 PurpleStoredImage *img; |
814 const char *custom_icon_file; | 819 const char *custom_icon_file, *dirname; |
815 const char *dirname; | 820 |
816 char *path; | 821 g_return_val_if_fail(node != NULL, NULL); |
817 guchar *data; | 822 |
818 size_t len; | 823 if ((img = g_hash_table_lookup(pointer_icon_cache, node))) |
819 | |
820 g_return_val_if_fail(contact != NULL, NULL); | |
821 | |
822 if ((img = g_hash_table_lookup(pointer_icon_cache, contact))) | |
823 { | 824 { |
824 return purple_imgstore_ref(img); | 825 return purple_imgstore_ref(img); |
825 } | 826 } |
826 | 827 |
827 custom_icon_file = purple_blist_node_get_string((PurpleBlistNode*)contact, "custom_buddy_icon"); | 828 custom_icon_file = purple_blist_node_get_string(node, |
829 "custom_buddy_icon"); | |
828 | 830 |
829 if (custom_icon_file == NULL) | 831 if (custom_icon_file == NULL) |
830 return NULL; | 832 return NULL; |
831 | 833 |
832 dirname = purple_buddy_icons_get_cache_dir(); | 834 dirname = purple_buddy_icons_get_cache_dir(); |
834 | 836 |
835 if (read_icon_file(path, &data, &len)) | 837 if (read_icon_file(path, &data, &len)) |
836 { | 838 { |
837 g_free(path); | 839 g_free(path); |
838 img = purple_buddy_icon_data_new(data, len, custom_icon_file); | 840 img = purple_buddy_icon_data_new(data, len, custom_icon_file); |
839 g_hash_table_insert(pointer_icon_cache, contact, img); | 841 g_hash_table_insert(pointer_icon_cache, node, img); |
840 return img; | 842 return img; |
841 } | 843 } |
842 g_free(path); | 844 g_free(path); |
843 | 845 |
844 return NULL; | 846 return NULL; |
845 } | 847 } |
846 | 848 |
847 PurpleStoredImage * | 849 PurpleStoredImage * |
848 purple_buddy_icons_set_custom_icon(PurpleContact *contact, | 850 purple_buddy_icons_node_set_custom_icon(PurpleBlistNode *node, |
849 guchar *icon_data, size_t icon_len) | 851 guchar *icon_data, size_t icon_len) |
850 { | 852 { |
853 char *old_icon; | |
851 PurpleStoredImage *old_img; | 854 PurpleStoredImage *old_img; |
852 PurpleStoredImage *img = NULL; | 855 PurpleStoredImage *img = NULL; |
853 char *old_icon; | 856 |
854 PurpleBlistNode *child; | 857 g_return_val_if_fail(node != NULL, NULL); |
855 | 858 |
856 old_img = g_hash_table_lookup(pointer_icon_cache, contact); | 859 if (!PURPLE_BLIST_NODE_IS_CONTACT(node) && |
857 | 860 !PURPLE_BLIST_NODE_IS_CHAT(node) && |
858 if (icon_data != NULL && icon_len > 0) | 861 !PURPLE_BLIST_NODE_IS_GROUP(node)) { |
859 { | 862 return NULL; |
863 } | |
864 | |
865 old_img = g_hash_table_lookup(pointer_icon_cache, node); | |
866 | |
867 if (icon_data != NULL && icon_len > 0) { | |
860 img = purple_buddy_icon_data_new(icon_data, icon_len, NULL); | 868 img = purple_buddy_icon_data_new(icon_data, icon_len, NULL); |
861 } | 869 } |
862 | 870 |
863 old_icon = g_strdup(purple_blist_node_get_string((PurpleBlistNode *)contact, | 871 old_icon = g_strdup(purple_blist_node_get_string(node, |
864 "custom_buddy_icon")); | 872 "custom_buddy_icon")); |
865 if (img && purple_buddy_icons_is_caching()) | 873 if (img && purple_buddy_icons_is_caching()) { |
866 { | |
867 const char *filename = purple_imgstore_get_filename(img); | 874 const char *filename = purple_imgstore_get_filename(img); |
868 purple_blist_node_set_string((PurpleBlistNode *)contact, | 875 purple_blist_node_set_string(node, "custom_buddy_icon", |
869 "custom_buddy_icon", | |
870 filename); | 876 filename); |
871 ref_filename(filename); | 877 ref_filename(filename); |
872 } | 878 } else { |
879 purple_blist_node_remove_setting(node, "custom_buddy_icon"); | |
880 } | |
881 unref_filename(old_icon); | |
882 | |
883 if (img) | |
884 g_hash_table_insert(pointer_icon_cache, node, img); | |
873 else | 885 else |
874 { | 886 g_hash_table_remove(pointer_icon_cache, node); |
875 purple_blist_node_remove_setting((PurpleBlistNode *)contact, | 887 |
876 "custom_buddy_icon"); | 888 if (PURPLE_BLIST_NODE_IS_CONTACT(node)) { |
877 } | 889 PurpleBlistNode *child; |
878 unref_filename(old_icon); | 890 for (child = node->child ; child ; child = child->next) |
879 | 891 { |
880 if (img) | 892 PurpleBuddy *buddy; |
881 g_hash_table_insert(pointer_icon_cache, contact, img); | 893 PurpleConversation *conv; |
882 else | 894 |
883 g_hash_table_remove(pointer_icon_cache, contact); | 895 if (!PURPLE_BLIST_NODE_IS_BUDDY(child)) |
884 | 896 continue; |
885 for (child = contact->node.child ; child ; child = child->next) | 897 |
886 { | 898 buddy = (PurpleBuddy *)child; |
887 PurpleBuddy *buddy; | 899 |
888 PurpleConversation *conv; | 900 conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, purple_buddy_get_name(buddy), purple_buddy_get_account(buddy)); |
889 | 901 if (conv) |
890 if (!PURPLE_BLIST_NODE_IS_BUDDY(child)) | 902 purple_conversation_update(conv, PURPLE_CONV_UPDATE_ICON); |
891 continue; | 903 |
892 | 904 /* Is this call necessary anymore? Can the buddies |
893 buddy = (PurpleBuddy *)child; | 905 * themselves need updating when the custom buddy |
894 | 906 * icon changes? */ |
895 conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, | 907 purple_blist_update_node_icon((PurpleBlistNode*)buddy); |
896 purple_buddy_get_name(buddy), | 908 } |
897 purple_buddy_get_account(buddy)); | 909 } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) { |
898 if (conv) | 910 PurpleConversation *conv = NULL; |
911 | |
912 conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, purple_chat_get_name((PurpleChat*)node), purple_chat_get_account((PurpleChat*)node)); | |
913 if (conv) { | |
899 purple_conversation_update(conv, PURPLE_CONV_UPDATE_ICON); | 914 purple_conversation_update(conv, PURPLE_CONV_UPDATE_ICON); |
900 | 915 } |
901 purple_blist_update_buddy_icon(buddy); | 916 } |
902 } | 917 |
903 | 918 purple_blist_update_node_icon(node); |
904 if (old_img) | 919 |
920 if (old_img) { | |
905 purple_imgstore_unref(old_img); | 921 purple_imgstore_unref(old_img); |
906 else if (old_icon) | 922 } else if (old_icon) { |
907 { | |
908 /* The old icon may not have been loaded into memory. In that | 923 /* The old icon may not have been loaded into memory. In that |
909 * case, we'll need to uncache the filename. The filenames | 924 * case, we'll need to uncache the filename. The filenames |
910 * are ref-counted, so this is safe. */ | 925 * are ref-counted, so this is safe. */ |
911 purple_buddy_icon_data_uncache_file(old_icon); | 926 purple_buddy_icon_data_uncache_file(old_icon); |
912 } | 927 } |
913 g_free(old_icon); | 928 g_free(old_icon); |
914 | 929 |
915 return img; | 930 return img; |
916 } | 931 } |
932 | |
933 #ifndef PURPLE_DISABLE_DEPRECATED | |
934 gboolean | |
935 purple_buddy_icons_has_custom_icon(PurpleContact *contact) | |
936 { | |
937 return purple_buddy_icons_node_has_custom_icon((PurpleBlistNode*)contact); | |
938 } | |
939 | |
940 PurpleStoredImage * | |
941 purple_buddy_icons_find_custom_icon(PurpleContact *contact) | |
942 { | |
943 return purple_buddy_icons_node_find_custom_icon((PurpleBlistNode*)contact); | |
944 } | |
945 | |
946 PurpleStoredImage * | |
947 purple_buddy_icons_set_custom_icon(PurpleContact *contact, guchar *icon_data, | |
948 size_t icon_len) | |
949 { | |
950 return purple_buddy_icons_node_set_custom_icon((PurpleBlistNode*)contact, icon_data, icon_len); | |
951 } | |
952 #endif | |
917 | 953 |
918 void | 954 void |
919 _purple_buddy_icon_set_old_icons_dir(const char *dirname) | 955 _purple_buddy_icon_set_old_icons_dir(const char *dirname) |
920 { | 956 { |
921 old_icons_dir = g_strdup(dirname); | 957 old_icons_dir = g_strdup(dirname); |
1136 ref_filename(filename); | 1172 ref_filename(filename); |
1137 g_free(path); | 1173 g_free(path); |
1138 } | 1174 } |
1139 } | 1175 } |
1140 } | 1176 } |
1141 else if (PURPLE_BLIST_NODE_IS_CONTACT(node)) | 1177 else if (PURPLE_BLIST_NODE_IS_CONTACT(node) || |
1178 PURPLE_BLIST_NODE_IS_CHAT(node) || | |
1179 PURPLE_BLIST_NODE_IS_GROUP(node)) | |
1142 { | 1180 { |
1143 const char *filename; | 1181 const char *filename; |
1144 | 1182 |
1145 filename = purple_blist_node_get_string(node, "custom_buddy_icon"); | 1183 filename = purple_blist_node_get_string(node, "custom_buddy_icon"); |
1146 if (filename != NULL) | 1184 if (filename != NULL) |