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)