| 33 #include "gtksmiley.h" |
33 #include "gtksmiley.h" |
| 34 #include "gtkthemes.h" |
34 #include "gtkthemes.h" |
| 35 #include "gtkwebview.h" |
35 #include "gtkwebview.h" |
| 36 |
36 |
| 37 GSList *smiley_themes = NULL; |
37 GSList *smiley_themes = NULL; |
| 38 struct smiley_theme *current_smiley_theme; |
38 struct PidginSmileyTheme *current_smiley_theme; |
| 39 |
39 |
| 40 static void pidgin_themes_destroy_smiley_theme_smileys(struct smiley_theme *theme); |
40 static void pidgin_themes_destroy_smiley_theme_smileys(struct PidginSmileyTheme *theme); |
| 41 |
41 |
| 42 gboolean pidgin_themes_smileys_disabled() |
42 gboolean pidgin_themes_smileys_disabled() |
| 43 { |
43 { |
| 44 if (!current_smiley_theme) |
44 if (!current_smiley_theme) |
| 45 return 1; |
45 return 1; |
| 46 |
46 |
| 47 return strcmp(current_smiley_theme->name, "none") == 0; |
47 return strcmp(current_smiley_theme->name, "none") == 0; |
| 48 } |
48 } |
| 49 |
49 |
| 50 static void |
50 static void |
| 51 pidgin_themes_destroy_smiley_theme(struct smiley_theme *theme) |
51 pidgin_themes_destroy_smiley_theme(struct PidginSmileyTheme *theme) |
| 52 { |
52 { |
| 53 pidgin_themes_destroy_smiley_theme_smileys(theme); |
53 pidgin_themes_destroy_smiley_theme_smileys(theme); |
| 54 |
54 |
| 55 g_free(theme->name); |
55 g_free(theme->name); |
| 56 g_free(theme->desc); |
56 g_free(theme->desc); |
| 87 if (!g_file_test(file, G_FILE_TEST_EXISTS)) return; |
87 if (!g_file_test(file, G_FILE_TEST_EXISTS)) return; |
| 88 if ((theme_dir = g_strdup(file)) == NULL) return ; |
88 if ((theme_dir = g_strdup(file)) == NULL) return ; |
| 89 |
89 |
| 90 if ((last_slash = g_strrstr(theme_dir, G_DIR_SEPARATOR_S)) != NULL) { |
90 if ((last_slash = g_strrstr(theme_dir, G_DIR_SEPARATOR_S)) != NULL) { |
| 91 GSList *iter = NULL; |
91 GSList *iter = NULL; |
| 92 struct smiley_theme *theme = NULL, *new_theme = NULL; |
92 struct PidginSmileyTheme *theme = NULL, *new_theme = NULL; |
| 93 |
93 |
| 94 *last_slash = 0; |
94 *last_slash = 0; |
| 95 |
95 |
| 96 /* Delete files on disk */ |
96 /* Delete files on disk */ |
| 97 pidgin_themes_remove_theme_dir(theme_dir); |
97 pidgin_themes_remove_theme_dir(theme_dir); |
| 98 |
98 |
| 99 /* Find theme in themes list and remove it */ |
99 /* Find theme in themes list and remove it */ |
| 100 for (iter = smiley_themes ; iter ; iter = iter->next) { |
100 for (iter = smiley_themes ; iter ; iter = iter->next) { |
| 101 theme = ((struct smiley_theme *)(iter->data)); |
101 theme = ((struct PidginSmileyTheme *)(iter->data)); |
| 102 if (!strcmp(theme->path, file)) |
102 if (!strcmp(theme->path, file)) |
| 103 break ; |
103 break ; |
| 104 } |
104 } |
| 105 if (iter) { |
105 if (iter) { |
| 106 if (theme == current_smiley_theme) { |
106 if (theme == current_smiley_theme) { |
| 107 new_theme = ((struct smiley_theme *)(NULL == iter->next ? (smiley_themes == iter ? NULL : smiley_themes->data) : iter->next->data)); |
107 new_theme = ((struct PidginSmileyTheme *)(NULL == iter->next ? (smiley_themes == iter ? NULL : smiley_themes->data) : iter->next->data)); |
| 108 if (new_theme) |
108 if (new_theme) |
| 109 purple_prefs_set_string(PIDGIN_PREFS_ROOT "/smileys/theme", new_theme->name); |
109 purple_prefs_set_string(PIDGIN_PREFS_ROOT "/smileys/theme", new_theme->name); |
| 110 else |
110 else |
| 111 current_smiley_theme = NULL; |
111 current_smiley_theme = NULL; |
| 112 } |
112 } |
| 120 g_free(theme_dir); |
120 g_free(theme_dir); |
| 121 } |
121 } |
| 122 |
122 |
| 123 static void _pidgin_themes_smiley_themeize(GtkWidget *webview, gboolean custom) |
123 static void _pidgin_themes_smiley_themeize(GtkWidget *webview, gboolean custom) |
| 124 { |
124 { |
| 125 struct smiley_list *list; |
125 struct PidginSmileyList *list; |
| 126 if (!current_smiley_theme) |
126 if (!current_smiley_theme) |
| 127 return; |
127 return; |
| 128 |
128 |
| 129 gtk_webview_remove_smileys(GTK_WEBVIEW(webview)); |
129 pidgin_webview_remove_smileys(PIDGIN_WEBVIEW(webview)); |
| 130 list = current_smiley_theme->list; |
130 list = current_smiley_theme->list; |
| 131 while (list) { |
131 while (list) { |
| 132 char *sml = !strcmp(list->sml, "default") ? NULL : list->sml; |
132 char *sml = !strcmp(list->sml, "default") ? NULL : list->sml; |
| 133 GSList *icons = list->smileys; |
133 GSList *icons = list->smileys; |
| 134 while (icons) { |
134 while (icons) { |
| 135 gtk_webview_associate_smiley(GTK_WEBVIEW(webview), sml, icons->data); |
135 pidgin_webview_associate_smiley(PIDGIN_WEBVIEW(webview), sml, icons->data); |
| 136 icons = icons->next; |
136 icons = icons->next; |
| 137 } |
137 } |
| 138 |
138 |
| 139 if (custom == TRUE) { |
139 if (custom == TRUE) { |
| 140 icons = pidgin_smileys_get_all(); |
140 icons = pidgin_smileys_get_all(); |
| 141 |
141 |
| 142 while (icons) { |
142 while (icons) { |
| 143 gtk_webview_associate_smiley(GTK_WEBVIEW(webview), sml, icons->data); |
143 pidgin_webview_associate_smiley(PIDGIN_WEBVIEW(webview), sml, icons->data); |
| 144 icons = icons->next; |
144 icons = icons->next; |
| 145 } |
145 } |
| 146 } |
146 } |
| 147 |
147 |
| 148 list = list->next; |
148 list = list->next; |
| 160 { |
160 { |
| 161 _pidgin_themes_smiley_themeize(webview, TRUE); |
161 _pidgin_themes_smiley_themeize(webview, TRUE); |
| 162 } |
162 } |
| 163 |
163 |
| 164 static void |
164 static void |
| 165 pidgin_themes_destroy_smiley_theme_smileys(struct smiley_theme *theme) |
165 pidgin_themes_destroy_smiley_theme_smileys(struct PidginSmileyTheme *theme) |
| 166 { |
166 { |
| 167 struct smiley_list *wer; |
167 struct PidginSmileyList *wer; |
| 168 |
168 |
| 169 for (wer = theme->list; wer != NULL; wer = theme->list) { |
169 for (wer = theme->list; wer != NULL; wer = theme->list) { |
| 170 while (wer->smileys) { |
170 while (wer->smileys) { |
| 171 GtkWebViewSmiley *uio = wer->smileys->data; |
171 PidginWebViewSmiley *uio = wer->smileys->data; |
| 172 gtk_webview_smiley_destroy(uio); |
172 pidgin_webview_smiley_destroy(uio); |
| 173 wer->smileys = g_slist_delete_link(wer->smileys, wer->smileys); |
173 wer->smileys = g_slist_delete_link(wer->smileys, wer->smileys); |
| 174 } |
174 } |
| 175 theme->list = wer->next; |
175 theme->list = wer->next; |
| 176 g_free(wer->sml); |
176 g_free(wer->sml); |
| 177 g_free(wer); |
177 g_free(wer); |
| 180 } |
180 } |
| 181 |
181 |
| 182 static void |
182 static void |
| 183 pidgin_smiley_themes_remove_non_existing(void) |
183 pidgin_smiley_themes_remove_non_existing(void) |
| 184 { |
184 { |
| 185 static struct smiley_theme *theme = NULL; |
185 static struct PidginSmileyTheme *theme = NULL; |
| 186 GSList *iter = NULL; |
186 GSList *iter = NULL; |
| 187 |
187 |
| 188 if (!smiley_themes) return ; |
188 if (!smiley_themes) return ; |
| 189 |
189 |
| 190 for (iter = smiley_themes ; iter ; iter = iter->next) { |
190 for (iter = smiley_themes ; iter ; iter = iter->next) { |
| 191 theme = ((struct smiley_theme *)(iter->data)); |
191 theme = ((struct PidginSmileyTheme *)(iter->data)); |
| 192 if (!g_file_test(theme->path, G_FILE_TEST_EXISTS)) { |
192 if (!g_file_test(theme->path, G_FILE_TEST_EXISTS)) { |
| 193 if (theme == current_smiley_theme) |
193 if (theme == current_smiley_theme) |
| 194 current_smiley_theme = ((struct smiley_theme *)(NULL == iter->next ? NULL : iter->next->data)); |
194 current_smiley_theme = ((struct PidginSmileyTheme *)(NULL == iter->next ? NULL : iter->next->data)); |
| 195 pidgin_themes_destroy_smiley_theme(theme); |
195 pidgin_themes_destroy_smiley_theme(theme); |
| 196 iter->data = NULL; |
196 iter->data = NULL; |
| 197 } |
197 } |
| 198 } |
198 } |
| 199 /* Remove all elements whose data is NULL */ |
199 /* Remove all elements whose data is NULL */ |
| 200 smiley_themes = g_slist_remove_all(smiley_themes, NULL); |
200 smiley_themes = g_slist_remove_all(smiley_themes, NULL); |
| 201 |
201 |
| 202 if (!current_smiley_theme && smiley_themes) { |
202 if (!current_smiley_theme && smiley_themes) { |
| 203 struct smiley_theme *smile = g_slist_last(smiley_themes)->data; |
203 struct PidginSmileyTheme *smile = g_slist_last(smiley_themes)->data; |
| 204 pidgin_themes_load_smiley_theme(smile->path, TRUE); |
204 pidgin_themes_load_smiley_theme(smile->path, TRUE); |
| 205 } |
205 } |
| 206 } |
206 } |
| 207 |
207 |
| 208 void pidgin_themes_load_smiley_theme(const char *file, gboolean load) |
208 void pidgin_themes_load_smiley_theme(const char *file, gboolean load) |
| 209 { |
209 { |
| 210 FILE *f = g_fopen(file, "rb"); |
210 FILE *f = g_fopen(file, "rb"); |
| 211 char buf[256]; |
211 char buf[256]; |
| 212 char *i; |
212 char *i; |
| 213 gsize line_nbr = 0; |
213 gsize line_nbr = 0; |
| 214 struct smiley_theme *theme=NULL; |
214 struct PidginSmileyTheme *theme=NULL; |
| 215 struct smiley_list *list = NULL; |
215 struct PidginSmileyList *list = NULL; |
| 216 GSList *lst = smiley_themes; |
216 GSList *lst = smiley_themes; |
| 217 char *dirname; |
217 char *dirname; |
| 218 |
218 |
| 219 if (!f) |
219 if (!f) |
| 220 return; |
220 return; |
| 221 |
221 |
| 222 while (lst) { |
222 while (lst) { |
| 223 struct smiley_theme *thm = lst->data; |
223 struct PidginSmileyTheme *thm = lst->data; |
| 224 if (!strcmp(thm->path, file)) { |
224 if (!strcmp(thm->path, file)) { |
| 225 theme = thm; |
225 theme = thm; |
| 226 break; |
226 break; |
| 227 } |
227 } |
| 228 lst = lst->next; |
228 lst = lst->next; |
| 266 i = buf; |
266 i = buf; |
| 267 while (isspace(*i)) |
267 while (isspace(*i)) |
| 268 i++; |
268 i++; |
| 269 |
269 |
| 270 if (*i == '[' && strchr(i, ']') && load) { |
270 if (*i == '[' && strchr(i, ']') && load) { |
| 271 struct smiley_list *child = g_new0(struct smiley_list, 1); |
271 struct PidginSmileyList *child = g_new0(struct PidginSmileyList, 1); |
| 272 child->sml = g_strndup(i+1, strchr(i, ']') - i - 1); |
272 child->sml = g_strndup(i+1, strchr(i, ']') - i - 1); |
| 273 child->files = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); |
273 child->files = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); |
| 274 |
274 |
| 275 if (theme->list) |
275 if (theme->list) |
| 276 list->next = child; |
276 list->next = child; |
| 316 } |
316 } |
| 317 l[li] = 0; |
317 l[li] = 0; |
| 318 if (!sfile) { |
318 if (!sfile) { |
| 319 sfile = g_build_filename(dirname, l, NULL); |
319 sfile = g_build_filename(dirname, l, NULL); |
| 320 } else { |
320 } else { |
| 321 GtkWebViewSmiley *smiley = gtk_webview_smiley_create(sfile, l, hidden, 0); |
321 PidginWebViewSmiley *smiley = pidgin_webview_smiley_create(sfile, l, hidden, 0); |
| 322 list->smileys = g_slist_prepend(list->smileys, smiley); |
322 list->smileys = g_slist_prepend(list->smileys, smiley); |
| 323 g_hash_table_insert (list->files, g_strdup(l), g_strdup(sfile)); |
323 g_hash_table_insert (list->files, g_strdup(l), g_strdup(sfile)); |
| 324 } |
324 } |
| 325 while (isspace(*i)) |
325 while (isspace(*i)) |
| 326 i++; |
326 i++; |
| 401 } |
401 } |
| 402 g_free(probedirs[l]); |
402 g_free(probedirs[l]); |
| 403 } |
403 } |
| 404 |
404 |
| 405 if (!current_smiley_theme && smiley_themes) { |
405 if (!current_smiley_theme && smiley_themes) { |
| 406 struct smiley_theme *smile = smiley_themes->data; |
406 struct PidginSmileyTheme *smile = smiley_themes->data; |
| 407 pidgin_themes_load_smiley_theme(smile->path, TRUE); |
407 pidgin_themes_load_smiley_theme(smile->path, TRUE); |
| 408 } |
408 } |
| 409 } |
409 } |
| 410 |
410 |
| 411 GSList *pidgin_themes_get_proto_smileys(const char *id) { |
411 GSList *pidgin_themes_get_proto_smileys(const char *id) { |
| 412 PurpleProtocol *protocol; |
412 PurpleProtocol *protocol; |
| 413 struct smiley_list *list, *def; |
413 struct PidginSmileyList *list, *def; |
| 414 |
414 |
| 415 if ((current_smiley_theme == NULL) || (current_smiley_theme->list == NULL)) |
415 if ((current_smiley_theme == NULL) || (current_smiley_theme->list == NULL)) |
| 416 return NULL; |
416 return NULL; |
| 417 |
417 |
| 418 def = list = current_smiley_theme->list; |
418 def = list = current_smiley_theme->list; |
| 441 purple_prefs_get_string(PIDGIN_PREFS_ROOT "/smileys/theme"); |
441 purple_prefs_get_string(PIDGIN_PREFS_ROOT "/smileys/theme"); |
| 442 |
442 |
| 443 pidgin_themes_smiley_theme_probe(); |
443 pidgin_themes_smiley_theme_probe(); |
| 444 |
444 |
| 445 for (l = smiley_themes; l; l = l->next) { |
445 for (l = smiley_themes; l; l = l->next) { |
| 446 struct smiley_theme *smile = l->data; |
446 struct PidginSmileyTheme *smile = l->data; |
| 447 if (smile->name && strcmp(current_theme, smile->name) == 0) { |
447 if (smile->name && strcmp(current_theme, smile->name) == 0) { |
| 448 pidgin_themes_load_smiley_theme(smile->path, TRUE); |
448 pidgin_themes_load_smiley_theme(smile->path, TRUE); |
| 449 break; |
449 break; |
| 450 } |
450 } |
| 451 } |
451 } |
| 452 |
452 |
| 453 /* If we still don't have a smiley theme, choose the first one */ |
453 /* If we still don't have a smiley theme, choose the first one */ |
| 454 if (!current_smiley_theme && smiley_themes) { |
454 if (!current_smiley_theme && smiley_themes) { |
| 455 struct smiley_theme *smile = smiley_themes->data; |
455 struct PidginSmileyTheme *smile = smiley_themes->data; |
| 456 pidgin_themes_load_smiley_theme(smile->path, TRUE); |
456 pidgin_themes_load_smiley_theme(smile->path, TRUE); |
| 457 } |
457 } |
| 458 } |
458 } |