summaryrefslogtreecommitdiff
path: root/gtk/gtkfilechoosernative.c
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2015-10-29 15:06:57 +0100
committerAlexander Larsson <alexl@redhat.com>2015-11-05 16:54:07 +0100
commit5094900180ac97e6bba2f86ee702d0649e019e6a (patch)
tree7527ba2439f350f7c0c75ce7af0c52ff038c9ded /gtk/gtkfilechoosernative.c
parent693db082a158952efd5a326a62814490c3c8f6ad (diff)
downloadgtk+-5094900180ac97e6bba2f86ee702d0649e019e6a.tar.gz
GtkFileChooserNative: Fallback and win32 implementation
This is a subclass on GtkNativeDialog that uses GtkFileChooserDialog as a fallback, but also has support for the win32 file chooser dialog.
Diffstat (limited to 'gtk/gtkfilechoosernative.c')
-rw-r--r--gtk/gtkfilechoosernative.c656
1 files changed, 656 insertions, 0 deletions
diff --git a/gtk/gtkfilechoosernative.c b/gtk/gtkfilechoosernative.c
new file mode 100644
index 0000000000..c43e86f730
--- /dev/null
+++ b/gtk/gtkfilechoosernative.c
@@ -0,0 +1,656 @@
+/* -*- Mode: C; c-file-style: "gnu"; tab-width: 8 -*- */
+/* GTK - The GIMP Toolkit
+ * gtkfilechoosernative.c: Native File selector dialog
+ * Copyright (C) 2015, 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/>.
+ */
+
+#include "config.h"
+
+#include "gtkfilechoosernativeprivate.h"
+#include "gtknativedialogprivate.h"
+
+#include "gtkprivate.h"
+#include "gtkfilechooserdialog.h"
+#include "gtkfilechooserprivate.h"
+#include "gtkfilechooserwidget.h"
+#include "gtkfilechooserwidgetprivate.h"
+#include "gtkfilechooserutils.h"
+#include "gtkfilechooserembed.h"
+#include "gtkfilesystem.h"
+#include "gtksizerequest.h"
+#include "gtktypebuiltins.h"
+#include "gtkintl.h"
+#include "gtksettings.h"
+#include "gtktogglebutton.h"
+#include "gtkstylecontext.h"
+#include "gtkheaderbar.h"
+#include "gtklabel.h"
+#include "gtkfilechooserentry.h"
+#include "gtkfilefilterprivate.h"
+
+/**
+ * SECTION:gtkfilechoosernative
+ * @Short_description: A native file chooser dialog, suitable for “File/Open” or “File/Save” commands
+ * @Title: GtkFileChooserNative
+ * @See_also: #GtkFileChooser, #GtkNativeDialog, #GtkFileChooserDialog
+ *
+ * #GtkFileChooserNative is an abstraction of a dialog box suitable
+ * for use with “File/Open” or “File/Save as” commands. By default, this
+ * just uses a #GtkFileChooserDialog to implement the actual dialog.
+ * However, on certain platforms, such as Windows, the native platform
+ * file chooser is uses instead.
+ *
+ * While the API of #GtkFileChooserNative closely mirrors #GtkFileChooserDialog, the main
+ * difference is that there is no access to any #GtkWindow or #GtkWidget for the dialog.
+ * This is required, as there may not be one in the case of a platform native dialog.
+ * Showing, hiding and running the dialog is handled by the #GtkNativeDialog functions.
+ *
+ * ## Typical usage ## {#gtkfilechoosernative-typical-usage}
+ *
+ * In the simplest of cases, you can the following code to use
+ * #GtkFileChooserDialog to select a file for opening:
+ *
+ * |[
+ * GtkFileChooserNative *native;
+ * GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN;
+ * gint res;
+ *
+ * native = gtk_file_chooser_native_new ("Open File",
+ * parent_window,
+ * action,
+ * "_Open",
+ * "_Cancel");
+ *
+ * res = gtk_native_dialog_run (GTK_NATIVE_DIALOG (native));
+ * if (res == GTK_RESPONSE_ACCEPT)
+ * {
+ * char *filename;
+ * GtkFileChooser *chooser = GTK_FILE_CHOOSER (native);
+ * filename = gtk_file_chooser_get_filename (chooser);
+ * open_file (filename);
+ * g_free (filename);
+ * }
+ *
+ * g_object_unref (native);
+ * ]|
+ *
+ * To use a dialog for saving, you can use this:
+ *
+ * |[
+ * GtkFileChooserNative *native;
+ * GtkFileChooser *chooser;
+ * GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_SAVE;
+ * gint res;
+ *
+ * native = gtk_file_chooser_native_new ("Save File",
+ * parent_window,
+ * action,
+ * "_Save",
+ * "_Cancel");
+ * chooser = GTK_FILE_CHOOSER (native);
+ *
+ * gtk_file_chooser_set_do_overwrite_confirmation (chooser, TRUE);
+ *
+ * if (user_edited_a_new_document)
+ * gtk_file_chooser_set_current_name (chooser,
+ * _("Untitled document"));
+ * else
+ * gtk_file_chooser_set_filename (chooser,
+ * existing_filename);
+ *
+ * res = gtk_native_dialog_run (GTK_NATIVE_DIALOG (native));
+ * if (res == GTK_RESPONSE_ACCEPT)
+ * {
+ * char *filename;
+ *
+ * filename = gtk_file_chooser_get_filename (chooser);
+ * save_to_file (filename);
+ * g_free (filename);
+ * }
+ *
+ * g_object_unref (native);
+ * ]|
+ *
+ * For more information on how to best set up a file dialog, see #GtkFileChooserDialog.
+ *
+ * ## Response Codes ## {#gtkfilechooserdialognative-responses}
+ *
+ * #GtkFileChooserNative inherits from #GtkNativeDialog, which means it
+ * will return #GTK_RESPONSE_ACCEPT if the user accepted, and
+ * #GTK_RESPONSE_CANCEL if he pressed cancel. It can also return
+ * #GTK_RESPONSE_DELETE_EVENT if the window was unexpectedly closed.
+ *
+ * ## Differences from #GtkFileChooserDialog ## {#gtkfilechooserdialognative-differences}
+ *
+ * There are a few things in the GtkFileChooser API that are not
+ * possible to use with #GtkFileChooserNative, as such use would
+ * prohibit the use of a native dialog.
+ *
+ * There is no support for the signals that are emitted when the user
+ * navigates in the dialog, including:
+ * * #GtkFileChooser::current-folder-changed
+ * * #GtkFileChooser::selection-changed
+ * * #GtkFileChooser::file-activated
+ * * #GtkFileChooser::confirm-overwrite
+ *
+ * You can also not use the methods that directly control user navigation:
+ * * gtk_file_chooser_unselect_filename()
+ * * gtk_file_chooser_select_all()
+ * * gtk_file_chooser_unselect_all()
+ *
+ * If you need any of the above you will have to use #GtkFileChooserDialog directly.
+ *
+ * No operations that change the the dialog work while the dialog is
+ * visible. Set all the properties that are required before showing the dialog.
+ *
+ * ## Win32 details ## {#gtkfilechooserdialognative-win32}
+ *
+ * On windows the IFileDialog implementation (added in Windows Vista) is
+ * used. It supports many of the features that #GtkFileChooserDialog
+ * does, but there are some things it does not handle:
+ *
+ * * Extra widgets added with gtk_file_chooser_set_extra_widget().
+ *
+ * * Use of custom previews by connecting to #GtkFileChooser::update-preview.
+ *
+ * * Any #GtkFileFilter added using a mimetype or custom filter.
+ *
+ * If any of these features are used the regular #GtkFileChooserDialog
+ * will be used in place of the native one.
+ */
+
+enum {
+ MODE_FALLBACK,
+ MODE_WIN32,
+};
+
+enum {
+ PROP_0,
+ PROP_ACCEPT_LABEL,
+ PROP_CANCEL_LABEL,
+ LAST_ARG,
+};
+
+static GParamSpec *native_props[LAST_ARG] = { NULL, };
+
+static void _gtk_file_chooser_native_iface_init (GtkFileChooserIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GtkFileChooserNative, gtk_file_chooser_native, GTK_TYPE_NATIVE_DIALOG,
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_FILE_CHOOSER,
+ _gtk_file_chooser_native_iface_init))
+
+
+/**
+ * gtk_file_chooser_native_get_accept_label:
+ * @self: a #GtFileChooserNative
+ *
+ * Retrieves the custom label text for the accept button.
+ *
+ * Returns: The custom label, or %NULL for the default. This string is
+ * owned by GTK+ and should not be modified or freed
+ *
+ * Since: 3.20
+ **/
+const char *
+gtk_file_chooser_native_get_accept_label (GtkFileChooserNative *self)
+{
+ g_return_val_if_fail (GTK_IS_FILE_CHOOSER_NATIVE (self), NULL);
+
+ return self->accept_label;
+}
+
+/**
+ * gtk_file_chooser_native_set_accept_label:
+ * @self: a #GtFileChooserNative
+ * @accept_label: (allow-none): custom label or %NULL for the default
+ *
+ * Sets the custom label text for the accept button.
+ *
+ * If characters in @label are preceded by an underscore, they are underlined.
+ * If you need a literal underscore character in a label, use “__” (two
+ * underscores). The first underlined character represents a keyboard
+ * accelerator called a mnemonic.
+ * Pressing Alt and that key activates the button.
+ *
+ * Since: 3.20
+ **/
+void
+gtk_file_chooser_native_set_accept_label (GtkFileChooserNative *self,
+ const char *accept_label)
+{
+ g_return_if_fail (GTK_IS_FILE_CHOOSER_NATIVE (self));
+
+ g_free (self->accept_label);
+ self->accept_label = g_strdup (accept_label);
+
+ g_object_notify_by_pspec (G_OBJECT (self), native_props[PROP_ACCEPT_LABEL]);
+}
+
+/**
+ * gtk_file_chooser_native_get_cancel_label:
+ * @self: a #GtFileChooserNative
+ *
+ * Retrieves the custom label text for the cancel button.
+ *
+ * Returns: The custom label, or %NULL for the default. This string is
+ * owned by GTK+ and should not be modified or freed
+ *
+ * Since: 3.20
+ **/
+const char *
+gtk_file_chooser_native_get_cancel_label (GtkFileChooserNative *self)
+{
+ g_return_val_if_fail (GTK_IS_FILE_CHOOSER_NATIVE (self), NULL);
+
+ return self->cancel_label;
+}
+
+/**
+ * gtk_file_chooser_native_set_cancel_label:
+ * @self: a #GtFileChooserNative
+ * @cancel_label: (allow-none): custom label or %NULL for the default
+ *
+ * Sets the custom label text for the cancel button.
+ *
+ * If characters in @label are preceded by an underscore, they are underlined.
+ * If you need a literal underscore character in a label, use “__” (two
+ * underscores). The first underlined character represents a keyboard
+ * accelerator called a mnemonic.
+ * Pressing Alt and that key activates the button.
+ *
+ * Since: 3.20
+ **/
+void
+gtk_file_chooser_native_set_cancel_label (GtkFileChooserNative *self,
+ const char *cancel_label)
+{
+ g_return_if_fail (GTK_IS_FILE_CHOOSER_NATIVE (self));
+
+ g_free (self->cancel_label);
+ self->cancel_label = g_strdup (cancel_label);
+
+ g_object_notify_by_pspec (G_OBJECT (self), native_props[PROP_CANCEL_LABEL]);
+}
+
+static void
+gtk_file_chooser_native_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+
+{
+ GtkFileChooserNative *self = GTK_FILE_CHOOSER_NATIVE (object);
+
+ switch (prop_id)
+ {
+ case PROP_ACCEPT_LABEL:
+ gtk_file_chooser_native_set_accept_label (self, g_value_get_string (value));
+ break;
+
+ case PROP_CANCEL_LABEL:
+ gtk_file_chooser_native_set_cancel_label (self, g_value_get_string (value));
+ break;
+
+ default:
+ g_object_set_property (G_OBJECT (self->dialog), pspec->name, value);
+ break;
+ }
+}
+
+static void
+gtk_file_chooser_native_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GtkFileChooserNative *self = GTK_FILE_CHOOSER_NATIVE (object);
+
+ switch (prop_id)
+ {
+ case PROP_ACCEPT_LABEL:
+ g_value_set_string (value, self->accept_label);
+ break;
+
+ case PROP_CANCEL_LABEL:
+ g_value_set_string (value, self->cancel_label);
+ break;
+
+ default:
+ g_object_get_property (G_OBJECT (self->dialog), pspec->name, value);
+ break;
+ }
+}
+
+static void
+gtk_file_chooser_native_finalize (GObject *object)
+{
+ GtkFileChooserNative *self = GTK_FILE_CHOOSER_NATIVE (object);
+
+ g_clear_pointer (&self->current_name, g_free);
+ g_clear_object (&self->current_file);
+ g_clear_object (&self->current_folder);
+
+ g_clear_pointer (&self->accept_label, g_free);
+ g_clear_pointer (&self->cancel_label, g_free);
+ gtk_widget_destroy (self->dialog);
+
+ g_slist_free_full (self->custom_files, g_object_unref);
+
+ G_OBJECT_CLASS (gtk_file_chooser_native_parent_class)->finalize (object);
+}
+
+static gint
+override_delete_handler (GtkDialog *dialog,
+ GdkEventAny *event,
+ gpointer data)
+{
+ return TRUE; /* Do not destroy */
+}
+
+static void
+gtk_file_chooser_native_init (GtkFileChooserNative *self)
+{
+ /* We always create a File chooser dialog and delegate all properties to it.
+ * This way we can reuse that store, plus we always have a dialog we can use
+ * in case something makes the native one not work (like the custom widgets) */
+ self->dialog = g_object_new (GTK_TYPE_FILE_CHOOSER_DIALOG, NULL);
+ self->cancel_button = gtk_dialog_add_button (GTK_DIALOG (self->dialog), _("_Cancel"), GTK_RESPONSE_CANCEL);
+ self->accept_button = gtk_dialog_add_button (GTK_DIALOG (self->dialog), _("_Open"), GTK_RESPONSE_ACCEPT);
+
+ gtk_dialog_set_default_response (GTK_DIALOG (self->dialog),
+ GTK_RESPONSE_ACCEPT);
+G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+ gtk_dialog_set_alternative_button_order (GTK_DIALOG (self->dialog),
+ GTK_RESPONSE_ACCEPT,
+ GTK_RESPONSE_CANCEL,
+ -1);
+G_GNUC_END_IGNORE_DEPRECATIONS
+
+ /* We don't want to destroy on delete event, instead we hide in the response cb */
+ g_signal_connect (self->dialog,
+ "delete-event",
+ G_CALLBACK (override_delete_handler),
+ NULL);
+
+ /* This is used, instead of the standard delegate, to ensure that signals are not delegated. */
+ g_object_set_qdata (G_OBJECT (self), GTK_FILE_CHOOSER_DELEGATE_QUARK, self->dialog);
+}
+
+/**
+ * gtk_file_chooser_native_new:
+ * @title: (allow-none): Title of the native, or %NULL
+ * @parent: (allow-none): Transient parent of the native, or %NULL
+ * @action: Open or save mode for the dialog
+ * @accept_label: (allow-none): text to go in the accept button, or %NULL for the default
+ * @cancel_label: (allow-none): text to go in the cancel button, or %NULL for the default
+ *
+ * Creates a new #GtkFileChooserNative.
+ *
+ * Returns: a new #GtkFileChooserNative
+ *
+ * Since: 3.20
+ **/
+GtkFileChooserNative *
+gtk_file_chooser_native_new (const gchar *title,
+ GtkWindow *parent,
+ GtkFileChooserAction action,
+ const gchar *accept_label,
+ const gchar *cancel_label)
+{
+ GtkFileChooserNative *result;
+
+ result = g_object_new (GTK_TYPE_FILE_CHOOSER_NATIVE,
+ "title", title,
+ "action", action,
+ "transient-for", parent,
+ "accept-label", accept_label,
+ "cancel-label", cancel_label,
+ NULL);
+
+ return result;
+}
+
+static void
+dialog_response_cb (GtkDialog *dialog,
+ gint response_id,
+ gpointer data)
+{
+ GtkFileChooserNative *self = data;
+
+ g_signal_handlers_disconnect_by_func (self->dialog, dialog_response_cb, self);
+ gtk_widget_hide (self->dialog);
+
+ _gtk_native_dialog_emit_response (GTK_NATIVE_DIALOG (self), response_id);
+}
+
+static void
+dialog_update_preview_cb (GtkFileChooser *file_chooser,
+ gpointer data)
+{
+ g_signal_emit_by_name (data, "update-preview");
+}
+
+static void
+show_dialog (GtkFileChooserNative *self)
+{
+ GtkFileChooserAction action;
+ const char *accept_label, *cancel_label;
+
+ action = gtk_file_chooser_get_action (GTK_FILE_CHOOSER (self->dialog));
+
+ accept_label = self->accept_label;
+ if (accept_label == NULL)
+ accept_label = (action == GTK_FILE_CHOOSER_ACTION_SAVE) ? _("_Save") : _("_Open");
+
+ gtk_button_set_label (GTK_BUTTON (self->accept_button), accept_label);
+
+ cancel_label = self->cancel_label;
+ if (cancel_label == NULL)
+ cancel_label = _("_Cancel");
+
+ gtk_button_set_label (GTK_BUTTON (self->cancel_button), cancel_label);
+
+ gtk_window_set_title (GTK_WINDOW (self->dialog),
+ gtk_native_dialog_get_title (GTK_NATIVE_DIALOG (self)));
+
+ gtk_window_set_transient_for (GTK_WINDOW (self->dialog),
+ gtk_native_dialog_get_transient_for (GTK_NATIVE_DIALOG (self)));
+
+ gtk_window_set_modal (GTK_WINDOW (self->dialog),
+ gtk_native_dialog_get_modal (GTK_NATIVE_DIALOG (self)));
+
+ g_signal_connect (self->dialog,
+ "response",
+ G_CALLBACK (dialog_response_cb),
+ self);
+
+ g_signal_connect (self->dialog,
+ "update-preview",
+ G_CALLBACK (dialog_update_preview_cb),
+ self);
+
+ gtk_window_present (GTK_WINDOW (self->dialog));
+}
+
+static void
+hide_dialog (GtkFileChooserNative *self)
+{
+ g_signal_handlers_disconnect_by_func (self->dialog, dialog_response_cb, self);
+ g_signal_handlers_disconnect_by_func (self->dialog, dialog_update_preview_cb, self);
+ gtk_widget_hide (self->dialog);
+}
+
+static gboolean
+gtk_file_chooser_native_set_current_folder (GtkFileChooser *chooser,
+ GFile *file,
+ GError **error)
+{
+ GtkFileChooserNative *self = GTK_FILE_CHOOSER_NATIVE (chooser);
+ gboolean res;
+
+ res = gtk_file_chooser_set_current_folder_file (GTK_FILE_CHOOSER (self->dialog),
+ file, error);
+
+
+ if (res)
+ {
+ g_set_object (&self->current_folder, file);
+
+ g_clear_object (&self->current_file);
+ }
+
+ return res;
+}
+
+static gboolean
+gtk_file_chooser_native_select_file (GtkFileChooser *chooser,
+ GFile *file,
+ GError **error)
+{
+ GtkFileChooserNative *self = GTK_FILE_CHOOSER_NATIVE (chooser);
+ gboolean res;
+
+ res = gtk_file_chooser_select_file (GTK_FILE_CHOOSER (self->dialog),
+ file, error);
+
+ if (res)
+ {
+ g_set_object (&self->current_file, file);
+
+ g_clear_object (&self->current_folder);
+ g_clear_pointer (&self->current_name, g_free);
+ }
+
+ return res;
+}
+
+static void
+gtk_file_chooser_native_set_current_name (GtkFileChooser *chooser,
+ const gchar *name)
+{
+ GtkFileChooserNative *self = GTK_FILE_CHOOSER_NATIVE (chooser);
+
+ gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (self->dialog), name);
+
+ g_clear_pointer (&self->current_name, g_free);
+ self->current_name = g_strdup (name);
+
+ g_clear_object (&self->current_file);
+}
+
+static GSList *
+gtk_file_chooser_native_get_files (GtkFileChooser *chooser)
+{
+ GtkFileChooserNative *self = GTK_FILE_CHOOSER_NATIVE (chooser);
+
+ switch (self->mode)
+ {
+ case MODE_WIN32:
+ return g_slist_copy_deep (self->custom_files, (GCopyFunc)g_object_ref, NULL);
+
+ case MODE_FALLBACK:
+ default:
+ return gtk_file_chooser_get_files (GTK_FILE_CHOOSER (self->dialog));
+ }
+}
+
+static void
+gtk_file_chooser_native_show (GtkNativeDialog *native)
+{
+ GtkFileChooserNative *self = GTK_FILE_CHOOSER_NATIVE (native);
+
+ self->mode = MODE_FALLBACK;
+
+#ifdef GDK_WINDOWING_WIN32
+ if (gtk_file_chooser_native_win32_show (self))
+ self->mode = MODE_WIN32;
+#endif
+
+ if (self->mode == MODE_FALLBACK)
+ show_dialog (self);
+}
+
+static void
+gtk_file_chooser_native_hide (GtkNativeDialog *native)
+{
+ GtkFileChooserNative *self = GTK_FILE_CHOOSER_NATIVE (native);
+
+ switch (self->mode)
+ {
+ case MODE_FALLBACK:
+ hide_dialog (self);
+ break;
+ case MODE_WIN32:
+#ifdef GDK_WINDOWING_WIN32
+ gtk_file_chooser_native_win32_hide (self);
+#endif
+ break;
+ }
+}
+
+static void
+gtk_file_chooser_native_class_init (GtkFileChooserNativeClass *class)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+ GtkNativeDialogClass *native_dialog_class = GTK_NATIVE_DIALOG_CLASS (class);
+
+ gobject_class->finalize = gtk_file_chooser_native_finalize;
+ gobject_class->set_property = gtk_file_chooser_native_set_property;
+ gobject_class->get_property = gtk_file_chooser_native_get_property;
+
+ native_dialog_class->show = gtk_file_chooser_native_show;
+ native_dialog_class->hide = gtk_file_chooser_native_hide;
+
+ _gtk_file_chooser_install_properties (gobject_class);
+
+ /**
+ * GtkFileChooserNative:accept-label:
+ *
+ * The text used for the label on the accept button in the dialog, or
+ * %NULL to use the default text.
+ */
+ native_props[PROP_ACCEPT_LABEL] =
+ g_param_spec_string ("accept-label",
+ P_("Accept label"),
+ P_("The label on the accept button"),
+ NULL,
+ GTK_PARAM_READWRITE);
+
+ /**
+ * GtkFileChooserNative:cancel-label:
+ *
+ * The text used for the label on the cancel button in the dialog, or
+ * %NULL to use the default text.
+ */
+ native_props[PROP_CANCEL_LABEL] =
+ g_param_spec_string ("cancel-label",
+ P_("Cancel label"),
+ P_("The label on the cancel button"),
+ NULL,
+ GTK_PARAM_READWRITE);
+
+ g_object_class_install_properties (gobject_class, LAST_ARG, native_props);
+}
+
+static void
+_gtk_file_chooser_native_iface_init (GtkFileChooserIface *iface)
+{
+ _gtk_file_chooser_delegate_iface_init (iface);
+ iface->select_file = gtk_file_chooser_native_select_file;
+ iface->set_current_name = gtk_file_chooser_native_set_current_name;
+ iface->set_current_folder = gtk_file_chooser_native_set_current_folder;
+ iface->get_files = gtk_file_chooser_native_get_files;
+}