Exemple #1
0
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;
}
Exemple #2
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;
}
Exemple #3
0
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);
}
Exemple #4
0
static void
trash_item_removed (gpointer data)
{
  TrashItem *item = data;

  trash_item_queue_notify (item, item->root->delete_notify);
  trash_item_unref (item);
}
Exemple #5
0
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);
}
Exemple #6
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;
}
Exemple #7
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;
}