From b2d8f146c3a767f4e4d87bba83eb49421554fa39 Mon Sep 17 00:00:00 2001 From: Elliott Sales de Andrade Date: Sun, 29 Sep 2019 00:58:53 -0400 Subject: [PATCH] Don't allow multiple file choosers for custom buddy icons. --- pidgin/gtkblist.c | 11 +++++++--- pidgin/gtkconv.c | 63 ++++++++++++++++++++++++++++++++++--------------------- 2 files changed, 47 insertions(+), 27 deletions(-) diff --git a/pidgin/gtkblist.c b/pidgin/gtkblist.c index 2b570f6e52..9d2c7ef782 100644 --- a/pidgin/gtkblist.c +++ b/pidgin/gtkblist.c @@ -1680,14 +1680,19 @@ set_node_custom_icon_cb(const gchar *filename, gpointer data) purple_buddy_icons_node_set_custom_icon_from_file(node, filename); } + g_object_set_data(G_OBJECT(data), "buddy-icon-chooser", NULL); } static void set_node_custom_icon(GtkWidget *w, PurpleBlistNode *node) { - /* This doesn't keep track of the returned dialog (so that successive - * calls could be made to re-display that dialog). Do we want that? */ - GtkWidget *win = pidgin_buddy_icon_chooser_new(NULL, set_node_custom_icon_cb, node); + GtkWidget *win = g_object_get_data(G_OBJECT(node), "buddy-icon-chooser"); + if (win == NULL) { + win = pidgin_buddy_icon_chooser_new(NULL, set_node_custom_icon_cb, + node); + g_object_set_data_full(G_OBJECT(node), "buddy-icon-chooser", win, + (GDestroyNotify)gtk_widget_destroy); + } gtk_widget_show_all(win); } diff --git a/pidgin/gtkconv.c b/pidgin/gtkconv.c index 0b864d7e25..2ebea7fdae 100644 --- a/pidgin/gtkconv.c +++ b/pidgin/gtkconv.c @@ -2236,30 +2236,31 @@ static void custom_icon_sel_cb(const char *filename, gpointer data) { if (filename) { - const gchar *name; - PurpleBuddy *buddy; - PurpleContact *contact; - PidginConversation *gtkconv = data; - PurpleConversation *conv = gtkconv->active_conv; - PurpleAccount *account = purple_conversation_get_account(conv); - - name = purple_conversation_get_name(conv); - buddy = purple_blist_find_buddy(account, name); - if (!buddy) { - purple_debug_info("custom-icon", "You can only set custom icons for people on your buddylist.\n"); - return; - } - contact = purple_buddy_get_contact(buddy); + PurpleContact *contact = data; purple_buddy_icons_node_set_custom_icon_from_file((PurpleBlistNode*)contact, filename); } + g_object_set_data(G_OBJECT(data), "buddy-icon-chooser", NULL); } static void -set_custom_icon_cb(GtkWidget *widget, PidginConversation *gtkconv) +set_custom_icon_cb(GtkWidget *widget, PurpleContact *contact) { - GtkWidget *win = pidgin_buddy_icon_chooser_new(GTK_WINDOW(gtkconv->win->window), - custom_icon_sel_cb, gtkconv); + GtkWidget *win = NULL; + + /* Should not happen as menu item should be disabled. */ + g_return_if_fail(contact != NULL); + + win = g_object_get_data(G_OBJECT(contact), "buddy-icon-chooser"); + if (win == NULL) { + GtkMenu *menu = GTK_MENU(gtk_widget_get_parent(widget)); + GtkWidget *toplevel = + gtk_widget_get_toplevel(gtk_menu_get_attach_widget(menu)); + win = pidgin_buddy_icon_chooser_new(GTK_WINDOW(toplevel), + custom_icon_sel_cb, contact); + g_object_set_data_full(G_OBJECT(contact), "buddy-icon-chooser", win, + (GDestroyNotify)gtk_widget_destroy); + } gtk_widget_show_all(win); } @@ -2355,7 +2356,8 @@ toggle_icon_animate_cb(GtkWidget *w, PidginConversation *gtkconv) static gboolean icon_menu(GtkWidget *widget, GdkEventButton *e, PidginConversation *gtkconv) { - static GtkWidget *menu = NULL; + GtkWidget *menu = NULL; + GList *old_menus = NULL; PurpleConversation *conv; PurpleBuddy *buddy; @@ -2372,10 +2374,14 @@ icon_menu(GtkWidget *widget, GdkEventButton *e, PidginConversation *gtkconv) * If a menu already exists, destroy it before creating a new one, * thus freeing-up the memory it occupied. */ - if (menu != NULL) + while ((old_menus = gtk_menu_get_for_attach_widget(widget)) != NULL) { + menu = old_menus->data; + gtk_menu_detach(GTK_MENU(menu)); gtk_widget_destroy(menu); + } menu = gtk_menu_new(); + gtk_menu_attach_to_widget(GTK_MENU(menu), widget, NULL); if (gtkconv->u.im->anim && !(gdk_pixbuf_animation_is_static_image(gtkconv->u.im->anim))) @@ -2385,22 +2391,31 @@ icon_menu(GtkWidget *widget, GdkEventButton *e, PidginConversation *gtkconv) gtkconv->u.im->icon_timer); } + conv = gtkconv->active_conv; + buddy = purple_blist_find_buddy(purple_conversation_get_account(conv), + purple_conversation_get_name(conv)); + pidgin_new_menu_item(menu, _("Hide Icon"), NULL, G_CALLBACK(remove_icon), gtkconv); pidgin_new_menu_item(menu, _("Save Icon As..."), GTK_STOCK_SAVE_AS, G_CALLBACK(icon_menu_save_cb), gtkconv); - pidgin_new_menu_item(menu, _("Set Custom Icon..."), NULL, - G_CALLBACK(set_custom_icon_cb), gtkconv); + if (buddy) { + PurpleContact *contact = purple_buddy_get_contact(buddy); + pidgin_new_menu_item(menu, _("Set Custom Icon..."), NULL, + G_CALLBACK(set_custom_icon_cb), contact); + } else { + GtkWidget *item = + pidgin_new_menu_item(menu, _("Set Custom Icon..."), NULL, + G_CALLBACK(set_custom_icon_cb), NULL); + gtk_widget_set_sensitive(item, FALSE); + } pidgin_new_menu_item(menu, _("Change Size"), NULL, G_CALLBACK(change_size_cb), gtkconv); /* Is there a custom icon for this person? */ - conv = gtkconv->active_conv; - buddy = purple_blist_find_buddy(purple_conversation_get_account(conv), - purple_conversation_get_name(conv)); if (buddy) { PurpleContact *contact = purple_buddy_get_contact(buddy); -- 2.11.4.GIT