From cdd4cad2ce3930bf1d484ab12371a5d6a354ea00 Mon Sep 17 00:00:00 2001 From: Stefano Karapetsas Date: Mon, 26 Dec 2011 19:52:59 +0100 Subject: ported nautilus-elementary UNDO-REDO (bzr rev 60) --- libcaja-private/caja-file-operations.c | 137 +++++++++++++++++++++++++++++++++ 1 file changed, 137 insertions(+) (limited to 'libcaja-private/caja-file-operations.c') diff --git a/libcaja-private/caja-file-operations.c b/libcaja-private/caja-file-operations.c index 90205b83..b35e98f6 100644 --- a/libcaja-private/caja-file-operations.c +++ b/libcaja-private/caja-file-operations.c @@ -68,6 +68,7 @@ #include "caja-trash-monitor.h" #include "caja-file-utilities.h" #include "caja-file-conflict-dialog.h" +#include "caja-undostack-manager.h" static gboolean confirm_trash_auto_value; @@ -88,6 +89,7 @@ typedef struct { gboolean merge_all; gboolean replace_all; gboolean delete_all; + CajaUndoStackActionData* undo_redo_data; } CommonJob; typedef struct { @@ -963,6 +965,10 @@ finalize_common (CommonJob *common) if (common->skip_readdir_error) { g_hash_table_destroy (common->skip_readdir_error); } + // Start UNDO-REDO + caja_undostack_manager_add_action (caja_undostack_manager_instance(), + common->undo_redo_data); + // End UNDO-REDO g_object_unref (common->progress); g_object_unref (common->cancellable); g_free (common); @@ -1758,6 +1764,8 @@ trash_files (CommonJob *job, GList *files, int *files_skipped) char *primary, *secondary, *details; int response; + guint64 mtime; + if (job_aborted (job)) { return; } @@ -1774,6 +1782,9 @@ trash_files (CommonJob *job, GList *files, int *files_skipped) file = l->data; error = NULL; + + mtime = caja_undostack_manager_get_file_modification_time (file); + if (!g_file_trash (file, job->cancellable, &error)) { if (job->skip_all_error) { (*files_skipped)++; @@ -1821,6 +1832,10 @@ trash_files (CommonJob *job, GList *files, int *files_skipped) } else { caja_file_changes_queue_file_removed (file); + // Start UNDO-REDO + caja_undostack_manager_data_add_trashed_file (job->undo_redo_data, file, mtime); + // End UNDO-REDO + files_trashed++; report_trash_progress (job, files_trashed, total_files); } @@ -1965,6 +1980,15 @@ trash_or_delete_internal (GList *files, } else { inhibit_power_manager ((CommonJob *)job, _("Deleting Files")); } + // Start UNDO-REDO + // FIXME: Disabled, because of missing mechanism to restore a file from trash in a clean way + // see http://www.mail-archive.com/nautilus-list@gnome.org/msg04664.html + if (try_trash && !caja_undostack_manager_is_undo_redo(caja_undostack_manager_instance())) { + job->common.undo_redo_data = caja_undostack_manager_data_new (CAJA_UNDOSTACK_MOVETOTRASH, g_list_length(files)); + GFile* src_dir = g_file_get_parent (files->data); + caja_undostack_manager_data_set_src_dir (job->common.undo_redo_data, src_dir); + } + // End UNDO-REDO g_io_scheduler_push_job (delete_job, job, @@ -3362,6 +3386,9 @@ create_dest_dir (CommonJob *job, } return CREATE_DEST_DIR_FAILED; } + // Start UNDO-REDO + caja_undostack_manager_data_add_origin_target_pair (job->undo_redo_data, src, *dest); + // End UNDO-REDO caja_file_changes_queue_file_added (*dest); return CREATE_DEST_DIR_SUCCESS; } @@ -3974,6 +4001,8 @@ copy_move_file (CopyMoveJob *copy_job, unique_name_nr = 1; + // TODO: Here we should get the previous file name UNDO + /* another file in the same directory might have handled the invalid * filename condition for us */ @@ -4116,6 +4145,10 @@ copy_move_file (CopyMoveJob *copy_job, FALSE); } + // Start UNDO-REDO + caja_undostack_manager_data_add_origin_target_pair (job->undo_redo_data, src, dest); + // End UNDO-REDO + g_object_unref (dest); return; } @@ -4535,6 +4568,16 @@ caja_file_operations_copy (GList *files, inhibit_power_manager ((CommonJob *)job, _("Copying Files")); + // Start UNDO-REDO + if (!caja_undostack_manager_is_undo_redo(caja_undostack_manager_instance())) { + job->common.undo_redo_data = caja_undostack_manager_data_new (CAJA_UNDOSTACK_COPY, g_list_length(files)); + GFile* src_dir = g_file_get_parent (files->data); + caja_undostack_manager_data_set_src_dir (job->common.undo_redo_data, src_dir); + g_object_ref (target_dir); + caja_undostack_manager_data_set_dest_dir (job->common.undo_redo_data, target_dir); + } + // End UNDO-REDO + g_io_scheduler_push_job (copy_job, job, NULL, /* destroy notify */ @@ -4693,6 +4736,10 @@ move_file_prepare (CopyMoveJob *move_job, caja_file_changes_queue_schedule_position_remove (dest); } + // Start UNDO-REDO + caja_undostack_manager_data_add_origin_target_pair (job->undo_redo_data, src, dest); + // End UNDO-REDO + return; } @@ -5060,6 +5107,20 @@ caja_file_operations_move (GList *files, inhibit_power_manager ((CommonJob *)job, _("Moving Files")); + // Start UNDO-REDO + if (!caja_undostack_manager_is_undo_redo(caja_undostack_manager_instance())) { + if (g_file_has_uri_scheme (g_list_first(files)->data, "trash")) { + job->common.undo_redo_data = caja_undostack_manager_data_new (CAJA_UNDOSTACK_RESTOREFROMTRASH, g_list_length(files)); + } else { + job->common.undo_redo_data = caja_undostack_manager_data_new (CAJA_UNDOSTACK_MOVE, g_list_length(files)); + } + GFile* src_dir = g_file_get_parent (files->data); + caja_undostack_manager_data_set_src_dir (job->common.undo_redo_data, src_dir); + g_object_ref (target_dir); + caja_undostack_manager_data_set_dest_dir (job->common.undo_redo_data, target_dir); + } + // End UNDO-REDO + g_io_scheduler_push_job (move_job, job, NULL, /* destroy notify */ @@ -5153,6 +5214,9 @@ link_file (CopyMoveJob *job, path, common->cancellable, &error)) { + // Start UNDO-REDO + caja_undostack_manager_data_add_origin_target_pair (common->undo_redo_data, src, dest); + // End UNDO-REDO g_free (path); if (debuting_files) { g_hash_table_replace (debuting_files, g_object_ref (dest), GINT_TO_POINTER (TRUE)); @@ -5363,6 +5427,16 @@ caja_file_operations_link (GList *files, } job->debuting_files = g_hash_table_new_full (g_file_hash, (GEqualFunc)g_file_equal, g_object_unref, NULL); + // Start UNDO-REDO + if (!caja_undostack_manager_is_undo_redo(caja_undostack_manager_instance())) { + job->common.undo_redo_data = caja_undostack_manager_data_new (CAJA_UNDOSTACK_CREATELINK, g_list_length(files)); + GFile* src_dir = g_file_get_parent (files->data); + caja_undostack_manager_data_set_src_dir (job->common.undo_redo_data, src_dir); + g_object_ref (target_dir); + caja_undostack_manager_data_set_dest_dir (job->common.undo_redo_data, target_dir); + } + // End UNDO-REDO + g_io_scheduler_push_job (link_job, job, NULL, /* destroy notify */ @@ -5394,6 +5468,16 @@ caja_file_operations_duplicate (GList *files, } job->debuting_files = g_hash_table_new_full (g_file_hash, (GEqualFunc)g_file_equal, g_object_unref, NULL); + // Start UNDO-REDO + if (!caja_undostack_manager_is_undo_redo(caja_undostack_manager_instance())) { + job->common.undo_redo_data = caja_undostack_manager_data_new (CAJA_UNDOSTACK_DUPLICATE, g_list_length(files)); + GFile* src_dir = g_file_get_parent (files->data); + caja_undostack_manager_data_set_src_dir (job->common.undo_redo_data, src_dir); + g_object_ref (src_dir); + caja_undostack_manager_data_set_dest_dir (job->common.undo_redo_data, src_dir); + } + // End UNDO-REDO + g_io_scheduler_push_job (copy_job, job, NULL, /* destroy notify */ @@ -5463,6 +5547,9 @@ set_permissions_file (SetPermissionsJob *job, if (!job_aborted (common) && g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_UNIX_MODE)) { current = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_MODE); + // Start UNDO-REDO + caja_undostack_manager_data_add_file_permissions(common->undo_redo_data, file, current); + // End UNDO-REDO current = (current & ~mask) | value; g_file_set_attribute_uint32 (file, G_FILE_ATTRIBUTE_UNIX_MODE, @@ -5546,6 +5633,15 @@ caja_file_set_permissions_recursive (const char *directory, job->done_callback = callback; job->done_callback_data = callback_data; + // Start UNDO-REDO + if (!caja_undostack_manager_is_undo_redo(caja_undostack_manager_instance())) { + job->common.undo_redo_data = caja_undostack_manager_data_new (CAJA_UNDOSTACK_RECURSIVESETPERMISSIONS, 1); + g_object_ref (job->file); + caja_undostack_manager_data_set_dest_dir (job->common.undo_redo_data, job->file); + caja_undostack_manager_data_set_recursive_permissions(job->common.undo_redo_data, file_permissions, file_mask, dir_permissions, dir_mask); + } + // End UNDO-REDO + g_io_scheduler_push_job (set_permissions_job, job, NULL, @@ -5790,6 +5886,13 @@ create_job (GIOSchedulerJob *io_job, res = g_file_make_directory (dest, common->cancellable, &error); + // Start UNDO-REDO + if (res) { + caja_undostack_manager_data_set_create_data(common->undo_redo_data, + g_file_get_uri(dest), + NULL); + } + // End UNDO-REDO } else { if (job->src) { res = g_file_copy (job->src, @@ -5798,6 +5901,13 @@ create_job (GIOSchedulerJob *io_job, common->cancellable, NULL, NULL, &error); + // Start UNDO-REDO + if (res) { + caja_undostack_manager_data_set_create_data(common->undo_redo_data, + g_file_get_uri(dest), + g_file_get_uri(job->src)); + } + // End UNDO-REDO } else { data = ""; length = 0; @@ -5820,6 +5930,13 @@ create_job (GIOSchedulerJob *io_job, res = g_output_stream_close (G_OUTPUT_STREAM (out), common->cancellable, &error); + // Start UNDO-REDO + if (res) { + caja_undostack_manager_data_set_create_data(common->undo_redo_data, + g_file_get_uri(dest), + g_strdup(data)); + } + // End UNDO-REDO } /* This will close if the write failed and we didn't close */ @@ -5984,6 +6101,12 @@ caja_file_operations_new_folder (GtkWidget *parent_view, job->has_position = TRUE; } + // Start UNDO-REDO + if (!caja_undostack_manager_is_undo_redo(caja_undostack_manager_instance())) { + job->common.undo_redo_data = caja_undostack_manager_data_new (CAJA_UNDOSTACK_CREATEFOLDER, 1); + } + // End UNDO-REDO + g_io_scheduler_push_job (create_job, job, NULL, /* destroy notify */ @@ -6022,6 +6145,12 @@ caja_file_operations_new_file_from_template (GtkWidget *parent_view, job->src = g_file_new_for_uri (template_uri); } + // Start UNDO-REDO + if (!caja_undostack_manager_is_undo_redo(caja_undostack_manager_instance())) { + job->common.undo_redo_data = caja_undostack_manager_data_new (CAJA_UNDOSTACK_CREATEFILEFROMTEMPLATE, 1); + } + // End UNDO-REDO + g_io_scheduler_push_job (create_job, job, NULL, /* destroy notify */ @@ -6059,6 +6188,12 @@ caja_file_operations_new_file (GtkWidget *parent_view, job->length = length; job->filename = g_strdup (target_filename); + // Start UNDO-REDO + if (!caja_undostack_manager_is_undo_redo(caja_undostack_manager_instance())) { + job->common.undo_redo_data = caja_undostack_manager_data_new (CAJA_UNDOSTACK_CREATEEMPTYFILE, 1); + } + // End UNDO-REDO + g_io_scheduler_push_job (create_job, job, NULL, /* destroy notify */ @@ -6122,6 +6257,8 @@ empty_trash_job_done (gpointer user_data) job->done_callback (job->done_callback_data); } + caja_undostack_manager_trash_has_emptied(caja_undostack_manager_instance()); + finalize_common ((CommonJob *)job); return FALSE; } -- cgit v1.2.1