]> Pileus Git - ~andy/gtk/blob - gtk/gtkfilechooser.c
d9f1c1a55e5a1bd5961411e8577cb9c78f6f996c
[~andy/gtk] / gtk / gtkfilechooser.c
1 /* GTK - The GIMP Toolkit
2  * gtkfilechooser.c: Abstract interface for file selector GUIs
3  * Copyright (C) 2003, Red Hat, Inc.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #include "gtkfilechooser.h"
22 #include "gtkfilechooserprivate.h"
23 #include "gtkfilesystem.h"
24 #include "gtkintl.h"
25 #include "gtktypebuiltins.h"
26
27 static void gtk_file_chooser_class_init (gpointer g_iface);
28
29 static GtkFilePath *gtk_file_chooser_get_path         (GtkFileChooser *chooser);
30
31 GType
32 gtk_file_chooser_get_type (void)
33 {
34   static GType file_chooser_type = 0;
35
36   if (!file_chooser_type)
37     {
38       static const GTypeInfo file_chooser_info =
39       {
40         sizeof (GtkFileChooserIface),  /* class_size */
41         NULL,                          /* base_init */
42         NULL,                          /* base_finalize */
43         (GClassInitFunc)gtk_file_chooser_class_init, /* class_init */
44       };
45
46       file_chooser_type = g_type_register_static (G_TYPE_INTERFACE,
47                                                   "GtkFileChooser",
48                                                   &file_chooser_info, 0);
49
50       g_type_interface_add_prerequisite (file_chooser_type, GTK_TYPE_WIDGET);
51     }
52
53   return file_chooser_type;
54 }
55
56 static void
57 gtk_file_chooser_class_init (gpointer g_iface)
58 {
59   GType iface_type = G_TYPE_FROM_INTERFACE (g_iface);
60
61   g_signal_new ("current-folder-changed",
62                 iface_type,
63                 G_SIGNAL_RUN_LAST,
64                 G_STRUCT_OFFSET (GtkFileChooserIface, current_folder_changed),
65                 NULL, NULL,
66                 g_cclosure_marshal_VOID__VOID,
67                 G_TYPE_NONE, 0);
68   g_signal_new ("selection-changed",
69                 iface_type,
70                 G_SIGNAL_RUN_LAST,
71                 G_STRUCT_OFFSET (GtkFileChooserIface, selection_changed),
72                 NULL, NULL,
73                 g_cclosure_marshal_VOID__VOID,
74                 G_TYPE_NONE, 0);
75   g_signal_new ("update-preview",
76                 iface_type,
77                 G_SIGNAL_RUN_LAST,
78                 G_STRUCT_OFFSET (GtkFileChooserIface, update_preview),
79                 NULL, NULL,
80                 g_cclosure_marshal_VOID__VOID,
81                 G_TYPE_NONE, 0);
82   g_signal_new ("file-activated",
83                 iface_type,
84                 G_SIGNAL_RUN_LAST,
85                 G_STRUCT_OFFSET (GtkFileChooserIface, file_activated),
86                 NULL, NULL,
87                 g_cclosure_marshal_VOID__VOID,
88                 G_TYPE_NONE, 0);
89   
90   g_object_interface_install_property (g_iface,
91                                        g_param_spec_enum ("action",
92                                                           _("Action"),
93                                                           _("The type of operation that the file selector is performing"),
94                                                           GTK_TYPE_FILE_CHOOSER_ACTION,
95                                                           GTK_FILE_CHOOSER_ACTION_OPEN,
96                                                           G_PARAM_READWRITE));
97   g_object_interface_install_property (g_iface,
98                                        g_param_spec_object ("file-system",
99                                                             _("File System"),
100                                                             _("File system object to use"),
101                                                             GTK_TYPE_FILE_SYSTEM,
102                                                             G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
103   g_object_interface_install_property (g_iface,
104                                        g_param_spec_object ("filter",
105                                                             _("Filter"),
106                                                             _("The current filter for selecting which files are displayed"),
107                                                             GTK_TYPE_FILE_FILTER,
108                                                             G_PARAM_READWRITE));
109   g_object_interface_install_property (g_iface,
110                                        g_param_spec_boolean ("folder-mode",
111                                                              _("Folder Mode"),
112                                                              _("Whether to select folders rather than files"),
113                                                              FALSE,
114                                                              G_PARAM_READWRITE));
115   g_object_interface_install_property (g_iface,
116                                        g_param_spec_boolean ("local-only",
117                                                              _("Local Only"),
118                                                              _("Whether the selected file(s) should be limited to local file: URLs"),
119                                                              TRUE,
120                                                              G_PARAM_READWRITE));
121   g_object_interface_install_property (g_iface,
122                                        g_param_spec_object ("preview-widget",
123                                                             _("Preview widget"),
124                                                             _("Application supplied widget for custom previews."),
125                                                             GTK_TYPE_WIDGET,
126                                                             G_PARAM_READWRITE));
127   g_object_interface_install_property (g_iface,
128                                        g_param_spec_boolean ("preview-widget-active",
129                                                              _("Preview Widget Active"),
130                                                              _("Whether the application supplied widget for custom previews should be shown."),
131                                                              TRUE,
132                                                              G_PARAM_READWRITE));
133   g_object_interface_install_property (g_iface,
134                                        g_param_spec_object ("extra-widget",
135                                                             _("Extra widget"),
136                                                             _("Application supplied widget for extra options."),
137                                                             GTK_TYPE_WIDGET,
138                                                             G_PARAM_READWRITE));
139   g_object_interface_install_property (g_iface,
140                                        g_param_spec_boolean ("select-multiple",
141                                                              _("Select Multiple"),
142                                                              _("Whether to allow multiple files to be selected"),
143                                                              FALSE,
144                                                              G_PARAM_READWRITE));
145   
146   g_object_interface_install_property (g_iface,
147                                        g_param_spec_boolean ("show-hidden",
148                                                              _("Show Hidden"),
149                                                              _("Whether the hidden files and folders should be displayed"),
150                                                              FALSE,
151                                                              G_PARAM_READWRITE));
152 }
153
154 /**
155  * gtk_file_chooser_error_quark:
156  *
157  * Registers an error quark for #GtkFileChooser if necessary.
158  * 
159  * Return value: The error quark used for #GtkFileChooser errors.
160  *
161  * Since: 2.4
162  **/
163 GQuark
164 gtk_file_chooser_error_quark (void)
165 {
166   static GQuark quark = 0;
167   if (quark == 0)
168     quark = g_quark_from_static_string ("gtk-file-chooser-error-quark");
169   return quark;
170 }
171
172 /**
173  * gtk_file_chooser_set_action:
174  * @chooser: a #GtkFileChooser
175  * @action: the action that the file selector is performing
176  * 
177  * Sets the type of operation that that the chooser is performing; the
178  * user interface is adapted to suit the selected action. For example,
179  * an option to create a new folder might be shown if the action is
180  * %GTK_FILE_CHOOSER_ACTION_SAVE but not if the action is
181  * %GTK_FILE_CHOOSER_ACTION_OPEN.
182  *
183  * Since: 2.4
184  **/
185 void
186 gtk_file_chooser_set_action (GtkFileChooser       *chooser,
187                              GtkFileChooserAction  action)
188 {
189   g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
190
191   g_object_set (chooser, "action", action, NULL);
192 }
193
194 /**
195  * gtk_file_chooser_get_action:
196  * @chooser: a #GtkFileChooser
197  * 
198  * Gets the type of operation that the file chooser is performing; see
199  * gtk_file_chooser_set_action().
200  * 
201  * Return value: the action that the file selector is performing
202  *
203  * Since: 2.4
204  **/
205 GtkFileChooserAction
206 gtk_file_chooser_get_action (GtkFileChooser *chooser)
207 {
208   GtkFileChooserAction action;
209   
210   g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), FALSE);
211
212   g_object_get (chooser, "action", &action, NULL);
213
214   return action;
215 }
216
217 /**
218  * gtk_file_chooser_set_folder_mode:
219  * @chooser: a #GtkFileChooser
220  * @folder_mode: %TRUE if the file chooser is used to select folders
221  *               rather than files.
222  * 
223  * Sets whether the file chooser is used to select folders
224  * rather than files. If in folder mode, only folders are displayed
225  * to the use, and not the individual files inside the folders
226  * and the user selects a single folder rather than one or
227  * more files.
228  *
229  * Since: 2.4
230  **/
231 void
232 gtk_file_chooser_set_folder_mode (GtkFileChooser *chooser,
233                                   gboolean        folder_mode)
234 {
235   g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
236
237   g_object_set (chooser, "folder-mode", folder_mode, NULL);
238 }
239
240 /**
241  * gtk_file_chooser_get_folder_mode:
242  * @chooser: a #GtkFileChooser
243  * 
244  * Gets whether the file chooser is used to select folders
245  * rather than files. See gtk_file_chooser_set_folder_mode()
246  * 
247  * Return value: %TRUE if the file chooser is used to select
248  *               folders rather than files.
249  *
250  * Since: 2.4
251  **/
252 gboolean
253 gtk_file_chooser_get_folder_mode (GtkFileChooser *chooser)
254 {
255   gboolean folder_mode;
256   
257   g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), FALSE);
258
259   g_object_get (chooser, "folder-mode", &folder_mode, NULL);
260
261   return folder_mode;
262 }
263
264 /**
265  * gtk_file_chooser_set_local_only:
266  * @chooser: a #GtkFileChooser
267  * @local_only: %TRUE if only local files can be selected
268  * 
269  * Sets whether only local files can be selected in the
270  * file selector. If @local_only is %TRUE (the default),
271  * then the selected file are files are guaranteed to be
272  * accessible through the operating systems native file
273  * file system and therefore the application only
274  * needs to worry about the filename functions in
275  * #GtkFileChooser, like gtk_file_chooser_get_filename(),
276  * rather than the URI functions like
277  * gtk_file_chooser_get_uri(),
278  *
279  * Since: 2.4
280  **/
281 void
282 gtk_file_chooser_set_local_only (GtkFileChooser *chooser,
283                                  gboolean        local_only)
284 {
285   g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
286
287   g_object_set (chooser, "local-only", local_only, NULL);
288 }
289
290 /**
291  * gtk_file_chooser_get_local_only:
292  * @chooser: a #GtkFileChoosre
293  * 
294  * Gets whether only local files can be selected in the
295  * file selector. See gtk_file_chooser_set_local_only()
296  * 
297  * Return value: %TRUE if only local files can be selected.
298  *
299  * Since: 2.4
300  **/
301 gboolean
302 gtk_file_chooser_get_local_only (GtkFileChooser *chooser)
303 {
304   gboolean local_only;
305   
306   g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), FALSE);
307
308   g_object_get (chooser, "local-only", &local_only, NULL);
309
310   return local_only;
311 }
312
313 /**
314  * gtk_file_chooser_set_select_multiple:
315  * @chooser: a #GtkFileChooser
316  * @select_multiple: %TRUE if multiple files can be selected.
317  * 
318  * Sets whether multiple files can be selected in the file
319  * selector. If the file selector if in folder mode (see
320  * gtk_file_selector_set_folder_mode()) then only one folder
321  * can be selected, without regard to this setting.
322  *
323  * Since: 2.4
324  **/
325 void
326 gtk_file_chooser_set_select_multiple (GtkFileChooser *chooser,
327                                       gboolean        select_multiple)
328 {
329   g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
330
331   g_object_set (chooser, "select-multiple", select_multiple, NULL);
332 }
333
334 /**
335  * gtk_file_chooser_get_select_multiple:
336  * @chooser: a #GtkFileChooser
337  * 
338  * Gets whether multiple files can be selected in the file
339  * selector. See gtk_file_chooser_set_select_multiple().
340  * 
341  * Return value: %TRUE if multiple files can be selected.
342  *
343  * Since: 2.4
344  **/
345 gboolean
346 gtk_file_chooser_get_select_multiple (GtkFileChooser *chooser)
347 {
348   gboolean select_multiple;
349   
350   g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), FALSE);
351
352   g_object_get (chooser, "select-multiple", &select_multiple, NULL);
353
354   return select_multiple;
355 }
356
357 /**
358  * gtk_file_chooser_get_filename:
359  * @chooser: a #GtkFileChooser
360  * 
361  * Gets the filename for the currently selected file in
362  * the file selector. If multiple files are selected,
363  * one of the filenames will be returned at random.
364  * 
365  * Return value: The currently selected filename, or %NULL
366  *  if no file is selected, or the selected file can't
367  *  be represented with a local filename. Free with g_free().
368  *
369  * Since: 2.4
370  **/
371 gchar *
372 gtk_file_chooser_get_filename (GtkFileChooser *chooser)
373 {
374   GtkFileSystem *file_system;
375   GtkFilePath *path;
376   gchar *result = NULL;
377   
378   g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
379
380   file_system = _gtk_file_chooser_get_file_system (chooser);
381   path = gtk_file_chooser_get_path (chooser);
382   if (path)
383     {
384       result = gtk_file_system_path_to_filename (file_system, path);
385       gtk_file_path_free (path);
386     }
387
388   return result;
389 }
390
391 /**
392  * gtk_file_chooser_set_filename:
393  * @chooser: a #GtkFileChooser
394  * @filename: the filename to set as current
395  * 
396  * Sets @filename as the current filename for the the file chooser;
397  * If the file name isn't in the current folder of @chooser, then the
398  * current folder of @chooser will be changed to the folder containing
399  * @filename. This is equivalent to a sequence of
400  * gtk_file_chooser_unselect_all() followed by gtk_file_chooser_select_filename().
401  *
402  * Note that the file must exist, or nothing will be done except
403  * for the directory change. To pre-enter a filename for the user, as in
404  * a save-as dialog, use gtk_file_chooser_set_current_name()
405  *
406  * Since: 2.4
407  **/
408 void
409 gtk_file_chooser_set_filename (GtkFileChooser *chooser,
410                                const gchar    *filename)
411 {
412   g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
413
414   gtk_file_chooser_unselect_all (chooser);
415   gtk_file_chooser_select_filename (chooser, filename);
416 }
417
418 /**
419  * gtk_file_chooser_select_filename:
420  * @chooser: a #GtkFileChooser
421  * @filename: the filename to select
422  * 
423  * Selects a filename. If the file name isn't in the current
424  * folder of @chooser, then the current folder of @chooser will
425  * be changed to the folder containing @filename.
426  *
427  * Since: 2.4
428  **/
429 void
430 gtk_file_chooser_select_filename (GtkFileChooser *chooser,
431                                   const gchar    *filename)
432 {
433   GtkFileSystem *file_system;
434   GtkFilePath *path;
435   
436   g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
437   g_return_if_fail (filename != NULL);
438
439   file_system = _gtk_file_chooser_get_file_system (chooser);
440
441   path = gtk_file_system_filename_to_path (file_system, filename);
442   if (path)
443     {
444       _gtk_file_chooser_select_path (chooser, path);
445       gtk_file_path_free (path);
446     }
447 }
448
449 /**
450  * gtk_file_chooser_unselect_filename:
451  * @chooser: a #GtkFileChooser
452  * @filename: the filename to unselect
453  * 
454  * Unselects a currently selected filename. If the filename
455  * is not in the current directory, does not exist, or
456  * is otherwise not currently selected, does nothing.
457  *
458  * Since: 2.4
459  **/
460 void
461 gtk_file_chooser_unselect_filename (GtkFileChooser *chooser,
462                                     const char     *filename)
463 {
464   GtkFileSystem *file_system;
465   GtkFilePath *path;
466   
467   g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
468   g_return_if_fail (filename != NULL);
469
470   file_system = _gtk_file_chooser_get_file_system (chooser);
471
472   path = gtk_file_system_filename_to_path (file_system, filename);
473   if (path)
474     {
475       _gtk_file_chooser_unselect_path (chooser, path);
476       gtk_file_path_free (path);
477     }
478 }
479
480 /* Converts a list of GtkFilePath* to a list of strings using the specified function */
481 static GSList *
482 file_paths_to_strings (GtkFileSystem *fs,
483                        GSList        *paths,
484                        gchar *      (*convert_func) (GtkFileSystem *fs, const GtkFilePath *path))
485 {
486   GSList *strings;
487
488   strings = NULL;
489
490   for (; paths; paths = paths->next)
491     {
492       GtkFilePath *path;
493       gchar *string;
494
495       path = paths->data;
496       string = (* convert_func) (fs, path);
497
498       if (string)
499         strings = g_slist_prepend (strings, string);
500     }
501
502   return g_slist_reverse (strings);
503 }
504
505 /**
506  * gtk_file_chooser_get_filenames:
507  * @chooser: a #GtkFileChooser
508  * 
509  * Lists all the selected files and subfolders in the current folder of
510  * @chooser. The returned names are full absolute paths. If files in the current
511  * folder cannot be represented as local filenames they will be ignored. (See
512  * gtk_file_chooser_get_uris())
513  * 
514  * Return value: a #GSList containing the filenames of all selected
515  *   files and subfolders in the current folder. Free the returned list
516  *   with g_slist_free(), and the filenames with g_free().
517  *
518  * Since: 2.4
519  **/
520 GSList *
521 gtk_file_chooser_get_filenames (GtkFileChooser *chooser)
522 {
523   GtkFileSystem *file_system;
524   GSList *paths;
525   GSList *result;
526   
527   g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
528
529   file_system = _gtk_file_chooser_get_file_system (chooser);
530   paths = _gtk_file_chooser_get_paths (chooser);
531
532   result = file_paths_to_strings (file_system, paths, gtk_file_system_path_to_filename);
533   gtk_file_paths_free (paths);
534   return result;
535 }
536
537 /**
538  * gtk_file_chooser_set_current_folder:
539  * @chooser: a #GtkFileChooser
540  * @filename: the full path of the new current folder
541  * 
542  * Sets the current folder for @chooser from a local filename.
543  * The user will be shown the full contents of the current folder,
544  * plus user interface elements for navigating to other folders.
545  *
546  * Since: 2.4
547  **/
548 void
549 gtk_file_chooser_set_current_folder (GtkFileChooser *chooser,
550                                      const gchar    *filename)
551 {
552   GtkFileSystem *file_system;
553   GtkFilePath *path;
554   
555   g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
556   g_return_if_fail (filename != NULL);
557
558   file_system = _gtk_file_chooser_get_file_system (chooser);
559
560   path = gtk_file_system_filename_to_path (file_system, filename);
561   if (path)
562     {
563       _gtk_file_chooser_set_current_folder_path (chooser, path);
564       gtk_file_path_free (path);
565     }
566 }
567
568 /**
569  * gtk_file_chooser_get_current_folder:
570  * @chooser: a #GtkFileChooser
571  * 
572  * Gets the current folder of @chooser as a local filename.
573  * See gtk_file_chooser_set_current_folder().
574  * 
575  * Return value: the full path of the current folder, or %NULL
576  *  if the current path cannot be represented as a local filename.
577  *  Free with g_free().
578  *
579  * Since: 2.4
580  **/
581 gchar *
582 gtk_file_chooser_get_current_folder (GtkFileChooser *chooser)
583 {
584   GtkFileSystem *file_system;
585   GtkFilePath *path;
586   gchar *filename;
587   
588   g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
589
590   file_system = _gtk_file_chooser_get_file_system (chooser);
591
592   path = _gtk_file_chooser_get_current_folder_path (chooser);
593   filename = gtk_file_system_path_to_filename (file_system, path);
594   gtk_file_path_free (path);
595
596   return filename;
597 }
598
599 /**
600  * gtk_file_chooser_set_current_name:
601  * @chooser: a #GtkFileChooser
602  * @name: the filename to use, as a UTF-8 string
603  * 
604  * Sets the current name in the file selector, as if entered
605  * by the user. Note that the name passed in here is a UTF-8
606  * string rather than a filename. This function is meant for
607  * such uses as a suggested name in a "Save As..." dialog.
608  *
609  * If you want to preselect a particular existing file, you
610  * should use gtk_file_chooser_set_filename() instead.
611  *
612  * Since: 2.4
613  **/
614 void
615 gtk_file_chooser_set_current_name  (GtkFileChooser *chooser,
616                                     const gchar    *name)
617 {
618   g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
619   g_return_if_fail (name != NULL);
620   
621   GTK_FILE_CHOOSER_GET_IFACE (chooser)->set_current_name (chooser, name);
622 }
623
624 /**
625  * gtk_file_chooser_get_uri:
626  * @chooser: a #GtkFileChooser
627  * 
628  * Gets the URI for the currently selected file in
629  * the file selector. If multiple files are selected,
630  * one of the filenames will be returned at random.
631  * 
632  * Return value: The currently selected URI, or %NULL
633  *  if no file is selected. Free with g_free()
634  *
635  * Since: 2.4
636  **/
637 gchar *
638 gtk_file_chooser_get_uri (GtkFileChooser *chooser)
639 {
640   GtkFileSystem *file_system;
641   GtkFilePath *path;
642   gchar *result = NULL;
643   
644   g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
645
646   file_system = _gtk_file_chooser_get_file_system (chooser);
647   path = gtk_file_chooser_get_path (chooser);
648   if (path)
649     {
650       result = gtk_file_system_path_to_uri (file_system, path);
651       gtk_file_path_free (path);
652     }
653
654   return result;
655 }
656
657 /**
658  * gtk_file_chooser_set_uri:
659  * @chooser: a #GtkFileChooser
660  * @uri: the URI to set as current
661  * 
662  * Sets the file referred to by @uri as the current file for the the
663  * file chooser; If the file name isn't in the current folder of @chooser,
664  * then the current folder of @chooser will be changed to the folder containing
665  * @uri. This is equivalent to a sequence of gtk_file_chooser_unselect_all()
666  * followed by gtk_file_chooser_select_uri().
667  *
668  * Note that the file must exist, or nothing will be done except
669  * for the directory change. To pre-enter a filename for the user, as in
670  * a save-as dialog, use gtk_file_chooser_set_current_name()
671  *
672  * Since: 2.4
673  **/
674 void
675 gtk_file_chooser_set_uri (GtkFileChooser *chooser,
676                           const char     *uri)
677 {
678   g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
679
680   gtk_file_chooser_unselect_all (chooser);
681   gtk_file_chooser_select_uri (chooser, uri);
682 }
683
684 /**
685  * gtk_file_chooser_select_uri:
686  * @chooser: a #GtkFileChooser
687  * @uri: the URI to select
688  * 
689  * Selects the file to by @uri. If the URI doesn't refer to a
690  * file in the current folder of @chooser, then the current folder of
691  * @chooser will be changed to the folder containing @filename.
692  *
693  * Since: 2.4
694  **/
695 void
696 gtk_file_chooser_select_uri (GtkFileChooser *chooser,
697                              const char     *uri)
698 {
699   GtkFileSystem *file_system;
700   GtkFilePath *path;
701   
702   g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
703   g_return_if_fail (uri != NULL);
704
705   file_system = _gtk_file_chooser_get_file_system (chooser);
706
707   path = gtk_file_system_uri_to_path (file_system, uri);
708   if (path)
709     {
710       _gtk_file_chooser_select_path (chooser, path);
711       gtk_file_path_free (path);
712     }
713 }
714
715 /**
716  * gtk_file_chooser_unselect_uri:
717  * @chooser: a #GtkFileChooser
718  * @uri: the URI to unselect
719  * 
720  * Unselects the file referred to by @uri. If the file
721  * is not in the current directory, does not exist, or
722  * is otherwise not currently selected, does nothing.
723  *
724  * Since: 2.4
725  **/
726 void
727 gtk_file_chooser_unselect_uri (GtkFileChooser *chooser,
728                                const char     *uri)
729 {
730   GtkFileSystem *file_system;
731   GtkFilePath *path;
732   
733   g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
734   g_return_if_fail (uri != NULL);
735
736   file_system = _gtk_file_chooser_get_file_system (chooser);
737
738   path = gtk_file_system_uri_to_path (file_system, uri);
739   if (path)
740     {
741       _gtk_file_chooser_unselect_path (chooser, path);
742       gtk_file_path_free (path);
743     }
744 }
745
746 /**
747  * gtk_file_chooser_select_all:
748  * @chooser: a #GtkFileChooser
749  * 
750  * Selects all the files in the current folder of a file chooser.
751  **/
752 void
753 gtk_file_chooser_select_all (GtkFileChooser *chooser)
754 {
755   g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
756   
757   GTK_FILE_CHOOSER_GET_IFACE (chooser)->select_all (chooser);
758 }
759
760 /**
761  * gtk_file_chooser_unselect_all:
762  * @chooser: a #GtkFileChooser
763  * 
764  * Unselects all the files in the current folder of a file chooser.
765  **/
766 void
767 gtk_file_chooser_unselect_all (GtkFileChooser *chooser)
768 {
769
770   g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
771   
772   GTK_FILE_CHOOSER_GET_IFACE (chooser)->unselect_all (chooser);
773 }
774
775 /**
776  * gtk_file_chooser_get_uris:
777  * @chooser: a #GtkFileChooser
778  * 
779  * Lists all the selected files and subfolders in the current folder of
780  * @chooser. The returned names are full absolute URIs.
781  * 
782  * Return value: a #GSList containing the URIs of all selected
783  *   files and subfolders in the current folder. Free the returned list
784  *   with g_slist_free(), and the filenames with g_free().
785  *
786  * Since: 2.4
787  **/
788 GSList *
789 gtk_file_chooser_get_uris (GtkFileChooser *chooser)
790 {
791   GtkFileSystem *file_system;
792   GSList *paths;
793   GSList *result;
794   
795   g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
796
797   file_system = _gtk_file_chooser_get_file_system (chooser);
798   paths = _gtk_file_chooser_get_paths (chooser);
799
800   result = file_paths_to_strings (file_system, paths, gtk_file_system_path_to_uri);
801   gtk_file_paths_free (paths);
802   return result;
803 }
804
805 /**
806  * gtk_file_chooser_set_current_folder_uri:
807  * @chooser: a #GtkFileChooser
808  * @uri: the URI for the new current folder
809  * 
810  * Sets the current folder for @chooser from an URI.
811  * The user will be shown the full contents of the current folder,
812  * plus user interface elements for navigating to other folders.
813  *
814  * Since: 2.4
815  **/
816 void
817 gtk_file_chooser_set_current_folder_uri (GtkFileChooser *chooser,
818                                          const gchar    *uri)
819 {
820   GtkFileSystem *file_system;
821   GtkFilePath *path;
822   
823   g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
824   g_return_if_fail (uri != NULL);
825
826   file_system = _gtk_file_chooser_get_file_system (chooser);
827
828   path = gtk_file_system_uri_to_path (file_system, uri);
829   if (path)
830     {
831       _gtk_file_chooser_set_current_folder_path (chooser, path);
832       gtk_file_path_free (path);
833     }
834 }
835
836 /**
837  * gtk_file_chooser_get_current_folder_uri:
838  * @chooser: a #GtkFileChooser
839  * 
840  * Gets the current folder of @chooser as an URI.
841  * See gtk_file_chooser_set_current_folder_uri().
842  * 
843  * Return value: the URI for the current folder.
844  *  Free with g_free().
845  *
846  * Since: 2.4
847  */
848 gchar *
849 gtk_file_chooser_get_current_folder_uri (GtkFileChooser *chooser)
850 {
851   GtkFileSystem *file_system;
852   GtkFilePath *path;
853   gchar *uri;
854   
855   g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
856
857   file_system = _gtk_file_chooser_get_file_system (chooser);
858
859   path = _gtk_file_chooser_get_current_folder_path (chooser);
860   uri = gtk_file_system_path_to_uri (file_system, path);
861   gtk_file_path_free (path);
862
863   return uri;
864 }
865
866 /**
867  * _gtk_file_chooser_set_current_folder_path:
868  * @chooser: a #GtkFileChooser
869  * @path: the #GtkFilePath for the new folder
870  * 
871  * Sets the current folder for @chooser from a #GtkFilePath.
872  * Internal function, see gtk_file_chooser_set_current_folder_uri().
873  *
874  * Since: 2.4
875  **/
876 void
877 _gtk_file_chooser_set_current_folder_path (GtkFileChooser    *chooser,
878                                            const GtkFilePath *path)
879 {
880   g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
881   g_return_if_fail (path != NULL);
882
883   GTK_FILE_CHOOSER_GET_IFACE (chooser)->set_current_folder (chooser, path);
884 }
885
886 /**
887  * _gtk_file_chooser_get_current_folder_path:
888  * @chooser: a #GtkFileChooser
889  * 
890  * Gets the current folder of @chooser as #GtkFilePath.
891  * See gtk_file_chooser_get_current_folder_uri().
892  * 
893  * Return value: the #GtkFilePath for the current folder.
894  * Free with gtk_file_path_free().
895  *
896  * Since: 2.4
897  */
898 GtkFilePath *
899 _gtk_file_chooser_get_current_folder_path (GtkFileChooser *chooser)
900 {
901   g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
902
903   return GTK_FILE_CHOOSER_GET_IFACE (chooser)->get_current_folder (chooser);  
904 }
905
906 /**
907  * _gtk_file_chooser_select_path:
908  * @chooser: a #GtkFileChooser
909  * @path: the path to select
910  * 
911  * Selects the file referred to by @path. An internal function. See
912  * _gtk_file_chooser_select_uri().
913  *
914  * Since: 2.4
915  **/
916 void
917 _gtk_file_chooser_select_path (GtkFileChooser    *chooser,
918                                const GtkFilePath *path)
919 {
920   g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
921
922   GTK_FILE_CHOOSER_GET_IFACE (chooser)->select_path (chooser, path);
923 }
924
925 /**
926  * _gtk_file_chooser_unselect_path:
927  * @chooser: a #GtkFileChooser
928  * @path: the filename to path
929  * 
930  * Unselects the file referred to by @path. An internal
931  * function. See _gtk_file_chooser_unselect_uri().
932  *
933  * Since: 2.4
934  **/
935 void
936 _gtk_file_chooser_unselect_path (GtkFileChooser    *chooser,
937                                  const GtkFilePath *path)
938 {
939   g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
940
941   GTK_FILE_CHOOSER_GET_IFACE (chooser)->unselect_path (chooser, path);
942 }
943
944 /**
945  * _gtk_file_chooser_get_paths:
946  * @chooser: a #GtkFileChooser
947  * 
948  * Lists all the selected files and subfolders in the current folder of @chooser
949  * as #GtkFilePath. An internal function, see gtk_file_chooser_get_uris().
950  * 
951  * Return value: a #GSList containing a #GtkFilePath for each selected
952  *   file and subfolder in the current folder.  Free the returned list
953  *   with g_slist_free(), and the paths with gtk_file_path_free().
954  *
955  * Since: 2.4
956  **/
957 GSList *
958 _gtk_file_chooser_get_paths (GtkFileChooser *chooser)
959 {
960   g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
961
962   return GTK_FILE_CHOOSER_GET_IFACE (chooser)->get_paths (chooser);
963 }
964
965 static GtkFilePath *
966 gtk_file_chooser_get_path (GtkFileChooser *chooser)
967 {
968   GSList *list;
969   GtkFilePath *result = NULL;
970   
971   g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
972
973   list = _gtk_file_chooser_get_paths (chooser);
974   if (list)
975     {
976       result = list->data;
977       list = g_slist_delete_link (list, list);
978       gtk_file_paths_free (list);
979     }
980
981   return result;
982 }
983
984 /**
985  * _gtk_file_chooser_get_file_system:
986  * @chooser: a #GtkFileChooser
987  * 
988  * Gets the #GtkFileSystem of @chooser; this is an internal
989  * implementation detail, used for conversion between paths
990  * and filenames and URIs.
991  * 
992  * Return value: the file system for @chooser.
993  *
994  * Since: 2.4
995  **/
996 GtkFileSystem *
997 _gtk_file_chooser_get_file_system (GtkFileChooser *chooser)
998 {
999   g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
1000
1001   return GTK_FILE_CHOOSER_GET_IFACE (chooser)->get_file_system (chooser);
1002 }
1003
1004 /* Preview widget
1005  */
1006 /**
1007  * gtk_file_chooser_set_preview_widget:
1008  * @chooser: a #GtkFileChooser
1009  * @preview_widget: widget for displaying preview.
1010  *
1011  * Sets an application-supplied widget to use to display a custom preview
1012  * of the currently selected file. To implement a preview, after setting the
1013  * preview widget, you connect to the ::selection-changed
1014  * signal, and call gtk_file_chooser_get_preview_filename() or
1015  * gtk_file_chooser_get_preview_uri() on each change. If you can
1016  * display a preview of the new file, update your widget and
1017  * set the preview active using gtk_file_chooser_set_preview_widget_active().
1018  * Otherwise, set the preview inactive.
1019  *
1020  * When there is no application-supplied preview widget, or the
1021  * application-supplied preview widget is not active, the file chooser
1022  * may display an internally generated preview of the current file or
1023  * it may display no preview at all.
1024  *
1025  * Since: 2.4
1026  **/
1027 void
1028 gtk_file_chooser_set_preview_widget (GtkFileChooser *chooser,
1029                                      GtkWidget      *preview_widget)
1030 {
1031   g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
1032
1033   g_object_set (chooser, "preview-widget", preview_widget, NULL);
1034 }
1035
1036 /**
1037  * gtk_file_chooser_get_preview_widget:
1038  * @chooser: a #GtkFileChooser
1039  * 
1040  * Gets the current preview widget; see
1041  * gtk_file_chooser_set_preview_widget().
1042  * 
1043  * Return value: the current preview widget, or %NULL
1044  *
1045  * Since: 2.4
1046  **/
1047 GtkWidget *
1048 gtk_file_chooser_get_preview_widget (GtkFileChooser *chooser)
1049 {
1050   GtkWidget *preview_widget;
1051   
1052   g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
1053
1054   g_object_get (chooser, "preview-widget", &preview_widget, NULL);
1055   
1056   /* Horrid hack; g_object_get() refs returned objects but
1057    * that contradicts the memory management conventions
1058    * for accessors.
1059    */
1060   if (preview_widget)
1061     g_object_unref (preview_widget);
1062
1063   return preview_widget;
1064 }
1065
1066 /**
1067  * gtk_file_chooser_set_preview_widget_active:
1068  * @chooser: a #GtkFileChooser
1069  * @active: whether to display the user-specified preview widget
1070  * 
1071  * Sets whether the preview widget set by
1072  * gtk_file_chooser_set_preview_widget_active() should be shown for the
1073  * current filename. When @active is set to false, the file chooser
1074  * may display an internally generated preview of the current file
1075  * or it may display no preview at all. See
1076  * gtk_file_chooser_set_preview_widget() for more details.
1077  *
1078  * Since: 2.4
1079  **/
1080 void
1081 gtk_file_chooser_set_preview_widget_active (GtkFileChooser *chooser,
1082                                             gboolean        active)
1083 {
1084   g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
1085   
1086   g_object_set (chooser, "preview-widget-active", active, NULL);
1087 }
1088
1089 /**
1090  * gtk_file_chooser_get_preview_widget_active:
1091  * @chooser: a #GtkFileChooser
1092  * 
1093  * Gets whether the preview widget set by
1094  * gtk_file_chooser_set_preview_widget_active() should be shown for the
1095  * current filename. See gtk_file_chooser_set_preview_widget_active().
1096  * 
1097  * Return value: %TRUE if the preview widget is active for the
1098  *  current filename.
1099  *
1100  * Since: 2.4
1101  **/
1102 gboolean
1103 gtk_file_chooser_get_preview_widget_active (GtkFileChooser *chooser)
1104 {
1105   gboolean active;
1106   
1107   g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), FALSE);
1108
1109   g_object_get (chooser, "preview-widget-active", &active, NULL);
1110
1111   return active;
1112 }
1113
1114 /**
1115  * gtk_file_chooser_get_preview_filename:
1116  * @chooser: a #GtkFileChooser
1117  * 
1118  * Gets the filename that should be previewed in a custom preview
1119  * Internal function, see gtk_file_chooser_get_preview_uri().
1120  * 
1121  * Return value: the #GtkFilePath for the file to preview, or %NULL if no file
1122  *  is selected. Free with gtk_file_path_free().
1123  *
1124  * Since: 2.4
1125  **/
1126 GtkFilePath *
1127 _gtk_file_chooser_get_preview_path (GtkFileChooser *chooser)
1128 {
1129   g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
1130
1131   return GTK_FILE_CHOOSER_GET_IFACE (chooser)->get_preview_path (chooser);
1132 }
1133
1134 /**
1135  * _gtk_file_chooser_add_shortcut_folder:
1136  * @chooser: a #GtkFileChooser
1137  * @path: path of the folder to add
1138  * @error: location to store error, or %NULL
1139  * 
1140  * Adds a folder to be displayed with the shortcut folders in a file chooser.
1141  * Internal function, see gtk_file_chooser_add_shortcut_folder().
1142  * 
1143  * Return value: %TRUE if the folder could be added successfully, %FALSE
1144  * otherwise.
1145  *
1146  * Since: 2.4
1147  **/
1148 gboolean
1149 _gtk_file_chooser_add_shortcut_folder (GtkFileChooser    *chooser,
1150                                        const GtkFilePath *path,
1151                                        GError           **error)
1152 {
1153   g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), FALSE);
1154   g_return_val_if_fail (path != NULL, FALSE);
1155
1156   return GTK_FILE_CHOOSER_GET_IFACE (chooser)->add_shortcut_folder (chooser, path, error);
1157 }
1158
1159 /**
1160  * _gtk_file_chooser_remove_shortcut_folder:
1161  * @chooser: a #GtkFileChooser
1162  * @path: path of the folder to remove
1163  * @error: location to store error, or %NULL
1164  * 
1165  * Removes a folder from the shortcut folders in a file chooser.  Internal
1166  * function, see gtk_file_chooser_remove_shortcut_folder().
1167  * 
1168  * Return value: %TRUE if the folder could be removed successfully, %FALSE
1169  * otherwise.
1170  *
1171  * Since: 2.4
1172  **/
1173 gboolean
1174 _gtk_file_chooser_remove_shortcut_folder (GtkFileChooser    *chooser,
1175                                           const GtkFilePath *path,
1176                                           GError           **error)
1177 {
1178   g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), FALSE);
1179   g_return_val_if_fail (path != NULL, FALSE);
1180
1181   return GTK_FILE_CHOOSER_GET_IFACE (chooser)->remove_shortcut_folder (chooser, path, error);
1182 }
1183
1184 /**
1185  * gtk_file_chooser_get_preview_filename:
1186  * @chooser: a #GtkFileChooser
1187  * 
1188  * Gets the filename that should be previewed in a custom preview
1189  * widget. See gtk_file_chooser_set_preview_widget().
1190  * 
1191  * Return value: the filename to preview, or %NULL if no file
1192  *  is selected, or if the selected file cannot be represented
1193  *  as a local filename. Free with g_free()
1194  *
1195  * Since: 2.4
1196  **/
1197 char *
1198 gtk_file_chooser_get_preview_filename (GtkFileChooser *chooser)
1199 {
1200   GtkFileSystem *file_system;
1201   GtkFilePath *path;
1202   gchar *result = NULL;
1203   
1204   g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
1205
1206   file_system = _gtk_file_chooser_get_file_system (chooser);
1207   path = _gtk_file_chooser_get_preview_path (chooser);
1208   if (path)
1209     {
1210       result = gtk_file_system_path_to_filename (file_system, path);
1211       gtk_file_path_free (path);
1212     }
1213
1214   return result;
1215 }
1216
1217 /**
1218  * gtk_file_chooser_get_preview_uri:
1219  * @chooser: a #GtkFileChooser
1220  * 
1221  * Gets the URI that should be previewed in a custom preview
1222  * widget. See gtk_file_chooser_set_preview_widget().
1223  * 
1224  * Return value: the URI for the file to preview, or %NULL if no file is
1225  * selected. Free with g_free().
1226  *
1227  * Since: 2.4
1228  **/
1229 char *
1230 gtk_file_chooser_get_preview_uri (GtkFileChooser *chooser)
1231 {
1232   GtkFileSystem *file_system;
1233   GtkFilePath *path;
1234   gchar *result = NULL;
1235   
1236   g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
1237
1238   file_system = _gtk_file_chooser_get_file_system (chooser);
1239   path = _gtk_file_chooser_get_preview_path (chooser);
1240   if (path)
1241     {
1242       result = gtk_file_system_path_to_uri (file_system, path);
1243       gtk_file_path_free (path);
1244     }
1245
1246   return result;
1247 }
1248
1249 /**
1250  * gtk_file_chooser_set_extra_widget:
1251  * @chooser: a #GtkFileChooser
1252  * @extra_widget: widget for extra options
1253  * 
1254  * Sets an application-supplied widget to provide extra options to the user.
1255  *
1256  * Since: 2.4
1257  **/
1258 void
1259 gtk_file_chooser_set_extra_widget (GtkFileChooser *chooser,
1260                                    GtkWidget      *extra_widget)
1261 {
1262   g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
1263
1264   g_object_set (chooser, "extra-widget", extra_widget, NULL);
1265 }
1266
1267 /**
1268  * gtk_file_chooser_get_extra_widget:
1269  * @chooser: a #GtkFileChooser
1270  * 
1271  * Gets the current preview widget; see
1272  * gtk_file_chooser_set_extra_widget().
1273  * 
1274  * Return value: the current extra widget, or %NULL
1275  *
1276  * Since: 2.4
1277  **/
1278 GtkWidget *
1279 gtk_file_chooser_get_extra_widget (GtkFileChooser *chooser)
1280 {
1281   GtkWidget *extra_widget;
1282   
1283   g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
1284
1285   g_object_get (chooser, "extra-widget", &extra_widget, NULL);
1286   
1287   /* Horrid hack; g_object_get() refs returned objects but
1288    * that contradicts the memory management conventions
1289    * for accessors.
1290    */
1291   if (extra_widget)
1292     g_object_unref (extra_widget);
1293
1294   return extra_widget;
1295 }
1296
1297 /**
1298  * gtk_file_chooser_add_filter:
1299  * @chooser: a #GtkFileChooser
1300  * @filter: a #GtkFileFilter
1301  * 
1302  * Adds @filter to the list of filters that the user can select between.
1303  * When a filter is selected, only files that are passed by that
1304  * filter are displayed.
1305  *
1306  * Since: 2.4
1307  **/
1308 void
1309 gtk_file_chooser_add_filter (GtkFileChooser *chooser,
1310                              GtkFileFilter  *filter)
1311 {
1312   g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
1313
1314   GTK_FILE_CHOOSER_GET_IFACE (chooser)->add_filter (chooser, filter);
1315 }
1316
1317 /**
1318  * gtk_file_chooser_remove_filter:
1319  * @chooser: a #GtkFileChooser
1320  * @filter: a #GtkFileFilter
1321  * 
1322  * Removes @filter from the list of filters that the user can select between.
1323  *
1324  * Since: 2.4
1325  **/
1326 void
1327 gtk_file_chooser_remove_filter (GtkFileChooser *chooser,
1328                                 GtkFileFilter  *filter)
1329 {
1330   g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
1331
1332   GTK_FILE_CHOOSER_GET_IFACE (chooser)->remove_filter (chooser, filter);
1333 }
1334
1335 /**
1336  * gtk_file_chooser_list_filters:
1337  * @choooser: a #GtkFileChooser
1338  * 
1339  * Lists the current set of user-selectable filters; see
1340  * gtk_file_chooser_add_filter(), gtk_file_chooser_remove_filter().
1341  * 
1342  * Return value: a #GSList containing the current set of
1343  *  user selectable filters. The contents of the list are
1344  *  owned by GTK+, but you must free the list itself with
1345  *  g_slist_free() when you are done with it.
1346  *
1347  * Since: 2.4
1348  **/
1349 GSList *
1350 gtk_file_chooser_list_filters  (GtkFileChooser *chooser)
1351 {
1352   g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
1353
1354   return GTK_FILE_CHOOSER_GET_IFACE (chooser)->list_filters (chooser);
1355 }
1356
1357 /**
1358  * gtk_file_chooser_set_filter:
1359  * @chooser: a #GtkFileChooser
1360  * @filter: a #GtkFileFilter
1361  * 
1362  * Sets the current filter; only the files that pass the
1363  * filter will be displayed. If the user-selectable list of filters
1364  * is non-empty, then the filter should be one of the filters
1365  * in that list. Setting the current filter when the list of
1366  * filters is empty is useful if you want to restrict the displayed
1367  * set of files without letting the user change it.
1368  *
1369  * Since: 2.4
1370  **/
1371 void
1372 gtk_file_chooser_set_filter (GtkFileChooser *chooser,
1373                              GtkFileFilter  *filter)
1374 {
1375   g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
1376   g_return_if_fail (GTK_IS_FILE_FILTER (filter));
1377
1378   g_object_set (chooser, "filter", filter, NULL);
1379 }
1380
1381 /**
1382  * gtk_file_chooser_get_filter:
1383  * @chooser: a #GtkFileChooser
1384  * 
1385  * Gets the current filter; see gtk_file_chooser_set_filter().
1386  * 
1387  * Return value: the current filter, or %NULL
1388  *
1389  * Since: 2.4
1390  **/
1391 GtkFileFilter *
1392 gtk_file_chooser_get_filter (GtkFileChooser *chooser)
1393 {
1394   GtkFileFilter *filter;
1395   
1396   g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
1397
1398   g_object_get (chooser, "filter", &filter, NULL);
1399   /* Horrid hack; g_object_get() refs returned objects but
1400    * that contradicts the memory management conventions
1401    * for accessors.
1402    */
1403   if (filter)
1404     g_object_unref (filter);
1405
1406   return filter;
1407 }
1408
1409 /**
1410  * gtk_file_chooser_add_shortcut_folder:
1411  * @chooser: a #GtkFileChooser
1412  * @folder: filename of the folder to add
1413  * @error: location to store error, or %NULL
1414  * 
1415  * Adds a folder to be displayed with the shortcut folders in a file chooser.
1416  * Note that shortcut folders do not get saved, as they are provided by the
1417  * application.  For example, you can use this to add a
1418  * "/usr/share/mydrawprogram/Clipart" folder to the volume list.
1419  * 
1420  * Return value: %TRUE if the folder could be added successfully, %FALSE
1421  * otherwise.  In the latter case, the @error will be set as appropriate.
1422  *
1423  * Since: 2.4
1424  **/
1425 gboolean
1426 gtk_file_chooser_add_shortcut_folder (GtkFileChooser    *chooser,
1427                                       const char        *folder,
1428                                       GError           **error)
1429 {
1430   GtkFilePath *path;
1431   gboolean result;
1432
1433   g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), FALSE);
1434   g_return_val_if_fail (folder != NULL, FALSE);
1435
1436   path = gtk_file_system_filename_to_path (_gtk_file_chooser_get_file_system (chooser), folder);
1437   if (!path)
1438     {
1439       g_set_error (error,
1440                    GTK_FILE_CHOOSER_ERROR,
1441                    GTK_FILE_CHOOSER_ERROR_BAD_FILENAME,
1442                    _("Invalid filename: %s"),
1443                    folder);
1444       return FALSE;
1445     }
1446
1447   result = GTK_FILE_CHOOSER_GET_IFACE (chooser)->add_shortcut_folder (chooser, path, error);
1448
1449   gtk_file_path_free (path);
1450
1451   return result;
1452 }
1453
1454 /**
1455  * gtk_file_chooser_remove_shortcut_folder:
1456  * @chooser: a #GtkFileChooser
1457  * @folder: filename of the folder to remove
1458  * @error: location to store error, or %NULL
1459  * 
1460  * Removes a folder from a file chooser's list of shortcut folders.
1461  * 
1462  * Return value: %TRUE if the operation succeeds, %FALSE otherwise.  
1463  * In the latter case, the @error will be set as appropriate.
1464  *
1465  * See also: gtk_file_chooser_add_shortcut_folder()
1466  *
1467  * Since: 2.4
1468  **/
1469 gboolean
1470 gtk_file_chooser_remove_shortcut_folder (GtkFileChooser    *chooser,
1471                                          const char        *folder,
1472                                          GError           **error)
1473 {
1474   GtkFilePath *path;
1475   gboolean result;
1476
1477   g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), FALSE);
1478   g_return_val_if_fail (folder != NULL, FALSE);
1479
1480   path = gtk_file_system_filename_to_path (_gtk_file_chooser_get_file_system (chooser), folder);
1481   if (!path)
1482     {
1483       g_set_error (error,
1484                    GTK_FILE_CHOOSER_ERROR,
1485                    GTK_FILE_CHOOSER_ERROR_BAD_FILENAME,
1486                    _("Invalid filename: %s"),
1487                    folder);
1488       return FALSE;
1489     }
1490
1491   result = GTK_FILE_CHOOSER_GET_IFACE (chooser)->remove_shortcut_folder (chooser, path, error);
1492
1493   gtk_file_path_free (path);
1494
1495   return result;
1496 }
1497
1498 /**
1499  * gtk_file_chooser_list_shortcut_folders:
1500  * @chooser: a #GtkFileChooser
1501  * 
1502  * Queries the list of shortcut folders in the file chooser, as set by
1503  * gtk_file_chooser_set_shortcut_folders().
1504  * 
1505  * Return value: A list of folder filenames, or %NULL if there are no shortcut
1506  * folders.  Free the returned list with g_slist_free(), and the filenames with
1507  * g_free().
1508  *
1509  * Since: 2.4
1510  **/
1511 GSList *
1512 gtk_file_chooser_list_shortcut_folders (GtkFileChooser *chooser)
1513 {
1514   GSList *folders;
1515   GSList *result;
1516
1517   g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
1518
1519   folders = GTK_FILE_CHOOSER_GET_IFACE (chooser)->list_shortcut_folders (chooser);
1520
1521   result = file_paths_to_strings (_gtk_file_chooser_get_file_system (chooser),
1522                                   folders,
1523                                   gtk_file_system_path_to_filename);
1524   gtk_file_paths_free (folders);
1525   return result;
1526 }
1527
1528 /**
1529  * gtk_file_chooser_add_shortcut_folder_uri:
1530  * @chooser: a #GtkFileChooser
1531  * @folder: URI of the folder to add
1532  * @error: location to store error, or %NULL
1533  * 
1534  * Adds a folder URI to be displayed with the shortcut folders in a file
1535  * chooser.  Note that shortcut folders do not get saved, as they are provided
1536  * by the application.  For example, you can use this to add a
1537  * "file:///usr/share/mydrawprogram/Clipart" folder to the volume list.
1538  * 
1539  * Return value: %TRUE if the folder could be added successfully, %FALSE
1540  * otherwise.  In the latter case, the @error will be set as appropriate.
1541  *
1542  * Since: 2.4
1543  **/
1544 gboolean
1545 gtk_file_chooser_add_shortcut_folder_uri (GtkFileChooser    *chooser,
1546                                           const char        *uri,
1547                                           GError           **error)
1548 {
1549   GtkFilePath *path;
1550   gboolean result;
1551
1552   g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), FALSE);
1553   g_return_val_if_fail (uri != NULL, FALSE);
1554
1555   path = gtk_file_system_uri_to_path (_gtk_file_chooser_get_file_system (chooser), uri);
1556   if (!path)
1557     {
1558       g_set_error (error,
1559                    GTK_FILE_CHOOSER_ERROR,
1560                    GTK_FILE_CHOOSER_ERROR_BAD_FILENAME,
1561                    _("Invalid filename: %s"),
1562                    uri);
1563       return FALSE;
1564     }
1565
1566   result = GTK_FILE_CHOOSER_GET_IFACE (chooser)->add_shortcut_folder (chooser, path, error);
1567
1568   gtk_file_path_free (path);
1569
1570   return result;
1571 }
1572
1573 /**
1574  * gtk_file_chooser_remove_shortcut_folder_uri:
1575  * @chooser: a #GtkFileChooser
1576  * @uri: URI of the folder to remove
1577  * @error: location to store error, or %NULL
1578  * 
1579  * Removes a folder URI from a file chooser's list of shortcut folders.
1580  * 
1581  * Return value: %TRUE if the operation succeeds, %FALSE otherwise.  
1582  * In the latter case, the @error will be set as appropriate.
1583  *
1584  * See also: gtk_file_chooser_add_shortcut_folder_uri()
1585  *
1586  * Since: 2.4
1587  **/
1588 gboolean
1589 gtk_file_chooser_remove_shortcut_folder_uri (GtkFileChooser    *chooser,
1590                                              const char        *uri,
1591                                              GError           **error)
1592 {
1593   GtkFilePath *path;
1594   gboolean result;
1595
1596   g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), FALSE);
1597   g_return_val_if_fail (uri != NULL, FALSE);
1598
1599   path = gtk_file_system_filename_to_path (_gtk_file_chooser_get_file_system (chooser), uri);
1600   if (!path)
1601     {
1602       g_set_error (error,
1603                    GTK_FILE_CHOOSER_ERROR,
1604                    GTK_FILE_CHOOSER_ERROR_BAD_FILENAME,
1605                    _("Invalid filename: %s"),
1606                    uri);
1607       return FALSE;
1608     }
1609
1610   result = GTK_FILE_CHOOSER_GET_IFACE (chooser)->remove_shortcut_folder (chooser, path, error);
1611
1612   gtk_file_path_free (path);
1613
1614   return result;
1615 }
1616
1617 /**
1618  * gtk_file_chooser_list_shortcut_folder_uris:
1619  * @chooser: a #GtkFileChooser
1620  * 
1621  * Queries the list of shortcut folders in the file chooser, as set by
1622  * gtk_file_chooser_set_shortcut_folder_uris().
1623  * 
1624  * Return value: A list of folder URIs, or %NULL if there are no shortcut
1625  * folders.  Free the returned list with g_slist_free(), and the URIs with
1626  * g_free().
1627  *
1628  * Since: 2.4
1629  **/
1630 GSList *
1631 gtk_file_chooser_list_shortcut_folder_uris (GtkFileChooser *chooser)
1632 {
1633   GSList *folders;
1634   GSList *result;
1635
1636   g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), NULL);
1637
1638   folders = GTK_FILE_CHOOSER_GET_IFACE (chooser)->list_shortcut_folders (chooser);
1639
1640   result = file_paths_to_strings (_gtk_file_chooser_get_file_system (chooser),
1641                                   folders,
1642                                   gtk_file_system_path_to_uri);
1643   gtk_file_paths_free (folders);
1644   return result;
1645 }