Fix runtime warning if bonjour xfer is cancelled early.
[pidgin-git.git] / pidgin / gtksmiley-manager.c
blob78bdaff09a1055c07fe796f47a9cf0ea9046ee74
1 /*
2 * pidgin
4 * Pidgin is the legal property of its developers, whose names are too numerous
5 * to list here. Please refer to the COPYRIGHT file distributed with this
6 * source distribution.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
23 #include "internal.h"
25 #include "debug.h"
26 #include "http.h"
27 #include "notify.h"
28 #include "smiley.h"
29 #include "smiley-custom.h"
30 #include "smiley-list.h"
32 #include "gtksmiley-manager.h"
33 #include "gtkutils.h"
34 #include "pidginstock.h"
36 #include "gtk3compat.h"
38 typedef struct
40 PurpleSmiley *smiley;
42 gchar *filename;
43 PurpleImage *new_image;
45 GtkDialog *window;
46 GtkImage *thumbnail;
47 GtkEntry *shortcut;
48 } SmileyEditDialog;
50 typedef struct
52 GtkDialog *window;
53 GtkListStore *model;
54 GtkTreeView *tree;
56 PurpleHttpConnection *running_request;
57 } SmileyManager;
59 enum
61 SMILEY_LIST_MODEL_ICON,
62 SMILEY_LIST_MODEL_SHORTCUT,
63 SMILEY_LIST_MODEL_PURPLESMILEY,
64 SMILEY_LIST_MODEL_N_COL
67 enum
69 PIDGIN_RESPONSE_MODIFY
72 static SmileyManager *smiley_manager = NULL;
74 static void
75 edit_dialog_update_buttons(SmileyEditDialog *edit_dialog);
77 static void
78 manager_list_fill(SmileyManager *manager);
81 /*******************************************************************************
82 * Custom smiley edit dialog image.
83 ******************************************************************************/
85 static void
86 edit_dialog_image_update_thumb(SmileyEditDialog *edit_dialog)
88 GdkPixbuf *pixbuf = NULL;
90 if (edit_dialog->new_image) {
91 pixbuf = pidgin_pixbuf_from_image(edit_dialog->new_image);
92 } else if (edit_dialog->filename) {
93 pixbuf = pidgin_pixbuf_new_from_file(edit_dialog->filename);
94 if (!pixbuf) {
95 g_free(edit_dialog->filename);
96 edit_dialog->filename = NULL;
100 if (pixbuf) {
101 pixbuf = pidgin_pixbuf_scale_down(pixbuf, 64, 64,
102 GDK_INTERP_HYPER, TRUE);
105 if (!pixbuf) {
106 GtkIconSize icon_size =
107 gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_SMALL);
108 pixbuf = gtk_widget_render_icon(GTK_WIDGET(edit_dialog->window),
109 PIDGIN_STOCK_TOOLBAR_SELECT_AVATAR, icon_size,
110 "PidginSmileyManager");
112 g_return_if_fail(pixbuf != NULL);
114 gtk_image_set_from_pixbuf(GTK_IMAGE(edit_dialog->thumbnail), pixbuf);
116 g_object_unref(G_OBJECT(pixbuf));
119 static gboolean
120 edit_dialog_set_image(SmileyEditDialog *edit_dialog, PurpleImage *image)
122 GdkPixbuf *tmp = NULL;
124 if (edit_dialog->new_image)
125 g_object_unref(edit_dialog->new_image);
127 if (edit_dialog->smiley) {
128 g_object_set_data(G_OBJECT(edit_dialog->smiley),
129 "pidgin-smiley-manager-list-thumb", NULL);
132 /* check, if image is valid */
133 if (image)
134 tmp = pidgin_pixbuf_from_image(image);
135 if (tmp)
136 g_object_unref(tmp);
137 else {
138 g_object_unref(image);
139 image = NULL;
142 edit_dialog->new_image = image;
144 edit_dialog_image_update_thumb(edit_dialog);
145 edit_dialog_update_buttons(edit_dialog);
147 return (image != NULL);
150 static void
151 edit_dialog_set_shortcut(SmileyEditDialog *edit_dialog,
152 const gchar *shortcut)
154 gtk_entry_set_text(edit_dialog->shortcut, shortcut ? shortcut : "");
157 static void
158 edit_dialog_image_choosen(const char *filename, gpointer _edit_dialog)
160 PurpleImage *image;
161 SmileyEditDialog *edit_dialog = _edit_dialog;
163 if (!filename)
164 return;
166 image = purple_image_new_from_file(filename, NULL);
167 if (!image)
168 return;
170 g_free(edit_dialog->filename);
171 edit_dialog->filename = NULL;
173 if (!edit_dialog_set_image(edit_dialog, image))
174 return;
175 edit_dialog->filename = g_strdup(filename);
177 gtk_widget_grab_focus(GTK_WIDGET(edit_dialog->shortcut));
180 static void
181 edit_dialog_image_choose(GtkWidget *widget, gpointer _edit_dialog)
183 GtkWidget *file_chooser;
184 file_chooser = pidgin_buddy_icon_chooser_new(
185 GTK_WINDOW(gtk_widget_get_toplevel(widget)),
186 edit_dialog_image_choosen, _edit_dialog);
187 gtk_window_set_title(GTK_WINDOW(file_chooser), _("Custom Smiley"));
188 gtk_window_set_role(GTK_WINDOW(file_chooser),
189 "file-selector-custom-smiley");
190 gtk_widget_show_all(file_chooser);
194 /*******************************************************************************
195 * Custom smiley edit dialog.
196 ******************************************************************************/
198 static void
199 edit_dialog_destroy(GtkWidget *window, gpointer _edit_dialog)
201 SmileyEditDialog *edit_dialog = _edit_dialog;
203 if (edit_dialog->smiley) {
204 g_object_set_data(G_OBJECT(edit_dialog->smiley),
205 "pidgin-smiley-manager-edit-dialog", NULL);
206 g_object_unref(edit_dialog->smiley);
209 if (edit_dialog->new_image)
210 g_object_unref(edit_dialog->new_image);
212 g_free(edit_dialog->filename);
213 g_free(edit_dialog);
216 static void
217 edit_dialog_save(SmileyEditDialog *edit_dialog)
219 const gchar *shortcut;
220 PurpleSmiley *existing_smiley;
221 gboolean shortcut_changed, image_changed;
223 shortcut = gtk_entry_get_text(edit_dialog->shortcut);
225 existing_smiley = purple_smiley_list_get_by_shortcut(
226 purple_smiley_custom_get_list(), shortcut);
228 if (existing_smiley && existing_smiley != edit_dialog->smiley) {
229 gchar *msg = g_strdup_printf(
230 _("A custom smiley for '%s' already exists. "
231 "Please use a different shortcut."), shortcut);
232 purple_notify_error(edit_dialog, _("Custom Smiley"),
233 _("Duplicate Shortcut"), msg, NULL);
234 g_free(msg);
235 return;
238 if (edit_dialog->smiley == NULL)
239 shortcut_changed = image_changed = TRUE;
240 else {
241 shortcut_changed = purple_strequal(purple_smiley_get_shortcut(
242 edit_dialog->smiley), shortcut);
243 image_changed = (edit_dialog->new_image != NULL);
246 if (!shortcut_changed && !image_changed) {
247 gtk_widget_destroy(GTK_WIDGET(edit_dialog->window));
248 return;
251 if (edit_dialog->new_image == NULL) {
252 edit_dialog->new_image = PURPLE_IMAGE(edit_dialog->smiley);
253 g_return_if_fail(edit_dialog->new_image);
256 if (edit_dialog->smiley)
257 purple_smiley_custom_remove(edit_dialog->smiley);
258 purple_smiley_custom_add(edit_dialog->new_image, shortcut);
260 if (smiley_manager)
261 manager_list_fill(smiley_manager);
263 gtk_widget_destroy(GTK_WIDGET(edit_dialog->window));
266 static void
267 edit_dialog_update_buttons(SmileyEditDialog *edit_dialog)
269 gboolean shortcut_ok, image_ok;
271 shortcut_ok = (gtk_entry_get_text_length(edit_dialog->shortcut) > 0);
272 image_ok = (edit_dialog->filename || edit_dialog->new_image);
274 gtk_dialog_set_response_sensitive(edit_dialog->window,
275 GTK_RESPONSE_ACCEPT, shortcut_ok && image_ok);
278 static void
279 edit_dialog_shortcut_changed(GtkEditable *shortcut, gpointer _edit_dialog)
281 SmileyEditDialog *edit_dialog = _edit_dialog;
283 edit_dialog_update_buttons(edit_dialog);
286 static void
287 edit_dialog_response(GtkDialog *window, gint response_id,
288 gpointer _edit_dialog)
290 SmileyEditDialog *edit_dialog = _edit_dialog;
292 switch (response_id) {
293 case GTK_RESPONSE_ACCEPT:
294 edit_dialog_save(edit_dialog);
295 break;
296 case GTK_RESPONSE_DELETE_EVENT:
297 case GTK_RESPONSE_CANCEL:
298 gtk_widget_destroy(GTK_WIDGET(edit_dialog->window));
299 break;
300 default:
301 g_warn_if_reached();
305 static SmileyEditDialog *
306 edit_dialog_show(SmileyManager *manager, PurpleSmiley *smiley)
308 SmileyEditDialog *edit_dialog;
309 GtkWidget *vbox, *hbox;
310 GtkLabel *label;
311 GtkButton *filech;
313 if (smiley) {
314 edit_dialog = g_object_get_data(G_OBJECT(smiley),
315 "pidgin-smiley-manager-edit-dialog");
316 if (edit_dialog) {
317 gtk_window_present(GTK_WINDOW(edit_dialog->window));
318 return edit_dialog;
322 edit_dialog = g_new0(SmileyEditDialog, 1);
324 edit_dialog->window = GTK_DIALOG(gtk_dialog_new_with_buttons(
325 smiley ? _("Edit Smiley") : _("Add Smiley"),
326 manager ? GTK_WINDOW(manager->window) : NULL,
327 GTK_DIALOG_DESTROY_WITH_PARENT,
328 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
329 smiley ? GTK_STOCK_SAVE : GTK_STOCK_ADD, GTK_RESPONSE_ACCEPT,
330 NULL));
331 gtk_dialog_set_default_response(
332 edit_dialog->window, GTK_RESPONSE_ACCEPT);
334 if (smiley) {
335 edit_dialog->smiley = smiley;
336 g_object_set_data(G_OBJECT(smiley),
337 "pidgin-smiley-manager-edit-dialog", edit_dialog);
338 g_object_ref(smiley);
342 /* The vbox */
343 vbox = gtk_grid_new();
344 gtk_grid_set_row_spacing(GTK_GRID(vbox), PIDGIN_HIG_BORDER);
345 gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(
346 edit_dialog->window)), vbox);
347 gtk_widget_show(vbox);
349 /* The hbox */
350 hbox = gtk_grid_new();
351 gtk_grid_set_column_spacing(GTK_GRID(hbox), PIDGIN_HIG_BORDER);
352 gtk_grid_attach(GTK_GRID(vbox), hbox, 0, 0, 1, 1);
354 label = GTK_LABEL(gtk_label_new_with_mnemonic(_("_Image:")));
355 gtk_grid_attach(GTK_GRID(hbox), GTK_WIDGET(label), 0, 0, 1, 1);
356 gtk_widget_show(GTK_WIDGET(label));
358 filech = GTK_BUTTON(gtk_button_new());
359 gtk_grid_attach_next_to(GTK_GRID(hbox), GTK_WIDGET(filech), NULL,
360 GTK_POS_RIGHT, 1, 1);
361 pidgin_set_accessible_label(GTK_WIDGET(filech), label);
363 edit_dialog->thumbnail = GTK_IMAGE(gtk_image_new());
364 gtk_container_add(GTK_CONTAINER(filech),
365 GTK_WIDGET(edit_dialog->thumbnail));
367 gtk_widget_show_all(hbox);
369 /* info */
370 hbox = gtk_grid_new();
371 gtk_grid_set_column_spacing(GTK_GRID(hbox), PIDGIN_HIG_BORDER);
373 gtk_grid_attach_next_to(GTK_GRID(vbox), hbox, NULL,
374 GTK_POS_BOTTOM, 1, 1);
376 /* Shortcut text */
377 label = GTK_LABEL(gtk_label_new_with_mnemonic(_("S_hortcut text:")));
378 gtk_grid_attach(GTK_GRID(hbox), GTK_WIDGET(label), 0, 0, 1, 1);
379 gtk_widget_show(GTK_WIDGET(label));
381 edit_dialog->shortcut = GTK_ENTRY(gtk_entry_new());
382 gtk_entry_set_activates_default(edit_dialog->shortcut, TRUE);
383 pidgin_set_accessible_label(GTK_WIDGET(edit_dialog->shortcut), label);
385 gtk_grid_attach_next_to(GTK_GRID(hbox),
386 GTK_WIDGET(edit_dialog->shortcut), NULL, GTK_POS_RIGHT, 1, 1);
388 gtk_widget_show(GTK_WIDGET(edit_dialog->shortcut));
389 gtk_widget_show(hbox);
390 gtk_widget_show(GTK_WIDGET(edit_dialog->window));
392 if (smiley) {
393 edit_dialog->filename = g_strdup(purple_image_get_path(
394 PURPLE_IMAGE(smiley)));
395 gtk_entry_set_text(edit_dialog->shortcut,
396 purple_smiley_get_shortcut(smiley));
399 edit_dialog_image_update_thumb(edit_dialog);
400 edit_dialog_update_buttons(edit_dialog);
402 g_signal_connect(edit_dialog->window, "response",
403 G_CALLBACK(edit_dialog_response), edit_dialog);
404 g_signal_connect(filech, "clicked",
405 G_CALLBACK(edit_dialog_image_choose), edit_dialog);
406 g_signal_connect(edit_dialog->shortcut, "changed",
407 G_CALLBACK(edit_dialog_shortcut_changed), edit_dialog);
409 g_signal_connect(edit_dialog->window, "destroy",
410 G_CALLBACK(edit_dialog_destroy), edit_dialog);
411 g_signal_connect(edit_dialog->window, "destroy",
412 G_CALLBACK(purple_notify_close_with_handle), edit_dialog);
414 return edit_dialog;
417 void
418 pidgin_smiley_manager_add(PurpleImage *image, const gchar *shortcut)
420 SmileyEditDialog *edit_dialog;
422 g_return_if_fail(image != NULL);
424 g_object_ref(image);
426 edit_dialog = edit_dialog_show(NULL, NULL);
427 edit_dialog_set_shortcut(edit_dialog, shortcut);
428 if (!edit_dialog_set_image(edit_dialog, image))
429 gtk_widget_destroy(GTK_WIDGET(edit_dialog->window));
433 /*******************************************************************************
434 * Custom smiley list Drag-and-drop support.
435 ******************************************************************************/
437 static void
438 smiley_list_dnd_url_got(PurpleHttpConnection *http_conn,
439 PurpleHttpResponse *response, gpointer _manager)
441 SmileyManager *manager = _manager;
442 SmileyEditDialog *edit_dialog;
443 PurpleImage *image;
444 const gchar *image_data;
445 size_t image_size;
447 g_return_if_fail(manager == smiley_manager);
448 g_return_if_fail(manager->running_request == http_conn);
449 manager->running_request = NULL;
451 if (!purple_http_response_is_successful(response))
452 return;
454 image_data = purple_http_response_get_data(response, &image_size);
455 image = purple_image_new_from_data((const guint8 *)image_data, image_size);
456 if (!image)
457 return;
459 edit_dialog = edit_dialog_show(manager, NULL);
460 if (!edit_dialog_set_image(edit_dialog, image))
461 gtk_widget_destroy(GTK_WIDGET(edit_dialog->window));
464 static void
465 smiley_list_dnd_recv(GtkWidget *widget, GdkDragContext *dc, gint x, gint y,
466 GtkSelectionData *sd, guint info, guint time, gpointer _manager)
468 SmileyManager *manager = _manager;
469 gchar content[1024];
471 /* We don't need anything, that is not 8-bit per element (char). */
472 if (gtk_selection_data_get_format(sd) != 8) {
473 gtk_drag_finish(dc, FALSE, FALSE, time);
474 return;
477 if (gtk_selection_data_get_length(sd) <= 0) {
478 gtk_drag_finish(dc, FALSE, FALSE, time);
479 return;
482 memset(&content, 0, sizeof(content));
483 memcpy(&content, gtk_selection_data_get_data(sd),
484 MIN((guint)gtk_selection_data_get_length(sd), sizeof(content)));
485 g_strstrip(content);
486 if (content[0] == '\0') {
487 gtk_drag_finish(dc, FALSE, FALSE, time);
488 return;
491 /* Well, it looks like the drag event was cool.
492 * Let's do something with it */
494 if (purple_str_has_caseprefix(content, "file://")) {
495 SmileyEditDialog *edit_dialog;
496 PurpleImage *image;
497 gchar *filename;
499 filename = g_filename_from_uri(content, NULL, NULL);
500 if (!filename || !g_file_test(filename, G_FILE_TEST_EXISTS)) {
501 purple_debug_warning("gtksmiley-manager",
502 "dropped file does not exists");
503 gtk_drag_finish(dc, FALSE, FALSE, time);
504 return;
507 image = purple_image_new_from_file(filename, NULL);
508 if (!image) {
509 purple_debug_warning("gtksmiley-manager",
510 "dropped file is not a valid image");
511 gtk_drag_finish(dc, FALSE, FALSE, time);
512 return;
514 edit_dialog = edit_dialog_show(manager, NULL);
515 if (!edit_dialog_set_image(edit_dialog, image)) {
516 gtk_widget_destroy(GTK_WIDGET(edit_dialog->window));
517 gtk_drag_finish(dc, FALSE, FALSE, time);
518 return;
521 gtk_drag_finish(dc, TRUE, FALSE, time);
522 return;
525 if (purple_str_has_caseprefix(content, "http://") ||
526 purple_str_has_caseprefix(content, "https://"))
528 purple_http_conn_cancel(smiley_manager->
529 running_request);
530 smiley_manager->running_request = purple_http_get(NULL,
531 smiley_list_dnd_url_got, manager, content);
533 gtk_drag_finish(dc, TRUE, FALSE, time);
534 return;
537 gtk_drag_finish(dc, FALSE, FALSE, time);
540 /*******************************************************************************
541 * Custom smiley list.
542 ******************************************************************************/
544 static void
545 smiley_list_selected(GtkTreeSelection *sel, gpointer _manager)
547 SmileyManager *manager = _manager;
548 gboolean sens;
550 sens = (gtk_tree_selection_count_selected_rows(sel) > 0);
552 gtk_dialog_set_response_sensitive(manager->window,
553 GTK_RESPONSE_NO, sens);
554 gtk_dialog_set_response_sensitive(manager->window,
555 PIDGIN_RESPONSE_MODIFY, sens);
558 static void
559 smiley_list_activated(GtkTreeView *tree, GtkTreePath *path,
560 GtkTreeViewColumn *col, gpointer _manager)
562 SmileyManager *manager = _manager;
563 GtkTreeIter iter;
564 PurpleSmiley *smiley = NULL;
566 if (!gtk_tree_model_get_iter(
567 GTK_TREE_MODEL(manager->model), &iter, path))
569 return;
572 gtk_tree_model_get(GTK_TREE_MODEL(manager->model), &iter,
573 SMILEY_LIST_MODEL_PURPLESMILEY, &smiley, -1);
574 g_return_if_fail(PURPLE_IS_SMILEY(smiley));
576 edit_dialog_show(manager, smiley);
579 static void
580 manager_list_add(SmileyManager *manager, PurpleSmiley *smiley)
582 GdkPixbuf *smiley_image;
583 GtkTreeIter iter;
585 smiley_image = g_object_get_data(G_OBJECT(smiley),
586 "pidgin-smiley-manager-list-thumb");
587 if (smiley_image == NULL) {
588 smiley_image = pidgin_pixbuf_from_image(PURPLE_IMAGE(smiley));
589 smiley_image = pidgin_pixbuf_scale_down(smiley_image,
590 22, 22, GDK_INTERP_BILINEAR, TRUE);
591 g_object_set_data_full(G_OBJECT(smiley),
592 "pidgin-smiley-manager-list-thumb",
593 smiley_image, g_object_unref);
596 gtk_list_store_append(manager->model, &iter);
597 gtk_list_store_set(manager->model, &iter,
598 SMILEY_LIST_MODEL_ICON, smiley_image,
599 SMILEY_LIST_MODEL_SHORTCUT, purple_smiley_get_shortcut(smiley),
600 SMILEY_LIST_MODEL_PURPLESMILEY, smiley,
601 -1);
604 static void
605 manager_list_fill(SmileyManager *manager)
607 GList *custom_smileys, *it;
608 gtk_list_store_clear(manager->model);
610 custom_smileys = purple_smiley_list_get_all(
611 purple_smiley_custom_get_list());
613 for (it = custom_smileys; it; it = g_list_next(it)) {
614 PurpleSmiley *smiley = it->data;
616 manager_list_add(manager, smiley);
618 g_list_free(custom_smileys);
621 static GtkWidget *
622 manager_list_create(SmileyManager *manager)
624 GtkTreeView *tree;
625 GtkTreeSelection *sel;
626 GtkCellRenderer *cellrend;
627 GtkTreeViewColumn *column;
628 GtkTargetEntry targets[3] = {
629 {"text/plain", 0, 0},
630 {"text/uri-list", 0, 1},
631 {"STRING", 0, 2}
634 manager->model = gtk_list_store_new(SMILEY_LIST_MODEL_N_COL,
635 GDK_TYPE_PIXBUF, /* icon */
636 G_TYPE_STRING, /* shortcut */
637 G_TYPE_OBJECT /* PurpleSmiley */
640 manager->tree = tree = GTK_TREE_VIEW(gtk_tree_view_new_with_model(
641 GTK_TREE_MODEL(manager->model)));
643 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(manager->model),
644 SMILEY_LIST_MODEL_SHORTCUT, GTK_SORT_ASCENDING);
646 g_object_unref(manager->model);
648 sel = gtk_tree_view_get_selection(tree);
649 gtk_tree_selection_set_mode(sel, GTK_SELECTION_MULTIPLE);
651 g_signal_connect(sel, "changed",
652 G_CALLBACK(smiley_list_selected), manager);
653 g_signal_connect(tree, "row-activated",
654 G_CALLBACK(smiley_list_activated), manager);
656 gtk_drag_dest_set(GTK_WIDGET(tree), GTK_DEST_DEFAULT_MOTION |
657 GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP,
658 targets, G_N_ELEMENTS(targets),
659 GDK_ACTION_COPY | GDK_ACTION_MOVE);
660 g_signal_connect(tree, "drag-data-received",
661 G_CALLBACK(smiley_list_dnd_recv), manager);
663 gtk_widget_show(GTK_WIDGET(tree));
665 /* setting up columns */
667 column = gtk_tree_view_column_new();
668 gtk_tree_view_column_set_title(column, _("Smiley"));
669 gtk_tree_view_column_set_resizable(column, TRUE);
670 gtk_tree_view_append_column(tree, column);
671 cellrend = gtk_cell_renderer_pixbuf_new();
672 gtk_tree_view_column_pack_start(column, cellrend, FALSE);
673 gtk_tree_view_column_add_attribute(column, cellrend,
674 "pixbuf", SMILEY_LIST_MODEL_ICON);
676 column = gtk_tree_view_column_new();
677 gtk_tree_view_column_set_title(column, _("Shortcut Text"));
678 gtk_tree_view_column_set_resizable(column, TRUE);
679 gtk_tree_view_append_column(tree, column);
680 cellrend = gtk_cell_renderer_text_new();
681 gtk_tree_view_column_pack_start(column, cellrend, TRUE);
682 gtk_tree_view_column_add_attribute(column, cellrend,
683 "text", SMILEY_LIST_MODEL_SHORTCUT);
685 manager_list_fill(manager);
687 return pidgin_make_scrollable(GTK_WIDGET(tree), GTK_POLICY_AUTOMATIC,
688 GTK_POLICY_AUTOMATIC, GTK_SHADOW_IN, -1, -1);
691 /*******************************************************************************
692 * Custom smiley manager window.
693 ******************************************************************************/
695 static void
696 manager_select_cb(GtkWidget *widget, gint resp, SmileyManager *manager)
698 GtkTreeSelection *selection = NULL;
699 GList *selected_rows, *selected_smileys = NULL, *it;
700 GtkTreeModel *model = GTK_TREE_MODEL(manager->model);
702 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(manager->tree));
703 selected_rows = gtk_tree_selection_get_selected_rows(selection, NULL);
704 for (it = selected_rows; it; it = g_list_next(it)) {
705 GtkTreePath *path = it->data;
706 GtkTreeIter iter;
707 PurpleSmiley *smiley = NULL;
709 if (!gtk_tree_model_get_iter(model, &iter, path))
710 continue;
712 gtk_tree_model_get(model, &iter,
713 SMILEY_LIST_MODEL_PURPLESMILEY, &smiley, -1);
714 if (!smiley)
715 continue;
717 selected_smileys = g_list_prepend(selected_smileys, smiley);
719 g_list_free_full(selected_rows, (GDestroyNotify)gtk_tree_path_free);
721 switch (resp) {
722 case GTK_RESPONSE_YES:
723 edit_dialog_show(manager, NULL);
724 break;
725 case GTK_RESPONSE_NO:
726 for (it = selected_smileys; it; it = g_list_next(it))
727 purple_smiley_custom_remove(it->data);
728 manager_list_fill(manager);
729 break;
730 case GTK_RESPONSE_DELETE_EVENT:
731 case GTK_RESPONSE_CLOSE:
732 gtk_widget_destroy(GTK_WIDGET(manager->window));
733 purple_http_conn_cancel(manager->running_request);
734 g_free(manager);
735 smiley_manager = NULL;
736 break;
737 case PIDGIN_RESPONSE_MODIFY:
738 for (it = selected_smileys; it; it = g_list_next(it))
739 edit_dialog_show(manager, it->data);
740 break;
741 default:
742 g_warn_if_reached();
745 g_list_free(selected_smileys);
748 void
749 pidgin_smiley_manager_show(void)
751 SmileyManager *manager;
752 GtkDialog *win;
753 GtkWidget *sw, *vbox;
755 if (smiley_manager) {
756 gtk_window_present(GTK_WINDOW(smiley_manager->window));
757 return;
760 manager = g_new0(SmileyManager, 1);
761 smiley_manager = manager;
763 manager->window = win = GTK_DIALOG(gtk_dialog_new_with_buttons(
764 _("Custom Smiley Manager"), NULL,
765 GTK_DIALOG_DESTROY_WITH_PARENT,
766 PIDGIN_STOCK_ADD, GTK_RESPONSE_YES,
767 PIDGIN_STOCK_MODIFY, PIDGIN_RESPONSE_MODIFY,
768 GTK_STOCK_DELETE, GTK_RESPONSE_NO,
769 GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
770 NULL));
772 gtk_window_set_default_size(GTK_WINDOW(win), 50, 400);
773 gtk_window_set_role(GTK_WINDOW(win), "custom_smiley_manager");
774 gtk_dialog_set_response_sensitive(win, GTK_RESPONSE_NO, FALSE);
775 gtk_dialog_set_response_sensitive(win, PIDGIN_RESPONSE_MODIFY, FALSE);
777 g_signal_connect(win, "response",
778 G_CALLBACK(manager_select_cb), manager);
780 /* The vbox */
781 vbox = gtk_dialog_get_content_area(win);
783 /* get the scrolled window with all stuff */
784 sw = manager_list_create(manager);
785 gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0);
786 gtk_widget_show(sw);
788 gtk_widget_show(GTK_WIDGET(win));