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"
27 GtkFileTime modification_time;
37 static void gtk_file_system_base_init (gpointer g_class);
38 static void gtk_file_folder_base_init (gpointer g_class);
41 gtk_file_system_error_quark (void)
43 static GQuark quark = 0;
45 quark = g_quark_from_static_string ("gtk-file-system-error-quark");
49 /*****************************************
51 *****************************************/
53 gtk_file_info_get_type (void)
55 static GType our_type = 0;
58 our_type = g_boxed_type_register_static ("GtkFileInfo",
59 (GBoxedCopyFunc) gtk_file_info_copy,
60 (GBoxedFreeFunc) gtk_file_info_free);
66 gtk_file_info_new (void)
70 info = g_new0 (GtkFileInfo, 1);
76 gtk_file_info_copy (GtkFileInfo *info)
78 GtkFileInfo *new_info;
80 g_return_val_if_fail (info != NULL, NULL);
82 new_info = g_memdup (info, sizeof (GtkFileInfo));
83 if (new_info->display_name)
84 new_info->display_name = g_strdup (new_info->display_name);
85 if (new_info->mime_type)
86 new_info->mime_type = g_strdup (new_info->mime_type);
88 g_object_ref (new_info->icon);
94 gtk_file_info_free (GtkFileInfo *info)
96 g_return_if_fail (info != NULL);
98 if (info->display_name)
99 g_free (info->display_name);
101 g_free (info->mime_type);
103 g_object_unref (info->icon);
106 G_CONST_RETURN gchar *
107 gtk_file_info_get_display_name (const GtkFileInfo *info)
109 g_return_val_if_fail (info != NULL, NULL);
111 return info->display_name;
115 * gtk_file_info_get_display_key:
116 * @info: a #GtkFileInfo
118 * Returns results of g_utf8_collate_key() on the display name
119 * for @info. This is useful when sorting a bunch of #GtkFileInfo
120 * structures since the collate key will be only computed once.
122 * Return value: The collate key for the display name, or %NULL
123 * if the display name hasn't been set.
125 G_CONST_RETURN gchar *
126 gtk_file_info_get_display_key (const GtkFileInfo *info)
128 g_return_val_if_fail (info != NULL, NULL);
130 if (!info->display_key && info->display_name)
132 /* Since info->display_key is only a cache, we cast off the const
134 ((GtkFileInfo *)info)->display_key = g_utf8_collate_key (info->display_name, -1);
138 return info->display_key;
142 gtk_file_info_set_display_name (GtkFileInfo *info,
143 const gchar *display_name)
145 g_return_if_fail (info != NULL);
147 if (info->display_name)
148 g_free (info->display_name);
149 if (info->display_key)
151 g_free (info->display_key);
152 info->display_key = NULL;
155 info->display_name = g_strdup (display_name);
159 gtk_file_info_get_is_folder (const GtkFileInfo *info)
161 g_return_val_if_fail (info != NULL, FALSE);
163 return info->is_folder;
167 gtk_file_info_set_is_folder (GtkFileInfo *info,
170 g_return_if_fail (info != NULL);
172 info->is_folder = is_folder != FALSE;
176 gtk_file_info_get_is_hidden (const GtkFileInfo *info)
178 g_return_val_if_fail (info != NULL, FALSE);
180 return info->is_hidden;
184 gtk_file_info_set_is_hidden (GtkFileInfo *info,
187 g_return_if_fail (info != NULL);
189 info->is_hidden = is_hidden != FALSE;
192 G_CONST_RETURN gchar *
193 gtk_file_info_get_mime_type (const GtkFileInfo *info)
195 g_return_val_if_fail (info != NULL, NULL);
197 return info->mime_type;
201 gtk_file_info_set_mime_type (GtkFileInfo *info,
202 const gchar *mime_type)
204 g_return_if_fail (info != NULL);
207 g_free (info->mime_type);
209 info->mime_type = g_strdup (mime_type);
213 gtk_file_info_get_modification_time (const GtkFileInfo *info)
215 g_return_val_if_fail (info != NULL, 0);
217 return info->modification_time;
221 gtk_file_info_set_modification_time (GtkFileInfo *info,
222 GtkFileTime modification_time)
224 g_return_if_fail (info != NULL);
226 info->modification_time = modification_time;
230 gtk_file_info_get_size (const GtkFileInfo *info)
232 g_return_val_if_fail (info != NULL, 0);
238 gtk_file_info_set_size (GtkFileInfo *info,
241 g_return_if_fail (info != NULL);
242 g_return_if_fail (size >= 0);
248 gtk_file_info_get_icon (const GtkFileInfo *info)
250 g_return_val_if_fail (info != NULL, NULL);
256 gtk_file_info_set_icon (GtkFileInfo *info,
259 g_return_if_fail (info != NULL);
260 g_return_if_fail (icon == NULL || GDK_IS_PIXBUF (icon));
262 if (icon != info->icon)
265 g_object_unref (info->icon);
270 g_object_ref (info->icon);
274 /*****************************************
276 *****************************************/
278 gtk_file_system_get_type (void)
280 static GType file_system_type = 0;
282 if (!file_system_type)
284 static const GTypeInfo file_system_info =
286 sizeof (GtkFileSystemIface), /* class_size */
287 gtk_file_system_base_init, /* base_init */
288 NULL, /* base_finalize */
291 file_system_type = g_type_register_static (G_TYPE_INTERFACE,
293 &file_system_info, 0);
295 g_type_interface_add_prerequisite (file_system_type, G_TYPE_OBJECT);
298 return file_system_type;
302 gtk_file_system_base_init (gpointer g_class)
304 static gboolean initialized = FALSE;
308 GType iface_type = G_TYPE_FROM_INTERFACE (g_class);
310 g_signal_new ("roots_changed",
313 G_STRUCT_OFFSET (GtkFileSystemIface, roots_changed),
315 g_cclosure_marshal_VOID__VOID,
323 gtk_file_system_list_roots (GtkFileSystem *file_system)
325 g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
327 return GTK_FILE_SYSTEM_GET_IFACE (file_system)->list_roots (file_system);
331 gtk_file_system_get_root_info (GtkFileSystem *file_system,
332 const GtkFilePath *path,
333 GtkFileInfoType types,
336 g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
337 g_return_val_if_fail (path != NULL, NULL);
338 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
340 return GTK_FILE_SYSTEM_GET_IFACE (file_system)->get_root_info (file_system, path, types, error);
344 gtk_file_system_get_folder (GtkFileSystem *file_system,
345 const GtkFilePath *path,
346 GtkFileInfoType types,
349 g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
350 g_return_val_if_fail (path != NULL, NULL);
351 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
353 return GTK_FILE_SYSTEM_GET_IFACE (file_system)->get_folder (file_system, path, types, error);
357 gtk_file_system_create_folder(GtkFileSystem *file_system,
358 const GtkFilePath *path,
361 g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), FALSE);
362 g_return_val_if_fail (path != NULL, FALSE);
363 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
365 return GTK_FILE_SYSTEM_GET_IFACE (file_system)->create_folder (file_system, path, error);
369 gtk_file_system_get_parent (GtkFileSystem *file_system,
370 const GtkFilePath *path,
371 GtkFilePath **parent,
374 GtkFilePath *tmp_parent = NULL;
377 g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), FALSE);
378 g_return_val_if_fail (path != NULL, FALSE);
379 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
381 result = GTK_FILE_SYSTEM_GET_IFACE (file_system)->get_parent (file_system, path, &tmp_parent, error);
382 g_assert (result || tmp_parent == NULL);
385 *parent = tmp_parent;
387 gtk_file_path_free (tmp_parent);
393 gtk_file_system_make_path (GtkFileSystem *file_system,
394 const GtkFilePath *base_path,
395 const gchar *display_name,
398 g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
399 g_return_val_if_fail (base_path != NULL, NULL);
400 g_return_val_if_fail (display_name != NULL, NULL);
401 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
403 return GTK_FILE_SYSTEM_GET_IFACE (file_system)->make_path (file_system, base_path, display_name, error);
407 * gtk_file_system_parse:
408 * @file_system: a #GtkFileSystem
409 * @base_path: reference folder with respect to which relative
410 * paths should be interpreted.
411 * @str: the string to parse
412 * @folder: location to store folder portion of result, or %NULL
413 * @file_part: location to store file portion of result, or %NULL
414 * @error: location to store error, or %NULL
416 * Given a string entered by a user, parse it (possibly using
417 * heuristics) into a folder path and a UTF-8 encoded
418 * filename part. (Suitable for passing to gtk_file_system_make_path())
420 * Note that the returned filename point may point to a subfolder
421 * of the returned folder. Adding a trailing path separator is needed
422 * to enforce the interpretation as a folder name.
424 * If parsing fails because the syntax of @str is not understood,
425 * and error of type GTK_FILE_SYSTEM_ERROR_BAD_FILENAME will
426 * be set in @error and %FALSE returned.
428 * If parsing fails because a path was encountered that doesn't
429 * exist on the filesystem, then an error of type
430 * %GTK_FILE_SYSTEM_ERROR_NONEXISTANT will be set in @error
431 * and %FALSE returned. (This only applies to parsing relative paths,
432 * not to interpretation of @file_part. No check is made as
433 * to whether @file_part exists.)
435 * Return value: %TRUE if the parsing succeeds, otherwise, %FALSE.
438 gtk_file_system_parse (GtkFileSystem *file_system,
439 const GtkFilePath *base_path,
441 GtkFilePath **folder,
445 GtkFilePath *tmp_folder = NULL;
446 gchar *tmp_file_part = NULL;
449 g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), FALSE);
450 g_return_val_if_fail (base_path != NULL, FALSE);
451 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
454 result = GTK_FILE_SYSTEM_GET_IFACE (file_system)->parse (file_system, base_path, str,
455 &tmp_folder, &tmp_file_part,
457 g_assert (result || (tmp_folder == NULL && tmp_file_part == NULL));
460 *folder = tmp_folder;
462 gtk_file_path_free (tmp_folder);
465 *file_part = tmp_file_part;
467 g_free (tmp_file_part);
474 gtk_file_system_path_to_uri (GtkFileSystem *file_system,
475 const GtkFilePath *path)
477 g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
478 g_return_val_if_fail (path != NULL, NULL);
480 return GTK_FILE_SYSTEM_GET_IFACE (file_system)->path_to_uri (file_system, path);
484 gtk_file_system_path_to_filename (GtkFileSystem *file_system,
485 const GtkFilePath *path)
487 g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
488 g_return_val_if_fail (path != NULL, NULL);
490 return GTK_FILE_SYSTEM_GET_IFACE (file_system)->path_to_filename (file_system, path);
494 gtk_file_system_uri_to_path (GtkFileSystem *file_system,
497 g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
498 g_return_val_if_fail (uri != NULL, NULL);
500 return GTK_FILE_SYSTEM_GET_IFACE (file_system)->uri_to_path (file_system, uri);
504 gtk_file_system_filename_to_path (GtkFileSystem *file_system,
505 const gchar *filename)
507 g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
508 g_return_val_if_fail (filename != NULL, NULL);
510 return GTK_FILE_SYSTEM_GET_IFACE (file_system)->filename_to_path (file_system, filename);
513 /*****************************************
515 *****************************************/
517 gtk_file_folder_get_type (void)
519 static GType file_folder_type = 0;
521 if (!file_folder_type)
523 static const GTypeInfo file_folder_info =
525 sizeof (GtkFileFolderIface), /* class_size */
526 gtk_file_folder_base_init, /* base_init */
527 NULL, /* base_finalize */
530 file_folder_type = g_type_register_static (G_TYPE_INTERFACE,
532 &file_folder_info, 0);
534 g_type_interface_add_prerequisite (file_folder_type, G_TYPE_OBJECT);
537 return file_folder_type;
541 gtk_file_folder_base_init (gpointer g_class)
543 static gboolean initialized = FALSE;
547 GType iface_type = G_TYPE_FROM_INTERFACE (g_class);
549 g_signal_new ("deleted",
552 G_STRUCT_OFFSET (GtkFileFolderIface, deleted),
554 g_cclosure_marshal_VOID__VOID,
556 g_signal_new ("files_added",
559 G_STRUCT_OFFSET (GtkFileFolderIface, files_added),
561 g_cclosure_marshal_VOID__POINTER,
564 g_signal_new ("files_changed",
567 G_STRUCT_OFFSET (GtkFileFolderIface, files_changed),
569 g_cclosure_marshal_VOID__POINTER,
572 g_signal_new ("files_removed",
575 G_STRUCT_OFFSET (GtkFileFolderIface, files_removed),
577 g_cclosure_marshal_VOID__POINTER,
586 gtk_file_folder_list_children (GtkFileFolder *folder,
591 GSList *tmp_children = NULL;
593 g_return_val_if_fail (GTK_IS_FILE_FOLDER (folder), FALSE);
594 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
596 result = GTK_FILE_FOLDER_GET_IFACE (folder)->list_children (folder, &tmp_children, error);
597 g_assert (result || tmp_children == NULL);
600 *children = tmp_children;
602 gtk_file_paths_free (tmp_children);
608 gtk_file_folder_get_info (GtkFileFolder *folder,
609 const GtkFilePath *path,
612 g_return_val_if_fail (GTK_IS_FILE_FOLDER (folder), NULL);
613 g_return_val_if_fail (path != NULL, NULL);
614 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
616 return GTK_FILE_FOLDER_GET_IFACE (folder)->get_info (folder, path, error);
620 gtk_file_paths_sort (GSList *paths)
622 return g_slist_sort (paths, (GCompareFunc)strcmp);
626 gtk_file_paths_free (GSList *paths)
630 for (tmp_list = paths; tmp_list; tmp_list = tmp_list->next)
631 gtk_file_path_free (tmp_list->data);
633 g_slist_free (paths);