summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Neumair <cneumair@gnome.org>2008-07-21 14:52:45 +0000
committerChristian Neumair <cneumair@src.gnome.org>2008-07-21 14:52:45 +0000
commit838b12f0f416c59c98924a3e70672235bc344298 (patch)
tree09b753f61e6d74537ff54261d21c46b8efa0e1ef
parent02cbb458f332df72ab305636699e570612e5c7cc (diff)
downloadnautilus-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--ChangeLog15
-rw-r--r--libnautilus-private/nautilus-file-private.h4
-rw-r--r--libnautilus-private/nautilus-file.c29
-rw-r--r--libnautilus-private/nautilus-file.h2
-rw-r--r--src/file-manager/fm-actions.h2
-rw-r--r--src/file-manager/fm-directory-view.c163
-rw-r--r--src/file-manager/nautilus-directory-view-ui.xml3
7 files changed, 214 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 433a10106..92149b1e1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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"/>