1 /* GTK - The GIMP Toolkit
2 * gtkfilesystem.c: Abstract file system interfaces
3 * Copyright (C) 2003, Red Hat, Inc.
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.
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.
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.
21 #include "gtkfilesystem.h"
25 GtkFileTime modification_time;
35 static void gtk_file_system_base_init (gpointer g_class);
36 static void gtk_file_folder_base_init (gpointer g_class);
39 gtk_file_system_error_quark (void)
41 static GQuark quark = 0;
43 quark = g_quark_from_static_string ("gtk-file-system-error-quark");
47 /*****************************************
49 *****************************************/
51 gtk_file_info_get_type (void)
53 static GType our_type = 0;
56 our_type = g_boxed_type_register_static ("GtkFileInfo",
57 (GBoxedCopyFunc) gtk_file_info_copy,
58 (GBoxedFreeFunc) gtk_file_info_free);
64 gtk_file_info_new (void)
68 info = g_new0 (GtkFileInfo, 1);
74 gtk_file_info_copy (GtkFileInfo *info)
76 GtkFileInfo *new_info;
78 g_return_val_if_fail (info != NULL, NULL);
80 new_info = g_memdup (info, sizeof (GtkFileInfo));
81 if (new_info->display_name)
82 new_info->display_name = g_strdup (new_info->display_name);
83 if (new_info->mime_type)
84 new_info->mime_type = g_strdup (new_info->mime_type);
86 g_object_ref (new_info->icon);
92 gtk_file_info_free (GtkFileInfo *info)
94 g_return_if_fail (info != NULL);
96 if (info->display_name)
97 g_free (info->display_name);
99 g_free (info->mime_type);
101 g_object_unref (info->icon);
104 G_CONST_RETURN gchar *
105 gtk_file_info_get_display_name (const GtkFileInfo *info)
107 g_return_val_if_fail (info != NULL, NULL);
109 return info->display_name;
113 * gtk_file_info_get_display_key:
114 * @info: a #GtkFileInfo
116 * Returns results of g_utf8_collate_key() on the display name
117 * for @info. This is useful when sorting a bunch of #GtkFileInfo
118 * structures since the collate key will be only computed once.
120 * Return value: The collate key for the display name, or %NULL
121 * if the display name hasn't been set.
123 G_CONST_RETURN gchar *
124 gtk_file_info_get_display_key (const GtkFileInfo *info)
126 g_return_val_if_fail (info != NULL, NULL);
128 if (!info->display_key && info->display_name)
130 /* Since info->display_key is only a cache, we cast off the const
132 ((GtkFileInfo *)info)->display_key = g_utf8_collate_key (info->display_name, -1);
136 return info->display_key;
140 gtk_file_info_set_display_name (GtkFileInfo *info,
141 const gchar *display_name)
143 g_return_if_fail (info != NULL);
145 if (info->display_name)
146 g_free (info->display_name);
147 if (info->display_key)
149 g_free (info->display_key);
150 info->display_key = NULL;
153 info->display_name = g_strdup (display_name);
157 gtk_file_info_get_is_folder (const GtkFileInfo *info)
159 g_return_val_if_fail (info != NULL, FALSE);
161 return info->is_folder;
165 gtk_file_info_set_is_folder (GtkFileInfo *info,
168 g_return_if_fail (info != NULL);
170 info->is_folder = is_folder != FALSE;
174 gtk_file_info_get_is_hidden (const GtkFileInfo *info)
176 g_return_val_if_fail (info != NULL, FALSE);
178 return info->is_hidden;
182 gtk_file_info_set_is_hidden (GtkFileInfo *info,
185 g_return_if_fail (info != NULL);
187 info->is_hidden = is_hidden != FALSE;
190 G_CONST_RETURN gchar *
191 gtk_file_info_get_mime_type (const GtkFileInfo *info)
193 g_return_val_if_fail (info != NULL, NULL);
195 return info->mime_type;
199 gtk_file_info_set_mime_type (GtkFileInfo *info,
200 const gchar *mime_type)
202 g_return_if_fail (info != NULL);
205 g_free (info->mime_type);
207 info->mime_type = g_strdup (mime_type);
211 gtk_file_info_get_modification_time (const GtkFileInfo *info)
213 g_return_val_if_fail (info != NULL, 0);
215 return info->modification_time;
219 gtk_file_info_set_modification_time (GtkFileInfo *info,
220 GtkFileTime modification_time)
222 g_return_if_fail (info != NULL);
224 info->modification_time = modification_time;
228 gtk_file_info_get_size (const GtkFileInfo *info)
230 g_return_val_if_fail (info != NULL, 0);
236 gtk_file_info_set_size (GtkFileInfo *info,
239 g_return_if_fail (info != NULL);
240 g_return_if_fail (size >= 0);
246 gtk_file_info_get_icon (const GtkFileInfo *info)
248 g_return_val_if_fail (info != NULL, NULL);
254 gtk_file_info_set_icon (GtkFileInfo *info,
257 g_return_if_fail (info != NULL);
258 g_return_if_fail (icon == NULL || GDK_IS_PIXBUF (icon));
260 if (icon != info->icon)
263 g_object_unref (info->icon);
268 g_object_ref (info->icon);
272 /*****************************************
274 *****************************************/
276 gtk_file_system_get_type (void)
278 static GType file_system_type = 0;
280 if (!file_system_type)
282 static const GTypeInfo file_system_info =
284 sizeof (GtkFileSystemIface), /* class_size */
285 gtk_file_system_base_init, /* base_init */
286 NULL, /* base_finalize */
289 file_system_type = g_type_register_static (G_TYPE_INTERFACE,
291 &file_system_info, 0);
293 g_type_interface_add_prerequisite (file_system_type, G_TYPE_OBJECT);
296 return file_system_type;
300 gtk_file_system_base_init (gpointer g_class)
302 static gboolean initialized = FALSE;
306 GType iface_type = G_TYPE_FROM_INTERFACE (g_class);
308 g_signal_new ("roots_changed",
311 G_STRUCT_OFFSET (GtkFileSystemIface, roots_changed),
313 g_cclosure_marshal_VOID__VOID,
321 gtk_file_system_list_roots (GtkFileSystem *file_system)
323 g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
325 return GTK_FILE_SYSTEM_GET_IFACE (file_system)->list_roots (file_system);
329 gtk_file_system_get_root_info (GtkFileSystem *file_system,
331 GtkFileInfoType types,
334 g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
335 g_return_val_if_fail (uri != NULL, NULL);
336 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
338 return GTK_FILE_SYSTEM_GET_IFACE (file_system)->get_root_info (file_system, uri, types, error);
342 gtk_file_system_get_folder (GtkFileSystem *file_system,
344 GtkFileInfoType types,
347 g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
348 g_return_val_if_fail (uri != NULL, NULL);
349 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
351 return GTK_FILE_SYSTEM_GET_IFACE (file_system)->get_folder (file_system, uri, types, error);
355 gtk_file_system_create_folder(GtkFileSystem *file_system,
359 g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), FALSE);
360 g_return_val_if_fail (uri != NULL, FALSE);
361 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
363 return GTK_FILE_SYSTEM_GET_IFACE (file_system)->create_folder (file_system, uri, error);
367 gtk_file_system_get_parent (GtkFileSystem *file_system,
372 gchar *tmp_parent = NULL;
375 g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), FALSE);
376 g_return_val_if_fail (uri != NULL, FALSE);
377 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
379 result = GTK_FILE_SYSTEM_GET_IFACE (file_system)->get_parent (file_system, uri, &tmp_parent, error);
380 g_assert (result || tmp_parent == NULL);
383 *parent = tmp_parent;
391 gtk_file_system_make_uri (GtkFileSystem *file_system,
392 const gchar *base_uri,
393 const gchar *display_name,
396 g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
397 g_return_val_if_fail (base_uri != NULL, NULL);
398 g_return_val_if_fail (display_name != NULL, NULL);
399 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
401 return GTK_FILE_SYSTEM_GET_IFACE (file_system)->make_uri (file_system, base_uri, display_name, error);
405 * gtk_file_system_parse:
406 * @file_system: a #GtkFileSystem
407 * @base_uri: reference folder with respect to which relative
408 * paths should be interpreted.
409 * @str: the string to parse
410 * @folder: location to store folder portion of result, or %NULL
411 * @file_part: location to store file portion of result, or %NULL
412 * @error: location to store error, or %NULL
414 * Given a string entered by a user, parse it (possibly using
415 * heuristics) into a folder URI and a UTF-8 encoded
416 * filename part. (Suitable for passing to gtk_file_system_make_uri())
418 * Note that the returned filename point may point to a subfolder
419 * of the returned folder. Adding a trailing path separator is needed
420 * to enforce the interpretation as a folder name.
422 * If parsing fails because the syntax of @str is not understood,
423 * and error of type GTK_FILE_SYSTEM_ERROR_BAD_FILENAME will
424 * be set in @error and %FALSE returned.
426 * If parsing fails because a path was encountered that doesn't
427 * exist on the filesystem, then an error of type
428 * %GTK_FILE_SYSTEM_ERROR_NONEXISTANT will be set in @error
429 * and %FALSE returned. (This only applies to parsing relative paths,
430 * not to interpretation of @file_part. No check is made as
431 * to whether @file_part exists.)
433 * Return value: %TRUE if the parsing succeeds, otherwise, %FALSE.
436 gtk_file_system_parse (GtkFileSystem *file_system,
437 const gchar *base_uri,
443 gchar *tmp_folder = NULL;
444 gchar *tmp_file_part = NULL;
447 g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), FALSE);
448 g_return_val_if_fail (base_uri != NULL, FALSE);
449 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
452 result = GTK_FILE_SYSTEM_GET_IFACE (file_system)->parse (file_system, base_uri, str,
453 &tmp_folder, &tmp_file_part,
455 g_assert (result || (tmp_folder == NULL && tmp_file_part == NULL));
458 *folder = tmp_folder;
463 *file_part = tmp_file_part;
465 g_free (tmp_file_part);
470 /*****************************************
472 *****************************************/
474 gtk_file_folder_get_type (void)
476 static GType file_folder_type = 0;
478 if (!file_folder_type)
480 static const GTypeInfo file_folder_info =
482 sizeof (GtkFileFolderIface), /* class_size */
483 gtk_file_folder_base_init, /* base_init */
484 NULL, /* base_finalize */
487 file_folder_type = g_type_register_static (G_TYPE_INTERFACE,
489 &file_folder_info, 0);
491 g_type_interface_add_prerequisite (file_folder_type, G_TYPE_OBJECT);
494 return file_folder_type;
498 gtk_file_folder_base_init (gpointer g_class)
500 static gboolean initialized = FALSE;
504 GType iface_type = G_TYPE_FROM_INTERFACE (g_class);
506 g_signal_new ("deleted",
509 G_STRUCT_OFFSET (GtkFileFolderIface, deleted),
511 g_cclosure_marshal_VOID__VOID,
513 g_signal_new ("files_added",
516 G_STRUCT_OFFSET (GtkFileFolderIface, files_added),
518 g_cclosure_marshal_VOID__POINTER,
521 g_signal_new ("files_changed",
524 G_STRUCT_OFFSET (GtkFileFolderIface, files_changed),
526 g_cclosure_marshal_VOID__POINTER,
529 g_signal_new ("files_removed",
532 G_STRUCT_OFFSET (GtkFileFolderIface, files_removed),
534 g_cclosure_marshal_VOID__POINTER,
543 gtk_file_folder_list_children (GtkFileFolder *folder,
548 GSList *tmp_children = NULL;
550 g_return_val_if_fail (GTK_IS_FILE_FOLDER (folder), FALSE);
551 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
553 result = GTK_FILE_FOLDER_GET_IFACE (folder)->list_children (folder, &tmp_children, error);
554 g_assert (result || tmp_children == NULL);
557 *children = tmp_children;
560 g_slist_foreach (tmp_children, (GFunc)g_free, NULL);
561 g_slist_free (tmp_children);
568 gtk_file_folder_get_info (GtkFileFolder *folder,
572 g_return_val_if_fail (GTK_IS_FILE_FOLDER (folder), NULL);
573 g_return_val_if_fail (uri != NULL, NULL);
574 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
576 return GTK_FILE_FOLDER_GET_IFACE (folder)->get_info (folder, uri, error);