* Copyright (C) 2003, Red Hat, Inc.
* Copyright (C) 2007-2008 Carlos Garnacho
*
- * This program is free software; you can redistribute it and/or modify
+ * This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
- * This program is distributed in the hope that it will be useful,
+ * This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * GNU Lesser General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Carlos Garnacho <carlos@imendio.com>
*/
#include "gtkicontheme.h"
#include "gtkprivate.h"
-#include "gtkalias.h"
-
/* #define DEBUG_MODE */
#ifdef DEBUG_MODE
#define DEBUG(x) g_debug (x);
#define DEBUG(x)
#endif
-#define GTK_FILE_SYSTEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_FILE_SYSTEM, GtkFileSystemPrivate))
-#define GTK_FOLDER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_FOLDER, GtkFolderPrivate))
#define FILES_PER_QUERY 100
/* The pointers we return for a GtkFileSystemVolume are opaque tokens; they are
};
static guint fs_signals [FS_LAST_SIGNAL] = { 0, };
-static guint folder_signals [FOLDER_LAST_SIGNAL] = { 0, };
-typedef struct GtkFileSystemPrivate GtkFileSystemPrivate;
-typedef struct GtkFolderPrivate GtkFolderPrivate;
typedef struct AsyncFuncData AsyncFuncData;
struct GtkFileSystemPrivate
GFileMonitor *bookmarks_monitor;
};
-struct GtkFolderPrivate
-{
- GFile *folder_file;
- GHashTable *children;
- GFileMonitor *directory_monitor;
- GFileEnumerator *enumerator;
- GCancellable *cancellable;
- gchar *attributes;
-
- guint finished_loading : 1;
-};
-
struct AsyncFuncData
{
GtkFileSystem *file_system;
GFile *file;
- GtkFolder *folder;
GCancellable *cancellable;
gchar *attributes;
G_DEFINE_TYPE (GtkFileSystem, _gtk_file_system, G_TYPE_OBJECT)
-G_DEFINE_TYPE (GtkFolder, _gtk_folder, G_TYPE_OBJECT)
-
-
-static void gtk_folder_set_finished_loading (GtkFolder *folder,
- gboolean finished_loading);
-static void gtk_folder_add_file (GtkFolder *folder,
- GFile *file,
- GFileInfo *info);
-
/* GtkFileSystemBookmark methods */
void
static void
gtk_file_system_dispose (GObject *object)
{
- GtkFileSystemPrivate *priv;
+ GtkFileSystem *file_system = GTK_FILE_SYSTEM (object);
+ GtkFileSystemPrivate *priv = file_system->priv;
DEBUG ("dispose");
- priv = GTK_FILE_SYSTEM_GET_PRIVATE (object);
-
if (priv->volumes)
{
g_slist_foreach (priv->volumes, (GFunc) g_object_unref, NULL);
static void
gtk_file_system_finalize (GObject *object)
{
- GtkFileSystemPrivate *priv;
+ GtkFileSystem *file_system = GTK_FILE_SYSTEM (object);
+ GtkFileSystemPrivate *priv = file_system->priv;
DEBUG ("finalize");
- priv = GTK_FILE_SYSTEM_GET_PRIVATE (object);
-
if (priv->bookmarks_monitor)
g_object_unref (priv->bookmarks_monitor);
}
static GFile *
-get_bookmarks_file (void)
+get_legacy_bookmarks_file (void)
{
GFile *file;
gchar *filename;
return file;
}
+static GFile *
+get_bookmarks_file (void)
+{
+ GFile *file;
+ gchar *filename;
+
+ filename = g_build_filename (g_get_user_config_dir (), "gtk-3.0", "bookmarks", NULL);
+ file = g_file_new_for_path (filename);
+ g_free (filename);
+
+ return file;
+}
+
static GSList *
read_bookmarks (GFile *file)
{
if (!*lines[i])
continue;
+ if (!g_utf8_validate (lines[i], -1, NULL))
+ continue;
+
bookmark = g_slice_new0 (GtkFileSystemBookmark);
if ((space = strchr (lines[i], ' ')) != NULL)
{
GError *error = NULL;
GString *contents;
+ GSList *l;
+ GFile *parent_file;
+ gchar *path;
contents = g_string_new ("");
- while (bookmarks)
+ for (l = bookmarks; l; l = l->next)
{
- GtkFileSystemBookmark *bookmark;
+ GtkFileSystemBookmark *bookmark = l->data;
gchar *uri;
- bookmark = bookmarks->data;
uri = g_file_get_uri (bookmark->file);
+ if (!uri)
+ continue;
+
g_string_append (contents, uri);
if (bookmark->label)
g_string_append_printf (contents, " %s", bookmark->label);
g_string_append_c (contents, '\n');
- bookmarks = bookmarks->next;
g_free (uri);
}
- if (!g_file_replace_contents (bookmarks_file,
- contents->str,
- strlen (contents->str),
- NULL, FALSE, 0, NULL,
- NULL, &error))
+ parent_file = g_file_get_parent (bookmarks_file);
+ path = g_file_get_path (parent_file);
+ if (g_mkdir_with_parents (path, 0700) == 0)
{
- g_critical ("%s", error->message);
- g_error_free (error);
+ if (!g_file_replace_contents (bookmarks_file,
+ contents->str,
+ strlen (contents->str),
+ NULL, FALSE, 0, NULL,
+ NULL, &error))
+ {
+ g_critical ("%s", error->message);
+ g_error_free (error);
+ }
}
-
+ g_free (path);
+ g_object_unref (parent_file);
g_string_free (contents, TRUE);
}
GFileMonitorEvent event,
gpointer data)
{
- GtkFileSystemPrivate *priv;
-
- priv = GTK_FILE_SYSTEM_GET_PRIVATE (data);
+ GtkFileSystem *file_system = GTK_FILE_SYSTEM (data);
+ GtkFileSystemPrivate *priv = file_system->priv;
switch (event)
{
static void
get_volumes_list (GtkFileSystem *file_system)
{
- GtkFileSystemPrivate *priv;
+ GtkFileSystemPrivate *priv = file_system->priv;
GList *l, *ll;
GList *drives;
GList *volumes;
GVolume *volume;
GMount *mount;
- priv = GTK_FILE_SYSTEM_GET_PRIVATE (file_system);
-
if (priv->volumes)
{
g_slist_foreach (priv->volumes, (GFunc) g_object_unref, NULL);
priv->volumes = g_slist_prepend (priv->volumes, g_object_ref (drive));
}
+
+ g_object_unref (drive);
}
g_list_free (drives);
/* see comment above in why we add an icon for a volume */
priv->volumes = g_slist_prepend (priv->volumes, g_object_ref (volume));
}
+
+ g_object_unref (volume);
}
/* add mounts that has no volume (/etc/mtab mounts, ftp, sftp,...) */
*/
if (mount_referenced_by_volume_activation_root (volumes, mount))
{
+ g_object_unref (mount);
continue;
}
/* show this mount */
priv->volumes = g_slist_prepend (priv->volumes, g_object_ref (mount));
+ g_object_unref (mount);
}
g_list_free (volumes);
DEBUG ("init");
- priv = GTK_FILE_SYSTEM_GET_PRIVATE (file_system);
+ file_system->priv = G_TYPE_INSTANCE_GET_PRIVATE (file_system,
+ GTK_TYPE_FILE_SYSTEM,
+ GtkFileSystemPrivate);
+ priv = file_system->priv;
/* Volumes */
priv->volume_monitor = g_volume_monitor_get ();
/* Bookmarks */
bookmarks_file = get_bookmarks_file ();
priv->bookmarks = read_bookmarks (bookmarks_file);
+ if (!priv->bookmarks)
+ {
+ GFile *legacy_bookmarks_file;
+
+ /* Read the legacy one and write it to the new one */
+ legacy_bookmarks_file = get_legacy_bookmarks_file ();
+ priv->bookmarks = read_bookmarks (legacy_bookmarks_file);
+ save_bookmarks (bookmarks_file, priv->bookmarks);
+
+ g_object_unref (legacy_bookmarks_file);
+ }
+
priv->bookmarks_monitor = g_file_monitor_file (bookmarks_file,
G_FILE_MONITOR_NONE,
NULL, &error);
GSList *
_gtk_file_system_list_volumes (GtkFileSystem *file_system)
{
- GtkFileSystemPrivate *priv;
+ GtkFileSystemPrivate *priv = file_system->priv;
GSList *list;
DEBUG ("list_volumes");
- g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
-
- priv = GTK_FILE_SYSTEM_GET_PRIVATE (file_system);
- get_volumes_list (GTK_FILE_SYSTEM (file_system));
+ get_volumes_list (file_system);
list = g_slist_copy (priv->volumes);
GSList *
_gtk_file_system_list_bookmarks (GtkFileSystem *file_system)
{
- GtkFileSystemPrivate *priv;
+ GtkFileSystemPrivate *priv = file_system->priv;
GSList *bookmarks, *files = NULL;
DEBUG ("list_bookmarks");
- priv = GTK_FILE_SYSTEM_GET_PRIVATE (file_system);
bookmarks = priv->bookmarks;
while (bookmarks)
return g_slist_reverse (files);
}
-gboolean
-_gtk_file_system_parse (GtkFileSystem *file_system,
- GFile *base_file,
- const gchar *str,
- GFile **folder,
- gchar **file_part,
- GError **error)
-{
- GFile *file;
- gboolean result = FALSE;
- gboolean is_dir = FALSE;
- gchar *last_slash = NULL;
-
- DEBUG ("parse");
-
- if (str && *str)
- is_dir = (str [strlen (str) - 1] == G_DIR_SEPARATOR);
-
- last_slash = strrchr (str, G_DIR_SEPARATOR);
-
- if (str[0] == '~')
- file = g_file_parse_name (str);
- else
- file = g_file_resolve_relative_path (base_file, str);
-
- if (g_file_equal (base_file, file))
- {
- /* this is when user types '.', could be the
- * beginning of a hidden file, ./ or ../
- */
- *folder = g_object_ref (file);
- *file_part = g_strdup (str);
- result = TRUE;
- }
- else if (is_dir)
- {
- /* it's a dir, or at least it ends with the dir separator */
- *folder = g_object_ref (file);
- *file_part = g_strdup ("");
- result = TRUE;
- }
- else
- {
- GFile *parent_file;
-
- parent_file = g_file_get_parent (file);
-
- if (!parent_file)
- {
- g_set_error (error,
- GTK_FILE_CHOOSER_ERROR,
- GTK_FILE_CHOOSER_ERROR_NONEXISTENT,
- "Could not get parent file");
- *folder = NULL;
- *file_part = NULL;
- }
- else
- {
- *folder = parent_file;
- result = TRUE;
-
- if (last_slash)
- *file_part = g_strdup (last_slash + 1);
- else
- *file_part = g_strdup (str);
- }
- }
-
- g_object_unref (file);
-
- return result;
-}
-
static void
free_async_data (AsyncFuncData *async_data)
{
g_object_unref (async_data->file);
g_object_unref (async_data->cancellable);
- if (async_data->folder)
- g_object_unref (async_data->folder);
-
g_free (async_data->attributes);
g_free (async_data);
}
-static void
-enumerate_children_callback (GObject *source_object,
- GAsyncResult *result,
- gpointer user_data)
-{
- GFileEnumerator *enumerator;
- AsyncFuncData *async_data;
- GtkFolder *folder = NULL;
- GFile *file;
- GError *error = NULL;
-
- file = G_FILE (source_object);
- async_data = (AsyncFuncData *) user_data;
- enumerator = g_file_enumerate_children_finish (file, result, &error);
-
- if (enumerator)
- {
- folder = g_object_new (GTK_TYPE_FOLDER,
- "file", source_object,
- "enumerator", enumerator,
- "attributes", async_data->attributes,
- NULL);
- g_object_unref (enumerator);
- }
-
- gdk_threads_enter ();
- ((GtkFileSystemGetFolderCallback) async_data->callback) (async_data->cancellable,
- folder, error, async_data->data);
- gdk_threads_leave ();
-
- free_async_data (async_data);
-
- if (error)
- g_error_free (error);
-}
-
-GCancellable *
-_gtk_file_system_get_folder (GtkFileSystem *file_system,
- GFile *file,
- const gchar *attributes,
- GtkFileSystemGetFolderCallback callback,
- gpointer data)
-{
- GCancellable *cancellable;
- AsyncFuncData *async_data;
-
- g_return_val_if_fail (GTK_IS_FILE_SYSTEM (file_system), NULL);
- g_return_val_if_fail (G_IS_FILE (file), NULL);
-
- cancellable = g_cancellable_new ();
-
- async_data = g_new0 (AsyncFuncData, 1);
- async_data->file_system = g_object_ref (file_system);
- async_data->file = g_object_ref (file);
- async_data->cancellable = g_object_ref (cancellable);
- async_data->attributes = g_strdup (attributes);
-
- async_data->callback = callback;
- async_data->data = data;
-
- g_file_enumerate_children_async (file,
- attributes,
- G_FILE_QUERY_INFO_NONE,
- G_PRIORITY_DEFAULT,
- cancellable,
- enumerate_children_callback,
- async_data);
- return cancellable;
-}
-
static void
query_info_callback (GObject *source_object,
GAsyncResult *result,
g_file_mount_enclosing_volume_finish (G_FILE (source_object), result, &error);
volume = _gtk_file_system_get_volume_for_file (async_data->file_system, G_FILE (source_object));
+ /* Silently drop G_IO_ERROR_ALREADY_MOUNTED error for gvfs backends without visible mounts. */
+ /* Better than doing query_info with additional I/O every time. */
+ if (error && g_error_matches (error, G_IO_ERROR, G_IO_ERROR_ALREADY_MOUNTED))
+ g_clear_error (&error);
+
gdk_threads_enter ();
((GtkFileSystemVolumeMountCallback) async_data->callback) (async_data->cancellable, volume,
error, async_data->data);
if (error)
g_error_free (error);
+
+ _gtk_file_system_volume_unref (volume);
}
GCancellable *
gint position,
GError **error)
{
- GtkFileSystemPrivate *priv;
+ GtkFileSystemPrivate *priv = file_system->priv;
GSList *bookmarks;
GtkFileSystemBookmark *bookmark;
gboolean result = TRUE;
GFile *bookmarks_file;
- priv = GTK_FILE_SYSTEM_GET_PRIVATE (file_system);
bookmarks = priv->bookmarks;
while (bookmarks)
GFile *file,
GError **error)
{
- GtkFileSystemPrivate *priv;
+ GtkFileSystemPrivate *priv = file_system->priv;
GtkFileSystemBookmark *bookmark;
GSList *bookmarks;
gboolean result = FALSE;
GFile *bookmarks_file;
- priv = GTK_FILE_SYSTEM_GET_PRIVATE (file_system);
-
if (!priv->bookmarks)
return FALSE;
_gtk_file_system_get_bookmark_label (GtkFileSystem *file_system,
GFile *file)
{
- GtkFileSystemPrivate *priv;
+ GtkFileSystemPrivate *priv = file_system->priv;
GSList *bookmarks;
gchar *label = NULL;
DEBUG ("get_bookmark_label");
- priv = GTK_FILE_SYSTEM_GET_PRIVATE (file_system);
bookmarks = priv->bookmarks;
while (bookmarks)
GFile *file,
const gchar *label)
{
- GtkFileSystemPrivate *priv;
+ GtkFileSystemPrivate *priv = file_system->priv;
gboolean changed = FALSE;
GFile *bookmarks_file;
GSList *bookmarks;
DEBUG ("set_bookmark_label");
- priv = GTK_FILE_SYSTEM_GET_PRIVATE (file_system);
bookmarks = priv->bookmarks;
while (bookmarks)
_gtk_file_system_get_volume_for_file (GtkFileSystem *file_system,
GFile *file)
{
- GtkFileSystemPrivate *priv;
GMount *mount;
DEBUG ("get_volume_for_file");
- priv = GTK_FILE_SYSTEM_GET_PRIVATE (file_system);
mount = g_file_find_enclosing_mount (file, NULL, NULL);
if (!mount && g_file_is_native (file))
return (GtkFileSystemVolume *) mount;
}
-/* GtkFolder methods */
-static void
-gtk_folder_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GtkFolderPrivate *priv;
-
- priv = GTK_FOLDER_GET_PRIVATE (object);
-
- switch (prop_id)
- {
- case PROP_FILE:
- priv->folder_file = g_value_dup_object (value);
- break;
- case PROP_ENUMERATOR:
- priv->enumerator = g_value_dup_object (value);
- break;
- case PROP_ATTRIBUTES:
- priv->attributes = g_value_dup_string (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gtk_folder_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GtkFolderPrivate *priv;
-
- priv = GTK_FOLDER_GET_PRIVATE (object);
-
- switch (prop_id)
- {
- case PROP_FILE:
- g_value_set_object (value, priv->folder_file);
- break;
- case PROP_ENUMERATOR:
- g_value_set_object (value, priv->enumerator);
- break;
- case PROP_ATTRIBUTES:
- g_value_set_string (value, priv->attributes);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-query_created_file_info_callback (GObject *source_object,
- GAsyncResult *result,
- gpointer user_data)
-{
- GFile *file = G_FILE (source_object);
- GError *error = NULL;
- GFileInfo *info;
- GtkFolder *folder;
- GSList *files;
-
- info = g_file_query_info_finish (file, result, &error);
-
- if (error)
- {
- g_error_free (error);
- return;
- }
-
- folder = GTK_FOLDER (user_data);
- gtk_folder_add_file (folder, file, info);
-
- files = g_slist_prepend (NULL, file);
- g_signal_emit (folder, folder_signals[FILES_ADDED], 0, files);
- g_slist_free (files);
-
- g_object_unref (info);
-}
-
-static void
-directory_monitor_changed (GFileMonitor *monitor,
- GFile *file,
- GFile *other_file,
- GFileMonitorEvent event,
- gpointer data)
-{
- GtkFolderPrivate *priv;
- GtkFolder *folder;
- GSList *files;
-
- folder = GTK_FOLDER (data);
- priv = GTK_FOLDER_GET_PRIVATE (folder);
- files = g_slist_prepend (NULL, file);
-
- gdk_threads_enter ();
-
- switch (event)
- {
- case G_FILE_MONITOR_EVENT_CREATED:
- g_file_query_info_async (file,
- priv->attributes,
- G_FILE_QUERY_INFO_NONE,
- G_PRIORITY_DEFAULT,
- priv->cancellable,
- query_created_file_info_callback,
- folder);
- break;
- case G_FILE_MONITOR_EVENT_DELETED:
- if (g_file_equal (file, priv->folder_file))
- g_signal_emit (folder, folder_signals[DELETED], 0);
- else
- g_signal_emit (folder, folder_signals[FILES_REMOVED], 0, files);
- break;
- default:
- break;
- }
-
- gdk_threads_leave ();
-
- g_slist_free (files);
-}
-
-static void
-enumerator_files_callback (GObject *source_object,
- GAsyncResult *result,
- gpointer user_data)
-{
- GFileEnumerator *enumerator;
- GtkFolderPrivate *priv;
- GtkFolder *folder;
- GError *error = NULL;
- GSList *files = NULL;
- GList *file_infos, *f;
-
- enumerator = G_FILE_ENUMERATOR (source_object);
- file_infos = g_file_enumerator_next_files_finish (enumerator, result, &error);
-
- if (error)
- {
- if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
- g_warning ("%s", error->message);
-
- g_error_free (error);
- return;
- }
-
- folder = GTK_FOLDER (user_data);
- priv = GTK_FOLDER_GET_PRIVATE (folder);
-
- if (!file_infos)
- {
- g_file_enumerator_close_async (enumerator,
- G_PRIORITY_DEFAULT,
- NULL, NULL, NULL);
-
- gtk_folder_set_finished_loading (folder, TRUE);
- return;
- }
-
- g_file_enumerator_next_files_async (enumerator, FILES_PER_QUERY,
- G_PRIORITY_DEFAULT,
- priv->cancellable,
- enumerator_files_callback,
- folder);
-
- for (f = file_infos; f; f = f->next)
- {
- GFileInfo *info;
- GFile *child_file;
-
- info = f->data;
- child_file = g_file_get_child (priv->folder_file, g_file_info_get_name (info));
- gtk_folder_add_file (folder, child_file, info);
- files = g_slist_prepend (files, child_file);
- }
-
- gdk_threads_enter ();
- g_signal_emit (folder, folder_signals[FILES_ADDED], 0, files);
- gdk_threads_leave ();
-
- g_list_foreach (file_infos, (GFunc) g_object_unref, NULL);
- g_list_free (file_infos);
-
- g_slist_foreach (files, (GFunc) g_object_unref, NULL);
- g_slist_free (files);
-}
-
-static void
-gtk_folder_constructed (GObject *object)
-{
- GtkFolderPrivate *priv;
- GError *error = NULL;
-
- priv = GTK_FOLDER_GET_PRIVATE (object);
- priv->directory_monitor = g_file_monitor_directory (priv->folder_file, G_FILE_MONITOR_NONE, NULL, &error);
-
- if (error)
- {
- g_warning ("%s", error->message);
- g_error_free (error);
- }
- else
- g_signal_connect (priv->directory_monitor, "changed",
- G_CALLBACK (directory_monitor_changed), object);
-
- g_file_enumerator_next_files_async (priv->enumerator,
- FILES_PER_QUERY,
- G_PRIORITY_DEFAULT,
- priv->cancellable,
- enumerator_files_callback,
- object);
- /* This isn't needed anymore */
- g_object_unref (priv->enumerator);
- priv->enumerator = NULL;
-}
-
-static void
-gtk_folder_finalize (GObject *object)
-{
- GtkFolderPrivate *priv;
-
- priv = GTK_FOLDER_GET_PRIVATE (object);
-
- g_hash_table_unref (priv->children);
-
- if (priv->folder_file)
- g_object_unref (priv->folder_file);
-
- if (priv->directory_monitor)
- g_object_unref (priv->directory_monitor);
-
- g_cancellable_cancel (priv->cancellable);
- g_object_unref (priv->cancellable);
- g_free (priv->attributes);
-
- G_OBJECT_CLASS (_gtk_folder_parent_class)->finalize (object);
-}
-
-static void
-_gtk_folder_class_init (GtkFolderClass *class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (class);
-
- object_class->set_property = gtk_folder_set_property;
- object_class->get_property = gtk_folder_get_property;
- object_class->constructed = gtk_folder_constructed;
- object_class->finalize = gtk_folder_finalize;
-
- g_object_class_install_property (object_class,
- PROP_FILE,
- g_param_spec_object ("file",
- "File",
- "GFile for the folder",
- G_TYPE_FILE,
- GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
- g_object_class_install_property (object_class,
- PROP_ENUMERATOR,
- g_param_spec_object ("enumerator",
- "Enumerator",
- "GFileEnumerator to list files",
- G_TYPE_FILE_ENUMERATOR,
- GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
- g_object_class_install_property (object_class,
- PROP_ATTRIBUTES,
- g_param_spec_string ("attributes",
- "Attributes",
- "Attributes to query for",
- NULL,
- GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
- folder_signals[FILES_ADDED] =
- g_signal_new ("files-added",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GtkFolderClass, files_added),
- NULL, NULL,
- g_cclosure_marshal_VOID__POINTER,
- G_TYPE_NONE, 1, G_TYPE_POINTER);
- folder_signals[FILES_REMOVED] =
- g_signal_new ("files-removed",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GtkFolderClass, files_removed),
- NULL, NULL,
- g_cclosure_marshal_VOID__POINTER,
- G_TYPE_NONE, 1, G_TYPE_POINTER);
- folder_signals[FILES_CHANGED] =
- g_signal_new ("files-changed",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GtkFolderClass, files_changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__POINTER,
- G_TYPE_NONE, 1, G_TYPE_POINTER);
- folder_signals[FINISHED_LOADING] =
- g_signal_new ("finished-loading",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GtkFolderClass, finished_loading),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
- folder_signals[DELETED] =
- g_signal_new ("deleted",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GtkFolderClass, deleted),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- g_type_class_add_private (object_class, sizeof (GtkFolderPrivate));
-}
-
-static void
-_gtk_folder_init (GtkFolder *folder)
-{
- GtkFolderPrivate *priv;
-
- priv = GTK_FOLDER_GET_PRIVATE (folder);
-
- priv->children = g_hash_table_new_full (g_file_hash,
- (GEqualFunc) g_file_equal,
- (GDestroyNotify) g_object_unref,
- (GDestroyNotify) g_object_unref);
- priv->cancellable = g_cancellable_new ();
-}
-
-static void
-gtk_folder_set_finished_loading (GtkFolder *folder,
- gboolean finished_loading)
-{
- GtkFolderPrivate *priv;
-
- priv = GTK_FOLDER_GET_PRIVATE (folder);
- priv->finished_loading = (finished_loading == TRUE);
-
- gdk_threads_enter ();
- g_signal_emit (folder, folder_signals[FINISHED_LOADING], 0);
- gdk_threads_leave ();
-}
-
-static void
-gtk_folder_add_file (GtkFolder *folder,
- GFile *file,
- GFileInfo *info)
-{
- GtkFolderPrivate *priv;
-
- priv = GTK_FOLDER_GET_PRIVATE (folder);
-
- g_hash_table_insert (priv->children,
- g_object_ref (file),
- g_object_ref (info));
-}
-
-GSList *
-_gtk_folder_list_children (GtkFolder *folder)
-{
- GtkFolderPrivate *priv;
- GList *files, *elem;
- GSList *children = NULL;
-
- priv = GTK_FOLDER_GET_PRIVATE (folder);
- files = g_hash_table_get_keys (priv->children);
- children = NULL;
-
- for (elem = files; elem; elem = elem->next)
- children = g_slist_prepend (children, g_object_ref (elem->data));
-
- g_list_free (files);
-
- return children;
-}
-
-GFileInfo *
-_gtk_folder_get_info (GtkFolder *folder,
- GFile *file)
-{
- GtkFolderPrivate *priv;
- GFileInfo *info;
-
- priv = GTK_FOLDER_GET_PRIVATE (folder);
- info = g_hash_table_lookup (priv->children, file);
-
- if (!info)
- return NULL;
-
- return g_object_ref (info);
-}
-
-gboolean
-_gtk_folder_is_finished_loading (GtkFolder *folder)
-{
- GtkFolderPrivate *priv;
-
- priv = GTK_FOLDER_GET_PRIVATE (folder);
-
- return priv->finished_loading;
-}
-
/* GtkFileSystemVolume public methods */
gchar *
_gtk_file_system_volume_get_display_name (GtkFileSystemVolume *volume)
return pixbuf;
}
+GtkFileSystemVolume *
+_gtk_file_system_volume_ref (GtkFileSystemVolume *volume)
+{
+ if (IS_ROOT_VOLUME (volume))
+ return volume;
+
+ if (G_IS_MOUNT (volume) ||
+ G_IS_VOLUME (volume) ||
+ G_IS_DRIVE (volume))
+ g_object_ref (volume);
+
+ return volume;
+}
+
void
-_gtk_file_system_volume_free (GtkFileSystemVolume *volume)
+_gtk_file_system_volume_unref (GtkFileSystemVolume *volume)
{
/* Root volume doesn't need to be freed */
if (IS_ROOT_VOLUME (volume))
return pixbuf;
}
+
+gboolean
+_gtk_file_info_consider_as_directory (GFileInfo *info)
+{
+ GFileType type = g_file_info_get_file_type (info);
+
+ return (type == G_FILE_TYPE_DIRECTORY ||
+ type == G_FILE_TYPE_MOUNTABLE ||
+ type == G_FILE_TYPE_SHORTCUT);
+}
+