]> Pileus Git - ~andy/gtk/blob - gtk/gtkfilechoosersettings.c
Include "config.h" instead of <config.h> Command used: find -name
[~andy/gtk] / gtk / gtkfilechoosersettings.c
1 /* GTK - The GIMP Toolkit
2  * gtkfilechoosersettings.c: Internal settings for the GtkFileChooser widget
3  * Copyright (C) 2006, Novell, Inc.
4  *
5  * Authors: Federico Mena-Quintero <federico@novell.com>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 /* TODO:
24  *
25  * - Persist these:
26  *   - hpaned position
27  *   - browse_for_other_folders?
28  *
29  * - Do we want lockdown?
30  */
31
32 #include "config.h"
33 #include <errno.h>
34 #include <string.h>
35 #include <glib.h>
36 #include <glib/gi18n-lib.h>
37 #include "gtkfilechoosersettings.h"
38 #include "gtkalias.h"
39
40 #define SETTINGS_GROUP          "Filechooser Settings"
41 #define LOCATION_MODE_KEY       "LocationMode"
42 #define SHOW_HIDDEN_KEY         "ShowHidden"
43 #define EXPAND_FOLDERS_KEY      "ExpandFolders"
44
45 #define MODE_PATH_BAR          "path-bar"
46 #define MODE_FILENAME_ENTRY    "filename-entry"
47
48 #define EQ(a, b) (g_ascii_strcasecmp ((a), (b)) == 0)
49
50 static char *
51 get_config_dirname (void)
52 {
53   return g_build_filename (g_get_user_config_dir (), "gtk-2.0", NULL);
54 }
55
56 static char *
57 get_config_filename (void)
58 {
59   return g_build_filename (g_get_user_config_dir (), "gtk-2.0", "gtkfilechooser.ini", NULL);
60 }
61
62 static void
63 ensure_settings_read (GtkFileChooserSettings *settings)
64 {
65   GError *error;
66   GKeyFile *key_file;
67   gchar *location_mode_str, *filename;
68   gboolean value;
69
70   if (settings->settings_read)
71     return;
72
73   key_file = g_key_file_new ();
74
75   filename = get_config_filename ();
76
77   error = NULL;
78   if (!g_key_file_load_from_file (key_file, filename, 0, &error))
79     {
80       /* Don't warn on non-existent file */
81       if (error->domain != G_FILE_ERROR ||
82           error->code != G_FILE_ERROR_NOENT)
83         g_warning ("Failed to read filechooser settings from \"%s\": %s",
84                    filename, error->message);
85
86       g_error_free (error);
87       goto out;
88     }
89
90   if (!g_key_file_has_group (key_file, SETTINGS_GROUP))
91     goto out;
92
93   location_mode_str = g_key_file_get_string (key_file, SETTINGS_GROUP,
94                                              LOCATION_MODE_KEY, NULL);
95   if (location_mode_str)
96     {
97       if (EQ (location_mode_str, MODE_PATH_BAR))
98         settings->location_mode = LOCATION_MODE_PATH_BAR;
99       else if (EQ (location_mode_str, MODE_FILENAME_ENTRY))
100         settings->location_mode = LOCATION_MODE_FILENAME_ENTRY;
101       else
102         g_warning ("Unknown location mode '%s' encountered in filechooser settings",
103                    location_mode_str);
104
105       g_free (location_mode_str);
106     }
107
108   value = g_key_file_get_boolean (key_file, SETTINGS_GROUP,
109                                   SHOW_HIDDEN_KEY, &error);
110   if (error)
111     {
112       g_warning ("Failed to read show-hidden setting in filechooser settings: %s",
113                  error->message);
114       g_clear_error (&error);
115     }
116   else
117     settings->show_hidden = value != FALSE;
118
119   value = g_key_file_get_boolean (key_file, SETTINGS_GROUP,
120                                   EXPAND_FOLDERS_KEY, &error);
121   if (error)
122     {
123       g_warning ("Failed to read expand-folders setting in filechooser settings: %s",
124                  error->message);
125       g_clear_error (&error);
126     }
127   else
128     settings->expand_folders = value != FALSE;
129
130  out:
131
132   g_key_file_free (key_file);
133   g_free (filename);
134
135   settings->settings_read = TRUE;
136 }
137
138 G_DEFINE_TYPE (GtkFileChooserSettings, _gtk_file_chooser_settings, G_TYPE_OBJECT)
139
140 static void
141 _gtk_file_chooser_settings_class_init (GtkFileChooserSettingsClass *class)
142 {
143 }
144
145 static void
146 _gtk_file_chooser_settings_init (GtkFileChooserSettings *settings)
147 {
148   settings->location_mode = LOCATION_MODE_PATH_BAR;
149   settings->show_hidden = FALSE;
150   settings->expand_folders = FALSE;
151 }
152
153 GtkFileChooserSettings *
154 _gtk_file_chooser_settings_new (void)
155 {
156   return g_object_new (GTK_FILE_CHOOSER_SETTINGS_TYPE, NULL);
157 }
158
159 LocationMode
160 _gtk_file_chooser_settings_get_location_mode (GtkFileChooserSettings *settings)
161 {
162   ensure_settings_read (settings);
163   return settings->location_mode;
164 }
165
166 void
167 _gtk_file_chooser_settings_set_location_mode (GtkFileChooserSettings *settings,
168                                               LocationMode location_mode)
169 {
170   settings->location_mode = location_mode;
171 }
172
173 gboolean
174 _gtk_file_chooser_settings_get_show_hidden (GtkFileChooserSettings *settings)
175 {
176   ensure_settings_read (settings);
177   return settings->show_hidden;
178 }
179
180 void
181 _gtk_file_chooser_settings_set_show_hidden (GtkFileChooserSettings *settings,
182                                             gboolean show_hidden)
183 {
184   settings->show_hidden = show_hidden != FALSE;
185 }
186
187 gboolean
188 _gtk_file_chooser_settings_get_expand_folders (GtkFileChooserSettings *settings)
189 {
190   ensure_settings_read (settings);
191   return settings->expand_folders;
192 }
193
194 void
195 _gtk_file_chooser_settings_set_expand_folders (GtkFileChooserSettings *settings,
196                                                gboolean expand_folders)
197 {
198   settings->expand_folders = expand_folders != FALSE;
199 }
200
201 gboolean
202 _gtk_file_chooser_settings_save (GtkFileChooserSettings *settings,
203                                  GError                **error)
204 {
205   const gchar *location_mode_str;
206   gchar *filename;
207   gchar *dirname;
208   gchar *contents;
209   gsize len;
210   gboolean retval;
211   GKeyFile *key_file;
212
213   g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
214
215   filename = get_config_filename ();
216   dirname = NULL;
217
218   retval = FALSE;
219
220   if (settings->location_mode == LOCATION_MODE_PATH_BAR)
221     location_mode_str = MODE_PATH_BAR;
222   else if (settings->location_mode == LOCATION_MODE_FILENAME_ENTRY)
223     location_mode_str = MODE_FILENAME_ENTRY;
224   else
225     {
226       g_assert_not_reached ();
227       return FALSE;
228     }
229
230   key_file = g_key_file_new ();
231
232   /* Initialise with the on-disk keyfile, so we keep unknown options */
233   g_key_file_load_from_file (key_file, filename, 0, NULL);
234
235   g_key_file_set_string (key_file, SETTINGS_GROUP,
236                          LOCATION_MODE_KEY, location_mode_str);
237   g_key_file_set_boolean (key_file, SETTINGS_GROUP,
238                           SHOW_HIDDEN_KEY, settings->show_hidden);
239   g_key_file_set_boolean (key_file, SETTINGS_GROUP,
240                           EXPAND_FOLDERS_KEY, settings->expand_folders);
241
242   contents = g_key_file_to_data (key_file, &len, error);
243   g_key_file_free (key_file);
244
245   if (!contents)
246     goto out;
247
248   if (!g_file_set_contents (filename, contents, len, NULL))
249     {
250       char *dirname;
251       int saved_errno;
252
253       /* Directory is not there? */
254
255       dirname = get_config_dirname ();
256       if (g_mkdir_with_parents (dirname, 0700) != 0) /* 0700 per the XDG basedir spec */
257         {
258           saved_errno = errno;
259           g_set_error (error,
260                        G_FILE_ERROR,
261                        g_file_error_from_errno (saved_errno),
262                        _("Error creating folder '%s': %s"),
263                        dirname, g_strerror (saved_errno));
264           goto out;
265         }
266
267       if (!g_file_set_contents (filename, contents, len, error))
268         goto out;
269     }
270
271   retval = TRUE;
272
273  out:
274
275   g_free (contents);
276   g_free (dirname);
277   g_free (filename);
278
279   return retval;
280 }