Commit 8cea4857 authored by Cyrille Pontvieux's avatar Cyrille Pontvieux Committed by Alexander Schwinn
Browse files

Split "thunar_transfer_job_execute" in multiple simpler functions to

keep the code human readable, and as preperation for Bug #16686
parent fffa7f2a
Loading
Loading
Loading
Loading
+202 −170
Original line number Diff line number Diff line
@@ -679,7 +679,9 @@ retry_copy:

      /* copy the item specified by this node (not recursively) */
      real_target_file = thunar_transfer_job_copy_file (job, node->source_file,
                                                        target_file, node->replace_confirmed, &err);
                                                        target_file,
                                                        node->replace_confirmed,
                                                        &err);
      if (G_LIKELY (real_target_file != NULL))
        {
          /* node->source_file == real_target_file means to skip the file */
@@ -870,81 +872,24 @@ thunar_transfer_job_verify_destination (ThunarTransferJob *transfer_job,
}



static gboolean
thunar_transfer_job_execute (ExoJob  *job,
thunar_transfer_job_prepare_untrash_file (ExoJob     *job,
                                          GFileInfo  *info,
                                          GFile      *file,
                                          GError    **error)
{
  ThunarThumbnailCache *thumbnail_cache;
  ThunarTransferNode   *node;
  ThunarApplication    *application;
  ThunarJobResponse  response;
  ThunarTransferJob    *transfer_job = THUNAR_TRANSFER_JOB (job);
  GFileInfo            *info;
  GFileCopyFlags        flags;
  gboolean              parent_exists;
  gboolean              move_successful;
  GError               *err = NULL;
  GList                *new_files_list = NULL;
  GList                *snext;
  GList                *sp;
  GList                *tnext;
  GList                *tp;
  GFile             *target_parent;
  gboolean           parent_exists;
  gchar             *base_name;
  gchar             *parent_display_name;

  _thunar_return_val_if_fail (THUNAR_IS_TRANSFER_JOB (job), FALSE);
  _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  if (exo_job_set_error_if_cancelled (job, error))
    return FALSE;

  exo_job_info_message (job, _("Collecting files..."));

  /* take a reference on the thumbnail cache */
  application = thunar_application_get ();
  thumbnail_cache = thunar_application_get_thumbnail_cache (application);
  g_object_unref (application);

  for (sp = transfer_job->source_node_list, tp = transfer_job->target_file_list;
       sp != NULL && tp != NULL && err == NULL;
       sp = snext, tp = tnext)
    {
      thunar_transfer_job_check_pause (transfer_job);

      /* determine the next list items */
      snext = sp->next;
      tnext = tp->next;

      /* determine the current source transfer node */
      node = sp->data;

      info = g_file_query_info (node->source_file,
                                G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
                                G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                exo_job_get_cancellable (job),
                                &err);

      if (G_UNLIKELY (info == NULL))
        break;

      flags = G_FILE_COPY_NOFOLLOW_SYMLINKS | G_FILE_COPY_NO_FALLBACK_FOR_MOVE | G_FILE_COPY_ALL_METADATA;

      /* check if we are moving a file out of the trash */
      if (transfer_job->type == THUNAR_TRANSFER_JOB_MOVE
          && thunar_g_file_is_trashed (node->source_file))
        {
          /* Using this flag when moving filled folders out of trash leaves a copy in trash and pops up a warning */
          flags &= ~G_FILE_COPY_NO_FALLBACK_FOR_MOVE;

  /* update progress information */
  exo_job_info_message (job, _("Trying to restore \"%s\""),
                        g_file_info_get_display_name (info));

  /* determine the parent file */
          target_parent = g_file_get_parent (tp->data);

  target_parent = g_file_get_parent (file);
  /* check if the parent exists */
  if (target_parent != NULL)
    parent_exists = g_file_query_exists (target_parent, exo_job_get_cancellable (job));
@@ -952,11 +897,12 @@ thunar_transfer_job_execute (ExoJob *job,
    parent_exists = FALSE;

  /* abort on cancellation */
          if (exo_job_set_error_if_cancelled (job, &err))
  if (exo_job_set_error_if_cancelled (job, error))
    {
              g_object_unref (target_parent);
      g_object_unref (info);
              break;
      if (target_parent != NULL)
        g_object_unref (target_parent);
      return FALSE;
    }

  if (target_parent != NULL && !parent_exists)
@@ -977,31 +923,33 @@ thunar_transfer_job_execute (ExoJob *job,
      /* abort if cancelled */
      if (G_UNLIKELY (response == THUNAR_JOB_RESPONSE_CANCEL))
        {
                  g_object_unref (target_parent);
          g_free (parent_display_name);
          g_object_unref (info);
                  break;
          if (target_parent != NULL)
            g_object_unref (target_parent);
          return FALSE;
        }

      /* try to create the parent directory */
      if (!g_file_make_directory_with_parents (target_parent,
                                               exo_job_get_cancellable (job),
                                                       &err))
                                               error))
        {
          if (!exo_job_is_cancelled (job))
            {
                      g_clear_error (&err);
              g_clear_error (error);

              /* overwrite the internal GIO error with something more user-friendly */
                      g_set_error (&err, G_IO_ERROR, G_IO_ERROR_FAILED,
              g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                           _("Failed to restore the folder \"%s\""),
                           parent_display_name);
            }

                  g_object_unref (target_parent);
          g_free (parent_display_name);
          g_object_unref (info);
                  break;
          if (target_parent != NULL)
            g_object_unref (target_parent);
          return FALSE;
        }

      /* clean up */
@@ -1010,55 +958,66 @@ thunar_transfer_job_execute (ExoJob *job,

  if (target_parent != NULL)
    g_object_unref (target_parent);
  return TRUE;
}

      if (transfer_job->type == THUNAR_TRANSFER_JOB_MOVE)

static gboolean
thunar_transfer_job_move_file (ExoJob                *job,
                               GFileInfo             *info,
                               GList                 *sp,
                               ThunarTransferNode    *node,
                               GList                 *tp,
                               GFileCopyFlags         move_flags,
                               ThunarThumbnailCache  *thumbnail_cache,
                               GList                **new_files_list_p,
                               GError               **error)
{
  ThunarTransferJob *transfer_job = THUNAR_TRANSFER_JOB (job);
  ThunarJobResponse  response;
  gboolean           move_successful;

  /* update progress information */
  exo_job_info_message (job, _("Trying to move \"%s\""),
                        g_file_info_get_display_name (info));

          /* try moving without overwriting */
          move_successful = g_file_move (node->source_file, tp->data,
                                         flags,
  move_successful = g_file_move (node->source_file,
                                 tp->data,
                                 move_flags,
                                 exo_job_get_cancellable (job),
                                         NULL, NULL, &err);

          /* if the file already exists, ask the user if they want to overwrite it */
          if (!move_successful && err->code == G_IO_ERROR_EXISTS)
                                 NULL, NULL, error);
  /* if the file already exists, ask the user if they want to overwrite or skip it */
  if (!move_successful && (*error)->code == G_IO_ERROR_EXISTS)
    {
              g_clear_error (&err);
      g_clear_error (error);
      response = thunar_job_ask_replace (THUNAR_JOB (job), node->source_file, tp->data, NULL);

      /* if the user chose to overwrite then try to do so */
      if (response == THUNAR_JOB_RESPONSE_YES)
        {
          node->replace_confirmed = TRUE;
                  move_successful = g_file_move (node->source_file, tp->data,
                                                 flags | G_FILE_COPY_OVERWRITE,
          move_successful = g_file_move (node->source_file,
                                         tp->data,
                                         move_flags | G_FILE_COPY_OVERWRITE,
                                         exo_job_get_cancellable (job),
                                                 NULL, NULL, &err);
                                         NULL, NULL, error);
        }

      /* if the user chose to cancel then abort all remaining file moves */
              if (response == THUNAR_JOB_RESPONSE_CANCEL)
      else if (response == THUNAR_JOB_RESPONSE_CANCEL)
        {
          /* release all the remaining source and target files, and free the lists */
          g_list_free_full (transfer_job->source_node_list, thunar_transfer_node_free);
          transfer_job->source_node_list = NULL;
          g_list_free_full (transfer_job->target_file_list, g_object_unref);
          transfer_job->target_file_list= NULL;
                  g_object_unref (info);
                  break;
          return FALSE;
        }

      /* if the user chose not to replace the file, so that response == THUNAR_JOB_RESPONSE_NO,
               * then err will be NULL but move_successfull will be FALSE, so that the source and target
       * then *error will be NULL but move_successful will be FALSE, so that the source and target
       * files will be released and the matching list items will be dropped below
       */
    }

          if (err == NULL)
  if (*error == NULL)
    {
      if (move_successful)
        {
@@ -1068,7 +1027,7 @@ thunar_transfer_job_execute (ExoJob *job,
                                            tp->data);

          /* add the target file to the new files list */
                  new_files_list = thunar_g_file_list_prepend (new_files_list, tp->data);
          *new_files_list_p = thunar_g_file_list_prepend (*new_files_list_p, tp->data);
        }

      /* release source and target files */
@@ -1081,10 +1040,13 @@ thunar_transfer_job_execute (ExoJob *job,
    }
  /* prepare for the fallback copy and delete if appropriate */
  else if (!exo_job_is_cancelled (job) &&
                   ((err->code == G_IO_ERROR_NOT_SUPPORTED) ||
                    (err->code == G_IO_ERROR_WOULD_MERGE) || (err->code == G_IO_ERROR_WOULD_RECURSE)) )
           (
            ((*error)->code == G_IO_ERROR_NOT_SUPPORTED) ||
            ((*error)->code == G_IO_ERROR_WOULD_MERGE) ||
            ((*error)->code == G_IO_ERROR_WOULD_RECURSE))
           )
    {
              g_clear_error (&err);
      g_clear_error (error);

      /* update progress information */
      exo_job_info_message (job, _("Could not move \"%s\" directly. "
@@ -1092,11 +1054,81 @@ thunar_transfer_job_execute (ExoJob *job,
                            g_file_info_get_display_name (info));

      /* if this call fails to collect the node, err will be non-NULL and the loop will exit */
              thunar_transfer_job_collect_node (transfer_job, node, &err);
      thunar_transfer_job_collect_node (transfer_job, node, error);
    }

  return TRUE;
}


static gboolean
thunar_transfer_job_execute (ExoJob  *job,
                             GError **error)
{
  ThunarThumbnailCache *thumbnail_cache;
  ThunarTransferNode   *node;
  ThunarApplication    *application;
  ThunarTransferJob    *transfer_job = THUNAR_TRANSFER_JOB (job);
  GFileInfo            *info;
  GError               *err = NULL;
  GList                *new_files_list = NULL;
  GList                *snext;
  GList                *sp;
  GList                *tnext;
  GList                *tp;

  _thunar_return_val_if_fail (THUNAR_IS_TRANSFER_JOB (job), FALSE);
  _thunar_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  if (exo_job_set_error_if_cancelled (job, error))
    return FALSE;

  exo_job_info_message (job, _("Collecting files..."));

  /* take a reference on the thumbnail cache */
  application = thunar_application_get ();
  thumbnail_cache = thunar_application_get_thumbnail_cache (application);
  g_object_unref (application);

  for (sp = transfer_job->source_node_list, tp = transfer_job->target_file_list;
       sp != NULL && tp != NULL && err == NULL;
       sp = snext, tp = tnext)
    {
      thunar_transfer_job_check_pause (transfer_job);

      /* determine the next list items */
      snext = sp->next;
      tnext = tp->next;

      /* determine the current source transfer node */
      node = sp->data;

      info = g_file_query_info (node->source_file,
                                G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME,
                                G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                exo_job_get_cancellable (job),
                                &err);

      if (G_UNLIKELY (info == NULL))
        break;

      /* check if we are moving a file out of the trash */
      if (transfer_job->type == THUNAR_TRANSFER_JOB_MOVE
          && thunar_g_file_is_trashed (node->source_file))
        {
          if (!thunar_transfer_job_prepare_untrash_file (job, info, tp->data, &err))
            break;
          if (!thunar_transfer_job_move_file (job, info, sp, node, tp,
                                              G_FILE_COPY_NOFOLLOW_SYMLINKS | G_FILE_COPY_ALL_METADATA,
                                              thumbnail_cache, &new_files_list, &err))
            break;
        }
      else if (transfer_job->type == THUNAR_TRANSFER_JOB_MOVE)
        {
          if (!thunar_transfer_job_move_file (job, info, sp, node, tp,
                                              G_FILE_COPY_NOFOLLOW_SYMLINKS | G_FILE_COPY_NO_FALLBACK_FOR_MOVE | G_FILE_COPY_ALL_METADATA,
                                              thumbnail_cache, &new_files_list, &err))
            break;
        }
      else if (transfer_job->type == THUNAR_TRANSFER_JOB_COPY)
        {
          if (!thunar_transfer_job_collect_node (THUNAR_TRANSFER_JOB (job), node, &err))