1 /* GTK - The GIMP Toolkit
2 * gtkfilechooserutils.c: Private utility functions useful for
3 * implementing a GtkFileChooser interface
4 * Copyright (C) 2003, Red Hat, Inc.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
21 #include "gtkfilechooserutils.h"
22 #include "gtkfilechooser.h"
23 #include "gtkfilesystem.h"
24 #include "gtktypebuiltins.h"
28 static gboolean delegate_set_current_folder (GtkFileChooser *chooser,
31 static GFile * delegate_get_current_folder (GtkFileChooser *chooser);
32 static void delegate_set_current_name (GtkFileChooser *chooser,
34 static gboolean delegate_select_file (GtkFileChooser *chooser,
37 static void delegate_unselect_file (GtkFileChooser *chooser,
39 static void delegate_select_all (GtkFileChooser *chooser);
40 static void delegate_unselect_all (GtkFileChooser *chooser);
41 static GSList * delegate_get_files (GtkFileChooser *chooser);
42 static GFile * delegate_get_preview_file (GtkFileChooser *chooser);
43 static GtkFileSystem *delegate_get_file_system (GtkFileChooser *chooser);
44 static void delegate_add_filter (GtkFileChooser *chooser,
45 GtkFileFilter *filter);
46 static void delegate_remove_filter (GtkFileChooser *chooser,
47 GtkFileFilter *filter);
48 static GSList * delegate_list_filters (GtkFileChooser *chooser);
49 static gboolean delegate_add_shortcut_folder (GtkFileChooser *chooser,
52 static gboolean delegate_remove_shortcut_folder (GtkFileChooser *chooser,
55 static GSList * delegate_list_shortcut_folders (GtkFileChooser *chooser);
56 static void delegate_notify (GObject *object,
59 static void delegate_current_folder_changed (GtkFileChooser *chooser,
61 static void delegate_selection_changed (GtkFileChooser *chooser,
63 static void delegate_update_preview (GtkFileChooser *chooser,
65 static void delegate_file_activated (GtkFileChooser *chooser,
68 static GtkFileChooserConfirmation delegate_confirm_overwrite (GtkFileChooser *chooser,
72 * _gtk_file_chooser_install_properties:
73 * @klass: the class structure for a type deriving from #GObject
75 * Installs the necessary properties for a class implementing
76 * #GtkFileChooser. A #GtkParamSpecOverride property is installed
77 * for each property, using the values from the #GtkFileChooserProp
78 * enumeration. The caller must make sure itself that the enumeration
79 * values don't collide with some other property values they
83 _gtk_file_chooser_install_properties (GObjectClass *klass)
85 g_object_class_override_property (klass,
86 GTK_FILE_CHOOSER_PROP_ACTION,
88 g_object_class_override_property (klass,
89 GTK_FILE_CHOOSER_PROP_EXTRA_WIDGET,
91 g_object_class_override_property (klass,
92 GTK_FILE_CHOOSER_PROP_FILTER,
94 g_object_class_override_property (klass,
95 GTK_FILE_CHOOSER_PROP_LOCAL_ONLY,
97 g_object_class_override_property (klass,
98 GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET,
100 g_object_class_override_property (klass,
101 GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET_ACTIVE,
102 "preview-widget-active");
103 g_object_class_override_property (klass,
104 GTK_FILE_CHOOSER_PROP_USE_PREVIEW_LABEL,
105 "use-preview-label");
106 g_object_class_override_property (klass,
107 GTK_FILE_CHOOSER_PROP_SELECT_MULTIPLE,
109 g_object_class_override_property (klass,
110 GTK_FILE_CHOOSER_PROP_SHOW_HIDDEN,
112 g_object_class_override_property (klass,
113 GTK_FILE_CHOOSER_PROP_DO_OVERWRITE_CONFIRMATION,
114 "do-overwrite-confirmation");
115 g_object_class_override_property (klass,
116 GTK_FILE_CHOOSER_PROP_CREATE_FOLDERS,
121 * _gtk_file_chooser_delegate_iface_init:
122 * @iface: a #GtkFileChoserIface structure
124 * An interface-initialization function for use in cases where
125 * an object is simply delegating the methods, signals of
126 * the #GtkFileChooser interface to another object.
127 * _gtk_file_chooser_set_delegate() must be called on each
128 * instance of the object so that the delegate object can
132 _gtk_file_chooser_delegate_iface_init (GtkFileChooserIface *iface)
134 iface->set_current_folder = delegate_set_current_folder;
135 iface->get_current_folder = delegate_get_current_folder;
136 iface->set_current_name = delegate_set_current_name;
137 iface->select_file = delegate_select_file;
138 iface->unselect_file = delegate_unselect_file;
139 iface->select_all = delegate_select_all;
140 iface->unselect_all = delegate_unselect_all;
141 iface->get_files = delegate_get_files;
142 iface->get_preview_file = delegate_get_preview_file;
143 iface->get_file_system = delegate_get_file_system;
144 iface->add_filter = delegate_add_filter;
145 iface->remove_filter = delegate_remove_filter;
146 iface->list_filters = delegate_list_filters;
147 iface->add_shortcut_folder = delegate_add_shortcut_folder;
148 iface->remove_shortcut_folder = delegate_remove_shortcut_folder;
149 iface->list_shortcut_folders = delegate_list_shortcut_folders;
153 * _gtk_file_chooser_set_delegate:
154 * @receiver: a #GObject implementing #GtkFileChooser
155 * @delegate: another #GObject implementing #GtkFileChooser
157 * Establishes that calls on @receiver for #GtkFileChooser
158 * methods should be delegated to @delegate, and that
159 * #GtkFileChooser signals emitted on @delegate should be
160 * forwarded to @receiver. Must be used in conjunction with
161 * _gtk_file_chooser_delegate_iface_init().
164 _gtk_file_chooser_set_delegate (GtkFileChooser *receiver,
165 GtkFileChooser *delegate)
167 g_return_if_fail (GTK_IS_FILE_CHOOSER (receiver));
168 g_return_if_fail (GTK_IS_FILE_CHOOSER (delegate));
170 g_object_set_data (G_OBJECT (receiver), I_("gtk-file-chooser-delegate"), delegate);
171 g_signal_connect (delegate, "notify",
172 G_CALLBACK (delegate_notify), receiver);
173 g_signal_connect (delegate, "current-folder-changed",
174 G_CALLBACK (delegate_current_folder_changed), receiver);
175 g_signal_connect (delegate, "selection-changed",
176 G_CALLBACK (delegate_selection_changed), receiver);
177 g_signal_connect (delegate, "update-preview",
178 G_CALLBACK (delegate_update_preview), receiver);
179 g_signal_connect (delegate, "file-activated",
180 G_CALLBACK (delegate_file_activated), receiver);
181 g_signal_connect (delegate, "confirm-overwrite",
182 G_CALLBACK (delegate_confirm_overwrite), receiver);
186 _gtk_file_chooser_delegate_get_quark (void)
188 static GQuark quark = 0;
190 if (G_UNLIKELY (quark == 0))
191 quark = g_quark_from_static_string ("gtk-file-chooser-delegate");
196 static GtkFileChooser *
197 get_delegate (GtkFileChooser *receiver)
199 return g_object_get_qdata (G_OBJECT (receiver),
200 GTK_FILE_CHOOSER_DELEGATE_QUARK);
204 delegate_select_file (GtkFileChooser *chooser,
208 return gtk_file_chooser_select_file (get_delegate (chooser), file, error);
212 delegate_unselect_file (GtkFileChooser *chooser,
215 gtk_file_chooser_unselect_file (get_delegate (chooser), file);
219 delegate_select_all (GtkFileChooser *chooser)
221 gtk_file_chooser_select_all (get_delegate (chooser));
225 delegate_unselect_all (GtkFileChooser *chooser)
227 gtk_file_chooser_unselect_all (get_delegate (chooser));
231 delegate_get_files (GtkFileChooser *chooser)
233 return gtk_file_chooser_get_files (get_delegate (chooser));
237 delegate_get_preview_file (GtkFileChooser *chooser)
239 return gtk_file_chooser_get_preview_file (get_delegate (chooser));
242 static GtkFileSystem *
243 delegate_get_file_system (GtkFileChooser *chooser)
245 return _gtk_file_chooser_get_file_system (get_delegate (chooser));
249 delegate_add_filter (GtkFileChooser *chooser,
250 GtkFileFilter *filter)
252 gtk_file_chooser_add_filter (get_delegate (chooser), filter);
256 delegate_remove_filter (GtkFileChooser *chooser,
257 GtkFileFilter *filter)
259 gtk_file_chooser_remove_filter (get_delegate (chooser), filter);
263 delegate_list_filters (GtkFileChooser *chooser)
265 return gtk_file_chooser_list_filters (get_delegate (chooser));
269 delegate_add_shortcut_folder (GtkFileChooser *chooser,
273 return _gtk_file_chooser_add_shortcut_folder (get_delegate (chooser), file, error);
277 delegate_remove_shortcut_folder (GtkFileChooser *chooser,
281 return _gtk_file_chooser_remove_shortcut_folder (get_delegate (chooser), file, error);
285 delegate_list_shortcut_folders (GtkFileChooser *chooser)
287 return _gtk_file_chooser_list_shortcut_folder_files (get_delegate (chooser));
291 delegate_set_current_folder (GtkFileChooser *chooser,
295 return gtk_file_chooser_set_current_folder_file (get_delegate (chooser), file, error);
299 delegate_get_current_folder (GtkFileChooser *chooser)
301 return gtk_file_chooser_get_current_folder_file (get_delegate (chooser));
305 delegate_set_current_name (GtkFileChooser *chooser,
308 gtk_file_chooser_set_current_name (get_delegate (chooser), name);
312 delegate_notify (GObject *object,
318 iface = g_type_interface_peek (g_type_class_peek (G_OBJECT_TYPE (object)),
319 gtk_file_chooser_get_type ());
320 if (g_object_interface_find_property (iface, pspec->name))
321 g_object_notify (data, pspec->name);
325 delegate_selection_changed (GtkFileChooser *chooser,
328 g_signal_emit_by_name (data, "selection-changed");
332 delegate_current_folder_changed (GtkFileChooser *chooser,
335 g_signal_emit_by_name (data, "current-folder-changed");
339 delegate_update_preview (GtkFileChooser *chooser,
342 g_signal_emit_by_name (data, "update-preview");
346 delegate_file_activated (GtkFileChooser *chooser,
349 g_signal_emit_by_name (data, "file-activated");
352 static GtkFileChooserConfirmation
353 delegate_confirm_overwrite (GtkFileChooser *chooser,
356 GtkFileChooserConfirmation conf;
358 g_signal_emit_by_name (data, "confirm-overwrite", &conf);
363 get_parent_for_uri (const char *uri)
368 file = g_file_new_for_uri (uri);
369 parent = g_file_get_parent (file);
371 g_object_unref (file);
376 /* Extracts the parent folders out of the supplied list of GtkRecentInfo* items, and returns
377 * a list of GFile* for those unique parents.
380 _gtk_file_chooser_extract_recent_folders (GList *infos)
388 folders = g_hash_table_new (g_file_hash, (GEqualFunc) g_file_equal);
390 for (l = infos; l; l = l->next)
392 GtkRecentInfo *info = l->data;
396 uri = gtk_recent_info_get_uri (info);
397 parent = get_parent_for_uri (uri);
401 if (!g_hash_table_lookup (folders, parent))
403 g_hash_table_insert (folders, parent, (gpointer) 1);
404 result = g_list_prepend (result, g_object_ref (parent));
407 g_object_unref (parent);
411 result = g_list_reverse (result);
413 g_hash_table_destroy (folders);
419 _gtk_file_chooser_get_settings_for_widget (GtkWidget *widget)
421 static GQuark file_chooser_settings_quark = 0;
422 GtkSettings *gtksettings;
425 if (G_UNLIKELY (file_chooser_settings_quark == 0))
426 file_chooser_settings_quark = g_quark_from_static_string ("-gtk-file-chooser-settings");
428 gtksettings = gtk_widget_get_settings (widget);
429 settings = g_object_get_qdata (G_OBJECT (gtksettings), file_chooser_settings_quark);
431 if (G_UNLIKELY (settings == NULL))
433 settings = g_settings_new ("org.gtk.Settings.FileChooser");
434 g_settings_delay (settings);
436 g_object_set_qdata_full (G_OBJECT (gtksettings),
437 file_chooser_settings_quark,