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);
294 return file_system_type;
298 gtk_file_system_base_init (gpointer g_class)
300 static gboolean initialized = FALSE;
304 GType iface_type = G_TYPE_FROM_INTERFACE (g_class);
306 g_signal_new ("roots_changed",
309 G_STRUCT_OFFSET (GtkFileSystemIface, roots_changed),
311 g_cclosure_marshal_VOID__VOID,
319 gtk_file_system_list_roots (GtkFileSystem *file_system)
321 g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
323 return GTK_FILE_SYSTEM_GET_IFACE (file_system)->list_roots (file_system);
327 gtk_file_system_get_root_info (GtkFileSystem *file_system,
329 GtkFileInfoType types,
332 g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
333 g_return_val_if_fail (uri != NULL, NULL);
334 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
336 return GTK_FILE_SYSTEM_GET_IFACE (file_system)->get_root_info (file_system, uri, types, error);
340 gtk_file_system_get_folder (GtkFileSystem *file_system,
342 GtkFileInfoType types,
345 g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
346 g_return_val_if_fail (uri != NULL, NULL);
347 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
349 return GTK_FILE_SYSTEM_GET_IFACE (file_system)->get_folder (file_system, uri, types, error);
353 gtk_file_system_create_folder(GtkFileSystem *file_system,
357 g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), FALSE);
358 g_return_val_if_fail (uri != NULL, FALSE);
359 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
361 return GTK_FILE_SYSTEM_GET_IFACE (file_system)->create_folder (file_system, uri, error);
365 gtk_file_system_get_parent (GtkFileSystem *file_system,
370 gchar *tmp_parent = NULL;
373 g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), FALSE);
374 g_return_val_if_fail (uri != NULL, FALSE);
375 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
377 result = GTK_FILE_SYSTEM_GET_IFACE (file_system)->get_parent (file_system, uri, &tmp_parent, error);
378 g_assert (result || tmp_parent == NULL);
381 *parent = tmp_parent;
389 gtk_file_system_make_uri (GtkFileSystem *file_system,
390 const gchar *base_uri,
391 const gchar *display_name,
394 g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
395 g_return_val_if_fail (base_uri != NULL, NULL);
396 g_return_val_if_fail (display_name != NULL, NULL);
397 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
399 return GTK_FILE_SYSTEM_GET_IFACE (file_system)->make_uri (file_system, base_uri, display_name, error);
403 * gtk_file_system_parse:
404 * @file_system: a #GtkFileSystem
405 * @base_uri: reference folder with respect to which relative
406 * paths should be interpreted.
407 * @str: the string to parse
408 * @folder: location to store folder portion of result, or %NULL
409 * @file_part: location to store file portion of result, or %NULL
410 * @error: location to store error, or %NULL
412 * Given a string entered by a user, parse it (possibly using
413 * heuristics) into a folder URI and a UTF-8 encoded
414 * filename part. (Suitable for passing to gtk_file_system_make_uri())
416 * Note that the returned filename point may point to a subfolder
417 * of the returned folder. Adding a trailing path separator is needed
418 * to enforce the interpretation as a folder name.
420 * If parsing fails because the syntax of @str is not understood,
421 * and error of type GTK_FILE_SYSTEM_ERROR_BAD_FILENAME will
422 * be set in @error and %FALSE returned.
424 * If parsing fails because a path was encountered that doesn't
425 * exist on the filesystem, then an error of type
426 * %GTK_FILE_SYSTEM_ERROR_NONEXISTANT will be set in @error
427 * and %FALSE returned. (This only applies to parsing relative paths,
428 * not to interpretation of @file_part. No check is made as
429 * to whether @file_part exists.)
431 * Return value: %TRUE if the parsing succeeds, otherwise, %FALSE.
434 gtk_file_system_parse (GtkFileSystem *file_system,
435 const gchar *base_uri,
441 gchar *tmp_folder = NULL;
442 gchar *tmp_file_part = NULL;
445 g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), FALSE);
446 g_return_val_if_fail (base_uri != NULL, FALSE);
447 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
450 result = GTK_FILE_SYSTEM_GET_IFACE (file_system)->parse (file_system, base_uri, str,
451 &tmp_folder, &tmp_file_part,
453 g_assert (result || (tmp_folder == NULL && tmp_file_part == NULL));
456 *folder = tmp_folder;
461 *file_part = tmp_file_part;
463 g_free (tmp_file_part);
468 /*****************************************
470 *****************************************/
472 gtk_file_folder_get_type (void)
474 static GType file_folder_type = 0;
476 if (!file_folder_type)
478 static const GTypeInfo file_folder_info =
480 sizeof (GtkFileFolderIface), /* class_size */
481 gtk_file_folder_base_init, /* base_init */
482 NULL, /* base_finalize */
485 file_folder_type = g_type_register_static (G_TYPE_INTERFACE,
487 &file_folder_info, 0);
490 return file_folder_type;
494 gtk_file_folder_base_init (gpointer g_class)
496 static gboolean initialized = FALSE;
500 GType iface_type = G_TYPE_FROM_INTERFACE (g_class);
502 g_signal_new ("deleted",
505 G_STRUCT_OFFSET (GtkFileFolderIface, deleted),
507 g_cclosure_marshal_VOID__VOID,
509 g_signal_new ("files_added",
512 G_STRUCT_OFFSET (GtkFileFolderIface, files_added),
514 g_cclosure_marshal_VOID__POINTER,
517 g_signal_new ("file_changed",
520 G_STRUCT_OFFSET (GtkFileFolderIface, file_changed),
522 g_cclosure_marshal_VOID__STRING,
525 g_signal_new ("file_removed",
528 G_STRUCT_OFFSET (GtkFileFolderIface, file_removed),
530 g_cclosure_marshal_VOID__STRING,
539 gtk_file_folder_list_children (GtkFileFolder *folder,
544 GSList *tmp_children = NULL;
546 g_return_val_if_fail (GTK_IS_FILE_FOLDER (folder), FALSE);
547 g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
549 result = GTK_FILE_FOLDER_GET_IFACE (folder)->list_children (folder, &tmp_children, error);
550 g_assert (result || tmp_children == NULL);
553 *children = tmp_children;
556 g_slist_foreach (tmp_children, (GFunc)g_free, NULL);
557 g_slist_free (tmp_children);
564 gtk_file_folder_get_info (GtkFileFolder *folder,
568 g_return_val_if_fail (GTK_IS_FILE_FOLDER (folder), NULL);
569 g_return_val_if_fail (uri != NULL, NULL);
570 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
572 return GTK_FILE_FOLDER_GET_IFACE (folder)->get_info (folder, uri, error);