Commit 838b12f0 authored by Christian Neumair's avatar Christian Neumair Committed by Christian Neumair

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
parent 02cbb458
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:
......
......@@ -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
......
......@@ -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)
......
......@@ -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);
......
......@@ -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"
......
......@@ -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)
{
......@@ -6382,6 +6404,72 @@ action_location_delete_callback (GtkAction *action,
eel_g_object_list_free (files);
}
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)
{
......@@ -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);
......
......@@ -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"/>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment