[Xfce4-commits] <thunar:master> Check free space before copying (bug #5658).
Nick Schermer
noreply at xfce.org
Sun Sep 30 21:38:01 CEST 2012
Updating branch refs/heads/master
to ecad36219b96785e0549dd8ca133123a90c09a42 (commit)
from 0901472b684d8621bbbbc50c04d95eb5783206f8 (commit)
commit ecad36219b96785e0549dd8ca133123a90c09a42
Author: Nick Schermer <nick at xfce.org>
Date: Sun Sep 30 21:36:40 2012 +0200
Check free space before copying (bug #5658).
thunar/thunar-dialogs.c | 29 ++++++++----
thunar/thunar-enum-types.c | 1 +
thunar/thunar-enum-types.h | 2 +
thunar/thunar-job.c | 28 +++++++++++
thunar/thunar-job.h | 3 +
thunar/thunar-transfer-job.c | 105 ++++++++++++++++++++++++++++++++++++++++++
6 files changed, 159 insertions(+), 9 deletions(-)
diff --git a/thunar/thunar-dialogs.c b/thunar/thunar-dialogs.c
index dc8b903..0021d2d 100644
--- a/thunar/thunar-dialogs.c
+++ b/thunar/thunar-dialogs.c
@@ -360,7 +360,8 @@ thunar_dialogs_show_job_ask (GtkWindow *parent,
GString *secondary = g_string_sized_new (256);
GString *primary = g_string_sized_new (256);
gint response;
- gint n, m;
+ gint n;
+ gboolean has_cancel = FALSE;
_thunar_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), THUNAR_JOB_RESPONSE_CANCEL);
_thunar_return_val_if_fail (g_utf8_validate (question, -1, NULL), THUNAR_JOB_RESPONSE_CANCEL);
@@ -411,13 +412,10 @@ thunar_dialogs_show_job_ask (GtkWindow *parent,
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (message), "%s", secondary->str);
/* add the buttons based on the possible choices */
- for (n = 5; n >= 0; --n)
+ for (n = 6; n >= 0; --n)
{
- /* "Cancel" should be the last button, but "Retry" was added last */
- m = (n == 5) ? 3 : (n == 3) ? 5 : n;
-
/* check if the response is set */
- response = choices & (1 << m);
+ response = choices & (1 << n);
if (response == 0)
continue;
@@ -443,11 +441,15 @@ thunar_dialogs_show_job_ask (GtkWindow *parent,
mnemonic = _("_Retry");
break;
- case THUNAR_JOB_RESPONSE_CANCEL:
- response = GTK_RESPONSE_CANCEL;
- mnemonic = _("_Cancel");
+ case THUNAR_JOB_RESPONSE_FORCE:
+ mnemonic = _("Copy _Anyway");
break;
+ case THUNAR_JOB_RESPONSE_CANCEL:
+ /* cancel is always the last option */
+ has_cancel = TRUE;
+ continue;
+
default:
g_assert_not_reached ();
break;
@@ -461,6 +463,15 @@ thunar_dialogs_show_job_ask (GtkWindow *parent,
gtk_dialog_set_default_response (GTK_DIALOG (message), response);
}
+ if (has_cancel)
+ {
+ button = gtk_button_new_with_mnemonic (_("_Cancel"));
+ gtk_widget_set_can_default (button, TRUE);
+ gtk_dialog_add_action_widget (GTK_DIALOG (message), button, GTK_RESPONSE_CANCEL);
+ gtk_widget_show (button);
+ gtk_dialog_set_default_response (GTK_DIALOG (message), GTK_RESPONSE_CANCEL);
+ }
+
/* run the question dialog */
response = gtk_dialog_run (GTK_DIALOG (message));
gtk_widget_destroy (message);
diff --git a/thunar/thunar-enum-types.c b/thunar/thunar-enum-types.c
index d671338..35654a9 100644
--- a/thunar/thunar-enum-types.c
+++ b/thunar/thunar-enum-types.c
@@ -240,6 +240,7 @@ thunar_job_response_get_type (void)
{ THUNAR_JOB_RESPONSE_CANCEL, "THUNAR_JOB_RESPONSE_CANCEL", "cancel" },
{ THUNAR_JOB_RESPONSE_NO_ALL, "THUNAR_JOB_RESPONSE_NO_ALL", "no-all" },
{ THUNAR_JOB_RESPONSE_RETRY, "THUNAR_JOB_RESPONSE_RETRY", "retry" },
+ { THUNAR_JOB_RESPONSE_FORCE, "THUNAR_JOB_RESPONSE_FORCE", "force" },
{ 0, NULL, NULL }
};
diff --git a/thunar/thunar-enum-types.h b/thunar/thunar-enum-types.h
index 7df8ee8..b950052 100644
--- a/thunar/thunar-enum-types.h
+++ b/thunar/thunar-enum-types.h
@@ -204,6 +204,7 @@ GType thunar_zoom_level_get_type (void) G_GNUC_CONST;
* @THUNAR_JOB_RESPONSE_NO_ALL :
* @THUNAR_JOB_RESPONSE_CANCEL :
* @THUNAR_JOB_RESPONSE_RETRY :
+ * @THUNAR_JOB_RESPONSE_FORCE :
*
* Possible responses for the ThunarJob::ask signal.
**/
@@ -215,6 +216,7 @@ typedef enum /*< flags >*/
THUNAR_JOB_RESPONSE_CANCEL = 1 << 3,
THUNAR_JOB_RESPONSE_NO_ALL = 1 << 4,
THUNAR_JOB_RESPONSE_RETRY = 1 << 5,
+ THUNAR_JOB_RESPONSE_FORCE = 1 << 6,
} ThunarJobResponse;
GType thunar_job_response_get_type (void) G_GNUC_CONST;
diff --git a/thunar/thunar-job.c b/thunar/thunar-job.c
index 0cd0389..0cd0c38 100644
--- a/thunar/thunar-job.c
+++ b/thunar/thunar-job.c
@@ -519,6 +519,34 @@ thunar_job_ask_skip (ThunarJob *job,
gboolean
+thunar_job_ask_no_size (ThunarJob *job,
+ const gchar *format,
+ ...)
+{
+ ThunarJobResponse response;
+ va_list var_args;
+
+ _thunar_return_val_if_fail (THUNAR_IS_JOB (job), THUNAR_JOB_RESPONSE_CANCEL);
+ _thunar_return_val_if_fail (format != NULL, THUNAR_JOB_RESPONSE_CANCEL);
+
+ /* check if the user already cancelled the job */
+ if (G_UNLIKELY (exo_job_is_cancelled (EXO_JOB (job))))
+ return THUNAR_JOB_RESPONSE_CANCEL;
+
+ /* ask the user what he wants to do */
+ va_start (var_args, format);
+ response = _thunar_job_ask_valist (job, format, var_args,
+ _("There is not enough space on the destination. Try to remove files to make space."),
+ THUNAR_JOB_RESPONSE_FORCE
+ | THUNAR_JOB_RESPONSE_CANCEL);
+ va_end (var_args);
+
+ return (response == THUNAR_JOB_RESPONSE_FORCE);
+}
+
+
+
+gboolean
thunar_job_files_ready (ThunarJob *job,
GList *file_list)
{
diff --git a/thunar/thunar-job.h b/thunar/thunar-job.h
index 8ed8a8b..f1f636b 100644
--- a/thunar/thunar-job.h
+++ b/thunar/thunar-job.h
@@ -84,6 +84,9 @@ ThunarJobResponse thunar_job_ask_replace (ThunarJob *job,
ThunarJobResponse thunar_job_ask_skip (ThunarJob *job,
const gchar *format,
...);
+gboolean thunar_job_ask_no_size (ThunarJob *job,
+ const gchar *format,
+ ...);
gboolean thunar_job_files_ready (ThunarJob *job,
GList *file_list);
void thunar_job_new_files (ThunarJob *job,
diff --git a/thunar/thunar-transfer-job.c b/thunar/thunar-transfer-job.c
index 650d27f..178a5bc 100644
--- a/thunar/thunar-transfer-job.c
+++ b/thunar/thunar-transfer-job.c
@@ -667,6 +667,96 @@ retry_remove:
}
+
+static gboolean
+thunar_transfer_job_veryify_destination (ThunarTransferJob *transfer_job,
+ GError **error)
+{
+ GFileInfo *filesystem_info;
+ guint64 free_space;
+ GFile *dest;
+ GFileInfo *dest_info;
+ gchar *dest_name = NULL;
+ gchar *base_name;
+ gboolean succeed = TRUE;
+ gchar *size_string;
+
+ _thunar_return_val_if_fail (THUNAR_IS_TRANSFER_JOB (transfer_job), FALSE);
+
+ /* no target file list */
+ if (transfer_job->target_file_list == NULL)
+ return TRUE;
+
+ /* total size is nul, should be fine */
+ if (transfer_job->total_size == 0)
+ return TRUE;
+
+ /* for all actions in thunar use the same target directory so
+ * although not all files are checked, this should work nicely */
+ dest = g_file_get_parent (G_FILE (transfer_job->target_file_list->data));
+
+ /* query information about the filesystem */
+ filesystem_info = g_file_query_filesystem_info (dest, THUNARX_FILESYSTEM_INFO_NAMESPACE,
+ exo_job_get_cancellable (EXO_JOB (transfer_job)),
+ NULL);
+
+ /* unable to query the info, this could happen on some backends */
+ if (filesystem_info == NULL)
+ {
+ g_object_unref (G_OBJECT (dest));
+ return TRUE;
+ }
+
+ /* some info about the file */
+ dest_info = g_file_query_info (dest, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, 0,
+ exo_job_get_cancellable (EXO_JOB (transfer_job)),
+ NULL);
+ if (dest_info != NULL)
+ {
+ dest_name = g_strdup (g_file_info_get_display_name (dest_info));
+ g_object_unref (G_OBJECT (dest_info));
+ }
+
+ if (dest_name == NULL)
+ {
+ base_name = g_file_get_basename (dest);
+ dest_name = g_filename_display_name (base_name);
+ g_free (base_name);
+ }
+
+ if (g_file_info_has_attribute (filesystem_info, G_FILE_ATTRIBUTE_FILESYSTEM_FREE))
+ {
+ free_space = g_file_info_get_attribute_uint64 (filesystem_info, G_FILE_ATTRIBUTE_FILESYSTEM_FREE);
+ if (transfer_job->total_size > free_space)
+ {
+ size_string = g_format_size (transfer_job->total_size - free_space);
+ succeed = thunar_job_ask_no_size (THUNAR_JOB (transfer_job),
+ _("Error while copying to \"%s\": %s more space is "
+ "required to copy to the destination"),
+ dest_name, size_string);
+ g_free (size_string);
+ }
+ }
+
+ if (succeed && g_file_info_get_attribute_boolean (filesystem_info, G_FILE_ATTRIBUTE_FILESYSTEM_READONLY))
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_READ_ONLY,
+ _("Error while copying to \"%s\": The destination is read-only"),
+ dest_name);
+
+ /* meh */
+ succeed = FALSE;
+ }
+
+ g_object_unref (filesystem_info);
+ g_object_unref (G_OBJECT (dest));
+ g_free (dest_name);
+
+ return succeed;
+}
+
+
+
static gboolean
thunar_transfer_job_execute (ExoJob *job,
GError **error)
@@ -856,6 +946,21 @@ thunar_transfer_job_execute (ExoJob *job,
/* continue if there were no errors yet */
if (G_LIKELY (err == NULL))
{
+ /* check destination */
+ if (!thunar_transfer_job_veryify_destination (transfer_job, &err))
+ {
+ if (err != NULL)
+ {
+ g_propagate_error (error, err);
+ return FALSE;
+ }
+ else
+ {
+ /* pretend nothing happened */
+ return TRUE;
+ }
+ }
+
/* transfer starts now */
transfer_job->start_time = g_get_real_time ();
More information about the Xfce4-commits
mailing list