static GFile * trash_backend_get_file (GVfsBackendTrash *backend, const char *filename, TrashItem **item_ret, gboolean *is_toplevel, GError **error) { const char *slash; gboolean is_top; TrashItem *item; GFile *file; file = NULL; filename++; slash = strchr (filename, '/'); is_top = slash == NULL; if (is_toplevel) *is_toplevel = is_top; if (!is_top) { char *toplevel; g_assert (slash[1]); toplevel = g_strndup (filename, slash - filename); if ((item = trash_root_lookup_item (backend->root, toplevel))) { file = trash_item_get_file (item); file = g_file_get_child (file, slash + 1); if (item_ret) *item_ret = item; else trash_item_unref (item); } g_free (toplevel); } else { if ((item = trash_root_lookup_item (backend->root, filename))) { file = g_object_ref (trash_item_get_file (item)); if (item_ret) *item_ret = item; else trash_item_unref (item); } } if (file == NULL) g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, _("No such file or directory")); return file; }
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; }
static void trash_item_invoke_closure (NotifyClosure *closure) { closure->func (closure->item, closure->user_data); trash_item_unref (closure->item); g_slice_free (NotifyClosure, closure); }
static void trash_item_removed (gpointer data) { TrashItem *item = data; trash_item_queue_notify (item, item->root->delete_notify); trash_item_unref (item); }
static void trash_backend_enumerate_root (GVfsBackendTrash *backend, GVfsJobEnumerate *job, GFileAttributeMatcher *attribute_matcher, GFileQueryInfoFlags flags) { GList *items, *node; g_vfs_job_succeeded (G_VFS_JOB (job)); items = trash_root_get_items (backend->root); for (node = items; node; node = node->next) { TrashItem *item = node->data; GFileInfo *info; info = g_file_query_info (trash_item_get_file (item), job->attributes, flags, G_VFS_JOB (job)->cancellable, NULL); if (info) { g_file_info_set_attribute_mask (info, attribute_matcher); g_file_info_set_name (info, trash_item_get_escaped_name (item)); trash_backend_add_info (item, info, TRUE); g_vfs_job_enumerate_add_info (job, info); g_object_unref (info); } trash_item_unref (item); } g_vfs_job_enumerate_done (job); g_list_free (items); }
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; }