* Boston, MA 02111-1307, USA.
*/
-
+#include <config.h>
+#include <gmodule.h>
#include "gtkfilesystem.h"
#include "gtkicontheme.h"
+#include "gtkmodules.h"
+#include "gtkintl.h"
+#include "gtkalias.h"
+#include "gtkstock.h"
#include <string.h>
gchar *display_name;
gchar *display_key;
gchar *mime_type;
-#if 0
- GtkFileIconType icon_type : 4;
-#endif
+ gchar *icon_name;
guint is_folder : 1;
guint is_hidden : 1;
};
GQuark
gtk_file_system_error_quark (void)
{
- static GQuark quark = 0;
- if (quark == 0)
- quark = g_quark_from_static_string ("gtk-file-system-error-quark");
- return quark;
+ return g_quark_from_static_string ("gtk-file-system-error-quark");
}
/*****************************************
static GType our_type = 0;
if (our_type == 0)
- our_type = g_boxed_type_register_static ("GtkFileInfo",
+ our_type = g_boxed_type_register_static (I_("GtkFileInfo"),
(GBoxedCopyFunc) gtk_file_info_copy,
(GBoxedFreeFunc) gtk_file_info_free);
new_info = g_memdup (info, sizeof (GtkFileInfo));
if (new_info->display_name)
new_info->display_name = g_strdup (new_info->display_name);
+ if (new_info->display_key)
+ new_info->display_key = g_strdup (new_info->display_key);
if (new_info->mime_type)
new_info->mime_type = g_strdup (new_info->mime_type);
+ if (new_info->icon_name)
+ new_info->icon_name = g_strdup (new_info->icon_name);
+ if (new_info->display_key)
+ new_info->display_key = g_strdup (new_info->display_key);
return new_info;
}
g_free (info->mime_type);
if (info->display_key)
g_free (info->display_key);
+ if (info->icon_name)
+ g_free (info->icon_name);
g_free (info);
}
* gtk_file_info_get_display_key:
* @info: a #GtkFileInfo
*
- * Returns results of g_utf8_collate_key() on the display name
- * for @info. This is useful when sorting a bunch of #GtkFileInfo
- * structures since the collate key will be only computed once.
+ * Returns for the collation key for the display name for @info.
+ * This is useful when sorting a bunch of #GtkFileInfo structures
+ * since the collate key will be only computed once.
*
* Return value: The collate key for the display name, or %NULL
* if the display name hasn't been set.
{
/* Since info->display_key is only a cache, we cast off the const
*/
- ((GtkFileInfo *)info)->display_key = g_utf8_collate_key (info->display_name, -1);
+ ((GtkFileInfo *)info)->display_key = g_utf8_collate_key_for_filename (info->display_name, -1);
}
return info->display_key;
{
g_return_if_fail (info != NULL);
+ if (display_name == info->display_name)
+ return;
+
if (info->display_name)
g_free (info->display_name);
if (info->display_key)
info->size = size;
}
-#if 0
void
-gtk_file_info_set_icon_type (GtkFileInfo *info,
- GtkFileIconType icon_type)
+gtk_file_info_set_icon_name (GtkFileInfo *info,
+ const gchar *icon_name)
{
g_return_if_fail (info != NULL);
+
+ if (info->icon_name)
+ g_free (info->icon_name);
- info->icon_type = icon_type;
+ info->icon_name = g_strdup (icon_name);
}
-GtkFileIconType
-gtk_file_info_get_icon_type (const GtkFileInfo *info)
+G_CONST_RETURN gchar *
+gtk_file_info_get_icon_name (const GtkFileInfo *info)
{
- g_return_val_if_fail (info != NULL, GTK_FILE_ICON_REGULAR);
-
- return info->icon_type;
+ g_return_val_if_fail (info != NULL, NULL);
+
+ return info->icon_name;
}
-typedef struct _IconCacheElement IconCacheElement;
-
-struct _IconCacheElement
+GdkPixbuf *
+gtk_file_info_render_icon (const GtkFileInfo *info,
+ GtkWidget *widget,
+ gint pixel_size,
+ GError **error)
{
- gint size;
- GdkPixbuf *pixbuf;
-};
+ GdkPixbuf *pixbuf = NULL;
-static void
-icon_cache_element_free (IconCacheElement *element)
-{
- if (element->pixbuf)
- g_object_unref (element->pixbuf);
- g_free (element);
-}
+ g_return_val_if_fail (info != NULL, NULL);
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
-static void
-icon_theme_changed (GtkIconTheme *icon_theme)
-{
- GHashTable *cache;
-
- /* Difference from the initial creation is that we don't
- * reconnect the signal
- */
- cache = g_hash_table_new_full (g_str_hash, g_str_equal,
- (GDestroyNotify)g_free,
- (GDestroyNotify)icon_cache_element_free);
- g_object_set_data_full (G_OBJECT (icon_theme), "gtk-file-icon-cache",
- cache, (GDestroyNotify)g_hash_table_destroy);
-}
-
-static GdkPixbuf *
-get_cached_icon (GtkWidget *widget,
- const gchar *name,
- gint pixel_size)
-{
- GtkIconTheme *icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget));
- GHashTable *cache = g_object_get_data (G_OBJECT (icon_theme), "gtk-file-icon-cache");
- IconCacheElement *element;
-
- if (!cache)
+ if (info->icon_name)
{
- cache = g_hash_table_new_full (g_str_hash, g_str_equal,
- (GDestroyNotify)g_free,
- (GDestroyNotify)icon_cache_element_free);
-
- g_object_set_data_full (G_OBJECT (icon_theme), "gtk-file-icon-cache",
- cache, (GDestroyNotify)g_hash_table_destroy);
- g_signal_connect (icon_theme, "changed",
- G_CALLBACK (icon_theme_changed), NULL);
- }
+ if (g_path_is_absolute (info->icon_name))
+ pixbuf = gdk_pixbuf_new_from_file_at_size (info->icon_name,
+ pixel_size,
+ pixel_size,
+ NULL);
+ else
+ {
+ GtkIconTheme *icon_theme;
- element = g_hash_table_lookup (cache, name);
- if (!element)
- {
- element = g_new0 (IconCacheElement, 1);
- g_hash_table_insert (cache, g_strdup (name), element);
+ icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget));
+ pixbuf = gtk_icon_theme_load_icon (icon_theme, info->icon_name,
+ pixel_size, 0, NULL);
+ }
}
- if (element->size != pixel_size)
+ if (!pixbuf)
{
- if (element->pixbuf)
- g_object_unref (element->pixbuf);
- element->size = pixel_size;
- element->pixbuf = gtk_icon_theme_load_icon (icon_theme, name,
- pixel_size, 0, NULL);
+ /* load a fallback icon */
+ pixbuf = gtk_widget_render_icon (widget, GTK_STOCK_FILE, GTK_ICON_SIZE_SMALL_TOOLBAR, NULL);
+ if (!pixbuf && error)
+ g_set_error (error,
+ GTK_FILE_SYSTEM_ERROR,
+ GTK_FILE_SYSTEM_ERROR_FAILED,
+ _("Could not get a stock icon for %s\n"),
+ info->icon_name);
}
- return element->pixbuf ? g_object_ref (element->pixbuf) : NULL;
+ return pixbuf;
}
-
-GdkPixbuf *
-gtk_file_info_render_icon (const GtkFileInfo *info,
- GtkWidget *widget,
- gint pixel_size)
+/*****************************************
+ * GtkFileSystemHandle *
+ *****************************************/
+
+enum
{
- const gchar *separator;
- GdkPixbuf *pixbuf;
- GString *icon_name;
+ PROP_0,
+ PROP_CANCELLED
+};
- g_return_val_if_fail (info != NULL, NULL);
- g_return_val_if_fail (widget != NULL, NULL);
- g_return_val_if_fail (pixel_size > 0, NULL);
+G_DEFINE_TYPE (GtkFileSystemHandle, gtk_file_system_handle, G_TYPE_OBJECT)
- if (info->icon_type != GTK_FILE_ICON_REGULAR)
- {
- const char *name = NULL; /* Quiet gcc */
-
- switch (info->icon_type)
- {
- case GTK_FILE_ICON_BLOCK_DEVICE:
- name ="gnome-fs-blockdev";
- break;
- case GTK_FILE_ICON_BROKEN_SYMBOLIC_LINK:
- name = "gnome-fs-symlink";
- break;
- case GTK_FILE_ICON_CHARACTER_DEVICE:
- name = "gnome-fs-chardev";
- break;
- case GTK_FILE_ICON_DIRECTORY:
- name = "gnome-fs-directory";
- break;
- case GTK_FILE_ICON_EXECUTABLE:
- name ="gnome-fs-executable";
- break;
- case GTK_FILE_ICON_FIFO:
- name = "gnome-fs-fifo";
- break;
- case GTK_FILE_ICON_SOCKET:
- name = "gnome-fs-socket";
- break;
- case GTK_FILE_ICON_REGULAR:
- g_assert_not_reached ();
- }
+static void
+gtk_file_system_handle_init (GtkFileSystemHandle *handle)
+{
+ handle->file_system = NULL;
+ handle->cancelled = FALSE;
+}
- return get_cached_icon (widget, name, pixel_size);
- }
-
- if (!info->mime_type)
- return NULL;
+static void
+gtk_file_system_handle_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+}
- separator = strchr (info->mime_type, '/');
- if (!separator)
- return NULL;
+static void
+gtk_file_system_handle_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GtkFileSystemHandle *handle = GTK_FILE_SYSTEM_HANDLE (object);
- icon_name = g_string_new ("gnome-mime-");
- g_string_append_len (icon_name, info->mime_type, separator - info->mime_type);
- g_string_append_c (icon_name, '-');
- g_string_append (icon_name, separator + 1);
- pixbuf = get_cached_icon (widget, icon_name->str, pixel_size);
- g_string_free (icon_name, TRUE);
- if (pixbuf)
- return pixbuf;
+ switch (prop_id)
+ {
+ case PROP_CANCELLED:
+ g_value_set_boolean (value, handle->cancelled);
+ break;
- icon_name = g_string_new ("gnome-mime-");
- g_string_append_len (icon_name, info->mime_type, separator - info->mime_type);
- pixbuf = get_cached_icon (widget, icon_name->str, pixel_size);
- g_string_free (icon_name, TRUE);
- if (pixbuf)
- return pixbuf;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
- return get_cached_icon (widget, "gnome-fs-regular", pixel_size);
+static void
+gtk_file_system_handle_class_init (GtkFileSystemHandleClass *klass)
+{
+ GObjectClass *o_class;
+
+ o_class = (GObjectClass *)klass;
+ o_class->set_property = gtk_file_system_handle_set_property;
+ o_class->get_property = gtk_file_system_handle_get_property;
+
+ g_object_class_install_property (o_class,
+ PROP_CANCELLED,
+ g_param_spec_boolean ("cancelled",
+ P_("Cancelled"),
+ P_("Whether or not the operation has been successfully cancelled"),
+ FALSE,
+ G_PARAM_READABLE));
}
-#endif
/*****************************************
* GtkFileSystem *
};
file_system_type = g_type_register_static (G_TYPE_INTERFACE,
- "GtkFileSystem",
+ I_("GtkFileSystem"),
&file_system_info, 0);
g_type_interface_add_prerequisite (file_system_type, G_TYPE_OBJECT);
{
GType iface_type = G_TYPE_FROM_INTERFACE (g_class);
- g_signal_new ("volumes-changed",
+ g_signal_new (I_("volumes-changed"),
iface_type,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkFileSystemIface, volumes_changed),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
- g_signal_new ("roots-changed",
- iface_type,
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GtkFileSystemIface, roots_changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
- g_signal_new ("bookmarks-changed",
+ g_signal_new (I_("bookmarks-changed"),
iface_type,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkFileSystemIface, bookmarks_changed),
return GTK_FILE_SYSTEM_GET_IFACE (file_system)->list_volumes (file_system);
}
-GSList *
-gtk_file_system_list_roots (GtkFileSystem *file_system)
+GtkFileSystemHandle *
+gtk_file_system_get_folder (GtkFileSystem *file_system,
+ const GtkFilePath *path,
+ GtkFileInfoType types,
+ GtkFileSystemGetFolderCallback callback,
+ gpointer data)
{
g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
+ g_return_val_if_fail (path != NULL, NULL);
+ g_return_val_if_fail (callback != NULL, NULL);
- return GTK_FILE_SYSTEM_GET_IFACE (file_system)->list_roots (file_system);
+ return GTK_FILE_SYSTEM_GET_IFACE (file_system)->get_folder (file_system, path, types, callback, data);
}
-GtkFileInfo *
-gtk_file_system_get_root_info (GtkFileSystem *file_system,
- const GtkFilePath *path,
- GtkFileInfoType types,
- GError **error)
+GtkFileSystemHandle *
+gtk_file_system_get_info (GtkFileSystem *file_system,
+ const GtkFilePath *path,
+ GtkFileInfoType types,
+ GtkFileSystemGetInfoCallback callback,
+ gpointer data)
{
g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
g_return_val_if_fail (path != NULL, NULL);
- g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+ g_return_val_if_fail (callback != NULL, NULL);
- return GTK_FILE_SYSTEM_GET_IFACE (file_system)->get_root_info (file_system, path, types, error);
+ return GTK_FILE_SYSTEM_GET_IFACE (file_system)->get_info (file_system, path, types, callback, data);
}
-GtkFileFolder *
-gtk_file_system_get_folder (GtkFileSystem *file_system,
- const GtkFilePath *path,
- GtkFileInfoType types,
- GError **error)
+GtkFileSystemHandle *
+gtk_file_system_create_folder (GtkFileSystem *file_system,
+ const GtkFilePath *path,
+ GtkFileSystemCreateFolderCallback callback,
+ gpointer data)
{
g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
g_return_val_if_fail (path != NULL, NULL);
- g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+ g_return_val_if_fail (callback != NULL, NULL);
- return GTK_FILE_SYSTEM_GET_IFACE (file_system)->get_folder (file_system, path, types, error);
+ return GTK_FILE_SYSTEM_GET_IFACE (file_system)->create_folder (file_system, path, callback, data);
}
-gboolean
-gtk_file_system_create_folder(GtkFileSystem *file_system,
- const GtkFilePath *path,
- GError **error)
+void
+gtk_file_system_cancel_operation (GtkFileSystemHandle *handle)
{
- g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), FALSE);
- g_return_val_if_fail (path != NULL, FALSE);
- g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+ g_return_if_fail (GTK_IS_FILE_SYSTEM_HANDLE (handle));
- return GTK_FILE_SYSTEM_GET_IFACE (file_system)->create_folder (file_system, path, error);
+ return GTK_FILE_SYSTEM_GET_IFACE (handle->file_system)->cancel_operation (handle);
+}
+
+/**
+ * gtk_file_system_get_volume_for_path:
+ * @file_system: a #GtkFileSystem
+ * @path: a #GtkFilePath
+ *
+ * Queries the file system volume that corresponds to a specific path.
+ * There might not be a volume for all paths (consinder for instance remote
+ * shared), so this can return NULL.
+ *
+ * Return value: the #GtkFileSystemVolume that corresponds to the specified
+ * @path, or NULL if there is no such volume. You should free this value with
+ * gtk_file_system_volume_free().
+ **/
+GtkFileSystemVolume *
+gtk_file_system_get_volume_for_path (GtkFileSystem *file_system,
+ const GtkFilePath *path)
+{
+ g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
+ g_return_val_if_fail (path != NULL, NULL);
+
+ return GTK_FILE_SYSTEM_GET_IFACE (file_system)->get_volume_for_path (file_system, path);
}
/**
*
* Return value: TRUE if the @volume was mounted successfully, FALSE otherwise.
**/
-gboolean
-gtk_file_system_volume_mount (GtkFileSystem *file_system,
- GtkFileSystemVolume *volume,
- GError **error)
+/* FIXME XXX: update documentation above */
+GtkFileSystemHandle *
+gtk_file_system_volume_mount (GtkFileSystem *file_system,
+ GtkFileSystemVolume *volume,
+ GtkFileSystemVolumeMountCallback callback,
+ gpointer data)
{
- g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), FALSE);
- g_return_val_if_fail (volume != NULL, FALSE);
- g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+ g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
+ g_return_val_if_fail (volume != NULL, NULL);
+ g_return_val_if_fail (callback != NULL, NULL);
- return GTK_FILE_SYSTEM_GET_IFACE (file_system)->volume_mount (file_system, volume, error);
+ return GTK_FILE_SYSTEM_GET_IFACE (file_system)->volume_mount (file_system, volume, callback, data);
}
/**
gint pixel_size,
GError **error)
{
+ gchar *icon_name;
+ GdkPixbuf *pixbuf;
+
g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
g_return_val_if_fail (volume != NULL, NULL);
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
g_return_val_if_fail (pixel_size > 0, NULL);
- g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ icon_name = gtk_file_system_volume_get_icon_name (file_system, volume,
+ error);
+ if (!icon_name)
+ {
+ return NULL;
+ }
+
+ pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget)),
+ icon_name, pixel_size, 0, NULL);
+ g_free (icon_name);
+
+ return pixbuf;
+}
+
+/**
+ * gtk_file_system_volume_get_icon_name:
+ * @file_system: a #GtkFileSystem
+ * @volume: a #GtkFileSystemVolume
+ * @error: location to store error, or %NULL
+ *
+ * Gets an icon name suitable for a #GtkFileSystemVolume.
+ *
+ * Return value: An icon name which can be used for rendering an icon for
+ * this volume, or %NULL if no icon name could be found. In the latter
+ * case, the @error value will be set as appropriate.
+ **/
+gchar *
+gtk_file_system_volume_get_icon_name (GtkFileSystem *file_system,
+ GtkFileSystemVolume *volume,
+ GError **error)
+{
+ g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
+ g_return_val_if_fail (volume != NULL, NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
- return GTK_FILE_SYSTEM_GET_IFACE (file_system)->volume_render_icon (file_system,
- volume,
- widget,
- pixel_size,
- error);
+ return GTK_FILE_SYSTEM_GET_IFACE (file_system)->volume_get_icon_name (file_system,
+ volume,
+ error);
}
/**
* @parent: location to store parent path name
* @error: location to store error, or %NULL
*
- * Gets the name of the parent folder of a file.
+ * Gets the name of the parent folder of a path. If the path has no parent, as when
+ * you request the parent of a file system root, then @parent will be set to %NULL.
*
- * Return value: TRUE if the operation was successful; note that in this case @parent
- * can be returned as %NULL if the base @path has no parent folder (i.e. if it is
- * already a file system root). If the operation fails, this function returns FALSE
- * and sets the @error value if it is specified.
+ * Return value: %TRUE if the operation was successful: @parent will be set to
+ * the name of the @path's parent, or to %NULL if @path is already a file system
+ * root. If the operation fails, this function returns %FALSE, sets @parent to
+ * NULL, and sets the @error value if it is specified.
**/
gboolean
gtk_file_system_get_parent (GtkFileSystem *file_system,
GtkFilePath **parent,
GError **error)
{
- GtkFilePath *tmp_parent = NULL;
gboolean result;
g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), FALSE);
g_return_val_if_fail (path != NULL, FALSE);
+ g_return_val_if_fail (parent != NULL, FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
- result = GTK_FILE_SYSTEM_GET_IFACE (file_system)->get_parent (file_system, path, &tmp_parent, error);
- g_assert (result || tmp_parent == NULL);
+ *parent = NULL;
+
+ result = GTK_FILE_SYSTEM_GET_IFACE (file_system)->get_parent (file_system, path, parent, error);
+ g_assert (result || *parent == NULL);
- if (parent)
- *parent = tmp_parent;
- else
- gtk_file_path_free (tmp_parent);
-
return result;
}
g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
g_return_val_if_fail (base_path != NULL, NULL);
g_return_val_if_fail (display_name != NULL, NULL);
- g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
return GTK_FILE_SYSTEM_GET_IFACE (file_system)->make_path (file_system, base_path, display_name, error);
}
g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), FALSE);
g_return_val_if_fail (base_path != NULL, FALSE);
+ g_return_val_if_fail (str != NULL, FALSE);
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
-
result = GTK_FILE_SYSTEM_GET_IFACE (file_system)->parse (file_system, base_path, str,
&tmp_folder, &tmp_file_part,
error);
return GTK_FILE_SYSTEM_GET_IFACE (file_system)->filename_to_path (file_system, filename);
}
-GdkPixbuf *
-gtk_file_system_render_icon (GtkFileSystem *file_system,
- const GtkFilePath *path,
- GtkWidget *widget,
- gint pixel_size,
- GError **error)
+/**
+ * gtk_file_system_path_is_local:
+ * @filesystem: a #GtkFileSystem
+ * @path: A #GtkFilePath from that filesystem
+ *
+ * Checks whether a #GtkFilePath is local; that is whether
+ * gtk_file_system_path_to_filename would return non-%NULL.
+ *
+ * Return value: %TRUE if the path is loca
+ **/
+gboolean
+gtk_file_system_path_is_local (GtkFileSystem *file_system,
+ const GtkFilePath *path)
{
- g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
- g_return_val_if_fail (path != NULL, NULL);
- g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
- g_return_val_if_fail (pixel_size > 0, NULL);
+ gchar *filename;
+ gboolean result;
+
+ g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), FALSE);
+ g_return_val_if_fail (path != NULL, FALSE);
- return GTK_FILE_SYSTEM_GET_IFACE (file_system)->render_icon (file_system, path, widget, pixel_size, error);
+ filename = gtk_file_system_path_to_filename (file_system, path);
+ result = filename != NULL;
+ g_free (filename);
+
+ return result;
}
/**
- * gtk_file_system_add_bookmark:
+ * gtk_file_system_insert_bookmark:
* @file_system: a #GtkFileSystem
- * @bookmark: path of the bookmark to add
+ * @path: path of the bookmark to add
+ * @position: index in the bookmarks list at which the @path should be inserted; use 0
+ * for the beginning, and -1 or the number of bookmarks itself for the end of the list.
* @error: location to store error, or %NULL
*
- * Adds a bookmark folder to the user's bookmarks list. If the operation succeeds,
- * the "bookmarks_changed" signal will be emitted.
+ * Adds a path for a folder to the user's bookmarks list. If the operation
+ * succeeds, the "bookmarks_changed" signal will be emitted. Bookmark paths are
+ * unique; if you try to insert a @path that already exists, the operation will
+ * fail and the @error will be set to #GTK_FILE_SYSTEM_ERROR_ALREADY_EXISTS. To
+ * reorder the list of bookmarks, use gtk_file_system_remove_bookmark() to
+ * remove the path in question, and call gtk_file_system_insert_bookmark() with
+ * the new position for the path.
*
* Return value: TRUE if the operation succeeds, FALSE otherwise. In the latter case,
* the @error value will be set.
**/
gboolean
-gtk_file_system_add_bookmark (GtkFileSystem *file_system,
- const GtkFilePath *path,
- GError **error)
+gtk_file_system_insert_bookmark (GtkFileSystem *file_system,
+ const GtkFilePath *path,
+ gint position,
+ GError **error)
{
g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), FALSE);
g_return_val_if_fail (path != NULL, FALSE);
- return GTK_FILE_SYSTEM_GET_IFACE (file_system)->add_bookmark (file_system, path, error);
+ return GTK_FILE_SYSTEM_GET_IFACE (file_system)->insert_bookmark (file_system, path, position, error);
}
/**
* gtk_file_system_remove_bookmark:
* @file_system: a #GtkFileSystem
- * @bookmark: path of the bookmark to remove
+ * @path: path of the bookmark to remove
* @error: location to store error, or %NULL
*
* Removes a bookmark folder from the user's bookmarks list. If the operation
- * succeeds, the "bookmarks_changed" signal will be emitted.
+ * succeeds, the "bookmarks_changed" signal will be emitted. If you try to remove
+ * a @path which does not exist in the bookmarks list, the operation will fail
+ * and the @error will be set to GTK_FILE_SYSTEM_ERROR_NONEXISTENT.
*
* Return value: TRUE if the operation succeeds, FALSE otherwise. In the latter
* case, the @error value will be set.
return GTK_FILE_SYSTEM_GET_IFACE (file_system)->list_bookmarks (file_system);
}
+/**
+ * gtk_file_system_get_bookmark_label:
+ * @file_system: a #GtkFileSystem
+ * @path: path of the bookmark
+ *
+ * Gets the label to display for a bookmark, or %NULL.
+ *
+ * Returns: the label for the bookmark @path
+ *
+ * Since: 2.8
+ */
+gchar *
+gtk_file_system_get_bookmark_label (GtkFileSystem *file_system,
+ const GtkFilePath *path)
+{
+ GtkFileSystemIface *iface;
+
+ g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
+ g_return_val_if_fail (path != NULL, NULL);
+
+ iface = GTK_FILE_SYSTEM_GET_IFACE (file_system);
+ if (iface->get_bookmark_label)
+ return iface->get_bookmark_label (file_system, path);
+
+ return NULL;
+}
+
+/**
+ * gtk_file_system_set_bookmark_label:
+ * @file_system: a #GtkFileSystem
+ * @path: path of the bookmark
+ * @label: the label for the bookmark, or %NULL to display
+ * the path itself
+ *
+ * Sets the label to display for a bookmark.
+ *
+ * Since: 2.8
+ */
+void
+gtk_file_system_set_bookmark_label (GtkFileSystem *file_system,
+ const GtkFilePath *path,
+ const gchar *label)
+{
+ GtkFileSystemIface *iface;
+
+ g_return_if_fail (GTK_IS_FILE_SYSTEM (file_system));
+ g_return_if_fail (path != NULL);
+
+ iface = GTK_FILE_SYSTEM_GET_IFACE (file_system);
+ if (iface->set_bookmark_label)
+ iface->set_bookmark_label (file_system, path, label);
+}
+
/*****************************************
* GtkFileFolder *
*****************************************/
};
file_folder_type = g_type_register_static (G_TYPE_INTERFACE,
- "GtkFileFolder",
+ I_("GtkFileFolder"),
&file_folder_info, 0);
g_type_interface_add_prerequisite (file_folder_type, G_TYPE_OBJECT);
{
GType iface_type = G_TYPE_FROM_INTERFACE (g_class);
- g_signal_new ("deleted",
+ g_signal_new (I_("deleted"),
iface_type,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkFileFolderIface, deleted),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
- g_signal_new ("files-added",
+ g_signal_new (I_("files-added"),
iface_type,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkFileFolderIface, files_added),
g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE, 1,
G_TYPE_POINTER);
- g_signal_new ("files-changed",
+ g_signal_new (I_("files-changed"),
iface_type,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkFileFolderIface, files_changed),
g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE, 1,
G_TYPE_POINTER);
- g_signal_new ("files-removed",
+ g_signal_new (I_("files-removed"),
iface_type,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkFileFolderIface, files_removed),
g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE, 1,
G_TYPE_POINTER);
+ g_signal_new (I_("finished-loading"),
+ iface_type,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GtkFileFolderIface, finished_loading),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
initialized = TRUE;
}
GError **error)
{
g_return_val_if_fail (GTK_IS_FILE_FOLDER (folder), NULL);
- g_return_val_if_fail (path != NULL, NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
return GTK_FILE_FOLDER_GET_IFACE (folder)->get_info (folder, path, error);
}
+gboolean
+gtk_file_folder_is_finished_loading (GtkFileFolder *folder)
+{
+ GtkFileFolderIface *iface;
+
+ g_return_val_if_fail (GTK_IS_FILE_FOLDER (folder), TRUE);
+
+ iface = GTK_FILE_FOLDER_GET_IFACE (folder);
+ if (!iface->is_finished_loading)
+ return TRUE;
+ else
+ return iface->is_finished_loading (folder);
+}
+
+
+/*****************************************
+ * GtkFilePath modules *
+ *****************************************/
+
+/* We make these real functions in case either copy or free are implemented as macros
+ */
+static gpointer
+gtk_file_path_real_copy (gpointer boxed)
+{
+ return gtk_file_path_copy ((GtkFilePath *) boxed);
+}
+
+static void
+gtk_file_path_real_free (gpointer boxed)
+{
+ gtk_file_path_free (boxed);
+}
+
+GType
+gtk_file_path_get_type (void)
+{
+ static GType our_type = 0;
+
+ if (our_type == 0)
+ our_type = g_boxed_type_register_static (I_("GtkFilePath"),
+ (GBoxedCopyFunc) gtk_file_path_real_copy,
+ (GBoxedFreeFunc) gtk_file_path_real_free);
+
+ return our_type;
+}
+
+
GSList *
gtk_file_paths_sort (GSList *paths)
{
/**
* gtk_file_paths_copy:
- * @paths: A #GSList of 3GtkFilePath structures.
+ * @paths: A #GSList of #GtkFilePath structures.
*
* Copies a list of #GtkFilePath structures.
*
g_slist_free (paths);
}
+
+/*****************************************
+ * GtkFileSystem modules *
+ *****************************************/
+
+typedef struct _GtkFileSystemModule GtkFileSystemModule;
+typedef struct _GtkFileSystemModuleClass GtkFileSystemModuleClass;
+
+struct _GtkFileSystemModule
+{
+ GTypeModule parent_instance;
+
+ GModule *library;
+
+ void (*init) (GTypeModule *module);
+ void (*exit) (void);
+ GtkFileSystem * (*create) (void);
+
+ gchar *path;
+};
+
+struct _GtkFileSystemModuleClass
+{
+ GTypeModuleClass parent_class;
+};
+
+G_DEFINE_TYPE (GtkFileSystemModule, _gtk_file_system_module, G_TYPE_TYPE_MODULE);
+#define GTK_TYPE_FILE_SYSTEM_MODULE (_gtk_file_system_module_get_type ())
+#define GTK_FILE_SYSTEM_MODULE(module) (G_TYPE_CHECK_INSTANCE_CAST ((module), GTK_TYPE_FILE_SYSTEM_MODULE, GtkFileSystemModule))
+
+
+static GSList *loaded_file_systems;
+
+static gboolean
+gtk_file_system_module_load (GTypeModule *module)
+{
+ GtkFileSystemModule *fs_module = GTK_FILE_SYSTEM_MODULE (module);
+
+ fs_module->library = g_module_open (fs_module->path, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
+ if (!fs_module->library)
+ {
+ g_warning (g_module_error());
+ return FALSE;
+ }
+
+ /* extract symbols from the lib */
+ if (!g_module_symbol (fs_module->library, "fs_module_init",
+ (gpointer *)&fs_module->init) ||
+ !g_module_symbol (fs_module->library, "fs_module_exit",
+ (gpointer *)&fs_module->exit) ||
+ !g_module_symbol (fs_module->library, "fs_module_create",
+ (gpointer *)&fs_module->create))
+ {
+ g_warning (g_module_error());
+ g_module_close (fs_module->library);
+
+ return FALSE;
+ }
+
+ /* call the filesystems's init function to let it */
+ /* setup anything it needs to set up. */
+ fs_module->init (module);
+
+ return TRUE;
+}
+
+static void
+gtk_file_system_module_unload (GTypeModule *module)
+{
+ GtkFileSystemModule *fs_module = GTK_FILE_SYSTEM_MODULE (module);
+
+ fs_module->exit();
+
+ g_module_close (fs_module->library);
+ fs_module->library = NULL;
+
+ fs_module->init = NULL;
+ fs_module->exit = NULL;
+ fs_module->create = NULL;
+}
+
+/* This only will ever be called if an error occurs during
+ * initialization
+ */
+static void
+gtk_file_system_module_finalize (GObject *object)
+{
+ GtkFileSystemModule *module = GTK_FILE_SYSTEM_MODULE (object);
+
+ g_free (module->path);
+
+ G_OBJECT_CLASS (_gtk_file_system_module_parent_class)->finalize (object);
+}
+
+static void
+_gtk_file_system_module_class_init (GtkFileSystemModuleClass *class)
+{
+ GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS (class);
+ GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+
+ module_class->load = gtk_file_system_module_load;
+ module_class->unload = gtk_file_system_module_unload;
+
+ gobject_class->finalize = gtk_file_system_module_finalize;
+}
+
+static void
+_gtk_file_system_module_init (GtkFileSystemModule *fs_module)
+{
+}
+
+
+static GtkFileSystem *
+_gtk_file_system_module_create (GtkFileSystemModule *fs_module)
+{
+ GtkFileSystem *fs;
+
+ if (g_type_module_use (G_TYPE_MODULE (fs_module)))
+ {
+ fs = fs_module->create ();
+ g_type_module_unuse (G_TYPE_MODULE (fs_module));
+ return fs;
+ }
+ return NULL;
+}
+
+
+GtkFileSystem *
+_gtk_file_system_create (const char *file_system_name)
+{
+ GSList *l;
+ char *module_path;
+ GtkFileSystemModule *fs_module;
+ GtkFileSystem *fs;
+
+ for (l = loaded_file_systems; l != NULL; l = l->next)
+ {
+ fs_module = l->data;
+
+ if (strcmp (G_TYPE_MODULE (fs_module)->name, file_system_name) == 0)
+ return _gtk_file_system_module_create (fs_module);
+ }
+
+ fs = NULL;
+ if (g_module_supported ())
+ {
+ module_path = _gtk_find_module (file_system_name, "filesystems");
+
+ if (module_path)
+ {
+ fs_module = g_object_new (GTK_TYPE_FILE_SYSTEM_MODULE, NULL);
+
+ g_type_module_set_name (G_TYPE_MODULE (fs_module), file_system_name);
+ fs_module->path = g_strdup (module_path);
+
+ loaded_file_systems = g_slist_prepend (loaded_file_systems,
+ fs_module);
+
+ fs = _gtk_file_system_module_create (fs_module);
+ }
+
+ g_free (module_path);
+ }
+
+ return fs;
+}
+
+#define __GTK_FILE_SYSTEM_C__
+#include "gtkaliasdef.c"