Add GtkAlertDialog
authorMatthias Clasen <mclasen@redhat.com>
Tue, 25 Oct 2022 04:12:28 +0000 (00:12 -0400)
committerMatthias Clasen <mclasen@redhat.com>
Sat, 29 Oct 2022 17:31:41 +0000 (13:31 -0400)
This is replacing GtkMessageDialog with an
async API for showing informational messages.

gtk/gtk.h
gtk/gtkalertdialog.c [new file with mode: 0644]
gtk/gtkalertdialog.h [new file with mode: 0644]
gtk/meson.build

index 2d9de5aa223cd0af9a5caf559c08b84386b8342a..51f30cefdcde2ad73e8b422d208fbc3357696297 100644 (file)
--- a/gtk/gtk.h
+++ b/gtk/gtk.h
@@ -38,6 +38,7 @@
 #include <gtk/gtkactionable.h>
 #include <gtk/gtkactionbar.h>
 #include <gtk/gtkadjustment.h>
+#include <gtk/gtkalertdialog.h>
 #include <gtk/deprecated/gtkappchooser.h>
 #include <gtk/deprecated/gtkappchooserdialog.h>
 #include <gtk/deprecated/gtkappchooserwidget.h>
diff --git a/gtk/gtkalertdialog.c b/gtk/gtkalertdialog.c
new file mode 100644 (file)
index 0000000..c1fbcd4
--- /dev/null
@@ -0,0 +1,752 @@
+/*
+ * GTK - The GIMP Toolkit
+ * Copyright (C) 2022 Red Hat, Inc.
+ * All rights reserved.
+ *
+ * This Library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This Library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "gtkalertdialog.h"
+
+#include "gtkbutton.h"
+#include "gtkmessagedialog.h"
+#include <glib/gi18n-lib.h>
+
+/**
+ * GtkAlertDialog:
+ *
+ * A `GtkAlertDialog` object collects the arguments that
+ * are needed to present a message to the user.
+ *
+ * The message is shown with the [method@Gtk.AlertDialog.choose]
+ * function. This API follows the GIO async pattern, and the result can
+ * be obtained by calling [method@Gtk.AlertDialog.choose_finish].
+ *
+ * If you don't need to wait for a button to be clicked, you can use
+ * [method@Gtk.AlertDialog.show].
+ *
+ * `GtkAlertDialog was added in GTK 4.10.
+ */
+
+/* {{{ GObject implementation */
+
+struct _GtkAlertDialog
+{
+  GObject parent_instance;
+
+  char *message;
+  char *detail;
+  char **buttons;
+
+  int cancel_button;
+  int default_button;
+
+  int cancel_return;
+
+  unsigned int modal : 1;
+};
+
+enum
+{
+  PROP_MODAL = 1,
+  PROP_MESSAGE,
+  PROP_DETAIL,
+  PROP_BUTTONS,
+  PROP_CANCEL_BUTTON,
+  PROP_DEFAULT_BUTTON,
+
+  NUM_PROPERTIES
+};
+
+static GParamSpec *properties[NUM_PROPERTIES];
+
+G_DEFINE_TYPE (GtkAlertDialog, gtk_alert_dialog, G_TYPE_OBJECT)
+
+static void
+gtk_alert_dialog_init (GtkAlertDialog *self)
+{
+  self->modal = TRUE;
+  self->cancel_button = -1;
+  self->default_button = -1;
+}
+
+static void
+gtk_alert_dialog_finalize (GObject *object)
+{
+  GtkAlertDialog *self = GTK_ALERT_DIALOG (object);
+
+  g_free (self->message);
+  g_free (self->detail);
+  g_strfreev (self->buttons);
+
+  G_OBJECT_CLASS (gtk_alert_dialog_parent_class)->finalize (object);
+}
+
+static void
+gtk_alert_dialog_get_property (GObject      *object,
+                              unsigned int  property_id,
+                              GValue       *value,
+                              GParamSpec   *pspec)
+{
+  GtkAlertDialog *self = GTK_ALERT_DIALOG (object);
+
+  switch (property_id)
+    {
+    case PROP_MODAL:
+      g_value_set_boolean (value, self->modal);
+      break;
+
+    case PROP_MESSAGE:
+      g_value_set_string (value, self->message);
+      break;
+
+    case PROP_DETAIL:
+      g_value_set_string (value, self->detail);
+      break;
+
+    case PROP_BUTTONS:
+      g_value_set_boxed (value, self->buttons);
+      break;
+
+    case PROP_CANCEL_BUTTON:
+      g_value_set_int (value, self->cancel_button);
+      break;
+
+    case PROP_DEFAULT_BUTTON:
+      g_value_set_int (value, self->default_button);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+      break;
+    }
+}
+
+static void
+gtk_alert_dialog_set_property (GObject      *object,
+                              unsigned int  prop_id,
+                              const GValue *value,
+                              GParamSpec   *pspec)
+{
+  GtkAlertDialog *self = GTK_ALERT_DIALOG (object);
+
+  switch (prop_id)
+    {
+    case PROP_MODAL:
+      gtk_alert_dialog_set_modal (self, g_value_get_boolean (value));
+      break;
+
+    case PROP_MESSAGE:
+      gtk_alert_dialog_set_message (self, g_value_get_string (value));
+      break;
+
+    case PROP_DETAIL:
+      gtk_alert_dialog_set_detail (self, g_value_get_string (value));
+      break;
+
+    case PROP_BUTTONS:
+      gtk_alert_dialog_set_buttons (self, g_value_get_boxed (value));
+      break;
+
+    case PROP_CANCEL_BUTTON:
+      gtk_alert_dialog_set_cancel_button (self, g_value_get_int (value));
+      break;
+
+    case PROP_DEFAULT_BUTTON:
+      gtk_alert_dialog_set_default_button (self, g_value_get_int (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+static void
+gtk_alert_dialog_class_init (GtkAlertDialogClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+  object_class->finalize = gtk_alert_dialog_finalize;
+  object_class->get_property = gtk_alert_dialog_get_property;
+  object_class->set_property = gtk_alert_dialog_set_property;
+
+  /**
+   * GtkAlertDialog:modal: (attributes org.gtk.Property.get=gtk_alert_dialog_get_modal org.gtk.Property.set=gtk_alert_dialog_set_modal)
+   *
+   * Whether the alert is modal.
+   *
+   * Since: 4.10
+   */
+  properties[PROP_MODAL] =
+      g_param_spec_boolean ("modal", NULL, NULL,
+                            TRUE,
+                            G_PARAM_READWRITE|G_PARAM_STATIC_STRINGS|G_PARAM_EXPLICIT_NOTIFY);
+
+  /**
+   * GtkAlertDialog:message: (attributes org.gtk.Property.get=gtk_alert_dialog_get_message org.gtk.Property.set=gtk_alert_dialog_set_message)
+   *
+   * The message for the alert.
+   *
+   * Since: 4.10
+   */
+  properties[PROP_MESSAGE] =
+      g_param_spec_string ("message", NULL, NULL,
+                           NULL,
+                           G_PARAM_READWRITE|G_PARAM_STATIC_STRINGS|G_PARAM_EXPLICIT_NOTIFY);
+
+  /**
+   * GtkAlertDialog:detail: (attributes org.gtk.Property.get=gtk_alert_dialog_get_detail org.gtk.Property.set=gtk_alert_dialog_set_detail)
+   *
+   * The detail text for the alert.
+   *
+   * Since: 4.10
+   */
+  properties[PROP_DETAIL] =
+      g_param_spec_string ("detail", NULL, NULL,
+                           NULL,
+                           G_PARAM_READWRITE|G_PARAM_STATIC_STRINGS|G_PARAM_EXPLICIT_NOTIFY);
+
+  /**
+   * GtkAlertDialog:buttons: (attributes org.gtk.Property.get=gtk_alert_dialog_get_buttons org.gtk.Property.set=gtk_alert_dialog_set_buttons)
+   *
+   * Labels for buttons to show in the alert.
+   *
+   * The labels should be translated and may contain
+   * a _ to indicate the mnemonic character.
+   *
+   * If this property is not set, then a 'Close' button is
+   * automatically created.
+   *
+   * Since: 4.10
+   */
+  properties[PROP_BUTTONS] =
+      g_param_spec_boxed ("buttons", NULL, NULL,
+                          G_TYPE_STRV,
+                          G_PARAM_READWRITE|G_PARAM_STATIC_STRINGS|G_PARAM_EXPLICIT_NOTIFY);
+
+  /**
+   * GtkAlertDialog:cancel-button: (attributes org.gtk.Property.get=gtk_alert_dialog_get_cancel_button org.gtk.Property.set=gtk_alert_dialog_set_cancel_button)
+   *
+   * This property determines what happens when the Escape key is
+   * pressed while the alert is shown.
+   *
+   * If this property holds the index of a button in [property@Gtk.AlertDialog:buttons],
+   * then pressing Escape is treated as if that button was pressed. If it is -1
+   * or not a valid index for the `buttons` array, then an error is returned.
+   *
+   * If `buttons` is `NULL`, then the automatically created 'Close' button
+   * is treated as both cancel and default button, so 0 is returned.
+   *
+   * Since: 4.10
+   */
+  properties[PROP_CANCEL_BUTTON] =
+      g_param_spec_int ("cancel-button", NULL, NULL,
+                        -1, G_MAXINT, -1,
+                        G_PARAM_READWRITE|G_PARAM_STATIC_STRINGS|G_PARAM_EXPLICIT_NOTIFY);
+
+  /**
+   * GtkAlertDialog:default-button: (attributes org.gtk.Property.get=gtk_alert_dialog_get_default_button org.gtk.Property.set=gtk_alert_dialog_set_default_button)
+   *
+   * This property determines what happens when the Return key is
+   * pressed while the alert is shown.
+   *
+   * If this property holds the index of a button in [property@Gtk.AlertDialog:buttons],
+   * then pressing Return is treated as if that button was pressed. If it is -1
+   * or not a valid index for the `buttons` array, then nothing happens.
+   *
+   * If `buttons` is `NULL`, then the automatically created 'Close' button
+   * is treated as both cancel and default button, so 0 is returned.
+   *
+   * Since: 4.10
+   */
+  properties[PROP_DEFAULT_BUTTON] =
+      g_param_spec_int ("default-button", NULL, NULL,
+                        -1, G_MAXINT, -1,
+                        G_PARAM_READWRITE|G_PARAM_STATIC_STRINGS|G_PARAM_EXPLICIT_NOTIFY);
+
+  g_object_class_install_properties (object_class, NUM_PROPERTIES, properties);
+}
+
+/* }}} */
+/* {{{ API: Constructor */
+
+/**
+ * gtk_alert_dialog_new:
+ * @format: printf()-style format string
+ * @...: arguments for @format
+ *
+ * Creates a new `GtkAlertDialog` object.
+ *
+ * The message will be set to the formatted string
+ * resulting from the arguments.
+ *
+ * Returns: the new `GtkAlertDialog`
+ *
+ * Since: 4.10
+ */
+GtkAlertDialog *
+gtk_alert_dialog_new (const char *format,
+                      ...)
+{
+  va_list args;
+  char *message;
+  GtkAlertDialog *dialog;
+
+  va_start (args, format);
+  message = g_strdup_vprintf (format, args);
+  va_end (args);
+
+  dialog = g_object_new (GTK_TYPE_ALERT_DIALOG,
+                         "message", message,
+                         NULL);
+  g_free (message);
+
+  return dialog;
+}
+
+/* }}} */
+/* {{{ API: Getters and setters */
+
+/**
+ * gtk_alert_dialog_get_modal:
+ * @self: a `GtkAlertDialog`
+ *
+ * Returns whether the alert blocks interaction
+ * with the parent window while it is presented.
+ *
+ * Returns: `TRUE` if the alert is modal
+ *
+ * Since: 4.10
+ */
+gboolean
+gtk_alert_dialog_get_modal (GtkAlertDialog *self)
+{
+  g_return_val_if_fail (GTK_IS_ALERT_DIALOG (self), TRUE);
+
+  return self->modal;
+}
+
+/**
+ * gtk_alert_dialog_set_modal:
+ * @self: a `GtkAlertDialog`
+ * @modal: the new value
+ *
+ * Sets whether the alert blocks interaction
+ * with the parent window while it is presented.
+ *
+ * Since: 4.10
+ */
+void
+gtk_alert_dialog_set_modal (GtkAlertDialog *self,
+                            gboolean        modal)
+{
+  g_return_if_fail (GTK_IS_ALERT_DIALOG (self));
+
+  if (self->modal == modal)
+    return;
+
+  self->modal = modal;
+
+  g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MODAL]);
+}
+
+/**
+ * gtk_alert_dialog_get_message:
+ * @self: a `GtkAlertDialog`
+ *
+ * Returns the message that will be shown in the alert.
+ *
+ * Returns: the message
+ *
+ * Since: 4.10
+ */
+const char *
+gtk_alert_dialog_get_message (GtkAlertDialog *self)
+{
+  g_return_val_if_fail (GTK_IS_ALERT_DIALOG (self), NULL);
+
+  return self->message;
+}
+
+/**
+ * gtk_alert_dialog_set_message:
+ * @self: a `GtkAlertDialog`
+ * @message: the new message
+ *
+ * Sets the message that will be shown in the alert.
+ *
+ * Since: 4.10
+ */
+void
+gtk_alert_dialog_set_message (GtkAlertDialog *self,
+                              const char     *message)
+{
+  char *new_message;
+
+  g_return_if_fail (GTK_IS_ALERT_DIALOG (self));
+  g_return_if_fail (message != NULL);
+
+  if (g_strcmp0 (self->message, message) == 0)
+    return;
+  new_message = g_strdup (message);
+  g_free (self->message);
+  self->message = new_message;
+
+  g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MESSAGE]);
+}
+
+/**
+ * gtk_alert_dialog_get_detail:
+ * @self: a `GtkAlertDialog`
+ *
+ * Returns the detail text that will be shown in the alert.
+ *
+ * Returns: the detail text
+ *
+ * Since: 4.10
+ */
+const char *
+gtk_alert_dialog_get_detail (GtkAlertDialog *self)
+{
+  g_return_val_if_fail (GTK_IS_ALERT_DIALOG (self), NULL);
+
+  return self->detail;
+}
+
+/**
+ * gtk_alert_dialog_set_detail:
+ * @self: a `GtkAlertDialog`
+ * @detail: the new detail text
+ *
+ * Sets the detail text that will be shown in the alert.
+ *
+ * Since: 4.10
+ */
+void
+gtk_alert_dialog_set_detail (GtkAlertDialog *self,
+                             const char     *detail)
+{
+  char *new_detail;
+
+  g_return_if_fail (GTK_IS_ALERT_DIALOG (self));
+  g_return_if_fail (detail != NULL);
+
+  if (g_strcmp0 (self->detail, detail) == 0)
+    return;
+
+  new_detail = g_strdup (detail);
+  g_free (self->detail);
+  self->detail = new_detail;
+
+  g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DETAIL]);
+}
+
+/**
+ * gtk_alert_dialog_get_buttons:
+ * @self: a `GtkAlertDialog`
+ *
+ * Returns the button labels for the alert.
+ *
+ * Returns: (nullable) (transfer none): the button labels
+ *
+ * Since: 4.10
+ */
+const char * const *
+gtk_alert_dialog_get_buttons (GtkAlertDialog *self)
+{
+  g_return_val_if_fail (GTK_IS_ALERT_DIALOG (self), NULL);
+
+  return (const char * const *) self->buttons;
+}
+
+/**
+ * gtk_alert_dialog_set_buttons:
+ * @self: a `GtkAlertDialog`
+ * @labels: the new button labels
+ *
+ * Sets the button labels for the alert.
+ *
+ * Since: 4.10
+ */
+void
+gtk_alert_dialog_set_buttons (GtkAlertDialog     *self,
+                              const char * const *labels)
+{
+  g_return_if_fail (GTK_IS_ALERT_DIALOG (self));
+  g_return_if_fail (labels != NULL);
+
+  g_strfreev (self->buttons);
+  self->buttons = g_strdupv ((char **)labels);
+
+  g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_BUTTONS]);
+}
+
+/**
+ * gtk_alert_dialog_get_cancel_button:
+ * @self: a `GtkAlertDialog`
+ *
+ * Returns the index of the cancel button.
+ *
+ * Returns: the index of the cancel button, or -1
+ *
+ * Since: 4.10
+ */
+int
+gtk_alert_dialog_get_cancel_button (GtkAlertDialog *self)
+{
+  g_return_val_if_fail (GTK_IS_ALERT_DIALOG (self), -1);
+
+  return self->cancel_button;
+}
+
+/**
+ * gtk_alert_dialog_set_cancel_button:
+ * @self: a `GtkAlertDialog`
+ * @button: the new cancel button
+ *
+ * Sets the index of the cancel button.
+ *
+ * See [property@Gtk.AlertDialog:cancel-button] for
+ * details of how this value is used.
+ *
+ * Since: 4.10
+ */
+void
+gtk_alert_dialog_set_cancel_button (GtkAlertDialog *self,
+                                    int             button)
+{
+  g_return_if_fail (GTK_IS_ALERT_DIALOG (self));
+
+  if (self->cancel_button == button)
+    return;
+
+  self->cancel_button = button;
+  g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_CANCEL_BUTTON]);
+}
+
+/**
+ * gtk_alert_dialog_get_default_button:
+ * @self: a `GtkAlertDialog`
+ *
+ * Returns the index of the default button.
+ *
+ * Returns: the index of the default button, or -1
+ *
+ * Since: 4.10
+ */
+int
+gtk_alert_dialog_get_default_button (GtkAlertDialog *self)
+{
+  g_return_val_if_fail (GTK_IS_ALERT_DIALOG (self), -1);
+
+  return self->default_button;
+}
+
+/**
+ * gtk_alert_dialog_set_default_button:
+ * @self: a `GtkAlertDialog`
+ * @button: the new default button
+ *
+ * Sets the index of the default button.
+ *
+ * See [property@Gtk.AlertDialog:default-button] for
+ * details of how this value is used.
+ *
+ * Since: 4.10
+ */
+void
+gtk_alert_dialog_set_default_button (GtkAlertDialog *self,
+                                     int             button)
+{
+  g_return_if_fail (GTK_IS_ALERT_DIALOG (self));
+
+  if (self->default_button == button)
+    return;
+
+  self->default_button = button;
+  g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DEFAULT_BUTTON]);
+}
+
+/* }}} */
+/* {{{ Async implementation */
+
+static void response_cb (GTask *task,
+                         int    response);
+
+static void
+cancelled_cb (GCancellable *cancellable,
+              GTask        *task)
+{
+  response_cb (task, GTK_RESPONSE_CLOSE);
+}
+
+static void
+response_cb (GTask *task,
+             int    response)
+{
+  GCancellable *cancellable;
+
+  cancellable = g_task_get_cancellable (task);
+
+  if (cancellable)
+    g_signal_handlers_disconnect_by_func (cancellable, cancelled_cb, task);
+
+  if (response >= 0)
+    {
+      g_task_return_int (task, response);
+    }
+  else
+    {
+      GtkAlertDialog *self = GTK_ALERT_DIALOG (g_task_get_source_object (task));
+
+      g_task_return_int (task, self->cancel_return);
+    }
+
+  g_object_unref (task);
+}
+
+static void
+dialog_response (GtkDialog *dialog,
+                 int        response,
+                 GTask     *task)
+{
+  response_cb (task, response);
+}
+
+/* }}} */
+/* {{{ Async API */
+
+/**
+ * gtk_alert_dialog_choose:
+ * @self: a `GtkAlertDialog`
+ * @parent: (nullable): the parent `GtkWindow`
+ * @cancellable: (nullable): a `GCancellable` to cancel the operation
+ * @callback: (nullable) (scope async): a callback to call when the operation is complete
+ * @user_data: (closure callback): data to pass to @callback
+ *
+ * This function shows the alert to the user.
+ *
+ * The @callback will be called when the alert is dismissed.
+ * It should call [method@Gtk.AlertDialog.choose_finish]
+ * to obtain the result.
+ *
+ * It is ok to pass `NULL` for the callback if the alert
+ * does not have more than one button. A simpler API for
+ * this case is [method@Gtk.AlertDialog.show].
+ *
+ * Since: 4.10
+ */
+void
+gtk_alert_dialog_choose (GtkAlertDialog       *self,
+                         GtkWindow           *parent,
+                         GCancellable        *cancellable,
+                         GAsyncReadyCallback  callback,
+                         gpointer             user_data)
+{
+  GtkMessageDialog *window;
+  GTask *task;
+
+  g_return_if_fail (GTK_IS_ALERT_DIALOG (self));
+
+  window = g_object_new (GTK_TYPE_MESSAGE_DIALOG,
+                         "transient-for", parent,
+                         "destroy-with-parent", TRUE,
+                         "modal", self->modal,
+                         "text", self->message,
+                         "secondary-text", self->detail,
+                         NULL);
+
+  if (self->buttons && self->buttons[0])
+    {
+      self->cancel_return = -1;
+      for (int i = 0; self->buttons[i]; i++)
+        {
+          gtk_dialog_add_button (GTK_DIALOG (window), self->buttons[i], i);
+          if (self->default_button == i)
+            gtk_dialog_set_default_response (GTK_DIALOG (window), i);
+          if (self->cancel_button == i)
+            self->cancel_return = i;
+        }
+    }
+  else
+    {
+      gtk_dialog_add_button (GTK_DIALOG (window), _("_Close"), 0);
+      gtk_dialog_set_default_response (GTK_DIALOG (window), 0);
+      self->cancel_return = 0;
+    }
+
+  task = g_task_new (self, cancellable, callback, user_data);
+  g_task_set_source_tag (task, gtk_alert_dialog_choose);
+  g_task_set_task_data (task, window, (GDestroyNotify) gtk_window_destroy);
+
+  if (cancellable)
+    g_signal_connect (cancellable, "cancelled", G_CALLBACK (cancelled_cb), task);
+
+  g_signal_connect (window, "response", G_CALLBACK (dialog_response), task);
+
+  gtk_window_present (GTK_WINDOW (window));
+}
+
+/**
+ * gtk_alert_dialog_choose_finish:
+ * @self: a `GtkAlertDialog`
+ * @result: a `GAsyncResult`
+ *
+ * Finishes the [method@Gtk.AlertDialog.choose] call
+ * and returns the index of the button that was clicked.
+ *
+ * Returns: the index of the button that was clicked, or -1 if
+ *   the dialog was cancelled and `[property@Gtk.AlertDialog:cancel-button]
+ *   is not set
+ *
+ * Since: 4.10
+ */
+int
+gtk_alert_dialog_choose_finish (GtkAlertDialog  *self,
+                                GAsyncResult   *result)
+{
+  GTask *task = G_TASK (result);
+
+  g_return_val_if_fail (g_task_get_source_tag (task) == gtk_alert_dialog_choose, -1);
+
+  return (int) g_task_propagate_int (task, NULL);
+}
+
+/**
+ * gtk_alert_dialog_show:
+ * @self: a `GtkAlertDialog`
+ * @parent: (nullable): the parent `GtkWindow`
+ *
+ * This function shows the alert to the user.
+ *
+ * If the alert has more than one button, you should use
+ * [method@Gtk.AlertDialog.choose] instead and provide
+ * a callback that can react to the button that was clicked.
+ *
+ * Since: 4.10
+ */
+void
+gtk_alert_dialog_show (GtkAlertDialog *self,
+                       GtkWindow      *parent)
+{
+  gtk_alert_dialog_choose (self, parent, NULL, NULL, NULL);
+}
+
+/* }}} */
+
+/* vim:set foldmethod=marker expandtab: */
diff --git a/gtk/gtkalertdialog.h b/gtk/gtkalertdialog.h
new file mode 100644 (file)
index 0000000..5d5d9f0
--- /dev/null
@@ -0,0 +1,96 @@
+/* GTK - The GIMP Toolkit
+ *
+ * Copyright (C) 2022 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
+#error "Only <gtk/gtk.h> can be included directly."
+#endif
+
+#include <gdk/gdk.h>
+#include <gtk/gtkwindow.h>
+
+G_BEGIN_DECLS
+
+#define GTK_TYPE_ALERT_DIALOG (gtk_alert_dialog_get_type ())
+
+GDK_AVAILABLE_IN_4_10
+G_DECLARE_FINAL_TYPE (GtkAlertDialog, gtk_alert_dialog, GTK, ALERT_DIALOG, GObject)
+
+GDK_AVAILABLE_IN_4_10
+GtkAlertDialog *gtk_alert_dialog_new               (const char *format,
+                                                     ...) G_GNUC_PRINTF (1, 2);
+
+GDK_AVAILABLE_IN_4_10
+gboolean        gtk_alert_dialog_get_modal          (GtkAlertDialog      *self);
+
+GDK_AVAILABLE_IN_4_10
+void            gtk_alert_dialog_set_modal          (GtkAlertDialog      *self,
+                                                     gboolean             modal);
+
+GDK_AVAILABLE_IN_4_10
+const char *    gtk_alert_dialog_get_message        (GtkAlertDialog      *self);
+
+GDK_AVAILABLE_IN_4_10
+void            gtk_alert_dialog_set_message        (GtkAlertDialog      *self,
+                                                     const char          *message);
+
+GDK_AVAILABLE_IN_4_10
+const char *    gtk_alert_dialog_get_detail         (GtkAlertDialog      *self);
+
+GDK_AVAILABLE_IN_4_10
+void            gtk_alert_dialog_set_detail         (GtkAlertDialog      *self,
+                                                     const char          *detail);
+
+GDK_AVAILABLE_IN_4_10
+const char * const *
+                gtk_alert_dialog_get_buttons        (GtkAlertDialog      *self);
+
+GDK_AVAILABLE_IN_4_10
+void            gtk_alert_dialog_set_buttons        (GtkAlertDialog      *self,
+                                                     const char * const  *labels);
+
+GDK_AVAILABLE_IN_4_10
+int             gtk_alert_dialog_get_cancel_button  (GtkAlertDialog      *self);
+
+GDK_AVAILABLE_IN_4_10
+void            gtk_alert_dialog_set_cancel_button  (GtkAlertDialog      *self,
+                                                     int                  button);
+GDK_AVAILABLE_IN_4_10
+int             gtk_alert_dialog_get_default_button (GtkAlertDialog      *self);
+
+GDK_AVAILABLE_IN_4_10
+void            gtk_alert_dialog_set_default_button (GtkAlertDialog      *self,
+                                                     int                  button);
+
+GDK_AVAILABLE_IN_4_10
+void            gtk_alert_dialog_choose             (GtkAlertDialog      *self,
+                                                     GtkWindow           *parent,
+                                                     GCancellable        *cancellable,
+                                                     GAsyncReadyCallback  callback,
+                                                     gpointer             user_data);
+
+GDK_AVAILABLE_IN_4_10
+int             gtk_alert_dialog_choose_finish      (GtkAlertDialog      *self,
+                                                     GAsyncResult        *result);
+
+GDK_AVAILABLE_IN_4_10
+void            gtk_alert_dialog_show               (GtkAlertDialog      *self,
+                                                     GtkWindow           *parent);
+
+G_END_DECLS
index 8981745746d647cd4fda3d02eb1598516ab35ef3..06cf4cec31d183fcbe0de8e690935f6ba46fcb28 100644 (file)
@@ -160,6 +160,7 @@ gtk_public_sources = files([
   'gtkactionable.c',
   'gtkactionbar.c',
   'gtkadjustment.c',
+  'gtkalertdialog.c',
   'gtkapplication.c',
   'gtkapplicationwindow.c',
   'gtkaspectframe.c',
@@ -422,6 +423,7 @@ gtk_public_headers = files([
   'gtkactionable.h',
   'gtkactionbar.h',
   'gtkadjustment.h',
+  'gtkalertdialog.h',
   'gtkapplication.h',
   'gtkapplicationwindow.h',
   'gtkaspectframe.h',