# HG changeset patch # User Sadrul Habib Chowdhury # Date 1209364166 0 # Node ID b70b4108799ef1ae4c5f7f100519bb47b310cfe1 # Parent ce984959bda060e126fe562b21d0ddfd40791645 Patch from Masca to use the buddy-icon selector to select a custom smiley. This gives us the preview widget for free, which is really nice. The patch also uses the icon-selector button we use for accounts in the smiley dialog, which is also very cool. This commit also includes some changes I made to make it possible to edit an existing smiley, by double clicking in the treeview. I merged this change with the changes in Masca's patch. I am hoping I didn't break anything in the process. If I did, let me know early before I forget whatever the heck I did! diff -r ce984959bda0 -r b70b4108799e pidgin/gtksmiley.c --- a/pidgin/gtksmiley.c Mon Apr 28 06:24:01 2008 +0000 +++ b/pidgin/gtksmiley.c Mon Apr 28 06:29:26 2008 +0000 @@ -34,12 +34,15 @@ #include "gtkimhtml.h" #include "gtksmiley.h" +#include "gtkutils.h" +#include "pidginstock.h" typedef struct { + PurpleSmiley *smiley; GtkWidget *parent; GtkWidget *smile; - GtkWidget *file_chooser; + GtkWidget *smiley_image; gchar *filename; } PidginSmiley; @@ -55,7 +58,7 @@ { ICON, SHORTCUT, - DATA, + SMILEY, N_COL }; @@ -184,26 +187,47 @@ { const gchar *entry; PurpleSmiley *emoticon; - gchar *file; entry = gtk_entry_get_text(GTK_ENTRY(s->smile)); - - if (s->filename == NULL || *entry == 0) { + emoticon = purple_smileys_find_by_shortcut(entry); + if (emoticon && emoticon != s->smiley) { purple_notify_error(s->parent, _("Custom Smiley"), - _("More Data needed"), - s->filename ? _("Please provide a shortcut to associate with the smiley.") - : _("Please select an image for the smiley.")); + _("Duplicate Shortcut"), + _("A custom smiley for the selected shortcut already exists. Please specify a different shortcut.")); return; } - purple_debug_info("gtksmiley", "adding a new smiley\n"); - file = g_path_get_basename(s->filename); - emoticon = purple_smiley_new_from_file(entry, s->filename, file); - purple_smileys_add(emoticon); - g_free(file); + if (s->smiley) { + if (s->filename) { + gchar *data = NULL; + size_t len; + GError *err = NULL; + + if (!g_file_get_contents(s->filename, &data, &len, &err)) { + purple_debug_error("gtksmiley", "Error reading %s: %s\n", + s->filename, err->message); + g_error_free(err); - if (gtk_smileys != NULL) - pidgin_smiley_add_to_list(emoticon); + return; + } + purple_smiley_set_data(s->smiley, (guchar*)data, len, FALSE); + } + purple_smiley_set_shortcut(s->smiley, entry); + } else { + if ((s->filename == NULL || *entry == 0)) { + purple_notify_error(s->parent, _("Custom Smiley"), + _("More Data needed"), + s->filename ? _("Please provide a shortcut to associate with the smiley.") + : _("Please select an image for the smiley.")); + return; + } + + purple_debug_info("gtksmiley", "adding a new smiley\n"); + emoticon = purple_smiley_new_from_file(entry, s->filename); + purple_smileys_add(emoticon); + if (gtk_smileys != NULL) + pidgin_smiley_add_to_list(emoticon); + } if (smiley_manager != NULL) refresh_list(); @@ -227,27 +251,50 @@ } } -static void do_add_file_cb(GtkWidget *widget, gint resp, PidginSmiley *s) +static void do_add_file_cb(const char *filename, gpointer data) { - if (resp == GTK_RESPONSE_ACCEPT) - s->filename = gtk_file_chooser_get_filename( - GTK_FILE_CHOOSER(s->file_chooser)); + PidginSmiley *s = data; + GdkPixbuf *pixbuf; + + if (!filename) + return; + + g_free(s->filename); + s->filename = g_strdup(filename); + pixbuf = gdk_pixbuf_new_from_file_at_scale(filename, 64, 64, FALSE, NULL); + gtk_image_set_from_pixbuf(GTK_IMAGE(s->smiley_image), pixbuf); + if (pixbuf) + gdk_pixbuf_unref(pixbuf); } -void pidgin_smiley_add(GtkWidget *widget) +static void +open_image_selector(GtkWidget *widget, PidginSmiley *psmiley) +{ + GtkWidget *file_chooser; + file_chooser = pidgin_buddy_icon_chooser_new(GTK_WINDOW(gtk_widget_get_toplevel(widget)), + do_add_file_cb, psmiley); + gtk_window_set_title(GTK_WINDOW(file_chooser), _("Custom Smiley")); + gtk_window_set_role(GTK_WINDOW(file_chooser), "file-selector-custom-smiley"); + gtk_widget_show_all(file_chooser); +} + +void pidgin_smiley_edit(GtkWidget *widget, PurpleSmiley *smiley) { GtkWidget *vbox; GtkWidget *hbox; GtkWidget *label; GtkWidget *filech; GtkWidget *window; + GdkPixbuf *pixbuf = NULL; + PurpleStoredImage *stored_img; PidginSmiley *s = g_new0(PidginSmiley, 1); + s->smiley = smiley; - window = gtk_dialog_new_with_buttons(_("Add Smiley"), + window = gtk_dialog_new_with_buttons(smiley ? _("Edit Smiley") : _("Add Smiley"), GTK_WINDOW(widget), GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR, - GTK_STOCK_ADD, GTK_RESPONSE_ACCEPT, + smiley ? GTK_STOCK_SAVE : GTK_STOCK_ADD, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL); s->parent = window; @@ -265,38 +312,46 @@ hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BORDER); gtk_container_add(GTK_CONTAINER(GTK_VBOX(vbox)), hbox); - label = gtk_label_new(_("Select the file:")); + label = gtk_label_new_with_mnemonic(_("Smiley _Image")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); gtk_widget_show(label); - s->file_chooser = gtk_file_chooser_dialog_new(_("Custom Smiley"), - GTK_WINDOW(window), - GTK_FILE_CHOOSER_ACTION_OPEN, - GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, - GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, - NULL); + filech = gtk_button_new(); + gtk_box_pack_end(GTK_BOX(hbox), filech, FALSE, FALSE, 0); + pidgin_set_accessible_label(filech, label); - g_signal_connect(s->file_chooser, "response", G_CALLBACK(do_add_file_cb), s); - - filech = gtk_file_chooser_button_new_with_dialog(GTK_WIDGET(s->file_chooser)); + s->smiley_image = gtk_image_new(); + gtk_container_add(GTK_CONTAINER(filech), s->smiley_image); + if (smiley && (stored_img = purple_smiley_get_stored_image(smiley))) { + pixbuf = pidgin_pixbuf_from_imgstore(stored_img); + purple_imgstore_unref(stored_img); + } else { + GtkIconSize icon_size = gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_SMALL); + pixbuf = gtk_widget_render_icon(window, PIDGIN_STOCK_TOOLBAR_SELECT_AVATAR, + icon_size, "PidginSmiley"); + } - gtk_box_pack_end(GTK_BOX(hbox), filech, TRUE, TRUE, 0); - gtk_widget_show(filech); + gtk_image_set_from_pixbuf(GTK_IMAGE(s->smiley_image), pixbuf); + if (pixbuf != NULL) + g_object_unref(G_OBJECT(pixbuf)); + g_signal_connect(G_OBJECT(filech), "clicked", G_CALLBACK(open_image_selector), s); - gtk_widget_show(hbox); + gtk_widget_show_all(hbox); /* info */ hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BORDER); gtk_container_add(GTK_CONTAINER(GTK_VBOX(vbox)),hbox); /* Smiley shortcut */ - label = gtk_label_new(_("Define Smiley's shortcut")); + label = gtk_label_new_with_mnemonic(_("Smiley S_hortcut")); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); gtk_widget_show(label); s->smile = gtk_entry_new(); gtk_entry_set_activates_default(GTK_ENTRY(s->smile), TRUE); - gtk_label_set_mnemonic_widget(GTK_LABEL(label), GTK_WIDGET(s->smile)); + pidgin_set_accessible_label(s->smile, label); + if (smiley) + gtk_entry_set_text(GTK_ENTRY(s->smile), purple_smiley_get_shortcut(smiley)); g_signal_connect(s->smile, "activate", G_CALLBACK(do_add), s); @@ -388,21 +443,12 @@ img = purple_smiley_get_stored_image(smiley); if (img != NULL) { - GdkPixbufLoader *loader = gdk_pixbuf_loader_new(); - GdkPixbuf *smiley_image = NULL; - - gdk_pixbuf_loader_write(loader, purple_imgstore_get_data(img), - purple_imgstore_get_size(img), NULL); - gdk_pixbuf_loader_close(loader, NULL); - smiley_image = gdk_pixbuf_loader_get_pixbuf(loader); - + GdkPixbuf *smiley_image = pidgin_pixbuf_from_imgstore(img); purple_imgstore_unref(img); if (smiley_image != NULL) sized_smiley = gdk_pixbuf_scale_simple(smiley_image, 22, 22, GDK_INTERP_HYPER); - - g_object_unref(loader); } @@ -411,7 +457,7 @@ gtk_list_store_set(smiley_manager->model, &iter, ICON, sized_smiley, SHORTCUT, purple_smiley_get_shortcut(smiley), - DATA, NULL, + SMILEY, smiley, -1); if (sized_smiley != NULL) @@ -443,6 +489,17 @@ GTK_RESPONSE_NO, selected > 0); } +static void smiley_edit_cb(GtkTreeView *treeview, GtkTreePath *path, GtkTreeViewColumn *col, gpointer data) +{ + GtkTreeIter iter; + SmileyManager *dialog = data; + PurpleSmiley *smiley = NULL; + + gtk_tree_model_get_iter(GTK_TREE_MODEL(dialog->model), &iter, path); + gtk_tree_model_get(GTK_TREE_MODEL(dialog->model), &iter, SMILEY, &smiley, -1); + pidgin_smiley_edit(gtk_widget_get_toplevel(GTK_WIDGET(treeview)), smiley); +} + static GtkWidget *smiley_list_create(SmileyManager *dialog) { GtkWidget *sw; @@ -454,14 +511,14 @@ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw), - GTK_SHADOW_NONE); + GTK_SHADOW_IN); gtk_widget_show(sw); /* Create the list model */ dialog->model = gtk_list_store_new(N_COL, GDK_TYPE_PIXBUF, /* ICON */ G_TYPE_STRING, /* SHORTCUT */ - G_TYPE_POINTER /* DATA */ + G_TYPE_POINTER /* SMILEY */ ); /* the actual treeview */ @@ -469,12 +526,13 @@ dialog->treeview = treeview; gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE); + sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview)); gtk_tree_selection_set_mode(sel, GTK_SELECTION_MULTIPLE); gtk_container_add(GTK_CONTAINER(sw), treeview); - g_signal_connect(G_OBJECT(sel), "changed", - G_CALLBACK(smile_selected_cb), dialog); + g_signal_connect(G_OBJECT(sel), "changed", G_CALLBACK(smile_selected_cb), dialog); + g_signal_connect(G_OBJECT(treeview), "row_activated", G_CALLBACK(smiley_edit_cb), dialog); gtk_widget_show(treeview); @@ -493,7 +551,7 @@ { switch (resp) { case GTK_RESPONSE_YES: - pidgin_smiley_add(dialog->window); + pidgin_smiley_edit(dialog->window, NULL); break; case GTK_RESPONSE_NO: smiley_delete(dialog); diff -r ce984959bda0 -r b70b4108799e pidgin/gtksmiley.h --- a/pidgin/gtksmiley.h Mon Apr 28 06:24:01 2008 +0000 +++ b/pidgin/gtksmiley.h Mon Apr 28 06:29:26 2008 +0000 @@ -70,10 +70,11 @@ void pidgin_smiley_manager_show(void); /** - * Displays the "Add smiley" Dialog Box + * Shows an editor for a smiley. * - * @param widget The parent widget to be linked + * @param widget The parent widget to be linked or @c NULL + * @param smiley The PurpleSmiley to be edited, or @c NULL for a new smiley */ -void pidgin_smiley_add(GtkWidget *widget); +void pidgin_smiley_edit(GtkWidget *widget, PurpleSmiley *smiley); #endif /* _PIDGIN_GTKSMILEY_H_*/