static gboolean trash_backend_delete (GVfsBackend *vfs_backend, GVfsJobDelete *job, const char *filename) { GVfsBackendTrash *backend = G_VFS_BACKEND_TRASH (vfs_backend); GError *error = NULL; g_debug ("before job: %d\n", G_OBJECT(job)->ref_count); if (filename[1] == '\0') g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, _("The trash folder may not be deleted")); else { gboolean is_toplevel; TrashItem *item; GFile *real; if (!backend->file_monitor && !backend->dir_monitor) trash_watcher_rescan (backend->watcher); real = trash_backend_get_file (backend, filename, &item, &is_toplevel, &error); if (real) { /* not interested in the 'real', but the item */ g_object_unref (real); if (!is_toplevel) g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, _("Items in the trash may not be modified")); else { if (trash_item_delete (item, &error)) { trash_backend_schedule_thaw (backend); g_vfs_job_succeeded (G_VFS_JOB (job)); trash_item_unref (item); return TRUE; } } trash_item_unref (item); } } g_vfs_job_failed_from_error (G_VFS_JOB (job), error); g_error_free (error); return TRUE; }
/* ======================= method implementations ======================= */ static gboolean trash_backend_open_for_read (GVfsBackend *vfs_backend, GVfsJobOpenForRead *job, const char *filename) { GVfsBackendTrash *backend = G_VFS_BACKEND_TRASH (vfs_backend); GError *error = NULL; if (filename[1] == '\0') g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY, _("Can't open directory")); else { GFile *real; if (!backend->file_monitor && !backend->dir_monitor) trash_watcher_rescan (backend->watcher); real = trash_backend_get_file (backend, filename, NULL, NULL, &error); if (real) { GFileInputStream *stream; stream = g_file_read (real, G_VFS_JOB (job)->cancellable, &error); g_object_unref (real); if (stream) { g_vfs_job_open_for_read_set_handle (job, stream); g_vfs_job_open_for_read_set_can_seek (job, TRUE); g_vfs_job_succeeded (G_VFS_JOB (job)); return TRUE; } } } g_vfs_job_failed_from_error (G_VFS_JOB (job), error); g_error_free (error); return TRUE; }
static void trash_backend_finalize (GObject *object) { GVfsBackendTrash *backend = G_VFS_BACKEND_TRASH (object); /* get rid of these first to stop a flood of event notifications * from being emitted while we're tearing down the TrashWatcher */ if (backend->file_monitor) g_object_unref (backend->file_monitor); backend->file_monitor = NULL; if (backend->dir_monitor) g_object_unref (backend->dir_monitor); backend->dir_monitor = NULL; trash_watcher_free (backend->watcher); trash_root_free (backend->root); }
static gboolean trash_backend_create_file_monitor (GVfsBackend *vfs_backend, GVfsJobCreateMonitor *job, const char *filename, GFileMonitorFlags flags) { GVfsBackendTrash *backend = G_VFS_BACKEND_TRASH (vfs_backend); GVfsMonitor *monitor; if (filename[1]) monitor = g_vfs_monitor_new (vfs_backend); else monitor = trash_backend_get_file_monitor (backend, TRUE); g_vfs_job_create_monitor_set_monitor (job, monitor); g_vfs_job_succeeded (G_VFS_JOB (job)); g_object_unref (monitor); return TRUE; }
static gboolean trash_backend_mount (GVfsBackend *vfs_backend, GVfsJobMount *job, GMountSpec *mount_spec, GMountSource *mount_source, gboolean is_automount) { GVfsBackendTrash *backend = G_VFS_BACKEND_TRASH (vfs_backend); backend->file_monitor = NULL; backend->dir_monitor = NULL; backend->root = trash_root_new (trash_backend_item_created, trash_backend_item_deleted, trash_backend_item_count_changed, backend); backend->watcher = trash_watcher_new (backend->root); g_vfs_job_succeeded (G_VFS_JOB (job)); return TRUE; }
static gboolean trash_backend_enumerate (GVfsBackend *vfs_backend, GVfsJobEnumerate *job, const char *filename, GFileAttributeMatcher *attribute_matcher, GFileQueryInfoFlags flags) { GVfsBackendTrash *backend = G_VFS_BACKEND_TRASH (vfs_backend); g_assert (filename[0] == '/'); trash_watcher_rescan (backend->watcher); if (filename[1]) trash_backend_enumerate_non_root (backend, job, filename, attribute_matcher, flags); else trash_backend_enumerate_root (backend, job, attribute_matcher, flags); return TRUE; }
static gboolean trash_backend_query_info (GVfsBackend *vfs_backend, GVfsJobQueryInfo *job, const char *filename, GFileQueryInfoFlags flags, GFileInfo *info, GFileAttributeMatcher *matcher) { GVfsBackendTrash *backend = G_VFS_BACKEND_TRASH (vfs_backend); g_assert (filename[0] == '/'); if (filename[1]) { GError *error = NULL; gboolean is_toplevel; TrashItem *item; GFile *real; real = trash_backend_get_file (backend, filename, &item, &is_toplevel, &error); if (real) { GFileInfo *real_info; real_info = g_file_query_info (real, job->attributes, flags, G_VFS_JOB (job)->cancellable, &error); g_object_unref (real); if (real_info) { g_file_info_copy_into (real_info, info); trash_backend_add_info (item, info, is_toplevel); g_vfs_job_succeeded (G_VFS_JOB (job)); trash_item_unref (item); g_object_unref (real_info); return TRUE; } trash_item_unref (item); } g_vfs_job_failed_from_error (G_VFS_JOB (job), error); g_error_free (error); } else { GIcon *icon; int n_items; n_items = trash_root_get_n_items (backend->root); g_file_info_set_file_type (info, G_FILE_TYPE_DIRECTORY); g_file_info_set_name (info, "/"); /* Translators: this is the display name of the backend */ g_file_info_set_display_name (info, _("Trash")); g_file_info_set_content_type (info, "inode/directory"); icon = g_themed_icon_new (n_items ? "user-trash-full" : "user-trash"); g_file_info_set_icon (info, icon); g_object_unref (icon); icon = g_themed_icon_new (n_items ? "user-trash-full-symbolic" : "user-trash-symbolic"); g_file_info_set_symbolic_icon (info, icon); g_object_unref (icon); g_file_info_set_attribute_uint32 (info, G_FILE_ATTRIBUTE_TRASH_ITEM_COUNT, n_items); g_vfs_job_succeeded (G_VFS_JOB (job)); } return TRUE; }
static gboolean trash_backend_pull (GVfsBackend *vfs_backend, GVfsJobPull *job, const gchar *source, const gchar *local_path, GFileCopyFlags flags, gboolean remove_source, GFileProgressCallback progress_callback, gpointer progress_callback_data) { GVfsBackendTrash *backend = G_VFS_BACKEND_TRASH (vfs_backend); GError *error = NULL; if (source[1] == '\0') g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, _("The trash folder may not be deleted")); else { gboolean is_toplevel; TrashItem *item; GFile *real; real = trash_backend_get_file (backend, source, &item, &is_toplevel, &error); if (real) { if (remove_source && !is_toplevel) g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, _("Items in the trash may not be modified")); else { GFile *destination; gboolean it_worked; destination = g_file_new_for_path (local_path); if (remove_source) it_worked = trash_item_restore (item, destination, flags, &error); else it_worked = g_file_copy (real, destination, flags, G_VFS_JOB (job)->cancellable, progress_callback, progress_callback_data, &error); g_object_unref (destination); if (it_worked) { g_vfs_job_succeeded (G_VFS_JOB (job)); trash_item_unref (item); g_object_unref (real); return TRUE; } } trash_item_unref (item); g_object_unref (real); } } g_vfs_job_failed_from_error (G_VFS_JOB (job), error); g_error_free (error); return TRUE; }