Beispiel #1
0
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;
}
Beispiel #2
0
/* ======================= 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;
}
Beispiel #3
0
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);
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
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;
}
Beispiel #7
0
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;
}
Beispiel #8
0
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;
}