summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFederico Mena Quintero <federico@novell.com>2006-03-29 00:59:08 +0000
committerFederico Mena Quintero <federico@src.gnome.org>2006-03-29 00:59:08 +0000
commitc28327bdf772ae81b5724efcd3a7b0417202ffc4 (patch)
tree4b8fca7d60d327b90f2168220f1722a8d2cf158a
parent7579fe92a60cb247118db2d65b644af5d9aacfc5 (diff)
downloadgtk+-c28327bdf772ae81b5724efcd3a7b0417202ffc4.tar.gz
New files with a simple framework for saving/loading settings from the
2006-03-28 Federico Mena Quintero <federico@novell.com> * gtk/gtkfilechoosersettings.[ch]: New files with a simple framework for saving/loading settings from the file chooser in $XDG_CONFIG_HOME/gtk-2.0/gtkfilechooser. * gtk/gtkfilechooserdefault.c (gtk_file_chooser_default_unmap): Save the current settings. (settings_save): New helper function. We save the location_mode and show_hidden flags. (gtk_file_chooser_default_map): Load the settings. (settings_load): New helper function. * gtk/gtkfilechooserentry.c (_gtk_file_chooser_entry_set_file_part): Oops, don't modify in_change. Our handlers are what set the file_part, so they *must* be run when we modify the text.
-rw-r--r--ChangeLog18
-rw-r--r--ChangeLog.pre-2-1018
-rw-r--r--gtk/Makefile.am2
-rw-r--r--gtk/gtkfilechooserdefault.c47
-rw-r--r--gtk/gtkfilechooserentry.c2
-rw-r--r--gtk/gtkfilechoosersettings.c535
-rw-r--r--gtk/gtkfilechoosersettings.h75
7 files changed, 689 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index be75616fe1..c0c42adb6b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2006-03-28 Federico Mena Quintero <federico@novell.com>
+
+ * gtk/gtkfilechoosersettings.[ch]: New files with a simple
+ framework for saving/loading settings from the file chooser in
+ $XDG_CONFIG_HOME/gtk-2.0/gtkfilechooser.
+
+ * gtk/gtkfilechooserdefault.c (gtk_file_chooser_default_unmap):
+ Save the current settings.
+ (settings_save): New helper function. We save the location_mode
+ and show_hidden flags.
+ (gtk_file_chooser_default_map): Load the settings.
+ (settings_load): New helper function.
+
+ * gtk/gtkfilechooserentry.c
+ (_gtk_file_chooser_entry_set_file_part): Oops, don't modify
+ in_change. Our handlers are what set the file_part, so they
+ *must* be run when we modify the text.
+
2006-03-27 Federico Mena Quintero <federico@novell.com>
* gtk/gtkfilechooserprivate.h (struct _GtkFileChooserDefault):
diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10
index be75616fe1..c0c42adb6b 100644
--- a/ChangeLog.pre-2-10
+++ b/ChangeLog.pre-2-10
@@ -1,3 +1,21 @@
+2006-03-28 Federico Mena Quintero <federico@novell.com>
+
+ * gtk/gtkfilechoosersettings.[ch]: New files with a simple
+ framework for saving/loading settings from the file chooser in
+ $XDG_CONFIG_HOME/gtk-2.0/gtkfilechooser.
+
+ * gtk/gtkfilechooserdefault.c (gtk_file_chooser_default_unmap):
+ Save the current settings.
+ (settings_save): New helper function. We save the location_mode
+ and show_hidden flags.
+ (gtk_file_chooser_default_map): Load the settings.
+ (settings_load): New helper function.
+
+ * gtk/gtkfilechooserentry.c
+ (_gtk_file_chooser_entry_set_file_part): Oops, don't modify
+ in_change. Our handlers are what set the file_part, so they
+ *must* be run when we modify the text.
+
2006-03-27 Federico Mena Quintero <federico@novell.com>
* gtk/gtkfilechooserprivate.h (struct _GtkFileChooserDefault):
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index fe60c73d73..3ebbfcb8fa 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -302,6 +302,7 @@ gtk_private_h_sources = \
gtkfilechooserentry.h \
gtkfilechooserdefault.h \
gtkfilechooserprivate.h \
+ gtkfilechoosersettings.h \
gtkfilechooserutils.h \
gtkfilesystemunix.h \
gtkfilesystemmodel.h \
@@ -382,6 +383,7 @@ gtk_c_sources = \
gtkfilechooserembed.c \
gtkfilechooserentry.c \
gtkfilechooserdefault.c \
+ gtkfilechoosersettings.c \
gtkfilechooserutils.c \
gtkfilechooserwidget.c \
gtkfilefilter.c \
diff --git a/gtk/gtkfilechooserdefault.c b/gtk/gtkfilechooserdefault.c
index 68a449a019..4855b10813 100644
--- a/gtk/gtkfilechooserdefault.c
+++ b/gtk/gtkfilechooserdefault.c
@@ -36,6 +36,7 @@
#include "gtkfilechooserdefault.h"
#include "gtkfilechooserembed.h"
#include "gtkfilechooserentry.h"
+#include "gtkfilechoosersettings.h"
#include "gtkfilechooserutils.h"
#include "gtkfilechooser.h"
#include "gtkfilesystemmodel.h"
@@ -691,7 +692,7 @@ gtk_file_chooser_default_init (GtkFileChooserDefault *impl)
impl->load_state = LOAD_EMPTY;
impl->reload_state = RELOAD_EMPTY;
impl->pending_select_paths = NULL;
- impl->location_mode = LOCATION_MODE_FILENAME_ENTRY;
+ impl->location_mode = LOCATION_MODE_PATH_BAR;
gtk_box_set_spacing (GTK_BOX (impl), 12);
@@ -4984,6 +4985,40 @@ get_is_file_filtered (GtkFileChooserDefault *impl,
return !result;
}
+static void
+settings_load (GtkFileChooserDefault *impl)
+{
+ GtkFileChooserSettings *settings;
+ LocationMode location_mode;
+ gboolean show_hidden;
+
+ settings = _gtk_file_chooser_settings_new ();
+
+ location_mode = _gtk_file_chooser_settings_get_location_mode (settings);
+ show_hidden = _gtk_file_chooser_settings_get_show_hidden (settings);
+
+ g_object_unref (settings);
+
+ location_mode_set (impl, location_mode, TRUE);
+ gtk_file_chooser_set_show_hidden (GTK_FILE_CHOOSER (impl), show_hidden);
+}
+
+static void
+settings_save (GtkFileChooserDefault *impl)
+{
+ GtkFileChooserSettings *settings;
+
+ settings = _gtk_file_chooser_settings_new ();
+
+ _gtk_file_chooser_settings_set_location_mode (settings, impl->location_mode);
+ _gtk_file_chooser_settings_set_show_hidden (settings, gtk_file_chooser_get_show_hidden (GTK_FILE_CHOOSER (impl)));
+
+ /* NULL GError */
+ _gtk_file_chooser_settings_save (settings, NULL);
+
+ g_object_unref (settings);
+}
+
/* GtkWidget::map method */
static void
gtk_file_chooser_default_map (GtkWidget *widget)
@@ -5024,6 +5059,8 @@ gtk_file_chooser_default_map (GtkWidget *widget)
bookmarks_changed_cb (impl->file_system, impl);
+ settings_load (impl);
+
profile_end ("end", NULL);
}
@@ -5035,6 +5072,8 @@ gtk_file_chooser_default_unmap (GtkWidget *widget)
impl = GTK_FILE_CHOOSER_DEFAULT (widget);
+ settings_save (impl);
+
GTK_WIDGET_CLASS (parent_class)->unmap (widget);
impl->reload_state = RELOAD_WAS_UNMAPPED;
@@ -5996,11 +6035,7 @@ gtk_file_chooser_default_get_paths (GtkFileChooser *chooser)
info.result = NULL;
info.path_from_entry = NULL;
- if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
- || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER
- || ((impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
- || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
- && impl->location_mode == LOCATION_MODE_FILENAME_ENTRY))
+ if (impl->location_entry)
{
gboolean is_well_formed, is_empty, is_file_part_empty;
diff --git a/gtk/gtkfilechooserentry.c b/gtk/gtkfilechooserentry.c
index 2abf9af5f1..acbd1206c2 100644
--- a/gtk/gtkfilechooserentry.c
+++ b/gtk/gtkfilechooserentry.c
@@ -982,9 +982,7 @@ _gtk_file_chooser_entry_set_file_part (GtkFileChooserEntry *chooser_entry,
{
g_return_if_fail (GTK_IS_FILE_CHOOSER_ENTRY (chooser_entry));
- chooser_entry->in_change = TRUE;
gtk_entry_set_text (GTK_ENTRY (chooser_entry), file_part);
- chooser_entry->in_change = FALSE;
}
diff --git a/gtk/gtkfilechoosersettings.c b/gtk/gtkfilechoosersettings.c
new file mode 100644
index 0000000000..861ca3f43f
--- /dev/null
+++ b/gtk/gtkfilechoosersettings.c
@@ -0,0 +1,535 @@
+/* GTK - The GIMP Toolkit
+ * gtkfilechoosersettings.c: Internal settings for the GtkFileChooser widget
+ * Copyright (C) 2006, Novell, Inc.
+ *
+ * Authors: Federico Mena-Quintero <federico@novell.com>
+ *
+ * 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, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* TODO:
+ *
+ * - Persist these:
+ * - hpaned position
+ * - browse_for_other_folders?
+ *
+ * - Do we want lockdown?
+ */
+
+#include <config.h>
+#include <errno.h>
+#include <string.h>
+#include <glib/gi18n-lib.h>
+#include "gtkfilechoosersettings.h"
+
+/* Increment this every time you change the configuration format */
+#define CONFIG_VERSION 0
+
+#define ELEMENT_TOPLEVEL "gtkfilechooser"
+#define ELEMENT_LOCATION "location"
+#define ELEMENT_SHOW_HIDDEN "show_hidden"
+#define ATTRIBUTE_VERSION "version"
+#define ATTRIBUTE_MODE "mode"
+#define ATTRIBUTE_VALUE "value"
+#define MODE_PATH_BAR "path-bar"
+#define MODE_FILENAME_ENTRY "filename-entry"
+#define VALUE_TRUE "true"
+#define VALUE_FALSE "false"
+
+#define EQ(a, b) (g_ascii_strcasecmp ((a), (b)) == 0)
+
+static char *
+get_config_dirname (void)
+{
+ return g_build_filename (g_get_user_config_dir (), "gtk-2.0", NULL);
+}
+
+static char *
+get_config_filename (void)
+{
+ return g_build_filename (g_get_user_config_dir (), "gtk-2.0", "gtkfilechooser", NULL);
+}
+
+static void
+set_defaults (GtkFileChooserSettings *settings)
+{
+ settings->location_mode = LOCATION_MODE_PATH_BAR;
+ settings->show_hidden = FALSE;
+}
+
+typedef enum {
+ STATE_START,
+ STATE_END,
+ STATE_ERROR,
+ STATE_IN_TOPLEVEL,
+ STATE_IN_LOCATION,
+ STATE_IN_SHOW_HIDDEN
+} State;
+
+struct parse_state {
+ GtkFileChooserSettings *settings;
+ int version;
+ State state;
+};
+
+static const char *
+get_attribute_value (const char **attribute_names,
+ const char **attribute_values,
+ const char *attribute)
+{
+ const char **name;
+ const char **value;
+
+ name = attribute_names;
+ value = attribute_values;
+
+ while (*name)
+ {
+ if (EQ (*name, attribute))
+ return *value;
+
+ name++;
+ value++;
+ }
+
+ return NULL;
+}
+
+static void
+set_missing_attribute_error (struct parse_state *state,
+ int line,
+ int col,
+ const char *attribute,
+ GError **error)
+{
+ state->state = STATE_ERROR;
+ g_set_error (error,
+ G_MARKUP_ERROR,
+ G_MARKUP_ERROR_INVALID_CONTENT,
+ _("Line %d, column %d: missing attribute \"%s\""),
+ line,
+ col,
+ attribute);
+}
+
+static void
+set_unexpected_element_error (struct parse_state *state,
+ int line,
+ int col,
+ const char *element,
+ GError **error)
+{
+ state->state = STATE_ERROR;
+ g_set_error (error,
+ G_MARKUP_ERROR,
+ G_MARKUP_ERROR_UNKNOWN_ELEMENT,
+ _("Line %d, column %d: unexpected element \"%s\""),
+ line,
+ col,
+ element);
+}
+
+static void
+set_unexpected_element_end_error (struct parse_state *state,
+ int line,
+ int col,
+ const char *expected_element,
+ const char *unexpected_element,
+ GError **error)
+{
+ state->state = STATE_ERROR;
+ g_set_error (error,
+ G_MARKUP_ERROR,
+ G_MARKUP_ERROR_UNKNOWN_ELEMENT,
+ _("Line %d, column %d: expected end of element \"%s\", but got element for \"%s\" instead"),
+ line,
+ col,
+ expected_element,
+ unexpected_element);
+}
+
+
+static void
+parse_start_element_cb (GMarkupParseContext *context,
+ const char *element_name,
+ const char **attribute_names,
+ const char **attribute_values,
+ gpointer data,
+ GError **error)
+{
+ struct parse_state *state;
+ int line, col;
+
+ state = data;
+ g_markup_parse_context_get_position (context, &line, &col);
+
+ switch (state->state)
+ {
+ case STATE_START:
+ if (EQ (element_name, ELEMENT_TOPLEVEL))
+ {
+ const char *version_str;
+
+ state->state = STATE_IN_TOPLEVEL;
+
+ version_str = get_attribute_value (attribute_names, attribute_values, ATTRIBUTE_VERSION);
+ if (!version_str)
+ state->version = -1;
+ else
+ if (sscanf (version_str, "%d", &state->version) != 1 || state->version < 0)
+ state->version = -1;
+ }
+ else
+ {
+ state->state = STATE_ERROR;
+ g_set_error (error,
+ G_MARKUP_ERROR,
+ G_MARKUP_ERROR_UNKNOWN_ELEMENT,
+ _("Line %d, column %d: expected \"%s\" at the toplevel, but found \"%s\" instead"),
+ line,
+ col,
+ ELEMENT_TOPLEVEL,
+ element_name);
+ }
+ break;
+
+ case STATE_END:
+ g_assert_not_reached ();
+ break;
+
+ case STATE_ERROR:
+ g_assert_not_reached ();
+ break;
+
+ case STATE_IN_TOPLEVEL:
+ if (EQ (element_name, ELEMENT_LOCATION))
+ {
+ const char *location_mode_str;
+
+ state->state = STATE_IN_LOCATION;
+
+ location_mode_str = get_attribute_value (attribute_names, attribute_values, ATTRIBUTE_MODE);
+ if (!location_mode_str)
+ set_missing_attribute_error (state, line, col, ATTRIBUTE_MODE, error);
+ else if (EQ (location_mode_str, MODE_PATH_BAR))
+ state->settings->location_mode = LOCATION_MODE_PATH_BAR;
+ else if (EQ (location_mode_str, MODE_FILENAME_ENTRY))
+ state->settings->location_mode = LOCATION_MODE_FILENAME_ENTRY;
+ else
+ {
+ state->state = STATE_ERROR;
+ g_set_error (error,
+ G_MARKUP_ERROR,
+ G_MARKUP_ERROR_INVALID_CONTENT,
+ _("Line %d, column %d: expected \"%s\" or \"%s\", but found \"%s\" instead"),
+ line,
+ col,
+ MODE_PATH_BAR,
+ MODE_FILENAME_ENTRY,
+ location_mode_str);
+ }
+ }
+ else if (EQ (element_name, ELEMENT_SHOW_HIDDEN))
+ {
+ const char *value_str;
+
+ state->state = STATE_IN_SHOW_HIDDEN;
+
+ value_str = get_attribute_value (attribute_names, attribute_values, ATTRIBUTE_VALUE);
+
+ if (!value_str)
+ set_missing_attribute_error (state, line, col, ATTRIBUTE_VALUE, error);
+ else if (EQ (value_str, VALUE_TRUE))
+ state->settings->show_hidden = TRUE;
+ else if (EQ (value_str, VALUE_FALSE))
+ state->settings->show_hidden = FALSE;
+ else
+ {
+ state->state = STATE_ERROR;
+ g_set_error (error,
+ G_MARKUP_ERROR,
+ G_MARKUP_ERROR_INVALID_CONTENT,
+ _("Line %d, column %d: expected \"%s\" or \"%s\", but found \"%s\" instead"),
+ line,
+ col,
+ VALUE_FALSE,
+ VALUE_TRUE,
+ value_str);
+ }
+ }
+ else
+ set_unexpected_element_error (state, line, col, element_name, error);
+
+ break;
+
+ case STATE_IN_LOCATION:
+ case STATE_IN_SHOW_HIDDEN:
+ set_unexpected_element_error (state, line, col, element_name, error);
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+static void
+parse_end_element_cb (GMarkupParseContext *context,
+ const char *element_name,
+ gpointer data,
+ GError **error)
+{
+ struct parse_state *state;
+ int line, col;
+
+ state = data;
+ g_markup_parse_context_get_position (context, &line, &col);
+
+ switch (state->state)
+ {
+ case STATE_START:
+ g_assert_not_reached ();
+ break;
+
+ case STATE_END:
+ g_assert_not_reached ();
+ break;
+
+ case STATE_ERROR:
+ g_assert_not_reached ();
+ break;
+
+ case STATE_IN_TOPLEVEL:
+ if (EQ (element_name, ELEMENT_TOPLEVEL))
+ state->state = STATE_END;
+ else
+ set_unexpected_element_end_error (state, line, col, ELEMENT_TOPLEVEL, element_name, error);
+
+ break;
+
+ case STATE_IN_LOCATION:
+ if (EQ (element_name, ELEMENT_LOCATION))
+ state->state = STATE_IN_TOPLEVEL;
+ else
+ set_unexpected_element_end_error (state, line, col, ELEMENT_LOCATION, element_name, error);
+
+ break;
+
+ case STATE_IN_SHOW_HIDDEN:
+ if (EQ (element_name, ELEMENT_SHOW_HIDDEN))
+ state->state = STATE_IN_TOPLEVEL;
+ else
+ set_unexpected_element_end_error (state, line, col, ELEMENT_SHOW_HIDDEN, element_name, error);
+
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+static gboolean
+parse_config (GtkFileChooserSettings *settings,
+ const char *contents,
+ GError **error)
+{
+ GMarkupParser parser = { 0, };
+ GMarkupParseContext *context;
+ struct parse_state state;
+ gboolean retval;
+
+ parser.start_element = parse_start_element_cb;
+ parser.end_element = parse_end_element_cb;
+
+ state.settings = settings;
+ state.version = -1;
+ state.state = STATE_START;
+
+ context = g_markup_parse_context_new (&parser,
+ 0,
+ &state,
+ NULL);
+
+ retval = g_markup_parse_context_parse (context, contents, -1, error);
+ g_markup_parse_context_free (context);
+
+ return retval;
+}
+
+static gboolean
+read_config (GtkFileChooserSettings *settings,
+ GError **error)
+{
+ char *filename;
+ char *contents;
+ gsize contents_len;
+ gboolean success;
+
+ filename = get_config_filename ();
+
+ success = g_file_get_contents (filename, &contents, &contents_len, error);
+ g_free (filename);
+
+ if (!success)
+ {
+ set_defaults (settings);
+ return FALSE;
+ }
+
+ success = parse_config (settings, contents, error);
+
+ g_free (contents);
+
+ return success;
+}
+
+static void
+ensure_settings_read (GtkFileChooserSettings *settings)
+{
+ if (settings->settings_read)
+ return;
+
+ /* NULL GError */
+ read_config (settings, NULL);
+
+ settings->settings_read = TRUE;
+}
+
+G_DEFINE_TYPE (GtkFileChooserSettings,
+ _gtk_file_chooser_settings,
+ G_TYPE_OBJECT);
+
+static void
+_gtk_file_chooser_settings_class_init (GtkFileChooserSettingsClass *class)
+{
+}
+
+static void
+_gtk_file_chooser_settings_init (GtkFileChooserSettings *settings)
+{
+}
+
+GtkFileChooserSettings *
+_gtk_file_chooser_settings_new (void)
+{
+ return g_object_new (GTK_FILE_CHOOSER_SETTINGS_TYPE, NULL);
+}
+
+LocationMode
+_gtk_file_chooser_settings_get_location_mode (GtkFileChooserSettings *settings)
+{
+ ensure_settings_read (settings);
+ return settings->location_mode;
+}
+
+void
+_gtk_file_chooser_settings_set_location_mode (GtkFileChooserSettings *settings,
+ LocationMode location_mode)
+{
+ settings->location_mode = location_mode;
+}
+
+gboolean
+_gtk_file_chooser_settings_get_show_hidden (GtkFileChooserSettings *settings)
+{
+ ensure_settings_read (settings);
+ return settings->show_hidden;
+}
+
+void
+_gtk_file_chooser_settings_set_show_hidden (GtkFileChooserSettings *settings,
+ gboolean show_hidden)
+{
+ settings->show_hidden = show_hidden ? TRUE : FALSE;
+}
+
+static char *
+settings_to_markup (GtkFileChooserSettings *settings)
+{
+ const char *location_mode_str;
+ const char *show_hidden_str;
+
+ if (settings->location_mode == LOCATION_MODE_PATH_BAR)
+ location_mode_str = MODE_PATH_BAR;
+ else if (settings->location_mode == LOCATION_MODE_FILENAME_ENTRY)
+ location_mode_str = MODE_FILENAME_ENTRY;
+ else
+ {
+ g_assert_not_reached ();
+ return NULL;
+ }
+
+ show_hidden_str = settings->show_hidden ? VALUE_TRUE : VALUE_FALSE;
+
+ return g_strdup_printf
+ ("<" ELEMENT_TOPLEVEL ">\n" /* <gtkfilechooser> */
+ " <" ELEMENT_LOCATION " " ATTRIBUTE_MODE "=\"%s\"/>\n" /* <location mode="path-bar"/> */
+ " <" ELEMENT_SHOW_HIDDEN " " ATTRIBUTE_VALUE "=\"%s\"/>\n" /* <show_hidden value="false"/> */
+ "</" ELEMENT_TOPLEVEL ">\n", /* </gtkfilechooser> */
+ location_mode_str,
+ show_hidden_str);
+}
+
+gboolean
+_gtk_file_chooser_settings_save (GtkFileChooserSettings *settings,
+ GError **error)
+{
+ char *contents;
+ char *filename;
+ char *dirname;
+ gboolean retval;
+
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ contents = settings_to_markup (settings);
+
+ filename = get_config_filename ();
+ dirname = NULL;
+
+ retval = FALSE;
+
+ if (!g_file_set_contents (filename, contents, -1, NULL))
+ {
+ char *dirname;
+ int saved_errno;
+
+ /* Directory is not there? */
+
+ dirname = get_config_dirname ();
+ if (g_mkdir_with_parents (dirname, 0700) != 0) /* 0700 per the XDG basedir spec */
+ {
+ saved_errno = errno;
+ g_set_error (error,
+ G_FILE_ERROR,
+ g_file_error_from_errno (saved_errno),
+ _("Could not create directory: %s"),
+ dirname);
+ goto out;
+ }
+
+ if (!g_file_set_contents (filename, contents, -1, error))
+ goto out;
+ }
+
+ retval = TRUE;
+
+ out:
+
+ g_free (contents);
+ g_free (dirname);
+ g_free (filename);
+
+ return retval;
+}
diff --git a/gtk/gtkfilechoosersettings.h b/gtk/gtkfilechoosersettings.h
new file mode 100644
index 0000000000..47f6abba68
--- /dev/null
+++ b/gtk/gtkfilechoosersettings.h
@@ -0,0 +1,75 @@
+/* GTK - The GIMP Toolkit
+ * gtkfilechoosersettings.h: Internal settings for the GtkFileChooser widget
+ * Copyright (C) 2006, Novell, Inc.
+ *
+ * Authors: Federico Mena-Quintero <federico@novell.com>
+ *
+ * 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, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GTK_FILE_CHOOSER_SETTINGS_H__
+#define __GTK_FILE_CHOOSER_SETTINGS_H__
+
+#include <glib-object.h>
+#include "gtkfilechooserprivate.h"
+
+G_BEGIN_DECLS
+
+#define GTK_FILE_CHOOSER_SETTINGS_TYPE (_gtk_file_chooser_settings_get_type ())
+
+typedef struct _GtkFileChooserSettings GtkFileChooserSettings;
+typedef struct _GtkFileChooserSettingsClass GtkFileChooserSettingsClass;
+
+struct _GtkFileChooserSettings
+{
+ GObject object;
+
+ LocationMode location_mode;
+
+ guint settings_read : 1;
+
+ guint show_hidden : 1;
+};
+
+struct _GtkFileChooserSettingsClass
+{
+ GObjectClass parent_class;
+};
+
+GType _gtk_file_chooser_settings_get_type (void) G_GNUC_CONST;
+
+GtkFileChooserSettings *_gtk_file_chooser_settings_new (void);
+
+LocationMode _gtk_file_chooser_settings_get_location_mode (GtkFileChooserSettings *settings);
+void _gtk_file_chooser_settings_set_location_mode (GtkFileChooserSettings *settings,
+ LocationMode location_mode);
+
+gboolean _gtk_file_chooser_settings_get_show_hidden (GtkFileChooserSettings *settings);
+void _gtk_file_chooser_settings_set_show_hidden (GtkFileChooserSettings *settings,
+ gboolean show_hidden);
+
+gboolean _gtk_file_chooser_settings_save (GtkFileChooserSettings *settings,
+ GError **error);
+
+/* FIXME: persist these options:
+ *
+ * - paned width
+ * - show_hidden
+ */
+
+G_END_DECLS
+
+#endif