gtk: Port to async dialog API

This commit is contained in:
Matthias Clasen
2022-10-28 11:32:55 -04:00
parent 6ed2d2b232
commit 9ab732ce2d
4 changed files with 109 additions and 190 deletions

View File

@@ -44,7 +44,7 @@
#include "gtklabel.h"
#include "gtklistitem.h"
#include "gtkmarshalers.h"
#include "gtkmessagedialog.h"
#include "gtkalertdialog.h"
#include "gtkmountoperation.h"
#include "gtkmultiselection.h"
#include "gtkpaned.h"
@@ -665,26 +665,12 @@ error_message (GtkFileChooserWidget *impl,
const char *detail)
{
GtkWindow *parent = get_toplevel (GTK_WIDGET (impl));
GtkWidget *dialog;
GtkAlertDialog *dialog;
dialog = gtk_message_dialog_new (parent,
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_OK,
"%s",
msg);
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
"%s", detail);
if (parent && gtk_window_has_group (parent))
gtk_window_group_add_window (gtk_window_get_group (parent),
GTK_WINDOW (dialog));
gtk_window_present (GTK_WINDOW (dialog));
g_signal_connect (dialog, "response",
G_CALLBACK (gtk_window_destroy),
NULL);
dialog = gtk_alert_dialog_new ("%s", msg);
gtk_alert_dialog_set_detail (dialog, detail);
gtk_alert_dialog_show (dialog, parent);
g_object_unref (dialog);
}
/* Shows a simple error dialog relative to a path. Frees the GError as well. */
@@ -1125,15 +1111,16 @@ typedef struct {
} ConfirmDeleteData;
static void
on_confirm_delete_response (GtkWidget *dialog,
int response,
gpointer user_data)
on_confirm_delete_response (GObject *source,
GAsyncResult *result,
void *user_data)
{
ConfirmDeleteData *data = user_data;
int button;
gtk_window_destroy (GTK_WINDOW (dialog));
button = gtk_alert_dialog_choose_finish (GTK_ALERT_DIALOG (source), result);
if (response == GTK_RESPONSE_ACCEPT)
if (button == 1)
{
GError *error = NULL;
@@ -1150,7 +1137,7 @@ confirm_delete (GtkFileChooserWidget *impl,
GFileInfo *info)
{
GtkWindow *toplevel;
GtkWidget *dialog;
GtkAlertDialog *dialog;
const char *name;
ConfirmDeleteData *data;
@@ -1158,30 +1145,16 @@ confirm_delete (GtkFileChooserWidget *impl,
toplevel = get_toplevel (GTK_WIDGET (impl));
dialog = gtk_message_dialog_new (toplevel,
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_QUESTION,
GTK_BUTTONS_NONE,
_("Are you sure you want to permanently delete “%s”?"),
name);
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
_("If you delete an item, it will be permanently lost."));
gtk_dialog_add_button (GTK_DIALOG (dialog), _("_Cancel"), GTK_RESPONSE_CANCEL);
gtk_dialog_add_button (GTK_DIALOG (dialog), _("_Delete"), GTK_RESPONSE_ACCEPT);
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
if (gtk_window_has_group (toplevel))
gtk_window_group_add_window (gtk_window_get_group (toplevel), GTK_WINDOW (dialog));
gtk_widget_show (dialog);
data = g_new (ConfirmDeleteData, 1);
data->impl = impl;
data->file = file;
g_signal_connect (dialog, "response",
G_CALLBACK (on_confirm_delete_response),
data);
dialog = gtk_alert_dialog_new (_("Are you sure you want to permanently delete “%s”?"), name);
gtk_alert_dialog_set_detail (dialog, _("If you delete an item, it will be permanently lost."));
gtk_alert_dialog_set_buttons (dialog, (const char *[]) { _("_Cancel"), _("_Delete"), NULL });
gtk_alert_dialog_set_cancel_button (dialog, 0);
gtk_alert_dialog_set_default_button (dialog, 1);
gtk_alert_dialog_choose (dialog, toplevel, NULL, on_confirm_delete_response, data);
}
static void
@@ -4928,18 +4901,6 @@ get_display_name_from_file_list (GtkFileChooserWidget *impl)
return g_file_info_get_display_name (info);
}
static void
add_custom_button_to_dialog (GtkDialog *dialog,
const char *mnemonic_label,
int response_id)
{
GtkWidget *button;
button = gtk_button_new_with_mnemonic (mnemonic_label);
gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button, response_id);
}
/* Every time we request a response explicitly, we need to save the selection to
* the recently-used list, as requesting a response means, “the dialog is confirmed”.
*/
@@ -4951,13 +4912,16 @@ request_response_and_add_to_recent_list (GtkFileChooserWidget *impl)
}
static void
on_confirm_overwrite_response (GtkWidget *dialog,
int response,
gpointer user_data)
on_confirm_overwrite_response (GObject *source,
GAsyncResult *result,
void *user_data)
{
GtkFileChooserWidget *impl = user_data;
int button;
if (response == GTK_RESPONSE_ACCEPT)
button = gtk_alert_dialog_choose_finish (GTK_ALERT_DIALOG (source), result);
if (button == 1)
{
/* Dialog is now going to be closed, so prevent any button/key presses to
* file list (will be restablished on next map()). Fixes data loss bug #2288 */
@@ -4965,8 +4929,6 @@ on_confirm_overwrite_response (GtkWidget *dialog,
request_response_and_add_to_recent_list (impl);
}
gtk_window_destroy (GTK_WINDOW (dialog));
}
/* Presents an overwrite confirmation dialog */
@@ -4976,33 +4938,24 @@ confirm_dialog_should_accept_filename (GtkFileChooserWidget *impl,
const char *folder_display_name)
{
GtkWindow *toplevel;
GtkWidget *dialog;
GtkAlertDialog *dialog;
char *detail;
toplevel = get_toplevel (GTK_WIDGET (impl));
dialog = gtk_message_dialog_new (toplevel,
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_QUESTION,
GTK_BUTTONS_NONE,
_("A file named “%s” already exists. Do you want to replace it?"),
file_part);
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
_("The file already exists in “%s”. Replacing it will "
"overwrite its contents."),
folder_display_name);
dialog = gtk_alert_dialog_new (_("A file named “%s” already exists. Do you want to replace it?"),
file_part);
detail = g_strdup_printf (_("The file already exists in “%s”. Replacing it will "
"overwrite its contents."),
folder_display_name);
gtk_alert_dialog_set_detail (dialog, detail);
g_free (detail);
gtk_dialog_add_button (GTK_DIALOG (dialog), _("_Cancel"), GTK_RESPONSE_CANCEL);
add_custom_button_to_dialog (GTK_DIALOG (dialog), _("_Replace"), GTK_RESPONSE_ACCEPT);
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
if (gtk_window_has_group (toplevel))
gtk_window_group_add_window (gtk_window_get_group (toplevel), GTK_WINDOW (dialog));
gtk_window_present (GTK_WINDOW (dialog));
g_signal_connect (dialog, "response",
G_CALLBACK (on_confirm_overwrite_response),
impl);
gtk_alert_dialog_set_buttons (dialog, (const char *[]) { _("_Cancel"), _("_Replace"), NULL });
gtk_alert_dialog_set_cancel_button (dialog, 0);
gtk_alert_dialog_set_default_button (dialog, 1);
gtk_alert_dialog_choose (dialog, toplevel, NULL, on_confirm_overwrite_response, impl);
g_object_unref (dialog);
}
struct GetDisplayNameData

View File

@@ -35,7 +35,7 @@
#include "gtkbox.h"
#include <glib/gi18n-lib.h>
#include "gtklabel.h"
#include "gtkmessagedialog.h"
#include "gtkalertdialog.h"
#include "gtkmountoperation.h"
#include "gtkprivate.h"
#include "gtkcheckbutton.h"
@@ -904,27 +904,27 @@ gtk_mount_operation_ask_password (GMountOperation *mount_op,
}
static void
question_dialog_button_clicked (GtkDialog *dialog,
int button_number,
GMountOperation *op)
question_dialog_button_clicked (GObject *source,
GAsyncResult *result,
void *user_data)
{
GtkMountOperationPrivate *priv;
GtkAlertDialog *dialog = GTK_ALERT_DIALOG (source);
GMountOperation *op = user_data;
GtkMountOperation *operation;
int button;
operation = GTK_MOUNT_OPERATION (op);
priv = operation->priv;
if (button_number >= 0)
button = gtk_alert_dialog_choose_finish (dialog, result);
if (button >= 0)
{
g_mount_operation_set_choice (op, button_number);
g_mount_operation_set_choice (op, button);
g_mount_operation_reply (op, G_MOUNT_OPERATION_HANDLED);
}
else
g_mount_operation_reply (op, G_MOUNT_OPERATION_ABORTED);
priv->dialog = NULL;
g_object_notify (G_OBJECT (operation), "is-showing");
gtk_window_destroy (GTK_WINDOW (dialog));
g_object_unref (op);
}
@@ -934,10 +934,9 @@ gtk_mount_operation_ask_question_do_gtk (GtkMountOperation *op,
const char *choices[])
{
GtkMountOperationPrivate *priv;
GtkWidget *dialog;
GtkAlertDialog *dialog;
const char *secondary = NULL;
char *primary;
int count, len = 0;
g_return_if_fail (GTK_IS_MOUNT_OPERATION (op));
g_return_if_fail (message != NULL);
@@ -952,36 +951,19 @@ gtk_mount_operation_ask_question_do_gtk (GtkMountOperation *op,
primary = g_strndup (message, primary - message);
}
dialog = gtk_message_dialog_new (priv->parent_window, 0,
GTK_MESSAGE_QUESTION,
GTK_BUTTONS_NONE, "%s",
primary != NULL ? primary : message);
dialog = gtk_alert_dialog_new ("%s", primary ? primary : message);
if (secondary)
gtk_alert_dialog_set_detail (dialog, secondary);
gtk_alert_dialog_set_buttons (dialog, choices);
gtk_alert_dialog_choose (dialog, priv->parent_window,
NULL,
question_dialog_button_clicked, g_object_ref (op));
g_object_unref (dialog);
g_free (primary);
if (secondary)
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
"%s", secondary);
/* First count the items in the list then
* add the buttons in reverse order */
while (choices[len] != NULL)
len++;
for (count = len - 1; count >= 0; count--)
gtk_dialog_add_button (GTK_DIALOG (dialog), choices[count], count);
g_signal_connect (G_OBJECT (dialog), "response",
G_CALLBACK (question_dialog_button_clicked), op);
priv->dialog = GTK_DIALOG (dialog);
g_object_notify (G_OBJECT (op), "is-showing");
if (priv->parent_window == NULL && priv->display)
gtk_window_set_display (GTK_WINDOW (dialog), priv->display);
gtk_widget_show (dialog);
g_object_ref (op);
}
static void
@@ -1367,18 +1349,6 @@ update_process_list_store (GtkMountOperation *mount_operation,
g_array_unref (pid_indices_to_remove);
}
static void
on_dialog_response (GtkDialog *dialog,
int response)
{
/* GTK_RESPONSE_NONE means the dialog were programmatically destroy, e.g. that
* GTK_DIALOG_DESTROY_WITH_PARENT kicked in - so it would trigger a warning to
* destroy the dialog in that case
*/
if (response != GTK_RESPONSE_NONE)
gtk_window_destroy (GTK_WINDOW (dialog));
}
static void
on_end_process_activated (GtkButton *button,
GtkMountOperation *op)
@@ -1406,25 +1376,17 @@ on_end_process_activated (GtkButton *button,
error = NULL;
if (!_gtk_mount_operation_kill_process (data->pid, &error))
{
GtkWidget *dialog;
GtkAlertDialog *dialog;
/* Use GTK_DIALOG_DESTROY_WITH_PARENT here since the parent dialog can be
* indeed be destroyed via the GMountOperation::abort signal... for example,
* this is triggered if the user yanks the device while we are showing
* the dialog...
*/
dialog = gtk_message_dialog_new (GTK_WINDOW (op->priv->dialog),
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
_("Unable to end process"));
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
"%s",
error->message);
gtk_widget_show (dialog);
g_signal_connect (dialog, "response", G_CALLBACK (on_dialog_response), NULL);
dialog = gtk_alert_dialog_new (_("Unable to end process"));
gtk_alert_dialog_set_detail (dialog, error->message);
gtk_alert_dialog_show (dialog, GTK_WINDOW (op->priv->dialog));
g_object_unref (dialog);
g_error_free (error);
}

View File

@@ -27,7 +27,7 @@
#include "gtklistitem.h"
#include "gtksignallistitemfactory.h"
#include "gtkentry.h"
#include "gtkfilechooserdialog.h"
#include "gtkfiledialog.h"
#include "gtkimage.h"
#include "gtklabel.h"
#include "gtkcheckbutton.h"
@@ -639,19 +639,21 @@ check_toggled_cb (GtkCheckButton *check_button,
}
static void
dialog_response_callback (GtkDialog *dialog,
int response_id,
GtkPrinterOptionWidget *widget)
dialog_response_callback (GObject *source,
GAsyncResult *result,
gpointer data)
{
GtkFileDialog *dialog = GTK_FILE_DIALOG (source);
GtkPrinterOptionWidget *widget = data;
GtkPrinterOptionWidgetPrivate *priv = widget->priv;
GFile *new_location = NULL;
char *uri = NULL;
if (response_id == GTK_RESPONSE_ACCEPT)
new_location = gtk_file_dialog_save_finish (dialog, result, NULL);
if (new_location)
{
GFileInfo *info;
new_location = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (dialog));
info = g_file_query_info (new_location,
"standard::display-name",
0,
@@ -680,8 +682,6 @@ dialog_response_callback (GtkDialog *dialog,
}
}
gtk_window_destroy (GTK_WINDOW (dialog));
if (new_location)
uri = g_file_get_uri (new_location);
else
@@ -706,33 +706,46 @@ filesave_choose_cb (GtkWidget *button,
GtkPrinterOptionWidget *widget)
{
GtkPrinterOptionWidgetPrivate *priv = widget->priv;
GtkWidget *dialog;
GtkWindow *toplevel;
GtkFileDialog *dialog;
GFile *current_folder = NULL;
char *current_name = NULL;
/* this will be unblocked in the dialog_response_callback function */
g_signal_handler_block (priv->source, priv->source_changed_handler);
toplevel = GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (widget)));
dialog = gtk_file_chooser_dialog_new (_("Select a filename"),
toplevel,
GTK_FILE_CHOOSER_ACTION_SAVE,
_("_Cancel"), GTK_RESPONSE_CANCEL,
_("_Select"), GTK_RESPONSE_ACCEPT,
NULL);
/* select the current filename in the dialog */
if (priv->source != NULL && priv->source->value != NULL)
{
priv->last_location = g_file_new_for_uri (priv->source->value);
if (priv->last_location)
gtk_file_chooser_set_file (GTK_FILE_CHOOSER (dialog), priv->last_location, NULL);
{
if (g_file_query_file_type (priv->last_location, 0, NULL) == G_FILE_TYPE_DIRECTORY)
{
current_folder = g_object_ref (priv->last_location);
current_name = NULL;
}
else
{
current_folder = g_file_get_parent (priv->last_location);
current_name = g_file_get_basename (priv->last_location);
if (strcmp (current_name, "/") == 0 ||
!g_utf8_validate (current_name, -1, NULL))
g_clear_pointer (&current_name, g_free);
}
}
}
g_signal_connect (dialog, "response",
G_CALLBACK (dialog_response_callback),
widget);
gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
gtk_window_present (GTK_WINDOW (dialog));
dialog = gtk_file_dialog_new ();
gtk_file_dialog_set_title (dialog, _("Select a filename"));
gtk_file_dialog_save (dialog,
GTK_WINDOW (gtk_widget_get_root (GTK_WIDGET (widget))),
current_folder,
current_name,
NULL,
dialog_response_callback, widget);
g_object_unref (current_folder);
g_free (current_name);
}
static char *

View File

@@ -24,7 +24,7 @@
#include "gtkshow.h"
#include "gtkwindowprivate.h"
#include "gtkmessagedialog.h"
#include "gtkalertdialog.h"
#include <glib/gi18n-lib.h>
typedef struct {
@@ -165,21 +165,12 @@ show_uri_done (GObject *object,
if (!gtk_show_uri_full_finish (parent, result, &error))
{
GtkWidget *dialog;
GtkAlertDialog *dialog;
dialog = gtk_message_dialog_new (parent,
GTK_DIALOG_DESTROY_WITH_PARENT |
GTK_DIALOG_MODAL,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
"%s", _("Could not show link"));
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
"%s", error->message);
g_signal_connect (dialog, "response",
G_CALLBACK (gtk_window_destroy), NULL);
gtk_window_present (GTK_WINDOW (dialog));
dialog = gtk_alert_dialog_new ("%s", _("Could not show link"));
gtk_alert_dialog_set_detail (dialog, error->message);
gtk_alert_dialog_show (dialog, parent);
g_object_unref (dialog);
g_error_free (error);
}