summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libcaja-private/caja-file-operations.c82
-rw-r--r--libcaja-private/caja-progress-info.c60
-rw-r--r--libcaja-private/caja-progress-info.h4
3 files changed, 114 insertions, 32 deletions
diff --git a/libcaja-private/caja-file-operations.c b/libcaja-private/caja-file-operations.c
index e2d5ba05..97b387cd 100644
--- a/libcaja-private/caja-file-operations.c
+++ b/libcaja-private/caja-file-operations.c
@@ -913,11 +913,12 @@ f (const char *format, ...) {
return res;
}
-#define op_job_new(__type, parent_window, should_start) ((__type *)(init_common (sizeof(__type), parent_window, should_start)))
+#define op_job_new(__type, parent_window, should_start, can_pause) ((__type *)(init_common (sizeof(__type), parent_window, should_start, can_pause)))
static gpointer
init_common (gsize job_size,
- GtkWindow *parent_window, gboolean should_start)
+ GtkWindow *parent_window,
+ gboolean should_start, gboolean can_pause)
{
CommonJob *common;
GdkScreen *screen;
@@ -928,7 +929,7 @@ init_common (gsize job_size,
common->parent_window = parent_window;
eel_add_weak_pointer (&common->parent_window);
}
- common->progress = caja_progress_info_new (should_start);
+ common->progress = caja_progress_info_new (should_start, can_pause);
common->cancellable = caja_progress_info_get_cancellable (common->progress);
common->time = g_timer_new ();
common->inhibit_cookie = -1;
@@ -1968,7 +1969,7 @@ trash_or_delete_internal (GList *files,
/* TODO: special case desktop icon link files ... */
- job = op_job_new (DeleteJob, parent_window, TRUE);
+ job = op_job_new (DeleteJob, parent_window, TRUE, TRUE);
job->files = eel_g_object_list_copy (files);
job->try_trash = try_trash;
job->user_cancel = FALSE;
@@ -2269,7 +2270,7 @@ caja_file_operations_unmount_mount_full (GtkWindow *parent_
if (response == GTK_RESPONSE_ACCEPT) {
EmptyTrashJob *job;
- job = op_job_new (EmptyTrashJob, parent_window, TRUE);
+ job = op_job_new (EmptyTrashJob, parent_window, TRUE, FALSE);
job->should_confirm = FALSE;
job->trash_dirs = get_trash_dirs_for_mount (mount);
job->done_callback = (CajaOpCallback)do_unmount;
@@ -3412,7 +3413,7 @@ copy_move_directory (CopyMoveJob *copy_job,
gboolean *skipped_file,
gboolean readonly_source_fs)
{
- GFileInfo *info;
+ GFileInfo *info, *nextinfo;
GError *error;
GFile *src_file;
GFileEnumerator *enumerator;
@@ -3464,16 +3465,28 @@ copy_move_directory (CopyMoveJob *copy_job,
if (enumerator) {
error = NULL;
+ nextinfo = g_file_enumerator_next_file (enumerator, job->cancellable, skip_error?NULL:&error);
while (!job_aborted (job) &&
- (info = g_file_enumerator_next_file (enumerator, job->cancellable, skip_error?NULL:&error)) != NULL) {
+ (info = nextinfo) != NULL) {
+ caja_progress_info_get_ready (job->progress);
+
+ nextinfo = g_file_enumerator_next_file (enumerator, job->cancellable, skip_error?NULL:&error);
src_file = g_file_get_child (src,
g_file_info_get_name (info));
+
+ if ((!nextinfo) && (!is_dir(src_file)))
+ /* this is the last file, cannot pause anymore */
+ caja_progress_info_disable_pause (job->progress);
+
copy_move_file (copy_job, src_file, *dest, same_fs, FALSE, &dest_fs_type,
source_info, transfer_info, NULL, NULL, FALSE, &local_skipped_file,
readonly_source_fs);
g_object_unref (src_file);
g_object_unref (info);
}
+ if (nextinfo)
+ g_object_unref (nextinfo);
+
g_file_enumerator_close (enumerator, job->cancellable, NULL);
g_object_unref (enumerator);
@@ -4084,8 +4097,6 @@ copy_move_file (CopyMoveJob *copy_job,
retry:
- caja_progress_info_get_ready (job->progress);
-
error = NULL;
flags = G_FILE_COPY_NOFOLLOW_SYMLINKS;
if (overwrite) {
@@ -4414,8 +4425,14 @@ copy_files (CopyMoveJob *job,
for (l = job->files;
l != NULL && !job_aborted (common);
l = l->next) {
+ caja_progress_info_get_ready (common->progress);
+
src = l->data;
+ if ((!l->next) && (!is_dir(src)))
+ /* this is the last file, cannot pause anymore */
+ caja_progress_info_disable_pause (common->progress);
+
if (i < job->n_icon_positions) {
point = &job->icon_positions[i];
} else {
@@ -4542,6 +4559,24 @@ copy_job (GIOSchedulerJob *io_job,
return FALSE;
}
+static gboolean
+contains_multiple_items (GList *files)
+{
+ GFile *first;
+
+ if (g_list_length (files) > 1) {
+ return TRUE;
+ } else {
+ if (files) {
+ first = files->data;
+ if (is_dir (first))
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
void
caja_file_operations_copy (GList *files,
GArray *relative_item_points,
@@ -4552,7 +4587,7 @@ caja_file_operations_copy (GList *files,
{
CopyMoveJob *job;
- job = op_job_new (CopyMoveJob, parent_window, FALSE);
+ job = op_job_new (CopyMoveJob, parent_window, FALSE, contains_multiple_items (files));
job->desktop_location = caja_get_desktop_location ();
job->done_callback = done_callback;
job->done_callback_data = done_callback_data;
@@ -4885,6 +4920,7 @@ move_files_prepare (CopyMoveJob *job,
total = left = g_list_length (job->files);
+ caja_progress_info_get_ready (common->progress);
report_move_progress (job, total, left);
i = 0;
@@ -4893,6 +4929,10 @@ move_files_prepare (CopyMoveJob *job,
l = l->next) {
src = l->data;
+ if ((!l->next) && (!(*fallbacks)) && (!is_dir(src)))
+ /* this is the last file and there are no fallbacks to process, cannot pause anymore */
+ caja_progress_info_disable_pause (common->progress);
+
if (i < job->n_icon_positions) {
point = &job->icon_positions[i];
} else {
@@ -4949,6 +4989,10 @@ common = &job->common;
fallback = l->data;
src = fallback->file;
+ if ((!l->next) && (!is_dir(src)))
+ /* this is the last file, cannot pause anymore */
+ caja_progress_info_disable_pause (common->progress);
+
if (fallback->has_position) {
point = &fallback->position;
} else {
@@ -5086,7 +5130,7 @@ caja_file_operations_move (GList *files,
{
CopyMoveJob *job;
- job = op_job_new (CopyMoveJob, parent_window, FALSE);
+ job = op_job_new (CopyMoveJob, parent_window, FALSE, contains_multiple_items (files));
job->is_move = TRUE;
job->done_callback = done_callback;
job->done_callback_data = done_callback_data;
@@ -5406,7 +5450,7 @@ caja_file_operations_link (GList *files,
{
CopyMoveJob *job;
- job = op_job_new (CopyMoveJob, parent_window, TRUE);
+ job = op_job_new (CopyMoveJob, parent_window, TRUE, FALSE);
job->done_callback = done_callback;
job->done_callback_data = done_callback_data;
job->files = eel_g_object_list_copy (files);
@@ -5447,7 +5491,7 @@ caja_file_operations_duplicate (GList *files,
{
CopyMoveJob *job;
- job = op_job_new (CopyMoveJob, parent_window, FALSE);
+ job = op_job_new (CopyMoveJob, parent_window, FALSE, contains_multiple_items (files));
job->done_callback = done_callback;
job->done_callback_data = done_callback_data;
job->files = eel_g_object_list_copy (files);
@@ -5619,7 +5663,7 @@ caja_file_set_permissions_recursive (const char *directory,
{
SetPermissionsJob *job;
- job = op_job_new (SetPermissionsJob, NULL, TRUE);
+ job = op_job_new (SetPermissionsJob, NULL, TRUE, TRUE);
job->file = g_file_new_for_uri (directory);
job->file_permissions = file_permissions;
job->file_mask = file_mask;
@@ -6087,7 +6131,7 @@ caja_file_operations_new_folder (GtkWidget *parent_view,
parent_window = (GtkWindow *)gtk_widget_get_ancestor (parent_view, GTK_TYPE_WINDOW);
}
- job = op_job_new (CreateJob, parent_window, TRUE);
+ job = op_job_new (CreateJob, parent_window, TRUE, FALSE);
job->done_callback = done_callback;
job->done_callback_data = done_callback_data;
job->dest_dir = g_file_new_for_uri (parent_dir);
@@ -6127,7 +6171,7 @@ caja_file_operations_new_file_from_template (GtkWidget *parent_view,
parent_window = (GtkWindow *)gtk_widget_get_ancestor (parent_view, GTK_TYPE_WINDOW);
}
- job = op_job_new (CreateJob, parent_window, TRUE);
+ job = op_job_new (CreateJob, parent_window, TRUE, FALSE);
job->done_callback = done_callback;
job->done_callback_data = done_callback_data;
job->dest_dir = g_file_new_for_uri (parent_dir);
@@ -6172,7 +6216,7 @@ caja_file_operations_new_file (GtkWidget *parent_view,
parent_window = (GtkWindow *)gtk_widget_get_ancestor (parent_view, GTK_TYPE_WINDOW);
}
- job = op_job_new (CreateJob, parent_window, TRUE);
+ job = op_job_new (CreateJob, parent_window, TRUE, FALSE);
job->done_callback = done_callback;
job->done_callback_data = done_callback_data;
job->dest_dir = g_file_new_for_uri (parent_dir);
@@ -6308,7 +6352,7 @@ caja_file_operations_empty_trash (GtkWidget *parent_view)
parent_window = (GtkWindow *)gtk_widget_get_ancestor (parent_view, GTK_TYPE_WINDOW);
}
- job = op_job_new (EmptyTrashJob, parent_window, TRUE);
+ job = op_job_new (EmptyTrashJob, parent_window, TRUE, TRUE);
job->trash_dirs = g_list_prepend (job->trash_dirs,
g_file_new_for_uri ("trash:"));
job->should_confirm = TRUE;
@@ -6534,7 +6578,7 @@ caja_file_mark_desktop_file_trusted (GFile *file,
{
MarkTrustedJob *job;
- job = op_job_new (MarkTrustedJob, parent_window, TRUE);
+ job = op_job_new (MarkTrustedJob, parent_window, TRUE, FALSE);
job->file = g_object_ref (file);
job->interactive = interactive;
job->done_callback = done_callback;
diff --git a/libcaja-private/caja-progress-info.c b/libcaja-private/caja-progress-info.c
index 2e65bc6d..1a48e131 100644
--- a/libcaja-private/caja-progress-info.c
+++ b/libcaja-private/caja-progress-info.c
@@ -75,6 +75,7 @@ struct _CajaProgressInfo
gboolean finished;
gboolean paused;
+ gboolean can_pause;
gboolean waiting;
GCond waiting_c;
@@ -399,16 +400,22 @@ get_first_queued_widget ()
}
static void
-start_button_update_view (GtkWidget *button, ProgressWidgetState state)
+start_button_update_view (ProgressWidgetData *data)
{
GtkWidget *toapply, *curimage;
+ GtkWidget *button = data->btstart;
+ ProgressWidgetState state = data->state;
+ gboolean as_pause;
- if (state == STATE_RUNNING || state == STATE_QUEUING)
+ if (state == STATE_RUNNING || state == STATE_QUEUING) {
toapply = g_object_get_data (G_OBJECT(button),
STARTBT_DATA_IMAGE_PAUSE);
- else
+ as_pause = TRUE;
+ } else {
toapply = g_object_get_data (G_OBJECT(button),
STARTBT_DATA_IMAGE_RESUME);
+ as_pause = FALSE;
+ }
curimage = g_object_get_data (G_OBJECT(button), STARTBT_DATA_CURIMAGE);
if (curimage != toapply) {
@@ -419,12 +426,19 @@ start_button_update_view (GtkWidget *button, ProgressWidgetState state)
gtk_widget_show (toapply);
g_object_set_data (G_OBJECT(button), STARTBT_DATA_CURIMAGE, toapply);
}
+
+ if (as_pause && !data->info->can_pause)
+ gtk_widget_set_sensitive (button, FALSE);
}
static void
-queue_button_update_view (GtkWidget *button, ProgressWidgetState state)
+queue_button_update_view (ProgressWidgetData *data)
{
- if (state == STATE_QUEUING || state == STATE_QUEUED)
+ GtkWidget *button = data->btqueue;
+ ProgressWidgetState state = data->state;
+
+ if ( (!data->info->can_pause) ||
+ (state == STATE_QUEUING || state == STATE_QUEUED) )
gtk_widget_set_sensitive (button, FALSE);
else
gtk_widget_set_sensitive (button, TRUE);
@@ -543,8 +557,8 @@ widget_state_transit_to (ProgressWidgetData *data,
widget_reposition_as_running (data->widget);
}
- start_button_update_view (data->btstart, data->state);
- queue_button_update_view (data->btqueue, data->state);
+ start_button_update_view (data);
+ queue_button_update_view (data);
update_data (data);
}
@@ -585,6 +599,7 @@ static void
update_status_icon_and_window (void)
{
char *tooltip;
+ gboolean toshow, window_shown;
tooltip = g_strdup_printf (ngettext ("%'d file operation active",
"%'d file operations active",
@@ -593,12 +608,15 @@ update_status_icon_and_window (void)
gtk_status_icon_set_tooltip_text (status_icon, tooltip);
g_free (tooltip);
- if (n_progress_ops == 0)
+ toshow = (n_progress_ops > 0);
+ window_shown = gtk_status_icon_get_visible (status_icon);
+
+ if (!toshow && window_shown)
{
gtk_status_icon_set_visible (status_icon, FALSE);
gtk_widget_hide (get_progress_window ());
}
- else
+ else if (toshow && !window_shown)
{
gtk_widget_show_all (get_progress_window ());
gtk_status_icon_set_visible (status_icon, TRUE);
@@ -617,12 +635,31 @@ op_finished (ProgressWidgetData *data)
update_status_icon_and_window ();
}
+static int
+do_disable_pause (CajaProgressInfo *info)
+{
+ info->can_pause = FALSE;
+
+ start_button_update_view (info->widget);
+ queue_button_update_view (info->widget);
+ return G_SOURCE_REMOVE;
+}
+
+void
+caja_progress_info_disable_pause (CajaProgressInfo *info)
+{
+ GSource *source = g_idle_source_new ();
+ g_source_set_callback (source, (GSourceFunc)do_disable_pause, info, NULL);
+ g_source_attach (source, NULL);
+}
+
static void
cancel_clicked (GtkWidget *button,
ProgressWidgetData *data)
{
caja_progress_info_cancel (data->info);
gtk_widget_set_sensitive (button, FALSE);
+ do_disable_pause(data->info);
}
static void
@@ -731,7 +768,7 @@ start_button_init (ProgressWidgetData *data)
resumeImage, unref_callback);
g_object_set_data (G_OBJECT(button), STARTBT_DATA_CURIMAGE, NULL);
- start_button_update_view (button, data->state);
+ start_button_update_view (data);
g_signal_connect (button, "clicked", (GCallback)start_clicked, data);
data->btstart = button;
@@ -941,12 +978,13 @@ caja_progress_info_init (CajaProgressInfo *info)
}
CajaProgressInfo *
-caja_progress_info_new (gboolean should_start)
+caja_progress_info_new (gboolean should_start, gboolean can_pause)
{
CajaProgressInfo *info;
info = g_object_new (CAJA_TYPE_PROGRESS_INFO, NULL);
info->waiting = !should_start;
+ info->can_pause = can_pause;
return info;
}
diff --git a/libcaja-private/caja-progress-info.h b/libcaja-private/caja-progress-info.h
index 2640b77e..61cdb02a 100644
--- a/libcaja-private/caja-progress-info.h
+++ b/libcaja-private/caja-progress-info.h
@@ -50,8 +50,9 @@ GType caja_progress_info_get_type (void) G_GNUC_CONST;
All methods are threadsafe.
*/
-CajaProgressInfo *caja_progress_info_new (gboolean should_start);
+CajaProgressInfo *caja_progress_info_new (gboolean should_start, gboolean can_pause);
void caja_progress_info_get_ready (CajaProgressInfo *info);
+void caja_progress_info_disable_pause (CajaProgressInfo *info);
GList * caja_get_all_progress_info (void);
@@ -82,5 +83,4 @@ void caja_progress_info_set_progress (CajaProgressInfo *info,
void caja_progress_info_pulse_progress (CajaProgressInfo *info);
-
#endif /* CAJA_PROGRESS_INFO_H */