| 795 /* Close any request dialogs */ |
775 /* Close any request dialogs */ |
| 796 purple_request_close_with_handle(prefs); |
776 purple_request_close_with_handle(prefs); |
| 797 |
777 |
| 798 purple_notify_close_with_handle(prefs); |
778 purple_notify_close_with_handle(prefs); |
| 799 |
779 |
| 800 g_clear_object(&prefs->theme.session); |
|
| 801 |
|
| 802 /* Unregister callbacks. */ |
780 /* Unregister callbacks. */ |
| 803 purple_prefs_disconnect_by_handle(prefs); |
781 purple_prefs_disconnect_by_handle(prefs); |
| 804 |
782 |
| 805 /* NULL-ify globals */ |
|
| 806 prefs_status_themes_combo_box = NULL; |
|
| 807 |
|
| 808 g_free(prefs->proxy.gnome_program_path); |
783 g_free(prefs->proxy.gnome_program_path); |
| 809 prefs = NULL; |
784 prefs = NULL; |
| 810 } |
|
| 811 |
|
| 812 static gchar * |
|
| 813 get_theme_markup(const char *name, gboolean custom, const char *author, |
|
| 814 const char *description) |
|
| 815 { |
|
| 816 |
|
| 817 return g_strdup_printf("<b>%s</b>%s%s%s%s\n<span foreground='dim grey'>%s</span>", |
|
| 818 name, custom ? " " : "", custom ? _("(Custom)") : "", |
|
| 819 author != NULL ? " - " : "", author != NULL ? author : "", |
|
| 820 description != NULL ? description : ""); |
|
| 821 } |
|
| 822 |
|
| 823 /* adds the themes to the theme list from the manager so they can be displayed in prefs */ |
|
| 824 static void |
|
| 825 prefs_themes_sort(PurpleTheme *theme) |
|
| 826 { |
|
| 827 GdkPixbuf *pixbuf = NULL; |
|
| 828 GtkTreeIter iter; |
|
| 829 gchar *image_full = NULL, *markup; |
|
| 830 const gchar *name, *author, *description; |
|
| 831 |
|
| 832 if (PIDGIN_IS_STATUS_ICON_THEME(theme)){ |
|
| 833 GtkListStore *store; |
|
| 834 |
|
| 835 store = prefs_status_icon_themes; |
|
| 836 |
|
| 837 image_full = purple_theme_get_image_full(theme); |
|
| 838 if (image_full != NULL){ |
|
| 839 pixbuf = pidgin_pixbuf_new_from_file_at_scale(image_full, PREFS_OPTIMAL_ICON_SIZE, PREFS_OPTIMAL_ICON_SIZE, TRUE); |
|
| 840 g_free(image_full); |
|
| 841 } else |
|
| 842 pixbuf = NULL; |
|
| 843 |
|
| 844 name = purple_theme_get_name(theme); |
|
| 845 author = purple_theme_get_author(theme); |
|
| 846 description = purple_theme_get_description(theme); |
|
| 847 |
|
| 848 markup = get_theme_markup(name, FALSE, author, description); |
|
| 849 |
|
| 850 gtk_list_store_append(store, &iter); |
|
| 851 gtk_list_store_set(store, &iter, 0, pixbuf, 1, markup, 2, name, -1); |
|
| 852 |
|
| 853 g_free(markup); |
|
| 854 if (pixbuf != NULL) |
|
| 855 g_object_unref(G_OBJECT(pixbuf)); |
|
| 856 |
|
| 857 } |
|
| 858 } |
|
| 859 |
|
| 860 static void |
|
| 861 prefs_set_active_theme_combo(GtkWidget *combo_box, GtkListStore *store, const gchar *current_theme) |
|
| 862 { |
|
| 863 GtkTreeIter iter; |
|
| 864 gchar *theme = NULL; |
|
| 865 gboolean unset = TRUE; |
|
| 866 |
|
| 867 if (current_theme && *current_theme && gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter)) { |
|
| 868 do { |
|
| 869 gtk_tree_model_get(GTK_TREE_MODEL(store), &iter, 2, &theme, -1); |
|
| 870 |
|
| 871 if (purple_strequal(current_theme, theme)) { |
|
| 872 gtk_combo_box_set_active_iter(GTK_COMBO_BOX(combo_box), &iter); |
|
| 873 unset = FALSE; |
|
| 874 } |
|
| 875 |
|
| 876 g_free(theme); |
|
| 877 } while (gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter)); |
|
| 878 } |
|
| 879 |
|
| 880 if (unset) |
|
| 881 gtk_combo_box_set_active(GTK_COMBO_BOX(combo_box), 0); |
|
| 882 } |
|
| 883 |
|
| 884 static void |
|
| 885 prefs_themes_refresh(void) |
|
| 886 { |
|
| 887 GdkPixbuf *pixbuf = NULL; |
|
| 888 gchar *tmp; |
|
| 889 GtkTreeIter iter; |
|
| 890 |
|
| 891 /* refresh the list of themes in the manager */ |
|
| 892 purple_theme_manager_refresh(); |
|
| 893 |
|
| 894 tmp = g_build_filename(PURPLE_DATADIR, "icons", "hicolor", "32x32", |
|
| 895 "apps", "im.pidgin.Pidgin3.png", NULL); |
|
| 896 pixbuf = pidgin_pixbuf_new_from_file_at_scale(tmp, PREFS_OPTIMAL_ICON_SIZE, PREFS_OPTIMAL_ICON_SIZE, TRUE); |
|
| 897 g_free(tmp); |
|
| 898 |
|
| 899 /* status icon themes */ |
|
| 900 gtk_list_store_clear(prefs_status_icon_themes); |
|
| 901 gtk_list_store_append(prefs_status_icon_themes, &iter); |
|
| 902 tmp = get_theme_markup(_("Default"), FALSE, _("Penguin Pimps"), |
|
| 903 _("The default Pidgin status icon theme")); |
|
| 904 gtk_list_store_set(prefs_status_icon_themes, &iter, 0, pixbuf, 1, tmp, 2, "", -1); |
|
| 905 g_free(tmp); |
|
| 906 if (pixbuf) |
|
| 907 g_object_unref(G_OBJECT(pixbuf)); |
|
| 908 |
|
| 909 purple_theme_manager_for_each_theme(prefs_themes_sort); |
|
| 910 |
|
| 911 /* set active */ |
|
| 912 prefs_set_active_theme_combo(prefs_status_themes_combo_box, prefs_status_icon_themes, purple_prefs_get_string(PIDGIN_PREFS_ROOT "/status/icon-theme")); |
|
| 913 } |
|
| 914 |
|
| 915 /* init all the theme variables so that the themes can be sorted later and used by pref pages */ |
|
| 916 static void |
|
| 917 prefs_themes_init(void) |
|
| 918 { |
|
| 919 prefs_status_icon_themes = gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING); |
|
| 920 } |
|
| 921 |
|
| 922 /* |
|
| 923 * prefs_theme_find_theme: |
|
| 924 * @path: A directory containing a theme. The theme could be at the |
|
| 925 * top level of this directory or in any subdirectory thereof. |
|
| 926 * @type: The type of theme to load. The loader for this theme type |
|
| 927 * will be used and this loader will determine what constitutes a |
|
| 928 * "theme." |
|
| 929 * |
|
| 930 * Attempt to load the given directory as a theme. If we are unable to |
|
| 931 * open the path as a theme then we recurse into path and attempt to |
|
| 932 * load each subdirectory that we encounter. |
|
| 933 * |
|
| 934 * Returns: A new reference to a #PurpleTheme. |
|
| 935 */ |
|
| 936 static PurpleTheme * |
|
| 937 prefs_theme_find_theme(const gchar *path, const gchar *type) |
|
| 938 { |
|
| 939 PurpleTheme *theme = purple_theme_manager_load_theme(path, type); |
|
| 940 GDir *dir = g_dir_open(path, 0, NULL); |
|
| 941 const gchar *next; |
|
| 942 |
|
| 943 while (!PURPLE_IS_THEME(theme) && (next = g_dir_read_name(dir))) { |
|
| 944 gchar *next_path = g_build_filename(path, next, NULL); |
|
| 945 |
|
| 946 if (g_file_test(next_path, G_FILE_TEST_IS_DIR)) |
|
| 947 theme = prefs_theme_find_theme(next_path, type); |
|
| 948 |
|
| 949 g_free(next_path); |
|
| 950 } |
|
| 951 |
|
| 952 g_dir_close(dir); |
|
| 953 |
|
| 954 return theme; |
|
| 955 } |
|
| 956 |
|
| 957 /* Eww. Seriously ewww. But thanks, grim! This is taken from guifications2 */ |
|
| 958 static gboolean |
|
| 959 purple_theme_file_copy(const gchar *source, const gchar *destination) |
|
| 960 { |
|
| 961 FILE *src, *dest; |
|
| 962 gint chr = EOF; |
|
| 963 |
|
| 964 if(!(src = g_fopen(source, "rb"))) |
|
| 965 return FALSE; |
|
| 966 if(!(dest = g_fopen(destination, "wb"))) { |
|
| 967 fclose(src); |
|
| 968 return FALSE; |
|
| 969 } |
|
| 970 |
|
| 971 while((chr = fgetc(src)) != EOF) { |
|
| 972 fputc(chr, dest); |
|
| 973 } |
|
| 974 |
|
| 975 fclose(dest); |
|
| 976 fclose(src); |
|
| 977 |
|
| 978 return TRUE; |
|
| 979 } |
|
| 980 |
|
| 981 static void |
|
| 982 free_theme_info(struct theme_info *info) |
|
| 983 { |
|
| 984 if (info != NULL) { |
|
| 985 g_free(info->type); |
|
| 986 g_free(info->extension); |
|
| 987 g_free(info->original_name); |
|
| 988 g_free(info); |
|
| 989 } |
|
| 990 } |
|
| 991 |
|
| 992 /* installs a theme, info is freed by function */ |
|
| 993 static void |
|
| 994 theme_install_theme(char *path, struct theme_info *info) |
|
| 995 { |
|
| 996 gchar *destdir; |
|
| 997 const char *tail; |
|
| 998 gboolean is_archive; |
|
| 999 PurpleTheme *theme = NULL; |
|
| 1000 |
|
| 1001 if (info == NULL) |
|
| 1002 return; |
|
| 1003 |
|
| 1004 /* check the extension */ |
|
| 1005 tail = info->extension ? info->extension : strrchr(path, '.'); |
|
| 1006 |
|
| 1007 if (!tail) { |
|
| 1008 free_theme_info(info); |
|
| 1009 return; |
|
| 1010 } |
|
| 1011 |
|
| 1012 is_archive = !g_ascii_strcasecmp(tail, ".gz") || !g_ascii_strcasecmp(tail, ".tgz"); |
|
| 1013 |
|
| 1014 /* Just to be safe */ |
|
| 1015 g_strchomp(path); |
|
| 1016 |
|
| 1017 destdir = g_build_filename(purple_data_dir(), "themes", "temp", NULL); |
|
| 1018 |
|
| 1019 /* We'll check this just to make sure. This also lets us do something different on |
|
| 1020 * other platforms, if need be */ |
|
| 1021 if (is_archive) { |
|
| 1022 #ifndef _WIN32 |
|
| 1023 gchar *path_escaped = g_shell_quote(path); |
|
| 1024 gchar *destdir_escaped = g_shell_quote(destdir); |
|
| 1025 gchar *command; |
|
| 1026 |
|
| 1027 if (!g_file_test(destdir, G_FILE_TEST_IS_DIR)) { |
|
| 1028 g_mkdir_with_parents(destdir, S_IRUSR | S_IWUSR | S_IXUSR); |
|
| 1029 } |
|
| 1030 |
|
| 1031 command = g_strdup_printf("tar > /dev/null xzf %s -C %s", path_escaped, destdir_escaped); |
|
| 1032 g_free(path_escaped); |
|
| 1033 g_free(destdir_escaped); |
|
| 1034 |
|
| 1035 /* Fire! */ |
|
| 1036 if (system(command)) { |
|
| 1037 purple_notify_error(NULL, NULL, _("Theme failed to unpack."), NULL, NULL); |
|
| 1038 g_free(command); |
|
| 1039 g_free(destdir); |
|
| 1040 free_theme_info(info); |
|
| 1041 return; |
|
| 1042 } |
|
| 1043 g_free(command); |
|
| 1044 #else |
|
| 1045 if (!winpidgin_gz_untar(path, destdir)) { |
|
| 1046 purple_notify_error(NULL, NULL, _("Theme failed to unpack."), NULL, NULL); |
|
| 1047 g_free(destdir); |
|
| 1048 free_theme_info(info); |
|
| 1049 return; |
|
| 1050 } |
|
| 1051 #endif |
|
| 1052 } |
|
| 1053 |
|
| 1054 if (is_archive) { |
|
| 1055 theme = prefs_theme_find_theme(destdir, info->type); |
|
| 1056 |
|
| 1057 if (PURPLE_IS_THEME(theme)) { |
|
| 1058 /* create the location for the theme */ |
|
| 1059 gchar *theme_dest = g_build_filename(purple_data_dir(), "themes", |
|
| 1060 purple_theme_get_name(theme), |
|
| 1061 "purple", info->type, NULL); |
|
| 1062 |
|
| 1063 if (!g_file_test(theme_dest, G_FILE_TEST_IS_DIR)) { |
|
| 1064 g_mkdir_with_parents(theme_dest, S_IRUSR | S_IWUSR | S_IXUSR); |
|
| 1065 } |
|
| 1066 |
|
| 1067 g_free(theme_dest); |
|
| 1068 theme_dest = g_build_filename(purple_data_dir(), "themes", |
|
| 1069 purple_theme_get_name(theme), |
|
| 1070 "purple", info->type, NULL); |
|
| 1071 |
|
| 1072 /* move the entire directory to new location */ |
|
| 1073 if (g_rename(purple_theme_get_dir(theme), theme_dest)) { |
|
| 1074 purple_debug_error("gtkprefs", "Error renaming %s to %s: " |
|
| 1075 "%s\n", purple_theme_get_dir(theme), theme_dest, |
|
| 1076 g_strerror(errno)); |
|
| 1077 } |
|
| 1078 |
|
| 1079 g_free(theme_dest); |
|
| 1080 if (g_remove(destdir) != 0) { |
|
| 1081 purple_debug_error("gtkprefs", |
|
| 1082 "couldn't remove temp (dest) path\n"); |
|
| 1083 } |
|
| 1084 g_object_unref(theme); |
|
| 1085 |
|
| 1086 prefs_themes_refresh(); |
|
| 1087 |
|
| 1088 } else { |
|
| 1089 /* something was wrong with the theme archive */ |
|
| 1090 g_unlink(destdir); |
|
| 1091 purple_notify_error(NULL, NULL, _("Theme failed to load."), NULL, NULL); |
|
| 1092 } |
|
| 1093 |
|
| 1094 } else { /* just a single file so copy it to a new temp directory and attempt to load it*/ |
|
| 1095 gchar *temp_path, *temp_file; |
|
| 1096 |
|
| 1097 temp_path = g_build_filename(purple_data_dir(), "themes", "temp", |
|
| 1098 "sub_folder", NULL); |
|
| 1099 |
|
| 1100 if (info->original_name != NULL) { |
|
| 1101 /* name was changed from the original (probably a dnd) change it back before loading */ |
|
| 1102 temp_file = g_build_filename(temp_path, info->original_name, NULL); |
|
| 1103 |
|
| 1104 } else { |
|
| 1105 gchar *source_name = g_path_get_basename(path); |
|
| 1106 temp_file = g_build_filename(temp_path, source_name, NULL); |
|
| 1107 g_free(source_name); |
|
| 1108 } |
|
| 1109 |
|
| 1110 if (!g_file_test(temp_path, G_FILE_TEST_IS_DIR)) { |
|
| 1111 g_mkdir_with_parents(temp_path, S_IRUSR | S_IWUSR | S_IXUSR); |
|
| 1112 } |
|
| 1113 |
|
| 1114 if (purple_theme_file_copy(path, temp_file)) { |
|
| 1115 /* find the theme, could be in subfolder */ |
|
| 1116 theme = prefs_theme_find_theme(temp_path, info->type); |
|
| 1117 |
|
| 1118 if (PURPLE_IS_THEME(theme)) { |
|
| 1119 gchar *theme_dest = |
|
| 1120 g_build_filename(purple_data_dir(), "themes", |
|
| 1121 purple_theme_get_name(theme), "purple", |
|
| 1122 info->type, NULL); |
|
| 1123 |
|
| 1124 if(!g_file_test(theme_dest, G_FILE_TEST_IS_DIR)) { |
|
| 1125 g_mkdir_with_parents(theme_dest, S_IRUSR | S_IWUSR | S_IXUSR); |
|
| 1126 } |
|
| 1127 |
|
| 1128 if (g_rename(purple_theme_get_dir(theme), theme_dest)) { |
|
| 1129 purple_debug_error("gtkprefs", "Error renaming %s to %s: " |
|
| 1130 "%s\n", purple_theme_get_dir(theme), theme_dest, |
|
| 1131 g_strerror(errno)); |
|
| 1132 } |
|
| 1133 |
|
| 1134 g_free(theme_dest); |
|
| 1135 g_object_unref(theme); |
|
| 1136 |
|
| 1137 prefs_themes_refresh(); |
|
| 1138 } else { |
|
| 1139 if (g_remove(temp_path) != 0) { |
|
| 1140 purple_debug_error("gtkprefs", |
|
| 1141 "couldn't remove temp path"); |
|
| 1142 } |
|
| 1143 purple_notify_error(NULL, NULL, _("Theme failed to load."), NULL, NULL); |
|
| 1144 } |
|
| 1145 } else { |
|
| 1146 purple_notify_error(NULL, NULL, _("Theme failed to copy."), NULL, NULL); |
|
| 1147 } |
|
| 1148 |
|
| 1149 g_free(temp_file); |
|
| 1150 g_free(temp_path); |
|
| 1151 } |
|
| 1152 |
|
| 1153 g_free(destdir); |
|
| 1154 free_theme_info(info); |
|
| 1155 } |
|
| 1156 |
|
| 1157 static void |
|
| 1158 theme_got_url(G_GNUC_UNUSED SoupSession *session, SoupMessage *msg, |
|
| 1159 gpointer _info) |
|
| 1160 { |
|
| 1161 struct theme_info *info = _info; |
|
| 1162 FILE *f; |
|
| 1163 gchar *path; |
|
| 1164 size_t wc; |
|
| 1165 |
|
| 1166 if (!SOUP_STATUS_IS_SUCCESSFUL(msg->status_code)) { |
|
| 1167 free_theme_info(info); |
|
| 1168 return; |
|
| 1169 } |
|
| 1170 |
|
| 1171 f = purple_mkstemp(&path, TRUE); |
|
| 1172 wc = fwrite(msg->response_body->data, msg->response_body->length, 1, f); |
|
| 1173 if (wc != 1) { |
|
| 1174 purple_debug_warning("theme_got_url", "Unable to write theme data.\n"); |
|
| 1175 fclose(f); |
|
| 1176 g_unlink(path); |
|
| 1177 g_free(path); |
|
| 1178 free_theme_info(info); |
|
| 1179 return; |
|
| 1180 } |
|
| 1181 fclose(f); |
|
| 1182 |
|
| 1183 theme_install_theme(path, info); |
|
| 1184 |
|
| 1185 g_unlink(path); |
|
| 1186 g_free(path); |
|
| 1187 } |
|
| 1188 |
|
| 1189 static void |
|
| 1190 theme_dnd_recv(GtkWidget *widget, GdkDragContext *dc, guint x, guint y, |
|
| 1191 GtkSelectionData *sd, guint info, guint t, gpointer user_data) |
|
| 1192 { |
|
| 1193 gchar *name = g_strchomp((gchar *)gtk_selection_data_get_data(sd)); |
|
| 1194 |
|
| 1195 if ((gtk_selection_data_get_length(sd) >= 0) |
|
| 1196 && (gtk_selection_data_get_format(sd) == 8)) { |
|
| 1197 /* Well, it looks like the drag event was cool. |
|
| 1198 * Let's do something with it */ |
|
| 1199 gchar *temp; |
|
| 1200 struct theme_info *info = g_new0(struct theme_info, 1); |
|
| 1201 info->type = g_strdup((gchar *)user_data); |
|
| 1202 info->extension = g_strdup(g_strrstr(name,".")); |
|
| 1203 temp = g_strrstr(name, "/"); |
|
| 1204 info->original_name = temp ? g_strdup(++temp) : NULL; |
|
| 1205 |
|
| 1206 if (!g_ascii_strncasecmp(name, "file://", 7)) { |
|
| 1207 GError *converr = NULL; |
|
| 1208 gchar *tmp; |
|
| 1209 /* It looks like we're dealing with a local file. Let's |
|
| 1210 * just untar it in the right place */ |
|
| 1211 if(!(tmp = g_filename_from_uri(name, NULL, &converr))) { |
|
| 1212 purple_debug_error("theme dnd", "%s", |
|
| 1213 converr ? converr->message : |
|
| 1214 "g_filename_from_uri error"); |
|
| 1215 free_theme_info(info); |
|
| 1216 return; |
|
| 1217 } |
|
| 1218 theme_install_theme(tmp, info); |
|
| 1219 g_free(tmp); |
|
| 1220 } else if (!g_ascii_strncasecmp(name, "http://", 7) || |
|
| 1221 !g_ascii_strncasecmp(name, "https://", 8)) { |
|
| 1222 /* Oo, a web drag and drop. This is where things |
|
| 1223 * will start to get interesting */ |
|
| 1224 SoupMessage *msg; |
|
| 1225 |
|
| 1226 if (prefs->theme.session == NULL) { |
|
| 1227 prefs->theme.session = soup_session_new(); |
|
| 1228 } |
|
| 1229 |
|
| 1230 soup_session_abort(prefs->theme.session); |
|
| 1231 |
|
| 1232 msg = soup_message_new("GET", name); |
|
| 1233 // purple_http_request_set_max_len(msg, PREFS_MAX_DOWNLOADED_THEME_SIZE); |
|
| 1234 soup_session_queue_message(prefs->theme.session, msg, theme_got_url, |
|
| 1235 info); |
|
| 1236 } else |
|
| 1237 free_theme_info(info); |
|
| 1238 |
|
| 1239 gtk_drag_finish(dc, TRUE, FALSE, t); |
|
| 1240 } |
|
| 1241 |
|
| 1242 gtk_drag_finish(dc, FALSE, FALSE, t); |
|
| 1243 } |
|
| 1244 |
|
| 1245 /* builds a theme combo box from a list store with columns: icon preview, markup, theme name */ |
|
| 1246 static void |
|
| 1247 prefs_build_theme_combo_box(GtkWidget *combo_box, GtkListStore *store, |
|
| 1248 const char *current_theme, const char *type) |
|
| 1249 { |
|
| 1250 GtkTargetEntry te[3] = { |
|
| 1251 {"text/plain", 0, 0}, |
|
| 1252 {"text/uri-list", 0, 1}, |
|
| 1253 {"STRING", 0, 2} |
|
| 1254 }; |
|
| 1255 |
|
| 1256 g_return_if_fail(store != NULL && current_theme != NULL); |
|
| 1257 |
|
| 1258 gtk_combo_box_set_model(GTK_COMBO_BOX(combo_box), |
|
| 1259 GTK_TREE_MODEL(store)); |
|
| 1260 |
|
| 1261 gtk_drag_dest_set(combo_box, GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP, te, |
|
| 1262 sizeof(te) / sizeof(GtkTargetEntry) , GDK_ACTION_COPY | GDK_ACTION_MOVE); |
|
| 1263 |
|
| 1264 g_signal_connect(G_OBJECT(combo_box), "drag_data_received", G_CALLBACK(theme_dnd_recv), (gpointer) type); |
|
| 1265 } |
|
| 1266 |
|
| 1267 /* sets the current icon theme */ |
|
| 1268 static void |
|
| 1269 prefs_set_status_icon_theme_cb(GtkComboBox *combo_box, gpointer user_data) |
|
| 1270 { |
|
| 1271 PidginStatusIconTheme *theme = NULL; |
|
| 1272 GtkTreeIter iter; |
|
| 1273 gchar *name = NULL; |
|
| 1274 |
|
| 1275 if(gtk_combo_box_get_active_iter(combo_box, &iter)) { |
|
| 1276 |
|
| 1277 gtk_tree_model_get(GTK_TREE_MODEL(prefs_status_icon_themes), &iter, 2, &name, -1); |
|
| 1278 |
|
| 1279 if(!name || *name) |
|
| 1280 theme = PIDGIN_STATUS_ICON_THEME(purple_theme_manager_find_theme(name, "status-icon")); |
|
| 1281 |
|
| 1282 g_free(name); |
|
| 1283 |
|
| 1284 pidgin_stock_load_status_icon_theme(theme); |
|
| 1285 pidgin_blist_refresh(purple_blist_get_default()); |
|
| 1286 } |
|
| 1287 } |
|
| 1288 |
|
| 1289 static void |
|
| 1290 bind_theme_page(PidginPrefsWindow *win) |
|
| 1291 { |
|
| 1292 /* Status Icon Themes */ |
|
| 1293 prefs_build_theme_combo_box(win->theme.status, prefs_status_icon_themes, |
|
| 1294 PIDGIN_PREFS_ROOT "/status/icon-theme", |
|
| 1295 "icon"); |
|
| 1296 prefs_status_themes_combo_box = win->theme.status; |
|
| 1297 } |
785 } |
| 1298 |
786 |
| 1299 static void |
787 static void |
| 1300 formatting_toggle_cb(TalkatuActionGroup *ag, GAction *action, const gchar *name, gpointer data) |
788 formatting_toggle_cb(TalkatuActionGroup *ag, GAction *action, const gchar *name, gpointer data) |
| 1301 { |
789 { |