Tue, 16 Aug 2022 01:00:44 -0500
Inline pidgin_buddy_icon_chooser_new
Current GTK guidance says not to use `gtk_file_chooser_set_current_folder`.
Additionally, native file dialogs do not support previews on Windows, macOS, or when using portals. GTK4 does away with the API entirely.
Removing all this functionality means it's just a wrapper around creating the dialog, so just inline that and drop the function entirely.
Testing Done:
Set an icon on a buddy, and also in a new account dialog.
Reviewed at https://reviews.imfreedom.org/r/1601/
| ChangeLog.API | file | annotate | diff | comparison | revisions | |
| pidgin/gtkaccount.c | file | annotate | diff | comparison | revisions | |
| pidgin/gtkblist.c | file | annotate | diff | comparison | revisions | |
| pidgin/gtkutils.c | file | annotate | diff | comparison | revisions | |
| pidgin/gtkutils.h | file | annotate | diff | comparison | revisions |
--- a/ChangeLog.API Tue Aug 16 00:18:33 2022 -0500 +++ b/ChangeLog.API Tue Aug 16 01:00:44 2022 -0500 @@ -871,6 +871,7 @@ * pidgin_blist_visibility_manager_add * pidgin_blist_visibility_manager_remove * PidginBlistLayout + * pidgin_buddy_icon_chooser_new * PidginBuddyList.connection_errors * PidginButtonStyle * pidgin_check_if_dir
--- a/pidgin/gtkaccount.c Tue Aug 16 00:18:33 2022 -0500 +++ b/pidgin/gtkaccount.c Tue Aug 16 01:00:44 2022 -0500 @@ -274,15 +274,18 @@ } static void -icon_filesel_choose_cb(const char *filename, gpointer data) +icon_filesel_choose_cb(GtkWidget *widget, gint response, gpointer data) { AccountPrefsDialog *dialog = data; - if (filename != NULL) - { + if (response == GTK_RESPONSE_ACCEPT) { + gchar *filename = NULL; + gpointer data = NULL; size_t len = 0; - gpointer data = pidgin_convert_buddy_icon(dialog->protocol, filename, &len); - set_dialog_icon(dialog, data, len, g_strdup(filename)); + + filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(widget)); + data = pidgin_convert_buddy_icon(dialog->protocol, filename, &len); + set_dialog_icon(dialog, data, len, filename); } g_clear_object(&dialog->icon_filesel); @@ -291,7 +294,15 @@ static void icon_select_cb(GtkWidget *button, AccountPrefsDialog *dialog) { - dialog->icon_filesel = pidgin_buddy_icon_chooser_new(GTK_WINDOW(dialog->window), icon_filesel_choose_cb, dialog); + dialog->icon_filesel = gtk_file_chooser_native_new(_("Buddy Icon"), + GTK_WINDOW(dialog->window), + GTK_FILE_CHOOSER_ACTION_OPEN, + _("_Open"), + _("_Cancel")); + + g_signal_connect(G_OBJECT(dialog->icon_filesel), "response", + G_CALLBACK(icon_filesel_choose_cb), dialog); + gtk_native_dialog_show(GTK_NATIVE_DIALOG(dialog->icon_filesel)); }
--- a/pidgin/gtkblist.c Tue Aug 16 00:18:33 2022 -0500 +++ b/pidgin/gtkblist.c Tue Aug 16 01:00:44 2022 -0500 @@ -191,14 +191,17 @@ } static void -set_node_custom_icon_cb(const gchar *filename, gpointer data) +set_node_custom_icon_cb(GtkWidget *widget, gint response, gpointer data) { - if (filename) { + if (response == GTK_RESPONSE_ACCEPT) { PurpleBlistNode *node = (PurpleBlistNode*)data; - - purple_buddy_icons_node_set_custom_icon_from_file(node, - filename); + gchar *filename = NULL; + + filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(widget)); + purple_buddy_icons_node_set_custom_icon_from_file(node, filename); + g_free(filename); } + g_object_set_data(G_OBJECT(data), "buddy-icon-chooser", NULL); } @@ -592,8 +595,13 @@ 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); + win = gtk_file_chooser_native_new(_("Buddy Icon"), NULL, + GTK_FILE_CHOOSER_ACTION_OPEN, + _("_Open"), _("_Cancel")); + + g_signal_connect(win, "response", G_CALLBACK(set_node_custom_icon_cb), + node); + g_object_set_data_full(G_OBJECT(node), "buddy-icon-chooser", win, g_object_unref); }
--- a/pidgin/gtkutils.c Tue Aug 16 00:18:33 2022 -0500 +++ b/pidgin/gtkutils.c Tue Aug 16 01:00:44 2022 -0500 @@ -90,8 +90,6 @@ struct _icon_chooser { GtkFileChooserNative *icon_filesel; - GtkWidget *icon_preview; - GtkWidget *icon_text; void (*callback)(const char*,gpointer); gpointer data; @@ -640,115 +638,6 @@ return all || purple_account_is_connected(purple_buddy_get_account(completion_entry->buddy)); } -static void -icon_filesel_choose_cb(GtkWidget *widget, gint response, struct _icon_chooser *dialog) -{ - char *filename, *current_folder; - - if (response != GTK_RESPONSE_ACCEPT) { - if (dialog->callback) - dialog->callback(NULL, dialog->data); - g_free(dialog); - return; - } - - filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog->icon_filesel)); - current_folder = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(dialog->icon_filesel)); - if (current_folder != NULL) { - purple_prefs_set_path(PIDGIN_PREFS_ROOT "/filelocations/last_icon_folder", current_folder); - g_free(current_folder); - } - - - if (dialog->callback) - dialog->callback(filename, dialog->data); - g_free(filename); - g_free(dialog); -} - - -static void -icon_preview_change_cb(GtkFileChooser *widget, struct _icon_chooser *dialog) -{ - GdkPixbuf *pixbuf; - int height, width; - char *basename, *markup, *size; - GStatBuf st; - char *filename; - - filename = gtk_file_chooser_get_preview_filename( - GTK_FILE_CHOOSER(dialog->icon_filesel)); - - if (!filename || g_stat(filename, &st) || !(pixbuf = purple_gdk_pixbuf_new_from_file_at_size(filename, 128, 128))) - { - gtk_image_set_from_pixbuf(GTK_IMAGE(dialog->icon_preview), NULL); - gtk_label_set_markup(GTK_LABEL(dialog->icon_text), ""); - g_free(filename); - return; - } - - gdk_pixbuf_get_file_info(filename, &width, &height); - basename = g_path_get_basename(filename); - size = g_format_size(st.st_size); - markup = g_strdup_printf(_("<b>File:</b> %s\n" - "<b>File size:</b> %s\n" - "<b>Image size:</b> %dx%d"), - basename, size, width, height); - - gtk_image_set_from_pixbuf(GTK_IMAGE(dialog->icon_preview), pixbuf); - gtk_label_set_markup(GTK_LABEL(dialog->icon_text), markup); - - g_object_unref(G_OBJECT(pixbuf)); - g_free(filename); - g_free(basename); - g_free(size); - g_free(markup); -} - -GtkFileChooserNative * -pidgin_buddy_icon_chooser_new(GtkWindow *parent, - void (*callback)(const char *, gpointer), - gpointer data) -{ - struct _icon_chooser *dialog = g_new0(struct _icon_chooser, 1); - - GtkWidget *vbox; - const char *current_folder; - - dialog->callback = callback; - dialog->data = data; - - current_folder = purple_prefs_get_path(PIDGIN_PREFS_ROOT "/filelocations/last_icon_folder"); - - dialog->icon_filesel = gtk_file_chooser_native_new( - _("Buddy Icon"), parent, GTK_FILE_CHOOSER_ACTION_OPEN, _("_Open"), - _("_Cancel")); - if ((current_folder != NULL) && (*current_folder != '\0')) - gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog->icon_filesel), - current_folder); - - dialog->icon_preview = gtk_image_new(); - dialog->icon_text = gtk_label_new(NULL); - - vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6); - gtk_widget_set_size_request(GTK_WIDGET(vbox), -1, 50); - gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(dialog->icon_preview), TRUE, FALSE, 0); - gtk_box_pack_end(GTK_BOX(vbox), GTK_WIDGET(dialog->icon_text), FALSE, FALSE, 0); - gtk_widget_show_all(vbox); - - gtk_file_chooser_set_preview_widget(GTK_FILE_CHOOSER(dialog->icon_filesel), vbox); - gtk_file_chooser_set_preview_widget_active(GTK_FILE_CHOOSER(dialog->icon_filesel), TRUE); - gtk_file_chooser_set_use_preview_label(GTK_FILE_CHOOSER(dialog->icon_filesel), FALSE); - - g_signal_connect(G_OBJECT(dialog->icon_filesel), "update-preview", - G_CALLBACK(icon_preview_change_cb), dialog); - g_signal_connect(G_OBJECT(dialog->icon_filesel), "response", - G_CALLBACK(icon_filesel_choose_cb), dialog); - icon_preview_change_cb(NULL, dialog); - - return dialog->icon_filesel; -} - /* * str_array_match: *
--- a/pidgin/gtkutils.h Tue Aug 16 00:18:33 2022 -0500 +++ b/pidgin/gtkutils.h Tue Aug 16 01:00:44 2022 -0500 @@ -205,20 +205,6 @@ GdkPixbuf *pidgin_create_icon_from_protocol(PurpleProtocol *protocol, PidginProtocolIconSize size, PurpleAccount *account); /** - * pidgin_buddy_icon_chooser_new: - * @parent: The parent window - * @callback: The callback to call when the window is closed. If the user chose an icon, the char* argument will point to its path - * @data: Data to pass to @callback - * - * Creates a File Selection widget for choosing a buddy icon - * - * Returns: (transfer full): The file dialog - */ -GtkFileChooserNative *pidgin_buddy_icon_chooser_new( - GtkWindow *parent, void (*callback)(const char *, gpointer), - gpointer data); - -/** * pidgin_convert_buddy_icon: * @protocol: The protocol to convert the icon * @path: The path of a file to convert