diff options
author | Christian Neumair <cneumair@gnome.org> | 2008-07-21 14:52:45 +0000 |
---|---|---|
committer | Christian Neumair <cneumair@src.gnome.org> | 2008-07-21 14:52:45 +0000 |
commit | 838b12f0f416c59c98924a3e70672235bc344298 (patch) | |
tree | 09b753f61e6d74537ff54261d21c46b8efa0e1ef | |
parent | 02cbb458f332df72ab305636699e570612e5c7cc (diff) | |
download | nautilus-838b12f0f416c59c98924a3e70672235bc344298.tar.gz |
Support restoring from trash (one item at a time).
2008-07-21 Christian Neumair <cneumair@gnome.org>
* libnautilus-private/nautilus-file-private.h:
* libnautilus-private/nautilus-file.c (update_info_internal),
(nautilus_file_get_trash_original_file):
* libnautilus-private/nautilus-file.h:
* src/file-manager/fm-actions.h:
* src/file-manager/fm-directory-view.c
(action_restore_from_trash_callback), (restore_from_trash),
(action_location_restore_from_trash_callback),
(update_restore_from_trash_action), (real_update_location_menu),
(real_update_menus):
* src/file-manager/nautilus-directory-view-ui.xml:
Support restoring from trash (one item at a time).
svn path=/trunk/; revision=14386
-rw-r--r-- | ChangeLog | 15 | ||||
-rw-r--r-- | libnautilus-private/nautilus-file-private.h | 4 | ||||
-rw-r--r-- | libnautilus-private/nautilus-file.c | 29 | ||||
-rw-r--r-- | libnautilus-private/nautilus-file.h | 2 | ||||
-rw-r--r-- | src/file-manager/fm-actions.h | 2 | ||||
-rw-r--r-- | src/file-manager/fm-directory-view.c | 163 | ||||
-rw-r--r-- | src/file-manager/nautilus-directory-view-ui.xml | 3 |
7 files changed, 214 insertions, 4 deletions
@@ -1,5 +1,20 @@ 2008-07-21 Christian Neumair <cneumair@gnome.org> + * libnautilus-private/nautilus-file-private.h: + * libnautilus-private/nautilus-file.c (update_info_internal), + (nautilus_file_get_trash_original_file): + * libnautilus-private/nautilus-file.h: + * src/file-manager/fm-actions.h: + * src/file-manager/fm-directory-view.c + (action_restore_from_trash_callback), (restore_from_trash), + (action_location_restore_from_trash_callback), + (update_restore_from_trash_action), (real_update_location_menu), + (real_update_menus): + * src/file-manager/nautilus-directory-view-ui.xml: + Support restoring from trash (one item at a time). + +2008-07-21 Christian Neumair <cneumair@gnome.org> + * src/nautilus-window-menus.c: * src/nautilus-zoom-control.c (nautilus_zoom_control_instance_init): diff --git a/libnautilus-private/nautilus-file-private.h b/libnautilus-private/nautilus-file-private.h index fb4e7e3e6..8b116c1f9 100644 --- a/libnautilus-private/nautilus-file-private.h +++ b/libnautilus-private/nautilus-file-private.h @@ -46,7 +46,7 @@ GNOME_VFS_FILE_INFO_GET_ACCESS_RIGHTS) #define NAUTILUS_FILE_DEFAULT_ATTRIBUTES \ - "standard::*,access::*,mountable::*,time::*,unix::*,owner::*,selinux::*,thumbnail::*,id::filesystem" + "standard::*,access::*,mountable::*,time::*,unix::*,owner::*,selinux::*,thumbnail::*,id::filesystem,trash::orig-path" /* These are in the typical sort order. Known things come first, then * things where we can't know, finally things where we don't yet know. @@ -120,6 +120,8 @@ struct NautilusFileDetails */ eel_ref_str filesystem_id; + char *trash_orig_path; + /* The following is for file operations in progress. Since * there are normally only a few of these, we can move them to * a separate hash table or something if required to keep the diff --git a/libnautilus-private/nautilus-file.c b/libnautilus-private/nautilus-file.c index d7854ce99..292f4990a 100644 --- a/libnautilus-private/nautilus-file.c +++ b/libnautilus-private/nautilus-file.c @@ -1561,6 +1561,7 @@ update_info_internal (NautilusFile *file, const char *activation_uri; const char *description; const char *filesystem_id; + const char *trash_orig_path; if (file->details->is_gone) { return FALSE; @@ -1832,6 +1833,13 @@ update_info_internal (NautilusFile *file, eel_ref_str_unref (file->details->filesystem_id); file->details->filesystem_id = eel_ref_str_get_unique (filesystem_id); } + + trash_orig_path = g_file_info_get_attribute_byte_string (info, "trash::orig-path"); + if (eel_strcmp (file->details->trash_orig_path, trash_orig_path) != 0) { + changed = TRUE; + g_free (file->details->trash_orig_path); + file->details->trash_orig_path = g_strdup (trash_orig_path); + } if (update_name) { name = g_file_info_get_name (info); @@ -6144,6 +6152,27 @@ nautilus_file_get_filesystem_id (NautilusFile *file) return g_strdup (eel_ref_str_peek (file->details->filesystem_id)); } +NautilusFile * +nautilus_file_get_trash_original_file (NautilusFile *file) +{ + GFile *location; + NautilusFile *original_file; + char *filename; + + original_file = NULL; + + if (file->details->trash_orig_path != NULL) { + /* file name is stored in URL encoding */ + filename = g_uri_unescape_string (file->details->trash_orig_path, ""); + location = g_file_new_for_path (filename); + original_file = nautilus_file_get (location); + g_object_unref (G_OBJECT (location)); + g_free (filename); + } + + return original_file; + +} void nautilus_file_mark_gone (NautilusFile *file) diff --git a/libnautilus-private/nautilus-file.h b/libnautilus-private/nautilus-file.h index f52a4222b..8e86ec04e 100644 --- a/libnautilus-private/nautilus-file.h +++ b/libnautilus-private/nautilus-file.h @@ -227,6 +227,8 @@ GFilesystemPreviewType nautilus_file_get_filesystem_use_preview (Nautilu char * nautilus_file_get_filesystem_id (NautilusFile *file); +NautilusFile * nautilus_file_get_trash_original_file (NautilusFile *file); + /* Permissions. */ gboolean nautilus_file_can_get_permissions (NautilusFile *file); gboolean nautilus_file_can_set_permissions (NautilusFile *file); diff --git a/src/file-manager/fm-actions.h b/src/file-manager/fm-actions.h index 6068b70bc..90cbcccbb 100644 --- a/src/file-manager/fm-actions.h +++ b/src/file-manager/fm-actions.h @@ -60,6 +60,8 @@ #define FM_ACTION_LOCATION_TRASH "LocationTrash" #define FM_ACTION_DELETE "Delete" #define FM_ACTION_LOCATION_DELETE "LocationDelete" +#define FM_ACTION_RESTORE_FROM_TRASH "Restore From Trash" +#define FM_ACTION_LOCATION_RESTORE_FROM_TRASH "LocationRestoreFromTrash" #define FM_ACTION_SHOW_HIDDEN_FILES "Show Hidden Files" #define FM_ACTION_CONNECT_TO_SERVER_LINK "Connect To Server Link" #define FM_ACTION_MOUNT_VOLUME "Mount Volume" diff --git a/src/file-manager/fm-directory-view.c b/src/file-manager/fm-directory-view.c index 79b0ed412..f2703ba75 100644 --- a/src/file-manager/fm-directory-view.c +++ b/src/file-manager/fm-directory-view.c @@ -281,6 +281,8 @@ static void trash_or_delete_files (GtkWindow const GList *files, gboolean delete_if_all_already_in_trash, FMDirectoryView *view); +static void restore_from_trash (NautilusFile *file, + FMDirectoryView *view); static void load_directory (FMDirectoryView *view, NautilusDirectory *directory); static void fm_directory_view_merge_menus (FMDirectoryView *view); @@ -998,6 +1000,26 @@ action_delete_callback (GtkAction *action, delete_selected_files (FM_DIRECTORY_VIEW (callback_data)); } +static void +action_restore_from_trash_callback (GtkAction *action, + gpointer callback_data) +{ + FMDirectoryView *view; + NautilusFile *file; + GList *selection; + + view = FM_DIRECTORY_VIEW (callback_data); + + selection = fm_directory_view_get_selection_for_file_transfer (view); + if (g_list_length (selection) == 1) { + file = NAUTILUS_FILE (selection->data); + restore_from_trash (file, view); + } + + nautilus_file_list_free (selection); + +} + static gboolean real_delete (FMDirectoryView *view) { @@ -6383,6 +6405,72 @@ action_location_delete_callback (GtkAction *action, } static void +restore_from_trash (NautilusFile *file, + FMDirectoryView *view) +{ + NautilusFile *original_file, *original_dir; + GFile *location, *original_dir_location; + GList list; + char *message, *file_name; + + g_assert (NAUTILUS_IS_FILE (file)); + g_assert (FM_IS_DIRECTORY_VIEW (view)); + + original_file = nautilus_file_get_trash_original_file (file); + if (original_file == NULL) { + file_name = nautilus_file_get_display_name (file); + message = g_strdup_printf (_("Could not determine original location of \"%s\" "), file_name); + g_free (file_name); + + eel_show_warning_dialog (message, + _("The item cannot be restored from trash"), + fm_directory_view_get_containing_window (view)); + g_free (message); + } + + + original_dir = NULL; + + if (original_file != NULL) { + original_dir = nautilus_file_get_parent (original_file); + } + + if (original_dir != NULL) { + location = nautilus_file_get_location (file); + original_dir_location = nautilus_file_get_location (original_dir); + + list.prev = NULL; + list.next = NULL; + list.data = location; + + nautilus_file_operations_move + (&list, NULL, + original_dir_location, + (GtkWindow *) view->details->window, + NULL, NULL); + + g_object_unref (location); + g_object_unref (original_dir_location); + } + + nautilus_file_unref (original_file); + nautilus_file_unref (original_dir); +} + +static void +action_location_restore_from_trash_callback (GtkAction *action, + gpointer callback_data) +{ + FMDirectoryView *view; + NautilusFile *file; + + view = FM_DIRECTORY_VIEW (callback_data); + file = view->details->location_popup_directory_as_file; + + restore_from_trash (file, view); +} + +static void fm_directory_view_init_show_hidden_files (FMDirectoryView *view) { NautilusWindowShowHiddenFilesMode mode; @@ -6541,6 +6629,10 @@ static const GtkActionEntry directory_view_entries[] = { /* label, accelerator */ N_("_Delete"), "<shift>Delete", /* tooltip */ N_("Delete each selected item, without moving to the Trash"), G_CALLBACK (action_delete_callback) }, + /* name, stock id */ { "Restore From Trash", NULL, + /* label, accelerator */ N_("_Restore"), NULL, + NULL, + G_CALLBACK (action_restore_from_trash_callback) }, /* * multiview-TODO: decide whether "Reset to Defaults" should * be window-wide, and not just view-wide. @@ -6632,6 +6724,9 @@ static const GtkActionEntry directory_view_entries[] = { /* label, accelerator */ N_("_Delete"), "", /* tooltip */ N_("Delete this folder, without moving to the Trash"), G_CALLBACK (action_location_delete_callback) }, + /* name, stock id */ { FM_ACTION_LOCATION_RESTORE_FROM_TRASH, NULL, + /* label, accelerator */ N_("_Restore"), NULL, NULL, + G_CALLBACK (action_location_restore_from_trash_callback) }, /* name, stock id */ { "Location Mount Volume", NULL, /* label, accelerator */ N_("_Mount Volume"), NULL, @@ -7008,6 +7103,43 @@ file_should_show_self (NautilusFile *file, #endif } +static void +update_restore_from_trash_action (GtkAction *action, + NautilusFile *file, + gboolean is_self) +{ + NautilusFile *original_file; + GFile *original_location; + char *tooltip, *tmp; + + if (file != NULL) { + original_file = nautilus_file_get_trash_original_file (file); + gtk_action_set_visible (action, original_file != NULL); + + if (original_file != NULL) { + original_location = nautilus_file_get_location (original_file); + + tmp = g_file_get_parse_name (original_location); + if (is_self) { + tooltip = g_strdup_printf (_("Move the open folder out of the trash to \"%s\""), tmp); + } else if (nautilus_file_is_directory (file)) { + tooltip = g_strdup_printf (_("Move the selected folder out of the trash to \"%s\""), tmp); + } else { + tooltip = g_strdup_printf (_("Move the selected file out of the trash to \"%s\""), tmp); + } + g_free (tmp); + + g_object_set (action, "tooltip", tooltip, NULL); + + g_object_unref (original_location); + } + + nautilus_file_unref (original_file); + } else { + gtk_action_set_visible (action, FALSE); + } + +} static void real_update_menus_volumes (FMDirectoryView *view, @@ -7195,7 +7327,7 @@ real_update_location_menu (FMDirectoryView *view) NautilusFile *file; gboolean is_special_link; gboolean is_desktop_or_home_dir; - gboolean can_delete_file; + gboolean can_delete_file, show_delete; gboolean show_separate_delete_command; gboolean show_open_folder_window; char *label; @@ -7253,9 +7385,15 @@ real_update_location_menu (FMDirectoryView *view) GPOINTER_TO_INT (g_object_get_data (G_OBJECT (action), "can-paste-according-to-destination"))); + show_delete = TRUE; + if (file != NULL && nautilus_file_is_in_trash (file)) { - label = _("_Delete from Trash"); + if (nautilus_file_is_self_owned (file)) { + show_delete = FALSE; + } + + label = _("_Delete Permanently"); tip = _("Delete the open folder permanently"); show_separate_delete_command = FALSE; } else { @@ -7269,8 +7407,12 @@ real_update_location_menu (FMDirectoryView *view) g_object_set (action, "label", label, "tooltip", tip, + "stock-id", (file != NULL && + nautilus_file_is_in_trash (file)) ? + NULL : NAUTILUS_ICON_TRASH, NULL); gtk_action_set_sensitive (action, can_delete_file); + gtk_action_set_visible (action, show_delete); action = gtk_action_group_get_action (view->details->dir_action_group, FM_ACTION_LOCATION_DELETE); @@ -7279,6 +7421,10 @@ real_update_location_menu (FMDirectoryView *view) gtk_action_set_sensitive (action, can_delete_file); } + action = gtk_action_group_get_action (view->details->dir_action_group, + FM_ACTION_LOCATION_RESTORE_FROM_TRASH); + update_restore_from_trash_action (action, file, TRUE); + real_update_location_menu_volumes (view); /* we silently assume that fm_directory_view_supports_properties always returns the same value. @@ -7493,7 +7639,7 @@ real_update_menus (FMDirectoryView *view) reset_extension_actions_menu (view, selection); if (all_selected_items_in_trash (view)) { - label = _("_Delete from Trash"); + label = _("_Delete Permanently"); tip = _("Delete all selected items permanently"); show_separate_delete_command = FALSE; } else { @@ -7507,6 +7653,8 @@ real_update_menus (FMDirectoryView *view) g_object_set (action, "label", label, "tooltip", tip, + "stock-id", all_selected_items_in_trash (view) ? + NULL : NAUTILUS_ICON_TRASH, NULL); gtk_action_set_sensitive (action, can_delete_files); @@ -7520,6 +7668,15 @@ real_update_menus (FMDirectoryView *view) NULL); } gtk_action_set_sensitive (action, can_delete_files); + + + action = gtk_action_group_get_action (view->details->dir_action_group, + FM_ACTION_RESTORE_FROM_TRASH); + if (selection_count == 1) { + update_restore_from_trash_action (action, selection->data, FALSE); + } else { + update_restore_from_trash_action (action, NULL, FALSE); + } action = gtk_action_group_get_action (view->details->dir_action_group, FM_ACTION_DUPLICATE); diff --git a/src/file-manager/nautilus-directory-view-ui.xml b/src/file-manager/nautilus-directory-view-ui.xml index e8a2a64d2..acf20dee6 100644 --- a/src/file-manager/nautilus-directory-view-ui.xml +++ b/src/file-manager/nautilus-directory-view-ui.xml @@ -68,6 +68,7 @@ <placeholder name="Dangerous File Items Placeholder"> <menuitem name="Trash" action="Trash"/> <menuitem name="Delete" action="Delete"/> + <menuitem name="Restore From Trash" action="Restore From Trash"/> </placeholder> <placeholder name="Extension Actions"/> </menu> @@ -151,6 +152,7 @@ <placeholder name="Dangerous File Actions"> <menuitem name="Trash" action="Trash"/> <menuitem name="Delete" action="Delete"/> + <menuitem name="Restore From Trash" action="Restore From Trash"/> </placeholder> <separator name="Appearance separator"/> <placeholder name="Icon Appearance Items"> @@ -183,6 +185,7 @@ <placeholder name="Dangerous File Actions"> <menuitem name="Trash" action="LocationTrash"/> <menuitem name="Delete" action="LocationDelete"/> + <menuitem name="Restore From Trash" action="LocationRestoreFromTrash"/> </placeholder> <separator name="Location After Dangerous Separator"/> <menuitem name="Location Mount Volume" action="Location Mount Volume"/> |