Mercurial > pidgin.yaz
comparison pidgin/gtksmiley.c @ 23144:dea8b856466e
propagate from branch 'im.pidgin.pidgin.custom_smiley' (head c134ff23eba5faac09c13e731e792fa612c91a9a)
to branch 'im.pidgin.pidgin.next.minor' (head 4d2d20241c7dac5915e142f0aa9811c9eab40111)
author | Sadrul Habib Chowdhury <imadil@gmail.com> |
---|---|
date | Mon, 12 May 2008 23:17:48 +0000 |
parents | d0ee799828d1 |
children | 99ef50c8da91 |
comparison
equal
deleted
inserted
replaced
23116:d53f72735830 | 23144:dea8b856466e |
---|---|
1 /** | |
2 * @file gtksmiley.c GTK+ Smiley Manager API | |
3 * @ingroup pidgin | |
4 */ | |
5 | |
6 /* | |
7 * pidgin | |
8 * | |
9 * Pidgin is the legal property of its developers, whose names are too numerous | |
10 * to list here. Please refer to the COPYRIGHT file distributed with this | |
11 * source distribution. | |
12 * | |
13 * This program is free software; you can redistribute it and/or modify | |
14 * it under the terms of the GNU General Public License as published by | |
15 * the Free Software Foundation; either version 2 of the License, or | |
16 * (at your option) any later version. | |
17 * | |
18 * This program is distributed in the hope that it will be useful, | |
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
21 * GNU General Public License for more details. | |
22 * | |
23 * You should have received a copy of the GNU General Public License | |
24 * along with this program; if not, write to the Free Software | |
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA | |
26 */ | |
27 | |
28 #include "internal.h" | |
29 #include "pidgin.h" | |
30 | |
31 #include "debug.h" | |
32 #include "notify.h" | |
33 #include "smiley.h" | |
34 | |
35 #include "gtkimhtml.h" | |
36 #include "gtksmiley.h" | |
37 #include "gtkutils.h" | |
38 #include "pidginstock.h" | |
39 | |
40 #define PIDGIN_RESPONSE_EDIT 1000 | |
41 | |
42 typedef struct | |
43 { | |
44 PurpleSmiley *smiley; | |
45 GtkWidget *parent; | |
46 GtkWidget *smile; | |
47 GtkWidget *smiley_image; | |
48 gchar *filename; | |
49 } PidginSmiley; | |
50 | |
51 typedef struct | |
52 { | |
53 GtkWidget *window; | |
54 | |
55 GtkWidget *treeview; | |
56 GtkListStore *model; | |
57 } SmileyManager; | |
58 | |
59 enum | |
60 { | |
61 ICON, | |
62 SHORTCUT, | |
63 SMILEY, | |
64 N_COL | |
65 }; | |
66 | |
67 static SmileyManager *smiley_manager = NULL; | |
68 static GSList *gtk_smileys = NULL; | |
69 | |
70 static void | |
71 pidgin_smiley_destroy(PidginSmiley *smiley) | |
72 { | |
73 gtk_widget_destroy(smiley->parent); | |
74 g_free(smiley->filename); | |
75 g_free(smiley); | |
76 } | |
77 | |
78 /****************************************************************************** | |
79 * GtkIMHtmlSmileys stuff | |
80 *****************************************************************************/ | |
81 /* Perhaps these should be in gtkimhtml.c instead. -- sadrul */ | |
82 static void add_gtkimhtml_to_list(GtkIMHtmlSmiley *gtksmiley) | |
83 { | |
84 gtk_smileys = g_slist_prepend(gtk_smileys, gtksmiley); | |
85 | |
86 purple_debug_info("gtksmiley", "adding %s to gtk_smileys\n", gtksmiley->smile); | |
87 } | |
88 | |
89 static void | |
90 shortcut_changed_cb(PurpleSmiley *smiley, gpointer dontcare, GtkIMHtmlSmiley *gtksmiley) | |
91 { | |
92 g_free(gtksmiley->smile); | |
93 gtksmiley->smile = g_strdup(purple_smiley_get_shortcut(smiley)); | |
94 } | |
95 | |
96 static GtkIMHtmlSmiley *smiley_purple_to_gtkimhtml(PurpleSmiley *smiley) | |
97 { | |
98 GtkIMHtmlSmiley *gtksmiley; | |
99 gchar *filename; | |
100 const gchar *file; | |
101 | |
102 file = purple_imgstore_get_filename(purple_smiley_get_stored_image(smiley)); | |
103 | |
104 filename = g_build_filename(purple_smileys_get_storing_dir(), file, NULL); | |
105 | |
106 gtksmiley = gtk_imhtml_smiley_create(filename, purple_smiley_get_shortcut(smiley), | |
107 FALSE, GTK_IMHTML_SMILEY_CUSTOM); | |
108 g_free(filename); | |
109 | |
110 /* Make sure the shortcut for the GtkIMHtmlSmiley is updated with the PurpleSmiley */ | |
111 g_signal_connect(G_OBJECT(smiley), "notify::shortcut", | |
112 G_CALLBACK(shortcut_changed_cb), gtksmiley); | |
113 | |
114 return gtksmiley; | |
115 } | |
116 | |
117 void pidgin_smiley_del_from_list(PurpleSmiley *smiley) | |
118 { | |
119 GSList *list = NULL; | |
120 GtkIMHtmlSmiley *gtksmiley; | |
121 | |
122 if (gtk_smileys == NULL) | |
123 return; | |
124 | |
125 list = gtk_smileys; | |
126 | |
127 for (; list; list = list->next) { | |
128 gtksmiley = (GtkIMHtmlSmiley*)list->data; | |
129 | |
130 if (strcmp(gtksmiley->smile, purple_smiley_get_shortcut(smiley))) | |
131 continue; | |
132 | |
133 gtk_imhtml_smiley_destroy(gtksmiley); | |
134 g_signal_handlers_disconnect_matched(G_OBJECT(smiley), G_SIGNAL_MATCH_DATA, | |
135 0, 0, NULL, NULL, gtksmiley); | |
136 break; | |
137 } | |
138 | |
139 if (list) | |
140 gtk_smileys = g_slist_delete_link(gtk_smileys, list); | |
141 } | |
142 | |
143 void pidgin_smiley_add_to_list(PurpleSmiley *smiley) | |
144 { | |
145 GtkIMHtmlSmiley *gtksmiley; | |
146 | |
147 gtksmiley = smiley_purple_to_gtkimhtml(smiley); | |
148 add_gtkimhtml_to_list(gtksmiley); | |
149 g_signal_connect(G_OBJECT(smiley), "destroy", G_CALLBACK(pidgin_smiley_del_from_list), NULL); | |
150 } | |
151 | |
152 void pidgin_smileys_init(void) | |
153 { | |
154 GList *smileys; | |
155 PurpleSmiley *smiley; | |
156 | |
157 if (gtk_smileys != NULL) | |
158 return; | |
159 | |
160 smileys = purple_smileys_get_all(); | |
161 | |
162 for (; smileys; smileys = g_list_delete_link(smileys, smileys)) { | |
163 smiley = (PurpleSmiley*)smileys->data; | |
164 | |
165 pidgin_smiley_add_to_list(smiley); | |
166 } | |
167 } | |
168 | |
169 void pidgin_smileys_uninit(void) | |
170 { | |
171 GSList *list; | |
172 GtkIMHtmlSmiley *gtksmiley; | |
173 | |
174 list = gtk_smileys; | |
175 | |
176 if (list == NULL) | |
177 return; | |
178 | |
179 for (; list; list = g_slist_delete_link(list, list)) { | |
180 gtksmiley = (GtkIMHtmlSmiley*)list->data; | |
181 gtk_imhtml_smiley_destroy(gtksmiley); | |
182 } | |
183 | |
184 gtk_smileys = NULL; | |
185 } | |
186 | |
187 GSList *pidgin_smileys_get_all(void) | |
188 { | |
189 return gtk_smileys; | |
190 } | |
191 | |
192 /****************************************************************************** | |
193 * Manager stuff | |
194 *****************************************************************************/ | |
195 | |
196 static void refresh_list(void); | |
197 | |
198 /****************************************************************************** | |
199 * The Add dialog | |
200 ******************************************************************************/ | |
201 | |
202 static void do_add(GtkWidget *widget, PidginSmiley *s) | |
203 { | |
204 const gchar *entry; | |
205 PurpleSmiley *emoticon; | |
206 | |
207 entry = gtk_entry_get_text(GTK_ENTRY(s->smile)); | |
208 emoticon = purple_smileys_find_by_shortcut(entry); | |
209 if (emoticon && emoticon != s->smiley) { | |
210 purple_notify_error(s->parent, _("Custom Smiley"), | |
211 _("Duplicate Shortcut"), | |
212 _("A custom smiley for the selected shortcut already exists. Please specify a different shortcut.")); | |
213 return; | |
214 } | |
215 | |
216 if (s->smiley) { | |
217 if (s->filename) { | |
218 gchar *data = NULL; | |
219 size_t len; | |
220 GError *err = NULL; | |
221 | |
222 if (!g_file_get_contents(s->filename, &data, &len, &err)) { | |
223 purple_debug_error("gtksmiley", "Error reading %s: %s\n", | |
224 s->filename, err->message); | |
225 g_error_free(err); | |
226 | |
227 return; | |
228 } | |
229 purple_smiley_set_data(s->smiley, (guchar*)data, len, FALSE); | |
230 } | |
231 purple_smiley_set_shortcut(s->smiley, entry); | |
232 } else { | |
233 if ((s->filename == NULL || *entry == 0)) { | |
234 purple_notify_error(s->parent, _("Custom Smiley"), | |
235 _("More Data needed"), | |
236 s->filename ? _("Please provide a shortcut to associate with the smiley.") | |
237 : _("Please select an image for the smiley.")); | |
238 return; | |
239 } | |
240 | |
241 purple_debug_info("gtksmiley", "adding a new smiley\n"); | |
242 emoticon = purple_smiley_new_from_file(entry, s->filename); | |
243 pidgin_smiley_add_to_list(emoticon); | |
244 } | |
245 | |
246 if (smiley_manager != NULL) | |
247 refresh_list(); | |
248 | |
249 gtk_widget_destroy(s->parent); | |
250 } | |
251 | |
252 static void do_add_select_cb(GtkWidget *widget, gint resp, PidginSmiley *s) | |
253 { | |
254 switch (resp) { | |
255 case GTK_RESPONSE_ACCEPT: | |
256 do_add(widget, s); | |
257 break; | |
258 case GTK_RESPONSE_DELETE_EVENT: | |
259 case GTK_RESPONSE_CANCEL: | |
260 gtk_widget_destroy(s->parent); | |
261 break; | |
262 default: | |
263 purple_debug_error("gtksmiley", "no valid response\n"); | |
264 break; | |
265 } | |
266 } | |
267 | |
268 static void do_add_file_cb(const char *filename, gpointer data) | |
269 { | |
270 PidginSmiley *s = data; | |
271 GdkPixbuf *pixbuf; | |
272 | |
273 if (!filename) | |
274 return; | |
275 | |
276 g_free(s->filename); | |
277 s->filename = g_strdup(filename); | |
278 pixbuf = gdk_pixbuf_new_from_file_at_scale(filename, 64, 64, FALSE, NULL); | |
279 gtk_image_set_from_pixbuf(GTK_IMAGE(s->smiley_image), pixbuf); | |
280 if (pixbuf) | |
281 gdk_pixbuf_unref(pixbuf); | |
282 gtk_widget_grab_focus(s->smile); | |
283 } | |
284 | |
285 static void | |
286 open_image_selector(GtkWidget *widget, PidginSmiley *psmiley) | |
287 { | |
288 GtkWidget *file_chooser; | |
289 file_chooser = pidgin_buddy_icon_chooser_new(GTK_WINDOW(gtk_widget_get_toplevel(widget)), | |
290 do_add_file_cb, psmiley); | |
291 gtk_window_set_title(GTK_WINDOW(file_chooser), _("Custom Smiley")); | |
292 gtk_window_set_role(GTK_WINDOW(file_chooser), "file-selector-custom-smiley"); | |
293 gtk_widget_show_all(file_chooser); | |
294 } | |
295 | |
296 void pidgin_smiley_edit(GtkWidget *widget, PurpleSmiley *smiley) | |
297 { | |
298 GtkWidget *vbox; | |
299 GtkWidget *hbox; | |
300 GtkWidget *label; | |
301 GtkWidget *filech; | |
302 GtkWidget *window; | |
303 GdkPixbuf *pixbuf = NULL; | |
304 PurpleStoredImage *stored_img; | |
305 | |
306 PidginSmiley *s = g_new0(PidginSmiley, 1); | |
307 s->smiley = smiley; | |
308 | |
309 window = gtk_dialog_new_with_buttons(smiley ? _("Edit Smiley") : _("Add Smiley"), | |
310 GTK_WINDOW(widget), | |
311 GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR, | |
312 smiley ? GTK_STOCK_SAVE : GTK_STOCK_ADD, GTK_RESPONSE_ACCEPT, | |
313 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, | |
314 NULL); | |
315 s->parent = window; | |
316 | |
317 gtk_container_set_border_width(GTK_CONTAINER(window), PIDGIN_HIG_BORDER); | |
318 | |
319 g_signal_connect(window, "response", G_CALLBACK(do_add_select_cb), s); | |
320 | |
321 /* The vbox */ | |
322 vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BORDER); | |
323 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(window)->vbox), vbox); | |
324 gtk_widget_show(vbox); | |
325 | |
326 /* The hbox */ | |
327 hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BORDER); | |
328 gtk_container_add(GTK_CONTAINER(GTK_VBOX(vbox)), hbox); | |
329 | |
330 label = gtk_label_new_with_mnemonic(_("Smiley _Image")); | |
331 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); | |
332 gtk_widget_show(label); | |
333 | |
334 filech = gtk_button_new(); | |
335 gtk_box_pack_end(GTK_BOX(hbox), filech, FALSE, FALSE, 0); | |
336 pidgin_set_accessible_label(filech, label); | |
337 | |
338 s->smiley_image = gtk_image_new(); | |
339 gtk_container_add(GTK_CONTAINER(filech), s->smiley_image); | |
340 if (smiley && (stored_img = purple_smiley_get_stored_image(smiley))) { | |
341 pixbuf = pidgin_pixbuf_from_imgstore(stored_img); | |
342 purple_imgstore_unref(stored_img); | |
343 } else { | |
344 GtkIconSize icon_size = gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_SMALL); | |
345 pixbuf = gtk_widget_render_icon(window, PIDGIN_STOCK_TOOLBAR_SELECT_AVATAR, | |
346 icon_size, "PidginSmiley"); | |
347 } | |
348 | |
349 gtk_image_set_from_pixbuf(GTK_IMAGE(s->smiley_image), pixbuf); | |
350 if (pixbuf != NULL) | |
351 g_object_unref(G_OBJECT(pixbuf)); | |
352 g_signal_connect(G_OBJECT(filech), "clicked", G_CALLBACK(open_image_selector), s); | |
353 | |
354 gtk_widget_show_all(hbox); | |
355 | |
356 /* info */ | |
357 hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BORDER); | |
358 gtk_container_add(GTK_CONTAINER(GTK_VBOX(vbox)),hbox); | |
359 | |
360 /* Smiley shortcut */ | |
361 label = gtk_label_new_with_mnemonic(_("Smiley S_hortcut")); | |
362 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); | |
363 gtk_widget_show(label); | |
364 | |
365 s->smile = gtk_entry_new(); | |
366 gtk_entry_set_activates_default(GTK_ENTRY(s->smile), TRUE); | |
367 pidgin_set_accessible_label(s->smile, label); | |
368 if (smiley) | |
369 gtk_entry_set_text(GTK_ENTRY(s->smile), purple_smiley_get_shortcut(smiley)); | |
370 | |
371 g_signal_connect(s->smile, "activate", G_CALLBACK(do_add), s); | |
372 | |
373 gtk_box_pack_end(GTK_BOX(hbox), s->smile, FALSE, FALSE, 0); | |
374 gtk_widget_show(s->smile); | |
375 | |
376 gtk_widget_show(hbox); | |
377 | |
378 gtk_widget_show(GTK_WIDGET(window)); | |
379 g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(pidgin_smiley_destroy), s); | |
380 g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(purple_notify_close_with_handle), s); | |
381 } | |
382 | |
383 /****************************************************************************** | |
384 * Delete smiley | |
385 *****************************************************************************/ | |
386 static void delete_foreach(GtkTreeModel *model, GtkTreePath *path, | |
387 GtkTreeIter *iter, gpointer data) | |
388 { | |
389 PurpleSmiley *smiley = NULL; | |
390 SmileyManager *dialog; | |
391 | |
392 dialog = (SmileyManager*)data; | |
393 | |
394 gtk_tree_model_get(model, iter, | |
395 SMILEY, &smiley, | |
396 -1); | |
397 | |
398 if(smiley != NULL) { | |
399 g_object_unref(G_OBJECT(smiley)); | |
400 pidgin_smiley_del_from_list(smiley); | |
401 purple_smiley_delete(smiley); | |
402 } | |
403 } | |
404 | |
405 static void append_to_list(GtkTreeModel *model, GtkTreePath *path, | |
406 GtkTreeIter *iter, gpointer data) | |
407 { | |
408 GList **list = data; | |
409 *list = g_list_prepend(*list, gtk_tree_path_copy(path)); | |
410 } | |
411 | |
412 static void smiley_delete(SmileyManager *dialog) | |
413 { | |
414 GtkTreeSelection *selection; | |
415 GList *list = NULL; | |
416 | |
417 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview)); | |
418 gtk_tree_selection_selected_foreach(selection, delete_foreach, dialog); | |
419 gtk_tree_selection_selected_foreach(selection, append_to_list, &list); | |
420 | |
421 while (list) { | |
422 GtkTreeIter iter; | |
423 if (gtk_tree_model_get_iter(GTK_TREE_MODEL(dialog->model), &iter, list->data)) | |
424 gtk_list_store_remove(GTK_LIST_STORE(dialog->model), &iter); | |
425 gtk_tree_path_free(list->data); | |
426 list = g_list_delete_link(list, list); | |
427 } | |
428 } | |
429 /****************************************************************************** | |
430 * The Smiley Manager | |
431 *****************************************************************************/ | |
432 static void add_columns(GtkWidget *treeview, SmileyManager *dialog) | |
433 { | |
434 GtkCellRenderer *rend; | |
435 GtkTreeViewColumn *column; | |
436 | |
437 /* Icon */ | |
438 column = gtk_tree_view_column_new(); | |
439 gtk_tree_view_column_set_title(column, _("Smiley")); | |
440 gtk_tree_view_column_set_resizable(column, TRUE); | |
441 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); | |
442 | |
443 rend = gtk_cell_renderer_pixbuf_new(); | |
444 gtk_tree_view_column_pack_start(column, rend, FALSE); | |
445 gtk_tree_view_column_add_attribute(column, rend, "pixbuf", ICON); | |
446 | |
447 /* Shortcut */ | |
448 column = gtk_tree_view_column_new(); | |
449 gtk_tree_view_column_set_title(column, _("Shortcut")); | |
450 gtk_tree_view_column_set_resizable(column, TRUE); | |
451 gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column); | |
452 | |
453 rend = gtk_cell_renderer_text_new(); | |
454 gtk_tree_view_column_pack_start(column, rend, TRUE); | |
455 gtk_tree_view_column_add_attribute(column, rend, "text", SHORTCUT); | |
456 } | |
457 | |
458 static void store_smiley_add(PurpleSmiley *smiley) | |
459 { | |
460 GtkTreeIter iter; | |
461 PurpleStoredImage *img; | |
462 GdkPixbuf *sized_smiley = NULL; | |
463 | |
464 if (smiley_manager == NULL) | |
465 return; | |
466 | |
467 img = purple_smiley_get_stored_image(smiley); | |
468 | |
469 if (img != NULL) { | |
470 GdkPixbuf *smiley_image = pidgin_pixbuf_from_imgstore(img); | |
471 purple_imgstore_unref(img); | |
472 | |
473 if (smiley_image != NULL) | |
474 sized_smiley = gdk_pixbuf_scale_simple(smiley_image, | |
475 22, 22, GDK_INTERP_HYPER); | |
476 g_object_unref(G_OBJECT(smiley_image)); | |
477 } | |
478 | |
479 | |
480 gtk_list_store_append(smiley_manager->model, &iter); | |
481 | |
482 gtk_list_store_set(smiley_manager->model, &iter, | |
483 ICON, sized_smiley, | |
484 SHORTCUT, purple_smiley_get_shortcut(smiley), | |
485 SMILEY, smiley, | |
486 -1); | |
487 | |
488 if (sized_smiley != NULL) | |
489 g_object_unref(G_OBJECT(sized_smiley)); | |
490 } | |
491 | |
492 static void populate_smiley_list(SmileyManager *dialog) | |
493 { | |
494 GList *list; | |
495 PurpleSmiley *emoticon; | |
496 | |
497 gtk_list_store_clear(dialog->model); | |
498 | |
499 for(list = purple_smileys_get_all(); list != NULL; | |
500 list = g_list_delete_link(list, list)) { | |
501 emoticon = (PurpleSmiley*)list->data; | |
502 | |
503 store_smiley_add(emoticon); | |
504 } | |
505 } | |
506 | |
507 static void smile_selected_cb(GtkTreeSelection *sel, SmileyManager *dialog) | |
508 { | |
509 gint selected; | |
510 | |
511 selected = gtk_tree_selection_count_selected_rows(sel); | |
512 | |
513 gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog->window), | |
514 GTK_RESPONSE_NO, selected > 0); | |
515 | |
516 gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog->window), | |
517 PIDGIN_RESPONSE_EDIT, selected > 0); | |
518 } | |
519 | |
520 static void | |
521 smiley_edit_iter(SmileyManager *dialog, GtkTreeIter *iter) | |
522 { | |
523 PurpleSmiley *smiley = NULL; | |
524 gtk_tree_model_get(GTK_TREE_MODEL(dialog->model), iter, SMILEY, &smiley, -1); | |
525 pidgin_smiley_edit(gtk_widget_get_toplevel(GTK_WIDGET(dialog->treeview)), smiley); | |
526 g_object_unref(G_OBJECT(smiley)); | |
527 } | |
528 | |
529 static void smiley_edit_cb(GtkTreeView *treeview, GtkTreePath *path, GtkTreeViewColumn *col, gpointer data) | |
530 { | |
531 GtkTreeIter iter; | |
532 SmileyManager *dialog = data; | |
533 | |
534 gtk_tree_model_get_iter(GTK_TREE_MODEL(dialog->model), &iter, path); | |
535 smiley_edit_iter(dialog, &iter); | |
536 } | |
537 | |
538 static void | |
539 edit_selected_cb(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) | |
540 { | |
541 smiley_edit_iter(data, iter); | |
542 } | |
543 | |
544 static GtkWidget *smiley_list_create(SmileyManager *dialog) | |
545 { | |
546 GtkWidget *sw; | |
547 GtkWidget *treeview; | |
548 GtkTreeSelection *sel; | |
549 | |
550 sw = gtk_scrolled_window_new(NULL, NULL); | |
551 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), | |
552 GTK_POLICY_AUTOMATIC, | |
553 GTK_POLICY_AUTOMATIC); | |
554 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), | |
555 GTK_SHADOW_IN); | |
556 gtk_widget_show(sw); | |
557 | |
558 /* Create the list model */ | |
559 dialog->model = gtk_list_store_new(N_COL, | |
560 GDK_TYPE_PIXBUF, /* ICON */ | |
561 G_TYPE_STRING, /* SHORTCUT */ | |
562 G_TYPE_OBJECT /* SMILEY */ | |
563 ); | |
564 | |
565 /* the actual treeview */ | |
566 treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(dialog->model)); | |
567 dialog->treeview = treeview; | |
568 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE); | |
569 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(dialog->model), SHORTCUT, GTK_SORT_ASCENDING); | |
570 g_object_unref(G_OBJECT(dialog->model)); | |
571 | |
572 sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); | |
573 gtk_tree_selection_set_mode(sel, GTK_SELECTION_MULTIPLE); | |
574 gtk_container_add(GTK_CONTAINER(sw), treeview); | |
575 | |
576 g_signal_connect(G_OBJECT(sel), "changed", G_CALLBACK(smile_selected_cb), dialog); | |
577 g_signal_connect(G_OBJECT(treeview), "row_activated", G_CALLBACK(smiley_edit_cb), dialog); | |
578 | |
579 gtk_widget_show(treeview); | |
580 | |
581 add_columns(treeview, dialog); | |
582 populate_smiley_list(dialog); | |
583 | |
584 return sw; | |
585 } | |
586 | |
587 static void refresh_list() | |
588 { | |
589 populate_smiley_list(smiley_manager); | |
590 } | |
591 | |
592 static void smiley_manager_select_cb(GtkWidget *widget, gint resp, SmileyManager *dialog) | |
593 { | |
594 GtkTreeSelection *selection = NULL; | |
595 | |
596 switch (resp) { | |
597 case GTK_RESPONSE_YES: | |
598 pidgin_smiley_edit(dialog->window, NULL); | |
599 break; | |
600 case GTK_RESPONSE_NO: | |
601 smiley_delete(dialog); | |
602 break; | |
603 case GTK_RESPONSE_DELETE_EVENT: | |
604 case GTK_RESPONSE_CLOSE: | |
605 gtk_widget_destroy(dialog->window); | |
606 g_free(smiley_manager); | |
607 smiley_manager = NULL; | |
608 break; | |
609 case PIDGIN_RESPONSE_EDIT: | |
610 /* Find smiley of selection... */ | |
611 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dialog->treeview)); | |
612 gtk_tree_selection_selected_foreach(selection, edit_selected_cb, dialog); | |
613 break; | |
614 default: | |
615 purple_debug_info("gtksmiley", "No valid selection\n"); | |
616 break; | |
617 } | |
618 } | |
619 | |
620 void pidgin_smiley_manager_show(void) | |
621 { | |
622 SmileyManager *dialog; | |
623 GtkWidget *win; | |
624 GtkWidget *sw; | |
625 GtkWidget *vbox; | |
626 | |
627 if (smiley_manager) { | |
628 gtk_window_present(GTK_WINDOW(smiley_manager->window)); | |
629 return; | |
630 } | |
631 | |
632 dialog = g_new0(SmileyManager, 1); | |
633 smiley_manager = dialog; | |
634 | |
635 dialog->window = win = gtk_dialog_new_with_buttons( | |
636 _("Custom Smiley Manager"), | |
637 NULL, | |
638 GTK_DIALOG_DESTROY_WITH_PARENT, | |
639 GTK_STOCK_ADD, GTK_RESPONSE_YES, | |
640 GTK_STOCK_EDIT, PIDGIN_RESPONSE_EDIT, | |
641 GTK_STOCK_DELETE, GTK_RESPONSE_NO, | |
642 GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, | |
643 NULL); | |
644 | |
645 gtk_window_set_default_size(GTK_WINDOW(win), 50, 400); | |
646 gtk_window_set_role(GTK_WINDOW(win), "custom_smiley_manager"); | |
647 gtk_container_set_border_width(GTK_CONTAINER(win),PIDGIN_HIG_BORDER); | |
648 gtk_dialog_set_response_sensitive(GTK_DIALOG(win), GTK_RESPONSE_NO, FALSE); | |
649 gtk_dialog_set_response_sensitive(GTK_DIALOG(win), PIDGIN_RESPONSE_EDIT, | |
650 FALSE); | |
651 | |
652 g_signal_connect(win, "response", G_CALLBACK(smiley_manager_select_cb), | |
653 dialog); | |
654 | |
655 /* The vbox */ | |
656 vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BORDER); | |
657 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(win)->vbox), vbox); | |
658 gtk_widget_show(vbox); | |
659 | |
660 /* get the scrolled window with all stuff */ | |
661 sw = smiley_list_create(dialog); | |
662 gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0); | |
663 gtk_widget_show(sw); | |
664 | |
665 gtk_widget_show(win); | |
666 } | |
667 |