gtkfiledialog: Allow devs to set custom accept labels
authorChristopher Davis <christopherdavis@gnome.org>
Fri, 16 Dec 2022 02:35:56 +0000 (21:35 -0500)
committerChristopher Davis <christopherdavis@gnome.org>
Fri, 16 Dec 2022 15:16:52 +0000 (10:16 -0500)
Accept labels can be used for additional context regarding
the purpose of a file. The old GtkFileChooser APIs allowed
developers to set it, but the initial FileDialog API was missing
this functionality.

This commit adds `gtk_file_dialog_set_accept_label ()` to
restore the missing functionality.

Closes https://gitlab.gnome.org/GNOME/gtk/-/issues/5421

gtk/gtkfiledialog.c
gtk/gtkfiledialog.h

index 8ccfeb54ba02da0e04122f4068098245e72570c7..d35deeac06afb278f2264175538d5493e563820b 100644 (file)
@@ -25,6 +25,7 @@
 #include "gtkfilechoosernativeprivate.h"
 #include "gtkdialogerror.h"
 #include <glib/gi18n-lib.h>
+#include "gdk/gdkprivate.h"
 #include "gdk/gdkdebugprivate.h"
 
 /**
@@ -51,6 +52,7 @@ struct _GtkFileDialog
   GObject parent_instance;
 
   char *title;
+  char *accept_label;
   unsigned int modal : 1;
 
   GListModel *filters;
@@ -67,6 +69,7 @@ enum
   PROP_SHORTCUT_FOLDERS,
   PROP_CURRENT_FILTER,
   PROP_CURRENT_FOLDER,
+  PROP_ACCEPT_LABEL,
 
   NUM_PROPERTIES
 };
@@ -87,6 +90,7 @@ gtk_file_dialog_finalize (GObject *object)
   GtkFileDialog *self = GTK_FILE_DIALOG (object);
 
   g_free (self->title);
+  g_free (self->accept_label);
   g_clear_object (&self->filters);
   g_clear_object (&self->shortcut_folders);
   g_clear_object (&self->current_filter);
@@ -129,6 +133,10 @@ gtk_file_dialog_get_property (GObject      *object,
       g_value_set_object (value, self->current_folder);
       break;
 
+    case PROP_ACCEPT_LABEL:
+      g_value_set_string (value, self->accept_label);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
       break;
@@ -169,6 +177,10 @@ gtk_file_dialog_set_property (GObject      *object,
       gtk_file_dialog_set_current_folder (self, g_value_get_object (value));
       break;
 
+    case PROP_ACCEPT_LABEL:
+      gtk_file_dialog_set_accept_label (self, g_value_get_string (value));
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -259,6 +271,18 @@ gtk_file_dialog_class_init (GtkFileDialogClass *class)
                            G_TYPE_FILE,
                            G_PARAM_READWRITE|G_PARAM_STATIC_STRINGS|G_PARAM_EXPLICIT_NOTIFY);
 
+  /**
+   * GtkFileDialog:accept-label: (attributes org.gtk.Property.get=gtk_file_dialog_get_accept_label org.gtk.Property.set=gtk_file_dialog_set_accept_label)
+   *
+   * Label for the file chooser's accept button.
+   *
+   * Since: 4.10
+   */
+  properties[PROP_ACCEPT_LABEL] =
+      g_param_spec_string ("accept-label", NULL, NULL,
+                           NULL,
+                           G_PARAM_READWRITE|G_PARAM_STATIC_STRINGS|G_PARAM_EXPLICIT_NOTIFY);
+
   g_object_class_install_properties (object_class, NUM_PROPERTIES, properties);
 }
 
@@ -656,24 +680,24 @@ create_file_chooser (GtkFileDialog        *self,
                      gboolean              select_multiple)
 {
   GtkFileChooserNative *chooser;
-  const char *accept;
+  const char *default_accept_label, *accept;
   const char *default_title, *title;
   GdkDisplay *display G_GNUC_UNUSED;
 
   switch (action)
     {
     case GTK_FILE_CHOOSER_ACTION_OPEN:
-      accept = _("_Open");
+      default_accept_label = _("_Open");
       default_title = select_multiple ? _("Pick Files") : _("Pick a File");
       break;
 
     case GTK_FILE_CHOOSER_ACTION_SAVE:
-      accept = _("_Save");
+      default_accept_label = _("_Save");
       default_title = _("Save a File");
       break;
 
     case GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER:
-      accept = _("_Select");
+      default_accept_label = _("_Select");
       default_title = select_multiple ? _("Select Folders") : _("Select a Folder");
       break;
 
@@ -686,6 +710,11 @@ create_file_chooser (GtkFileDialog        *self,
   else
     title = default_title;
 
+  if (self->accept_label)
+    accept = self->accept_label;
+  else
+    accept = default_accept_label;
+
   chooser = gtk_file_chooser_native_new (title, parent, action, accept, _("_Cancel"));
 
   if (parent)
@@ -1136,6 +1165,44 @@ gtk_file_dialog_select_multiple_folders_finish (GtkFileDialog   *self,
   return finish_multiple_files_op (self, G_TASK (result), error);
 }
 
+/**
+ * gtk_file_dialog_get_accept_label:
+ * @self: a `GtkFileDialog`
+ *
+ * Returns: (nullable): the label shown on the file chooser's accept button.
+ *
+ * Since: 4.10
+ */
+const char *
+gtk_file_dialog_get_accept_label (GtkFileDialog *self)
+{
+  g_return_val_if_fail (GTK_IS_FILE_DIALOG (self), NULL);
+
+  return self->accept_label;
+}
+
+/**
+ * gtk_file_dialog_set_accept_label:
+ * @self: a `GtkFileDialog`
+ * @accept_label: (nullable): the new accept label
+ *
+ * Sets the label shown on the file chooser's accept button.
+ *
+ * Leaving the accept label unset or setting it as `NULL` will fall back to
+ * a default label, depending on what API is used to launch the file dialog.
+ *
+ * Since: 4.10
+ */
+void
+gtk_file_dialog_set_accept_label (GtkFileDialog *self,
+                                  const char    *accept_label)
+{
+  g_return_if_fail (GTK_IS_FILE_DIALOG (self));
+
+  if (g_set_str (&self->accept_label, accept_label))
+    g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ACCEPT_LABEL]);
+}
+
 /* }}} */
 
 /* vim:set foldmethod=marker expandtab: */
index 34664d646bce64f4e6b3676b1859c3806c658d06..5c3cac52bc5c3c2981cbfd4f5d954831bef45ff1 100644 (file)
@@ -148,4 +148,11 @@ GListModel *     gtk_file_dialog_select_multiple_folders_finish
                                                       GAsyncResult         *result,
                                                       GError              **error);
 
+GDK_AVAILABLE_IN_4_10
+const char *    gtk_file_dialog_get_accept_label     (GtkFileDialog        *self);
+
+GDK_AVAILABLE_IN_4_10
+void             gtk_file_dialog_set_accept_label    (GtkFileDialog        *self,
+                                                      const char           *accept_label);
+
 G_END_DECLS