Migrate xmpp-caps.xml to XDG cache dir
[pidgin-git.git] / pidgin / gtksmiley-manager.c
blob3e3f6d4115aab942d5a4e139d13c2101f52d4e18
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, TRUE);
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 = (g_strcmp0(purple_smiley_get_shortcut(
242 edit_dialog->smiley), shortcut) != 0);
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 =
253 purple_smiley_get_image(edit_dialog->smiley);
254 g_return_if_fail(edit_dialog->new_image);
257 if (edit_dialog->smiley)
258 purple_smiley_custom_remove(edit_dialog->smiley);
259 purple_smiley_custom_add(edit_dialog->new_image, shortcut);
261 if (smiley_manager)
262 manager_list_fill(smiley_manager);
264 gtk_widget_destroy(GTK_WIDGET(edit_dialog->window));
267 static void
268 edit_dialog_update_buttons(SmileyEditDialog *edit_dialog)
270 gboolean shortcut_ok, image_ok;
272 shortcut_ok = (gtk_entry_get_text_length(edit_dialog->shortcut) > 0);
273 image_ok = (edit_dialog->filename || edit_dialog->new_image);
275 gtk_dialog_set_response_sensitive(edit_dialog->window,
276 GTK_RESPONSE_ACCEPT, shortcut_ok && image_ok);
279 static void
280 edit_dialog_shortcut_changed(GtkEditable *shortcut, gpointer _edit_dialog)
282 SmileyEditDialog *edit_dialog = _edit_dialog;
284 edit_dialog_update_buttons(edit_dialog);
287 static void
288 edit_dialog_response(GtkDialog *window, gint response_id,
289 gpointer _edit_dialog)
291 SmileyEditDialog *edit_dialog = _edit_dialog;
293 switch (response_id) {
294 case GTK_RESPONSE_ACCEPT:
295 edit_dialog_save(edit_dialog);
296 break;
297 case GTK_RESPONSE_DELETE_EVENT:
298 case GTK_RESPONSE_CANCEL:
299 gtk_widget_destroy(GTK_WIDGET(edit_dialog->window));
300 break;
301 default:
302 g_warn_if_reached();
306 static SmileyEditDialog *
307 edit_dialog_show(SmileyManager *manager, PurpleSmiley *smiley)
309 SmileyEditDialog *edit_dialog;
310 GtkWidget *vbox, *hbox;
311 GtkLabel *label;
312 GtkButton *filech;
314 if (smiley) {
315 edit_dialog = g_object_get_data(G_OBJECT(smiley),
316 "pidgin-smiley-manager-edit-dialog");
317 if (edit_dialog) {
318 gtk_window_present(GTK_WINDOW(edit_dialog->window));
319 return edit_dialog;
323 edit_dialog = g_new0(SmileyEditDialog, 1);
325 edit_dialog->window = GTK_DIALOG(gtk_dialog_new_with_buttons(
326 smiley ? _("Edit Smiley") : _("Add Smiley"),
327 manager ? GTK_WINDOW(manager->window) : NULL,
328 GTK_DIALOG_DESTROY_WITH_PARENT,
329 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
330 smiley ? GTK_STOCK_SAVE : GTK_STOCK_ADD, GTK_RESPONSE_ACCEPT,
331 NULL));
332 gtk_dialog_set_default_response(
333 edit_dialog->window, GTK_RESPONSE_ACCEPT);
335 if (smiley) {
336 edit_dialog->smiley = smiley;
337 g_object_set_data(G_OBJECT(smiley),
338 "pidgin-smiley-manager-edit-dialog", edit_dialog);
339 g_object_ref(smiley);
343 /* The vbox */
344 vbox = gtk_grid_new();
345 gtk_grid_set_row_spacing(GTK_GRID(vbox), PIDGIN_HIG_BORDER);
346 gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(
347 edit_dialog->window)), vbox);
348 gtk_widget_show(vbox);
350 /* The hbox */
351 hbox = gtk_grid_new();
352 gtk_grid_set_column_spacing(GTK_GRID(hbox), PIDGIN_HIG_BORDER);
353 gtk_grid_attach(GTK_GRID(vbox), hbox, 0, 0, 1, 1);
355 label = GTK_LABEL(gtk_label_new_with_mnemonic(_("_Image:")));
356 gtk_grid_attach(GTK_GRID(hbox), GTK_WIDGET(label), 0, 0, 1, 1);
357 gtk_widget_show(GTK_WIDGET(label));
359 filech = GTK_BUTTON(gtk_button_new());
360 gtk_grid_attach_next_to(GTK_GRID(hbox), GTK_WIDGET(filech), NULL,
361 GTK_POS_RIGHT, 1, 1);
362 pidgin_set_accessible_label(GTK_WIDGET(filech), label);
364 edit_dialog->thumbnail = GTK_IMAGE(gtk_image_new());
365 gtk_container_add(GTK_CONTAINER(filech),
366 GTK_WIDGET(edit_dialog->thumbnail));
368 gtk_widget_show_all(hbox);
370 /* info */
371 hbox = gtk_grid_new();
372 gtk_grid_set_column_spacing(GTK_GRID(hbox), PIDGIN_HIG_BORDER);
374 gtk_grid_attach_next_to(GTK_GRID(vbox), hbox, NULL,
375 GTK_POS_BOTTOM, 1, 1);
377 /* Shortcut text */
378 label = GTK_LABEL(gtk_label_new_with_mnemonic(_("S_hortcut text:")));
379 gtk_grid_attach(GTK_GRID(hbox), GTK_WIDGET(label), 0, 0, 1, 1);
380 gtk_widget_show(GTK_WIDGET(label));
382 edit_dialog->shortcut = GTK_ENTRY(gtk_entry_new());
383 gtk_entry_set_activates_default(edit_dialog->shortcut, TRUE);
384 pidgin_set_accessible_label(GTK_WIDGET(edit_dialog->shortcut), label);
386 gtk_grid_attach_next_to(GTK_GRID(hbox),
387 GTK_WIDGET(edit_dialog->shortcut), NULL, GTK_POS_RIGHT, 1, 1);
389 gtk_widget_show(GTK_WIDGET(edit_dialog->shortcut));
390 gtk_widget_show(hbox);
391 gtk_widget_show(GTK_WIDGET(edit_dialog->window));
393 if (smiley) {
394 edit_dialog->filename = g_strdup(purple_image_get_path(
395 purple_smiley_get_image(smiley)));
396 gtk_entry_set_text(edit_dialog->shortcut,
397 purple_smiley_get_shortcut(smiley));
400 edit_dialog_image_update_thumb(edit_dialog);
401 edit_dialog_update_buttons(edit_dialog);
403 g_signal_connect(edit_dialog->window, "response",
404 G_CALLBACK(edit_dialog_response), edit_dialog);
405 g_signal_connect(filech, "clicked",
406 G_CALLBACK(edit_dialog_image_choose), edit_dialog);
407 g_signal_connect(edit_dialog->shortcut, "changed",
408 G_CALLBACK(edit_dialog_shortcut_changed), edit_dialog);
410 g_signal_connect(edit_dialog->window, "destroy",
411 G_CALLBACK(edit_dialog_destroy), edit_dialog);
412 g_signal_connect(edit_dialog->window, "destroy",
413 G_CALLBACK(purple_notify_close_with_handle), edit_dialog);
415 return edit_dialog;
418 void
419 pidgin_smiley_manager_add(PurpleImage *image, const gchar *shortcut)
421 SmileyEditDialog *edit_dialog;
423 g_return_if_fail(image != NULL);
425 g_object_ref(image);
427 edit_dialog = edit_dialog_show(NULL, NULL);
428 edit_dialog_set_shortcut(edit_dialog, shortcut);
429 if (!edit_dialog_set_image(edit_dialog, image))
430 gtk_widget_destroy(GTK_WIDGET(edit_dialog->window));
434 /*******************************************************************************
435 * Custom smiley list Drag-and-drop support.
436 ******************************************************************************/
438 static void
439 smiley_list_dnd_url_got(PurpleHttpConnection *http_conn,
440 PurpleHttpResponse *response, gpointer _manager)
442 SmileyManager *manager = _manager;
443 SmileyEditDialog *edit_dialog;
444 PurpleImage *image;
445 const gchar *image_data;
446 size_t image_size;
448 g_return_if_fail(manager == smiley_manager);
449 g_return_if_fail(manager->running_request == http_conn);
450 manager->running_request = NULL;
452 if (!purple_http_response_is_successful(response))
453 return;
455 image_data = purple_http_response_get_data(response, &image_size);
456 image = purple_image_new_from_data(g_memdup(image_data, image_size),
457 image_size);
458 if (!image)
459 return;
461 edit_dialog = edit_dialog_show(manager, NULL);
462 if (!edit_dialog_set_image(edit_dialog, image))
463 gtk_widget_destroy(GTK_WIDGET(edit_dialog->window));
466 static void
467 smiley_list_dnd_recv(GtkWidget *widget, GdkDragContext *dc, gint x, gint y,
468 GtkSelectionData *sd, guint info, guint time, gpointer _manager)
470 SmileyManager *manager = _manager;
471 gchar content[1024];
473 /* We don't need anything, that is not 8-bit per element (char). */
474 if (gtk_selection_data_get_format(sd) != 8) {
475 gtk_drag_finish(dc, FALSE, FALSE, time);
476 return;
479 if (gtk_selection_data_get_length(sd) <= 0) {
480 gtk_drag_finish(dc, FALSE, FALSE, time);
481 return;
484 memset(&content, 0, sizeof(content));
485 memcpy(&content, gtk_selection_data_get_data(sd),
486 MIN((guint)gtk_selection_data_get_length(sd), sizeof(content)));
487 g_strstrip(content);
488 if (content[0] == '\0') {
489 gtk_drag_finish(dc, FALSE, FALSE, time);
490 return;
493 /* Well, it looks like the drag event was cool.
494 * Let's do something with it */
496 if (purple_str_has_caseprefix(content, "file://")) {
497 SmileyEditDialog *edit_dialog;
498 PurpleImage *image;
499 gchar *filename;
501 filename = g_filename_from_uri(content, NULL, NULL);
502 if (!filename || !g_file_test(filename, G_FILE_TEST_EXISTS)) {
503 purple_debug_warning("gtksmiley-manager",
504 "dropped file does not exists");
505 gtk_drag_finish(dc, FALSE, FALSE, time);
506 return;
509 image = purple_image_new_from_file(filename, TRUE);
510 if (!image) {
511 purple_debug_warning("gtksmiley-manager",
512 "dropped file is not a valid image");
513 gtk_drag_finish(dc, FALSE, FALSE, time);
514 return;
516 edit_dialog = edit_dialog_show(manager, NULL);
517 if (!edit_dialog_set_image(edit_dialog, image)) {
518 gtk_widget_destroy(GTK_WIDGET(edit_dialog->window));
519 gtk_drag_finish(dc, FALSE, FALSE, time);
520 return;
523 gtk_drag_finish(dc, TRUE, FALSE, time);
524 return;
527 if (purple_str_has_caseprefix(content, "http://") ||
528 purple_str_has_caseprefix(content, "https://"))
530 purple_http_conn_cancel(smiley_manager->
531 running_request);
532 smiley_manager->running_request = purple_http_get(NULL,
533 smiley_list_dnd_url_got, manager, content);
535 gtk_drag_finish(dc, TRUE, FALSE, time);
536 return;
539 gtk_drag_finish(dc, FALSE, FALSE, time);
542 /*******************************************************************************
543 * Custom smiley list.
544 ******************************************************************************/
546 static void
547 smiley_list_selected(GtkTreeSelection *sel, gpointer _manager)
549 SmileyManager *manager = _manager;
550 gboolean sens;
552 sens = (gtk_tree_selection_count_selected_rows(sel) > 0);
554 gtk_dialog_set_response_sensitive(manager->window,
555 GTK_RESPONSE_NO, sens);
556 gtk_dialog_set_response_sensitive(manager->window,
557 PIDGIN_RESPONSE_MODIFY, sens);
560 static void
561 smiley_list_activated(GtkTreeView *tree, GtkTreePath *path,
562 GtkTreeViewColumn *col, gpointer _manager)
564 SmileyManager *manager = _manager;
565 GtkTreeIter iter;
566 PurpleSmiley *smiley = NULL;
568 if (!gtk_tree_model_get_iter(
569 GTK_TREE_MODEL(manager->model), &iter, path))
571 return;
574 gtk_tree_model_get(GTK_TREE_MODEL(manager->model), &iter,
575 SMILEY_LIST_MODEL_PURPLESMILEY, &smiley, -1);
576 g_return_if_fail(PURPLE_IS_SMILEY(smiley));
578 edit_dialog_show(manager, smiley);
581 static void
582 manager_list_add(SmileyManager *manager, PurpleSmiley *smiley)
584 GdkPixbuf *smiley_image;
585 GtkTreeIter iter;
587 smiley_image = g_object_get_data(G_OBJECT(smiley),
588 "pidgin-smiley-manager-list-thumb");
589 if (smiley_image == NULL) {
590 smiley_image = pidgin_pixbuf_from_image(
591 purple_smiley_get_image(smiley));
592 smiley_image = pidgin_pixbuf_scale_down(smiley_image,
593 22, 22, GDK_INTERP_BILINEAR, TRUE);
594 g_object_set_data_full(G_OBJECT(smiley),
595 "pidgin-smiley-manager-list-thumb",
596 smiley_image, g_object_unref);
599 gtk_list_store_append(manager->model, &iter);
600 gtk_list_store_set(manager->model, &iter,
601 SMILEY_LIST_MODEL_ICON, smiley_image,
602 SMILEY_LIST_MODEL_SHORTCUT, purple_smiley_get_shortcut(smiley),
603 SMILEY_LIST_MODEL_PURPLESMILEY, smiley,
604 -1);
607 static void
608 manager_list_fill(SmileyManager *manager)
610 GList *custom_smileys, *it;
611 gtk_list_store_clear(manager->model);
613 custom_smileys = purple_smiley_list_get_all(
614 purple_smiley_custom_get_list());
616 for (it = custom_smileys; it; it = g_list_next(it)) {
617 PurpleSmiley *smiley = it->data;
619 manager_list_add(manager, smiley);
621 g_list_free(custom_smileys);
624 static GtkWidget *
625 manager_list_create(SmileyManager *manager)
627 GtkTreeView *tree;
628 GtkTreeSelection *sel;
629 GtkCellRenderer *cellrend;
630 GtkTreeViewColumn *column;
631 GtkTargetEntry targets[3] = {
632 {"text/plain", 0, 0},
633 {"text/uri-list", 0, 1},
634 {"STRING", 0, 2}
637 manager->model = gtk_list_store_new(SMILEY_LIST_MODEL_N_COL,
638 GDK_TYPE_PIXBUF, /* icon */
639 G_TYPE_STRING, /* shortcut */
640 G_TYPE_OBJECT /* PurpleSmiley */
643 manager->tree = tree = GTK_TREE_VIEW(gtk_tree_view_new_with_model(
644 GTK_TREE_MODEL(manager->model)));
646 gtk_tree_view_set_rules_hint(tree, TRUE);
647 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(manager->model),
648 SMILEY_LIST_MODEL_SHORTCUT, GTK_SORT_ASCENDING);
650 g_object_unref(manager->model);
652 sel = gtk_tree_view_get_selection(tree);
653 gtk_tree_selection_set_mode(sel, GTK_SELECTION_MULTIPLE);
655 g_signal_connect(sel, "changed",
656 G_CALLBACK(smiley_list_selected), manager);
657 g_signal_connect(tree, "row-activated",
658 G_CALLBACK(smiley_list_activated), manager);
660 gtk_drag_dest_set(GTK_WIDGET(tree), GTK_DEST_DEFAULT_MOTION |
661 GTK_DEST_DEFAULT_HIGHLIGHT | GTK_DEST_DEFAULT_DROP,
662 targets, G_N_ELEMENTS(targets),
663 GDK_ACTION_COPY | GDK_ACTION_MOVE);
664 g_signal_connect(tree, "drag-data-received",
665 G_CALLBACK(smiley_list_dnd_recv), manager);
667 gtk_widget_show(GTK_WIDGET(tree));
669 /* setting up columns */
671 column = gtk_tree_view_column_new();
672 gtk_tree_view_column_set_title(column, _("Smiley"));
673 gtk_tree_view_column_set_resizable(column, TRUE);
674 gtk_tree_view_append_column(tree, column);
675 cellrend = gtk_cell_renderer_pixbuf_new();
676 gtk_tree_view_column_pack_start(column, cellrend, FALSE);
677 gtk_tree_view_column_add_attribute(column, cellrend,
678 "pixbuf", SMILEY_LIST_MODEL_ICON);
680 column = gtk_tree_view_column_new();
681 gtk_tree_view_column_set_title(column, _("Shortcut Text"));
682 gtk_tree_view_column_set_resizable(column, TRUE);
683 gtk_tree_view_append_column(tree, column);
684 cellrend = gtk_cell_renderer_text_new();
685 gtk_tree_view_column_pack_start(column, cellrend, TRUE);
686 gtk_tree_view_column_add_attribute(column, cellrend,
687 "text", SMILEY_LIST_MODEL_SHORTCUT);
689 manager_list_fill(manager);
691 return pidgin_make_scrollable(GTK_WIDGET(tree), GTK_POLICY_AUTOMATIC,
692 GTK_POLICY_AUTOMATIC, GTK_SHADOW_IN, -1, -1);
695 /*******************************************************************************
696 * Custom smiley manager window.
697 ******************************************************************************/
699 static void
700 manager_select_cb(GtkWidget *widget, gint resp, SmileyManager *manager)
702 GtkTreeSelection *selection = NULL;
703 GList *selected_rows, *selected_smileys = NULL, *it;
704 GtkTreeModel *model = GTK_TREE_MODEL(manager->model);
706 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(manager->tree));
707 selected_rows = gtk_tree_selection_get_selected_rows(selection, NULL);
708 for (it = selected_rows; it; it = g_list_next(it)) {
709 GtkTreePath *path = it->data;
710 GtkTreeIter iter;
711 PurpleSmiley *smiley = NULL;
713 if (!gtk_tree_model_get_iter(model, &iter, path))
714 continue;
716 gtk_tree_model_get(model, &iter,
717 SMILEY_LIST_MODEL_PURPLESMILEY, &smiley, -1);
718 if (!smiley)
719 continue;
721 selected_smileys = g_list_prepend(selected_smileys, smiley);
723 g_list_free_full(selected_rows, (GDestroyNotify)gtk_tree_path_free);
725 switch (resp) {
726 case GTK_RESPONSE_YES:
727 edit_dialog_show(manager, NULL);
728 break;
729 case GTK_RESPONSE_NO:
730 for (it = selected_smileys; it; it = g_list_next(it))
731 purple_smiley_custom_remove(it->data);
732 manager_list_fill(manager);
733 break;
734 case GTK_RESPONSE_DELETE_EVENT:
735 case GTK_RESPONSE_CLOSE:
736 gtk_widget_destroy(GTK_WIDGET(manager->window));
737 purple_http_conn_cancel(manager->running_request);
738 g_free(manager);
739 smiley_manager = NULL;
740 break;
741 case PIDGIN_RESPONSE_MODIFY:
742 for (it = selected_smileys; it; it = g_list_next(it))
743 edit_dialog_show(manager, it->data);
744 break;
745 default:
746 g_warn_if_reached();
749 g_list_free(selected_smileys);
752 void
753 pidgin_smiley_manager_show(void)
755 SmileyManager *manager;
756 GtkDialog *win;
757 GtkWidget *sw, *vbox;
759 if (smiley_manager) {
760 gtk_window_present(GTK_WINDOW(smiley_manager->window));
761 return;
764 manager = g_new0(SmileyManager, 1);
765 smiley_manager = manager;
767 manager->window = win = GTK_DIALOG(gtk_dialog_new_with_buttons(
768 _("Custom Smiley Manager"), NULL,
769 GTK_DIALOG_DESTROY_WITH_PARENT,
770 PIDGIN_STOCK_ADD, GTK_RESPONSE_YES,
771 PIDGIN_STOCK_MODIFY, PIDGIN_RESPONSE_MODIFY,
772 GTK_STOCK_DELETE, GTK_RESPONSE_NO,
773 GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
774 NULL));
776 gtk_window_set_default_size(GTK_WINDOW(win), 50, 400);
777 gtk_window_set_role(GTK_WINDOW(win), "custom_smiley_manager");
778 gtk_dialog_set_response_sensitive(win, GTK_RESPONSE_NO, FALSE);
779 gtk_dialog_set_response_sensitive(win, PIDGIN_RESPONSE_MODIFY, FALSE);
781 g_signal_connect(win, "response",
782 G_CALLBACK(manager_select_cb), manager);
784 /* The vbox */
785 vbox = gtk_dialog_get_content_area(win);
787 /* get the scrolled window with all stuff */
788 sw = manager_list_create(manager);
789 gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0);
790 gtk_widget_show(sw);
792 gtk_widget_show(GTK_WIDGET(win));