[nautilus/undo-manager: 3/3] undostack-manager: move to a vfunc-based undo/redo actions
- From: Cosimo Cecchi <cosimoc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nautilus/undo-manager: 3/3] undostack-manager: move to a vfunc-based undo/redo actions
- Date: Mon, 29 Nov 2010 09:22:42 +0000 (UTC)
commit ad52d982d35860ae157b7b14cd7f343a4e632ef8
Author: Cosimo Cecchi <cosimoc gnome org>
Date: Mon Nov 29 10:19:31 2010 +0100
undostack-manager: move to a vfunc-based undo/redo actions
Instead of having huge switch-case blocks, separate each undo/redo
snippet in a separate vfunc.
Add a vfunc to refresh action labels and descriptions.
This makes the code more readable and maintainable, but there's still a
bunch of work to do to make this work properly.
libnautilus-private/nautilus-undostack-manager.c | 1861 +++++++++++----------
libnautilus-private/nautilus-undostack-manager.h | 21 +-
2 files changed, 985 insertions(+), 897 deletions(-)
---
diff --git a/libnautilus-private/nautilus-undostack-manager.c b/libnautilus-private/nautilus-undostack-manager.c
index b9038af..91c7012 100644
--- a/libnautilus-private/nautilus-undostack-manager.c
+++ b/libnautilus-private/nautilus-undostack-manager.c
@@ -2,6 +2,7 @@
/* nautilus-undostack-manager.h - Manages undo/redo of file operations
*
* Copyright (C) 2007-2010 Amos Brocco
+ * Copyright (C) 2010 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
@@ -18,7 +19,9 @@
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
- * Author: Amos Brocco <amos brocco unifr ch>
+ * Authors: Amos Brocco <amos brocco unifr ch>
+ * Cosimo Cecchi <cosimoc redhat com>
+ *
*/
#include <config.h>
@@ -36,21 +39,31 @@
/* Default depth of the undo/redo stack. */
#define DEFAULT_UNDO_DEPTH 32
-struct _NautilusUndoStackActionData
-{
+struct _NautilusUndoStackActionData {
/* Common stuff */
NautilusUndoStackActionType type;
+
+ void (* undo_func) (NautilusUndoStackActionData *data);
+ void (* redo_func) (NautilusUndoStackActionData *data);
+
+ NautilusUndoStackFinishCallback callback;
+ gpointer callback_user_data;
+
NautilusUndoStackManager *manager;
eel_boolean_bit is_valid : 1;
eel_boolean_bit locked : 1; /* True if the action is being undone/redone */
eel_boolean_bit freed : 1; /* True if the action must be freed after undo/redo */
guint count; /* Number of items */
- /* Cached labels/descriptions */
- char *undo_label;
- char *undo_description;
- char *redo_label;
- char *redo_description;
+ void (* strings_func) (NautilusUndoStackActionData *data,
+ guint count,
+ gchar **labels,
+ gchar **descriptions);
+
+ gchar *undo_label;
+ gchar *redo_label;
+ gchar *undo_description;
+ gchar *redo_description;
/* Copy / Move stuff */
GFile *src_dir;
@@ -81,15 +94,12 @@ struct _NautilusUndoStackActionData
guint32 new_permissions;
/* Group */
- char *original_group_name;
- char *new_group_name;
-
- /* Owner */
- char *original_user_name;
- char *new_user_name;
-
+ char *original_name;
+ char *new_name;
};
+typedef struct _NautilusUndoStackActionData UndoData;
+
struct _NautilusUndoStackManagerPrivate
{
GQueue *stack;
@@ -99,9 +109,8 @@ struct _NautilusUndoStackManagerPrivate
guint undo_levels;
guint index;
- eel_boolean_bit dispose_has_run : 1;
- eel_boolean_bit undo_redo_flag : 1;
- eel_boolean_bit confirm_delete : 1;
+ guint undo_redo_flag : 1;
+ guint confirm_delete : 1;
};
#define NAUTILUS_UNDO_STACK_MANAGER_GET_PRIVATE(o) \
@@ -128,11 +137,6 @@ static NautilusUndoStackActionData * stack_scroll_right (NautilusUndoStackManage
static NautilusUndoStackActionData * get_next_redo_action (NautilusUndoStackManagerPrivate *priv);
static NautilusUndoStackActionData * get_next_undo_action (NautilusUndoStackManagerPrivate *priv);
-static char *get_undo_label (NautilusUndoStackActionData *action);
-static char *get_undo_description (NautilusUndoStackActionData *action);
-static char *get_redo_label (NautilusUndoStackActionData *action);
-static char *get_redo_description (NautilusUndoStackActionData *action);
-
static void do_menu_update (NautilusUndoStackManager * manager);
static void undo_redo_done_transfer_callback (GHashTable * debuting_uris, gpointer data);
static void undo_redo_op_callback (gpointer callback_data);
@@ -161,13 +165,12 @@ nautilus_undo_stack_manager_init (NautilusUndoStackManager * self)
priv->stack = g_queue_new ();
priv->mutex = g_mutex_new ();
priv->index = 0;
- priv->dispose_has_run = FALSE;
priv->undo_redo_flag = FALSE;
priv->confirm_delete = FALSE;
}
static void
-free_undo_stack_action_data (NautilusUndoStackActionData *action)
+undo_stack_action_data_free (NautilusUndoStackActionData *action)
{
g_return_if_fail (action != NULL);
@@ -178,10 +181,8 @@ free_undo_stack_action_data (NautilusUndoStackActionData *action)
g_free (action->redo_label);
g_free (action->redo_description);
- g_free (action->original_group_name);
- g_free (action->original_user_name);
- g_free (action->new_group_name);
- g_free (action->new_user_name);
+ g_free (action->original_name);
+ g_free (action->new_name);
if (action->sources) {
g_list_free_full (action->sources, g_free);
@@ -217,7 +218,7 @@ nautilus_undo_stack_manager_finalize (GObject * object)
g_mutex_lock (priv->mutex);
- g_queue_foreach (priv->stack, (GFunc) free_undo_stack_action_data, NULL);
+ g_queue_foreach (priv->stack, (GFunc) undo_stack_action_data_free, NULL);
g_queue_free (priv->stack);
g_mutex_unlock (priv->mutex);
@@ -384,6 +385,71 @@ nautilus_undo_stack_manager_is_undo_redo (NautilusUndoStackManager *manager)
return FALSE;
}
+static void
+refresh_strings (UndoData *action)
+{
+ gchar **descriptions;
+ gchar **labels;
+
+ descriptions = (gchar **) g_malloc0 (3 * sizeof (gchar *));
+ descriptions[2] = NULL;
+
+ labels = (gchar **) g_malloc0 (3 * sizeof (gchar *));
+ labels[2] = NULL;
+
+ action->strings_func (action, action->count,
+ labels, descriptions);
+
+ action->undo_label = labels[0];
+ action->redo_label = labels[1];
+
+ action->undo_description = descriptions[0];
+ action->redo_description = descriptions[1];
+
+ g_free (descriptions);
+ g_free (labels);
+}
+
+static const gchar *
+get_redo_label (UndoData *action)
+{
+ if (action->redo_label == NULL) {
+ refresh_strings (action);
+ }
+
+ return action->redo_label;
+}
+
+static const gchar *
+get_undo_label (UndoData *action)
+{
+ if (action->undo_label == NULL) {
+ refresh_strings (action);
+ }
+
+ return action->undo_label;
+}
+
+static const char *
+get_undo_description (UndoData *action)
+{
+ if (action->undo_description == NULL) {
+ refresh_strings (action);
+ }
+
+ return action->undo_description;
+}
+
+static const char *
+get_redo_description (UndoData *action)
+{
+ if (action->redo_description == NULL) {
+ refresh_strings (action);
+ }
+
+ return action->redo_description;
+}
+
/**
* nautilus_undo_stack_manager_request_menu_update:
* @manager:
@@ -396,329 +462,462 @@ nautilus_undo_stack_manager_request_menu_update (NautilusUndoStackManager *manag
do_menu_update (manager);
}
-/**
- * nautilus_undo_stack_manager_redo:
- * @manager:
- * @cb:
- * @user_data:
- *
- * Redoes the last file operation.
- */
-void
-nautilus_undo_stack_manager_redo (NautilusUndoStackManager *manager,
- NautilusUndoStackFinishCallback callback,
- gpointer user_data)
+
+/* undo helpers */
+
+static void
+delete_uris (NautilusUndoStackManager *self,
+ GList *uris,
+ UndoData *action)
+{
+ if (self->priv->confirm_delete) {
+ nautilus_file_operations_delete (uris, NULL,
+ undo_redo_done_delete_callback, action);
+ } else {
+ self->priv->undo_redo_flag = FALSE;
+
+ /* We skip the confirmation message */
+ GList *f;
+ for (f = uris; f != NULL; f = f->next) {
+ g_file_delete (f->data, NULL, NULL);
+ }
+
+ /* Here we must do what's necessary for the callback */
+ undo_redo_done_transfer_callback (NULL, action);
+ }
+}
+
+static void
+create_undo_func (UndoData *action)
{
- NautilusUndoStackManagerPrivate *priv;
- NautilusUndoStackActionData *action;
- NautilusFile *file;
GList *uris;
- char *new_name;
- char *parent_uri;
+ gchar *uri;
- priv = manager->priv;
+ uri = g_file_get_uri (action->target_file);
+ uris = construct_gfile_list_from_uri (uri);
- /* Update the menus invalidating undo/redo while an operation is already underway */
- g_mutex_lock (priv->mutex);
- action = stack_scroll_left (priv);
- /* Action will be NULL if redo is not possible */
- if (action != NULL) {
- action->locked = TRUE;
+ delete_uris (action->manager, uris, action);
+
+ g_free (uri);
+ g_list_free_full (uris, g_object_unref);
+}
+
+static void
+copy_or_link_undo_func (UndoData *action)
+{
+ GList *uris;
+
+ uris = construct_gfile_list (action->destinations, action->dest_dir);
+ uris = g_list_reverse (uris); /* Deleting must be done in reverse */
+
+ delete_uris (action->manager, uris, action);
+
+ g_list_free_full (uris, g_object_unref);
+}
+
+static void
+restore_undo_func (UndoData *action)
+{
+ GList *uris;
+
+ uris = construct_gfile_list (action->destinations, action->dest_dir);
+ nautilus_file_operations_trash_or_delete (uris, NULL,
+ undo_redo_done_delete_callback, action);
+
+ g_list_free_full (uris, g_object_unref);
+}
+
+static void
+trash_undo_func (UndoData *action)
+{
+ NautilusUndoStackManagerPrivate *priv = action->manager->priv;
+ GHashTable *files_to_restore;
+
+ /* Internally managed op, clear the undo_redo_flag.
+ * Same as calling nautilus_undo_stack_manager_is_undo_redo()
+ * minus the function call and unused return val.
+ */
+
+ priv->undo_redo_flag = FALSE;
+ files_to_restore = retrieve_files_to_restore (action->trashed);
+
+ if (g_hash_table_size (files_to_restore) > 0) {
+ GList *gfiles_in_trash, *l;
+ GFile *item;
+ GFile *dest;
+ char *value;
+
+ gfiles_in_trash = g_hash_table_get_keys (files_to_restore);
+
+ for (l = gfiles_in_trash; l != NULL; l = l->next) {
+ item = l->data;
+ value = g_hash_table_lookup (files_to_restore, item);
+ dest = g_file_new_for_uri (value);
+ g_file_move (item, dest, G_FILE_COPY_NOFOLLOW_SYMLINKS, NULL, NULL, NULL, NULL);
+ g_object_unref (dest);
+ }
+
+ g_list_free (gfiles_in_trash);
}
- g_mutex_unlock (priv->mutex);
- do_menu_update (manager);
- uris = NULL;
- if (action != NULL) {
- action->locked = TRUE; /* Remember to unlock when redo is finished */
- priv->undo_redo_flag = TRUE;
- switch (action->type) {
- case NAUTILUS_UNDO_STACK_COPY:
- uris = construct_gfile_list (action->sources, action->src_dir);
- nautilus_file_operations_copy (uris, NULL, action->dest_dir, NULL, undo_redo_done_transfer_callback, action);
- g_list_free_full (uris, g_object_unref);
- break;
- case NAUTILUS_UNDO_STACK_CREATE_FILE_FROM_TEMPLATE:
- {
- GFile *parent;
- parent = g_file_get_parent (action->target_file);
- parent_uri = g_file_get_uri (parent);
- new_name = g_file_get_parse_name (action->target_file);
- nautilus_file_operations_new_file_from_template (NULL,
- NULL,
- parent_uri,
- new_name, action->template, undo_redo_done_create_callback, action);
- g_free (parent_uri);
- g_free (new_name);
- g_object_unref (parent);
- }
- break;
- case NAUTILUS_UNDO_STACK_DUPLICATE:
- uris = construct_gfile_list (action->sources, action->src_dir);
- nautilus_file_operations_duplicate (uris, NULL, NULL, undo_redo_done_transfer_callback, action);
- g_list_free_full (uris, g_object_unref);
- break;
- case NAUTILUS_UNDO_STACK_RESTORE_FROM_TRASH:
- case NAUTILUS_UNDO_STACK_MOVE:
- uris = construct_gfile_list (action->sources, action->src_dir);
- nautilus_file_operations_move (uris, NULL, action->dest_dir, NULL, undo_redo_done_transfer_callback, action);
- g_list_free_full (uris, g_object_unref);
- break;
- case NAUTILUS_UNDO_STACK_RENAME:
- new_name = g_file_get_basename (action->new_file);
- file = nautilus_file_get (action->old_file);
- nautilus_file_rename (file, new_name, undo_redo_done_rename_callback, action);
- g_object_unref (file);
- g_free (new_name);
- break;
- case NAUTILUS_UNDO_STACK_CREATE_EMPTY_FILE:
- {
- GFile *parent;
- parent = g_file_get_parent (action->target_file);
- parent_uri = g_file_get_uri (parent);
- new_name = g_file_get_parse_name (action->target_file);
- nautilus_file_operations_new_file (NULL, NULL, parent_uri,
- new_name,
- action->template,
- action->count, undo_redo_done_create_callback, action);
- g_free (parent_uri);
- g_free (new_name);
- }
- break;
- case NAUTILUS_UNDO_STACK_CREATE_FOLDER:
- {
- GFile *parent;
- parent = g_file_get_parent (action->target_file);
- parent_uri = g_file_get_uri (parent);
- nautilus_file_operations_new_folder (NULL, NULL, parent_uri, undo_redo_done_create_callback, action);
- g_free (parent_uri);
- }
- break;
- case NAUTILUS_UNDO_STACK_MOVE_TO_TRASH:
- if (g_hash_table_size (action->trashed) > 0) {
- GList *uri_to_trash;
- uri_to_trash = g_hash_table_get_keys (action->trashed);
- uris = uri_list_to_gfile_list (uri_to_trash);
- nautilus_file_operations_trash_or_delete (uris, NULL, undo_redo_done_delete_callback, action);
- g_list_free (uri_to_trash);
- g_list_free_full (uris, g_object_unref);
- }
- break;
- case NAUTILUS_UNDO_STACK_CREATE_LINK:
- uris = construct_gfile_list (action->sources, action->src_dir);
- nautilus_file_operations_link (uris, NULL, action->dest_dir, NULL, undo_redo_done_transfer_callback, action);
- g_list_free_full (uris, g_object_unref);
- break;
- case NAUTILUS_UNDO_STACK_SET_PERMISSIONS:
- file = nautilus_file_get (action->target_file);
- nautilus_file_set_permissions (file, action->new_permissions, undo_redo_done_rename_callback, action);
- g_object_unref (file);
- break;
- case NAUTILUS_UNDO_STACK_RECURSIVE_SET_PERMISSIONS:
- parent_uri = g_file_get_uri (action->dest_dir);
- nautilus_file_set_permissions_recursive (parent_uri,
- action->file_permissions,
- action->file_mask,
- action->dir_permissions,
- action->dir_mask,
- undo_redo_op_callback,
- action);
- g_free (parent_uri);
- break;
- case NAUTILUS_UNDO_STACK_CHANGE_GROUP:
- file = nautilus_file_get (action->target_file);
- nautilus_file_set_group (file,
- action->new_group_name,
- undo_redo_done_rename_callback,
- action);
- g_object_unref (file);
- break;
- case NAUTILUS_UNDO_STACK_CHANGE_OWNER:
- file = nautilus_file_get (action->target_file);
- nautilus_file_set_owner (file,
- action->new_user_name,
- undo_redo_done_rename_callback,
- action);
- g_object_unref (file);
- break;
- default:
- priv->undo_redo_flag = FALSE;
- break; /* We shouldn't be here */
+ g_hash_table_destroy (files_to_restore);
+
+ /* Here we must do what's necessary for the callback */
+ undo_redo_done_transfer_callback (NULL, action);
+}
+
+static void
+move_undo_func (UndoData *action)
+{
+ GList *uris;
+
+ uris = construct_gfile_list (action->destinations, action->dest_dir);
+ nautilus_file_operations_move (uris, NULL,
+ action->src_dir, NULL,
+ undo_redo_done_transfer_callback, action);
+
+ g_list_free_full (uris, g_object_unref);
+}
+
+static void
+rename_undo_func (UndoData *action)
+{
+ gchar *new_name;
+ NautilusFile *file;
+
+ new_name = g_file_get_basename (action->old_file);
+ file = nautilus_file_get (action->new_file);
+
+ nautilus_file_rename (file, new_name,
+ undo_redo_done_rename_callback, action);
+
+ nautilus_file_unref (file);
+ g_free (new_name);
+}
+
+static void
+set_permissions_undo_func (UndoData *action)
+{
+ NautilusFile *file;
+
+ file = nautilus_file_get (action->target_file);
+
+ nautilus_file_set_permissions (file,
+ action->current_permissions,
+ undo_redo_done_rename_callback, action);
+
+ nautilus_file_unref (file);
+}
+
+static void
+recursive_permissions_undo_func (UndoData *action)
+{
+ NautilusUndoStackManagerPrivate *priv = action->manager->priv;
+
+ /* Internally managed op, clear the undo_redo_flag. */
+ priv->undo_redo_flag = FALSE;
+
+ if (g_hash_table_size (action->original_permissions) > 0) {
+ GList *gfiles_list;
+ guint32 *perm;
+ GList *l;
+ GFile *dest;
+ char *item;
+
+ gfiles_list = g_hash_table_get_keys (action->original_permissions);
+ for (l = gfiles_list; l != NULL; l = l->next) {
+ item = l->data;
+ perm = g_hash_table_lookup (action->original_permissions, item);
+ dest = g_file_new_for_uri (item);
+ g_file_set_attribute_uint32 (dest,
+ G_FILE_ATTRIBUTE_UNIX_MODE,
+ *perm, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, NULL);
+ g_object_unref (dest);
}
+
+ g_list_free (gfiles_list);
+ /* Here we must do what's necessary for the callback */
+ undo_redo_done_transfer_callback (NULL, action);
}
+}
- if (callback != NULL) {
- callback (user_data);
+static void
+change_group_undo_func (UndoData *action)
+{
+ NautilusFile *file;
+
+ file = nautilus_file_get (action->target_file);
+
+ nautilus_file_set_group (file,
+ action->original_name,
+ undo_redo_done_rename_callback, action);
+
+ nautilus_file_unref (file);
+}
+
+static void
+change_owner_undo_func (UndoData *action)
+{
+ NautilusFile *file;
+
+ file = nautilus_file_get (action->target_file);
+
+ nautilus_file_set_owner (file,
+ action->original_name,
+ undo_redo_done_rename_callback, action);
+
+ nautilus_file_unref (file);
+}
+
+/* redo helpers */
+
+static void
+copy_redo_func (UndoData *action)
+{
+ GList *locations;
+
+ locations = construct_gfile_list (action->sources, action->src_dir);
+ nautilus_file_operations_copy (locations, NULL,
+ action->dest_dir, NULL,
+ undo_redo_done_transfer_callback, action);
+
+ g_list_free_full (locations, g_object_unref);
+}
+
+static void
+create_from_template_redo_func (UndoData *action)
+{
+ GFile *parent;
+ gchar *parent_uri, *new_name;
+
+ parent = g_file_get_parent (action->target_file);
+ parent_uri = g_file_get_uri (parent);
+ new_name = g_file_get_parse_name (action->target_file);
+ nautilus_file_operations_new_file_from_template (NULL, NULL,
+ parent_uri, new_name,
+ action->template,
+ undo_redo_done_create_callback, action);
+
+ g_free (parent_uri);
+ g_free (new_name);
+ g_object_unref (parent);
+}
+
+static void
+duplicate_redo_func (UndoData *action)
+{
+ GList *locations;
+
+ locations = construct_gfile_list (action->sources, action->src_dir);
+ nautilus_file_operations_duplicate (locations, NULL, NULL,
+ undo_redo_done_transfer_callback, action);
+
+ g_list_free_full (locations, g_object_unref);
+}
+
+static void
+move_restore_redo_func (UndoData *action)
+{
+ GList *locations;
+
+ locations = construct_gfile_list (action->sources, action->src_dir);
+ nautilus_file_operations_move (locations, NULL,
+ action->dest_dir, NULL,
+ undo_redo_done_transfer_callback, action);
+
+ g_list_free_full (locations, g_object_unref);
+}
+
+static void
+rename_redo_func (UndoData *action)
+{
+ gchar *new_name;
+ NautilusFile *file;
+
+ new_name = g_file_get_basename (action->new_file);
+ file = nautilus_file_get (action->old_file);
+ nautilus_file_rename (file, new_name,
+ undo_redo_done_rename_callback, action);
+
+ nautilus_file_unref (file);
+ g_free (new_name);
+}
+
+static void
+create_empty_redo_func (UndoData *action)
+{
+ GFile *parent;
+ gchar *parent_uri;
+ gchar *new_name;
+
+ parent = g_file_get_parent (action->target_file);
+ parent_uri = g_file_get_uri (parent);
+ new_name = g_file_get_parse_name (action->target_file);
+ nautilus_file_operations_new_file (NULL, NULL, parent_uri,
+ new_name,
+ action->template,
+ action->count, undo_redo_done_create_callback, action);
+
+ g_free (parent_uri);
+ g_free (new_name);
+ g_object_unref (parent);
+}
+
+static void
+create_folder_redo_func (UndoData *action)
+{
+ GFile *parent;
+ gchar *parent_uri;
+
+ parent = g_file_get_parent (action->target_file);
+ parent_uri = g_file_get_uri (parent);
+ nautilus_file_operations_new_folder (NULL, NULL, parent_uri,
+ undo_redo_done_create_callback, action);
+
+ g_free (parent_uri);
+ g_object_unref (parent);
+}
+
+static void
+trash_redo_func (UndoData *action)
+{
+ if (g_hash_table_size (action->trashed) > 0) {
+ GList *uri_to_trash, *locations;
+
+ uri_to_trash = g_hash_table_get_keys (action->trashed);
+ locations = uri_list_to_gfile_list (uri_to_trash);
+ nautilus_file_operations_trash_or_delete (locations, NULL,
+ undo_redo_done_delete_callback, action);
+ g_list_free (uri_to_trash);
+ g_list_free_full (locations, g_object_unref);
}
}
-/**
- * nautilus_undo_stack_manager_undo:
- * @manager:
- * @user_data:
- * @callback:
- *
- * Undoes the operation on the top of the undo stack, if there is one.
- * When the operation is finished, @callback will be called with
- * @user_data.
- */
-void
-nautilus_undo_stack_manager_undo (NautilusUndoStackManager *manager,
- NautilusUndoStackFinishCallback callback,
- gpointer user_data)
+static void
+create_link_redo_func (UndoData *action)
+{
+ GList *locations;
+
+ locations = construct_gfile_list (action->sources, action->src_dir);
+ nautilus_file_operations_link (locations, NULL,
+ action->dest_dir, NULL,
+ undo_redo_done_transfer_callback, action);
+ g_list_free_full (locations, g_object_unref);
+}
+
+static void
+set_permissions_redo_func (UndoData *action)
{
- NautilusUndoStackManagerPrivate *priv;
- NautilusUndoStackActionData *action;
NautilusFile *file;
- GList *uris;
- GHashTable *files_to_restore;
- char *new_name;
- priv = manager->priv;
+ file = nautilus_file_get (action->target_file);
+ nautilus_file_set_permissions (file, action->new_permissions,
+ undo_redo_done_rename_callback, action);
+
+ nautilus_file_unref (file);
+}
+
+static void
+recursive_permissions_redo_func (UndoData *action)
+{
+ gchar *parent_uri;
+
+ parent_uri = g_file_get_uri (action->dest_dir);
+ nautilus_file_set_permissions_recursive (parent_uri,
+ action->file_permissions,
+ action->file_mask,
+ action->dir_permissions,
+ action->dir_mask,
+ undo_redo_op_callback,
+ action);
+ g_free (parent_uri);
+}
+
+static void
+change_group_redo_func (UndoData *action)
+{
+ NautilusFile *file;
+
+ file = nautilus_file_get (action->target_file);
+ nautilus_file_set_group (file,
+ action->new_name,
+ undo_redo_done_rename_callback,
+ action);
+
+ nautilus_file_unref (file);
+}
+
+static void
+change_owner_redo_func (UndoData *action)
+{
+ NautilusFile *file;
+
+ file = nautilus_file_get (action->target_file);
+ nautilus_file_set_owner (file,
+ action->new_name,
+ undo_redo_done_rename_callback,
+ action);
+
+ nautilus_file_unref (file);
+}
+
+static void
+do_undo_redo (NautilusUndoStackManager *self,
+ gboolean undo,
+ NautilusUndoStackFinishCallback callback,
+ gpointer user_data)
+{
+ NautilusUndoStackManagerPrivate *priv = self->priv;
+ UndoData *action;
/* Update the menus invalidating undo/redo while an operation is already underway */
g_mutex_lock (priv->mutex);
- action = stack_scroll_right (priv);
+
+ if (undo) {
+ action = stack_scroll_right (priv);
+ } else {
+ action = stack_scroll_left (priv);
+ }
+
+ /* Action will be NULL if redo is not possible */
if (action != NULL) {
- action->locked = TRUE;
+ action->locked = TRUE; /* Remember to unlock when finished */
}
+
g_mutex_unlock (priv->mutex);
- do_menu_update (manager);
- uris = NULL;
+ do_menu_update (self);
+
if (action != NULL) {
- /* Note: Internal managed ops have to call nautilus_undo_stack_manager_is_undo_redo (manager);
- * TODO: AW - this is really awkward. */
priv->undo_redo_flag = TRUE;
- switch (action->type) {
- case NAUTILUS_UNDO_STACK_CREATE_EMPTY_FILE:
- case NAUTILUS_UNDO_STACK_CREATE_FILE_FROM_TEMPLATE:
- case NAUTILUS_UNDO_STACK_CREATE_FOLDER:
- uris = construct_gfile_list_from_uri (g_file_get_uri (action->target_file));
- case NAUTILUS_UNDO_STACK_COPY:
- case NAUTILUS_UNDO_STACK_DUPLICATE:
- case NAUTILUS_UNDO_STACK_CREATE_LINK:
- if (!uris) {
- uris = construct_gfile_list (action->destinations, action->dest_dir);
- uris = g_list_reverse (uris); /* Deleting must be done in reverse */
- }
- if (priv->confirm_delete) {
- nautilus_file_operations_delete (uris, NULL, undo_redo_done_delete_callback, action);
- g_list_free_full (uris, g_object_unref);
- } else {
- priv->undo_redo_flag = FALSE;
- /* We skip the confirmation message */
- GList *f;
- for (f = uris; f != NULL; f = f->next) {
- g_file_delete (f->data, NULL, NULL);
- g_object_unref (f->data);
- }
- g_list_free (uris);
- /* Here we must do what's necessary for the callback */
- undo_redo_done_transfer_callback (NULL, action);
- }
- break;
- case NAUTILUS_UNDO_STACK_RESTORE_FROM_TRASH:
- uris = construct_gfile_list (action->destinations, action->dest_dir);
- nautilus_file_operations_trash_or_delete (uris, NULL, undo_redo_done_delete_callback, action);
- g_list_free_full (uris, g_object_unref);
- break;
- case NAUTILUS_UNDO_STACK_MOVE_TO_TRASH:
- /* Internally managed op, clear the undo_redo_flag.
- * Same as calling nautilus_undo_stack_manager_is_undo_redo()
- * minus the function call and unused return val.
- */
- priv->undo_redo_flag = FALSE;
- files_to_restore = retrieve_files_to_restore (action->trashed);
- if (g_hash_table_size (files_to_restore) > 0) {
- GList *gfiles_in_trash, *l;
- GFile *item;
- GFile *dest;
- char *value;
-
- gfiles_in_trash = g_hash_table_get_keys (files_to_restore);
- for (l = gfiles_in_trash; l != NULL; l = l->next) {
- item = l->data;
- value = g_hash_table_lookup (files_to_restore, item);
- dest = g_file_new_for_uri (value);
- g_file_move (item, dest, G_FILE_COPY_NOFOLLOW_SYMLINKS, NULL, NULL, NULL, NULL);
- g_object_unref (dest);
- }
-
- g_list_free (gfiles_in_trash);
- }
- g_hash_table_destroy (files_to_restore);
- /* Here we must do what's necessary for the callback */
- undo_redo_done_transfer_callback (NULL, action);
- break;
- case NAUTILUS_UNDO_STACK_MOVE:
- uris = construct_gfile_list (action->destinations, action->dest_dir);
- nautilus_file_operations_move (uris, NULL, action->src_dir, NULL, undo_redo_done_transfer_callback, action);
- g_list_free_full (uris, g_object_unref);
- break;
- case NAUTILUS_UNDO_STACK_RENAME:
- new_name = g_file_get_basename (action->old_file);
- file = nautilus_file_get (action->new_file);
- nautilus_file_rename (file, new_name, undo_redo_done_rename_callback, action);
- nautilus_file_unref (file);
- g_free (new_name);
- break;
- case NAUTILUS_UNDO_STACK_SET_PERMISSIONS:
- file = nautilus_file_get (action->target_file);
- nautilus_file_set_permissions (file,
- action->current_permissions,
- undo_redo_done_rename_callback, action);
- nautilus_file_unref (file);
- break;
- case NAUTILUS_UNDO_STACK_RECURSIVE_SET_PERMISSIONS:
- /* Internally managed op, clear the undo_redo_flag. */
- priv->undo_redo_flag = FALSE;
- if (g_hash_table_size (action->original_permissions) > 0) {
- GList *gfiles_list;
- guint32 *perm;
- GList *l;
- GFile *dest;
- char *item;
-
- gfiles_list = g_hash_table_get_keys (action->original_permissions);
- for (l = gfiles_list; l != NULL; l = l->next) {
- item = l->data;
- perm = g_hash_table_lookup (action->original_permissions, item);
- dest = g_file_new_for_uri (item);
- g_file_set_attribute_uint32 (dest,
- G_FILE_ATTRIBUTE_UNIX_MODE,
- *perm, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, NULL);
- g_object_unref (dest);
- }
-
- g_list_free (gfiles_list);
- /* Here we must do what's necessary for the callback */
- undo_redo_done_transfer_callback (NULL, action);
- }
- break;
- case NAUTILUS_UNDO_STACK_CHANGE_GROUP:
- file = nautilus_file_get (action->target_file);
- nautilus_file_set_group (file,
- action->original_group_name,
- undo_redo_done_rename_callback, action);
- nautilus_file_unref (file);
- break;
- case NAUTILUS_UNDO_STACK_CHANGE_OWNER:
- file = nautilus_file_get (action->target_file);
- nautilus_file_set_owner (file,
- action->original_user_name,
- undo_redo_done_rename_callback, action);
- nautilus_file_unref (file);
- break;
- default:
- g_assert_not_reached ();
- break;
+
+ if (undo) {
+ action->undo_func (action);
+ } else {
+ action->redo_func (action);
}
}
if (callback != NULL) {
callback (user_data);
}
+
+}
+
+void
+nautilus_undo_stack_manager_redo (NautilusUndoStackManager *manager,
+ NautilusUndoStackFinishCallback callback,
+ gpointer user_data)
+{
+ do_undo_redo (manager, FALSE, callback, user_data);
+}
+
+void
+nautilus_undo_stack_manager_undo (NautilusUndoStackManager *manager,
+ NautilusUndoStackFinishCallback callback,
+ gpointer user_data)
+{
+ do_undo_redo (manager, TRUE, callback, user_data);
}
/**
@@ -734,13 +933,10 @@ nautilus_undo_stack_manager_add_action (NautilusUndoStackManager *manager,
{
NautilusUndoStackManagerPrivate *priv;
- g_return_if_fail (manager != NULL);
- g_return_if_fail (action != NULL);
-
priv = manager->priv;
if (!(action && action->is_valid)) {
- free_undo_stack_action_data (action);
+ undo_stack_action_data_free (action);
return;
}
@@ -822,32 +1018,6 @@ nautilus_undo_stack_manager_get_file_modification_time (GFile * file)
}
/**
- * nautilus_undo_stack_action_data_new:
- * @manager:
- * @items_count:
- *
- * Returns: a new undo data container.
- */
-NautilusUndoStackActionData *
-nautilus_undo_stack_action_data_new (NautilusUndoStackActionType type,
- gint items_count)
-{
- NautilusUndoStackActionData *data;
-
- data = g_slice_new0 (NautilusUndoStackActionData);
- data->type = type;
- data->count = items_count;
-
- if (type == NAUTILUS_UNDO_STACK_MOVE_TO_TRASH) {
- data->trashed = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
- } else if (type == NAUTILUS_UNDO_STACK_RECURSIVE_SET_PERMISSIONS) {
- data->original_permissions = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
- }
-
- return data;
-}
-
-/**
* nautilus_undo_stack_action_data_set_src_dir:
* @action_data:
* @src:
@@ -858,8 +1028,6 @@ void
nautilus_undo_stack_action_data_set_src_dir (NautilusUndoStackActionData *action_data,
GFile *src)
{
- g_return_if_fail (action_data != NULL);
-
action_data->src_dir = src;
}
@@ -874,8 +1042,6 @@ void
nautilus_undo_stack_action_data_set_dest_dir (NautilusUndoStackActionData *action_data,
GFile *dest)
{
- g_return_if_fail (action_data != NULL);
-
action_data->dest_dir = dest;
}
@@ -895,8 +1061,6 @@ nautilus_undo_stack_action_data_add_origin_target_pair (NautilusUndoStackActionD
char *src_relative;
char *dest_relative;
- g_return_if_fail (action_data != NULL);
-
src_relative = g_file_get_relative_path (action_data->src_dir, origin);
action_data->sources = g_list_append (action_data->sources, src_relative);
dest_relative = g_file_get_relative_path (action_data->dest_dir, target);
@@ -921,7 +1085,11 @@ nautilus_undo_stack_action_data_add_trashed_file (NautilusUndoStackActionData *a
guint64 *modification_time;
char *original_uri;
- g_return_if_fail (action_data != NULL);
+ if (action_data->trashed == NULL) {
+ action_data->trashed =
+ g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, g_free);
+ }
modification_time = g_new (guint64, 1);
*modification_time = mtime;
@@ -949,7 +1117,10 @@ nautilus_undo_stack_action_data_add_file_permissions (NautilusUndoStackActionDat
guint32 *current_permissions;
char *original_uri;
- g_return_if_fail (action_data != NULL);
+ if (action_data->original_permissions == NULL) {
+ action_data->original_permissions =
+ g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+ }
current_permissions = g_new (guint32, 1);
*current_permissions = permission;
@@ -976,9 +1147,6 @@ nautilus_undo_stack_action_data_set_file_permissions (NautilusUndoStackActionDat
guint32 current_permissions,
guint32 new_permissions)
{
- g_return_if_fail (action_data != NULL);
- g_return_if_fail (G_IS_FILE (file));
-
action_data->target_file = g_object_ref (file);
action_data->current_permissions = current_permissions;
action_data->new_permissions = new_permissions;
@@ -1001,12 +1169,9 @@ nautilus_undo_stack_action_data_set_owner_change_information (NautilusUndoStackA
const char *current_user,
const char *new_user)
{
- g_return_if_fail (action_data != NULL);
- g_return_if_fail (G_IS_FILE (file));
-
action_data->target_file = g_object_ref (file);
- action_data->original_user_name = g_strdup (current_user);
- action_data->new_user_name = g_strdup (new_user);
+ action_data->original_name = g_strdup (current_user);
+ action_data->new_name = g_strdup (new_user);
action_data->is_valid = TRUE;
}
@@ -1026,12 +1191,9 @@ nautilus_undo_stack_action_data_set_group_change_information (NautilusUndoStackA
const char *current_group,
const char *new_group)
{
- g_return_if_fail (action_data != NULL);
- g_return_if_fail (G_IS_FILE (file));
-
action_data->target_file = g_object_ref (file);
- action_data->original_group_name = g_strdup (current_group);
- action_data->new_group_name = g_strdup (new_group);
+ action_data->original_name = g_strdup (current_group);
+ action_data->new_name = g_strdup (new_group);
action_data->is_valid = TRUE;
}
@@ -1053,8 +1215,6 @@ nautilus_undo_stack_action_data_set_recursive_permissions (NautilusUndoStackActi
guint32 dir_permissions,
guint32 dir_mask)
{
- g_return_if_fail (action_data != NULL);
-
action_data->file_permissions = file_permissions;
action_data->file_mask = file_mask;
action_data->dir_permissions = dir_permissions;
@@ -1076,9 +1236,6 @@ nautilus_undo_stack_action_data_set_create_data (NautilusUndoStackActionData *ac
GFile *file,
const char *template)
{
- g_return_if_fail (action_data != NULL);
- g_return_if_fail (G_IS_FILE (file));
-
action_data->target_file = g_object_ref (file);
action_data->template = g_strdup (template);
@@ -1098,8 +1255,6 @@ nautilus_undo_stack_action_data_set_rename_information (NautilusUndoStackActionD
GFile *old_file,
GFile *new_file)
{
- g_return_if_fail (action_data != NULL);
-
action_data->old_file = g_object_ref (old_file);
action_data->new_file = g_object_ref (new_file);
@@ -1147,7 +1302,7 @@ stack_clear_n_oldest (GQueue * stack, guint n)
if (action->locked) {
action->freed = TRUE;
} else {
- free_undo_stack_action_data (action);
+ undo_stack_action_data_free (action);
}
}
}
@@ -1175,7 +1330,7 @@ clear_redo_actions (NautilusUndoStackManagerPrivate *priv)
while (priv->index > 0) {
NautilusUndoStackActionData *head;
head = (NautilusUndoStackActionData *)g_queue_pop_head (priv->stack);
- free_undo_stack_action_data (head);
+ undo_stack_action_data_free (head);
priv->index--;
}
}
@@ -1210,504 +1365,6 @@ get_first_target_short_name (NautilusUndoStackActionData *action)
return file_name;
}
-static char *
-get_undo_description (NautilusUndoStackActionData *action)
-{
- char *description;
- char *source;
- guint count;
-
- g_return_val_if_fail (action != NULL, NULL);
-
- description = NULL;
- source = NULL;
-
- if (action->undo_description != NULL)
- return action->undo_description;
-
- if (action->src_dir) {
- source = g_file_get_path (action->src_dir);
- }
- count = action->count;
- switch (action->type) {
- case NAUTILUS_UNDO_STACK_COPY:
- if (count != 1) {
- description = g_strdup_printf (_("Delete %d copied items"), count);
- } else {
- char *name;
- name = get_first_target_short_name (action);
- description = g_strdup_printf (_("Delete '%s'"), name);
- g_free (name);
- }
- break;
- case NAUTILUS_UNDO_STACK_DUPLICATE:
- if (count != 1) {
- description = g_strdup_printf (_("Delete %d duplicated items"), count);
- } else {
- char *name;
- name = get_first_target_short_name (action);
- description = g_strdup_printf (_("Delete '%s'"), name);
- g_free (name);
- }
- break;
- case NAUTILUS_UNDO_STACK_MOVE:
- if (count != 1) {
- description = g_strdup_printf (_("Move %d items back to '%s'"), count, source);
- } else {
- char *name;
- name = get_first_target_short_name (action);
- description = g_strdup_printf (_("Move '%s' back to '%s'"), name, source);
- g_free (name);
- }
- break;
- case NAUTILUS_UNDO_STACK_RENAME:
- {
- char *from_name;
- char *to_name;
- from_name = g_file_get_parse_name (action->new_file);
- to_name = g_file_get_parse_name (action->old_file);
- description = g_strdup_printf (_("Rename '%s' as '%s'"), from_name, to_name);
- g_free (from_name);
- g_free (to_name);
- }
- break;
- case NAUTILUS_UNDO_STACK_CREATE_FILE_FROM_TEMPLATE:
- case NAUTILUS_UNDO_STACK_CREATE_EMPTY_FILE:
- case NAUTILUS_UNDO_STACK_CREATE_FOLDER:
- {
- char *name;
- name = g_file_get_parse_name (action->target_file);
- description = g_strdup_printf (_("Delete '%s'"), name);
- g_free (name);
- }
- break;
- case NAUTILUS_UNDO_STACK_MOVE_TO_TRASH:
- {
- count = g_hash_table_size (action->trashed);
- if (count != 1) {
- description = g_strdup_printf (_("Restore %d items from trash"), count);
- } else {
- GList *keys, *first;
- char *item, *name, *orig_path;
- GFile *file;
-
- keys = g_hash_table_get_keys (action->trashed);
- first = g_list_first (keys);
- item = (char *) first->data;
- file = g_file_new_for_commandline_arg (item);
- name = g_file_get_basename (file);
- orig_path = g_file_get_path (file);
- description = g_strdup_printf (_("Restore '%s' to '%s'"), name, orig_path);
- g_free (name);
- g_free (orig_path);
- g_list_free (keys);
- g_object_unref (file);
- }
- }
- break;
- case NAUTILUS_UNDO_STACK_RESTORE_FROM_TRASH:
- {
- if (count != 1) {
- description = g_strdup_printf (_("Move %d items back to trash"), count);
- } else {
- char *name;
- name = get_first_target_short_name (action);
- description = g_strdup_printf (_("Move '%s' back to trash"), name);
- g_free (name);
- }
- }
- break;
- case NAUTILUS_UNDO_STACK_CREATE_LINK:
- {
- if (count != 1) {
- description = g_strdup_printf (_("Delete links to %d items"), count);
- } else {
- char *name;
- name = get_first_target_short_name (action);
- description = g_strdup_printf (_("Delete link to '%s'"), name);
- g_free (name);
- }
- }
- break;
- case NAUTILUS_UNDO_STACK_RECURSIVE_SET_PERMISSIONS:
- {
- char *name;
- name = g_file_get_path (action->dest_dir);
- description = g_strdup_printf (_("Restore original permissions of items enclosed in '%s'"), name);
- g_free (name);
- }
- break;
- case NAUTILUS_UNDO_STACK_SET_PERMISSIONS:
- {
- char *name;
- name = g_file_get_parse_name (action->target_file);
- description = g_strdup_printf (_("Restore original permissions of '%s'"), name);
- g_free (name);
- }
- break;
- case NAUTILUS_UNDO_STACK_CHANGE_GROUP:
- {
- char *name;
- name = g_file_get_parse_name (action->target_file);
- description = g_strdup_printf (_("Restore group of '%s' to '%s'"),
- name, action->original_group_name);
- g_free (name);
- }
- break;
- case NAUTILUS_UNDO_STACK_CHANGE_OWNER:
- {
- char *name;
- name = g_file_get_parse_name (action->target_file);
- description = g_strdup_printf (_("Restore owner of '%s' to '%s'"),
- name, action->original_user_name);
- g_free (name);
- }
- break;
- default:
- break;
- }
- if (source) {
- g_free (source);
- }
- action->undo_description = description;
-
- return description;
-}
-
-static char *
-get_redo_description (NautilusUndoStackActionData *action)
-{
- char *description;
- char *destination;
- guint count;
-
- description = NULL;
- destination = NULL;
-
- g_return_val_if_fail (action != NULL, NULL);
-
- if (action->redo_description != NULL) {
- return action->redo_description;
- }
-
- if (action->dest_dir) {
- destination = g_file_get_path (action->dest_dir);
- }
-
- count = action->count;
- switch (action->type) {
- case NAUTILUS_UNDO_STACK_COPY:
- if (count != 1) {
- description = g_strdup_printf (_("Copy %d items to '%s'"), count, destination);
- } else {
- char *name;
- name= get_first_target_short_name (action);
- description = g_strdup_printf (_("Copy '%s' to '%s'"), name, destination);
- g_free (name);
- }
- break;
- case NAUTILUS_UNDO_STACK_DUPLICATE:
- if (count != 1) {
- description = g_strdup_printf (_("Duplicate of %d items in '%s'"), count, destination);
- } else {
- char *name;
- name = get_first_target_short_name (action);
- description = g_strdup_printf (_("Duplicate '%s' in '%s'"), name, destination);
- g_free (name);
- }
- break;
- case NAUTILUS_UNDO_STACK_MOVE:
- if (count != 1) {
- description = g_strdup_printf (_("Move %d items to '%s'"), count, destination);
- } else {
- char *name;
- name = get_first_target_short_name (action);
- description = g_strdup_printf (_("Move '%s' to '%s'"), name, destination);
- g_free (name);
- }
- break;
- case NAUTILUS_UNDO_STACK_RENAME:
- {
- char *from_name;
- char *to_name;
- from_name = g_file_get_parse_name (action->old_file);
- to_name = g_file_get_parse_name (action->new_file);
- description = g_strdup_printf (_("Rename '%s' as '%s'"), from_name, to_name);
- g_free (from_name);
- g_free (to_name);
- }
- break;
- case NAUTILUS_UNDO_STACK_CREATE_FILE_FROM_TEMPLATE:
- {
- char *name;
- name = g_file_get_parse_name (action->target_file);
- description = g_strdup_printf (_("Create new file '%s' from template "), name);
- g_free (name);
- }
- break;
- case NAUTILUS_UNDO_STACK_CREATE_EMPTY_FILE:
- {
- char *name;
- name = g_file_get_parse_name (action->target_file);
- description = g_strdup_printf (_("Create an empty file '%s'"), name);
- g_free (name);
- }
- break;
- case NAUTILUS_UNDO_STACK_CREATE_FOLDER:
- {
- char *name;
- name = g_file_get_parse_name (action->target_file);
- description = g_strdup_printf (_("Create a new folder '%s'"), name);
- g_free (name);
- }
- break;
- case NAUTILUS_UNDO_STACK_MOVE_TO_TRASH:
- {
- count = g_hash_table_size (action->trashed);
- if (count != 1) {
- description = g_strdup_printf (_("Move %d items to trash"), count);
- } else {
- GList *keys;
- GList *first;
- char *item;
- char *name;
-
- keys = g_hash_table_get_keys (action->trashed);
- first = g_list_first (keys);
- item = (char *) first->data;
- name = g_file_get_parse_name (action->target_file);
- description = g_strdup_printf (_("Move '%s' to trash"), name);
- g_free (name);
- g_list_free (keys);
- }
- }
- break;
- case NAUTILUS_UNDO_STACK_RESTORE_FROM_TRASH:
- {
- if (count != 1) {
- description = g_strdup_printf (_("Restore %d items from trash"), count);
- } else {
- char *name;
- name = get_first_target_short_name (action);
- description = g_strdup_printf (_("Restore '%s' from trash"), name);
- g_free (name);
- }
- }
- break;
- case NAUTILUS_UNDO_STACK_CREATE_LINK:
- {
- if (count != 1) {
- description = g_strdup_printf (_("Create links to %d items"), count);
- } else {
- char *name;
- name = get_first_target_short_name (action);
- description = g_strdup_printf (_("Create link to '%s'"), name);
- g_free (name);
- }
- }
- break;
- case NAUTILUS_UNDO_STACK_RECURSIVE_SET_PERMISSIONS:
- {
- char *name;
- name = g_file_get_path (action->dest_dir);
- description = g_strdup_printf (_("Set permissions of items enclosed in '%s'"), name);
- g_free (name);
- }
- break;
- case NAUTILUS_UNDO_STACK_SET_PERMISSIONS:
- {
- char *name;
- name = g_file_get_parse_name (action->target_file);
- description = g_strdup_printf (_("Set permissions of '%s'"), name);
- g_free (name);
- }
- break;
- case NAUTILUS_UNDO_STACK_CHANGE_GROUP:
- {
- char *name;
- name = g_file_get_parse_name (action->target_file);
- description = g_strdup_printf (_("Set group of '%s' to '%s'"), name, action->new_group_name);
- g_free (name);
- }
- break;
- case NAUTILUS_UNDO_STACK_CHANGE_OWNER:
- {
- char *name;
- name = g_file_get_parse_name (action->target_file);
- description = g_strdup_printf (_("Set owner of '%s' to '%s'"), name, action->new_user_name);
- g_free (name);
- }
- break;
- default:
- break;
- }
-
- if (destination) {
- g_free (destination);
- }
-
- action->redo_description = description;
-
- return description;
-}
-
-static char *
-get_undo_label (NautilusUndoStackActionData *action)
-{
- char *label;
- guint count;
-
- g_return_val_if_fail (action != NULL, NULL);
-
- if (action->redo_label != NULL) {
- return action->redo_label;
- }
-
- label = NULL;
- count = action->count;
- switch (action->type) {
- case NAUTILUS_UNDO_STACK_COPY:
- label = g_strdup_printf (ngettext ("_Undo copy of %d item",
- "_Undo copy of %d items", count), count);
- break;
- case NAUTILUS_UNDO_STACK_DUPLICATE:
- label = g_strdup_printf (ngettext ("_Undo duplicate of %d item",
- "_Undo duplicate of %d items", count), count);
- break;
- case NAUTILUS_UNDO_STACK_MOVE:
- label = g_strdup_printf (ngettext ("_Undo move of %d item",
- "_Undo move of %d items", count), count);
- break;
- case NAUTILUS_UNDO_STACK_RENAME:
- label = g_strdup_printf (ngettext ("_Undo rename of %d item",
- "_Undo rename of %d items", count), count);
- break;
- case NAUTILUS_UNDO_STACK_CREATE_EMPTY_FILE:
- label = g_strdup_printf (_("_Undo creation of an empty file"));
- break;
- case NAUTILUS_UNDO_STACK_CREATE_FILE_FROM_TEMPLATE:
- label = g_strdup_printf (_("_Undo creation of a file from template"));
- break;
- case NAUTILUS_UNDO_STACK_CREATE_FOLDER:
- label = g_strdup_printf (ngettext ("_Undo creation of %d folder",
- "_Undo creation of %d folders", count), count);
- break;
- case NAUTILUS_UNDO_STACK_MOVE_TO_TRASH:
- label = g_strdup_printf (ngettext ("_Undo move to trash of %d item",
- "_Undo move to trash of %d items", count), count);
- break;
- case NAUTILUS_UNDO_STACK_RESTORE_FROM_TRASH:
- label = g_strdup_printf (ngettext ("_Undo restore from trash of %d item",
- "_Undo restore from trash of %d items", count), count);
- break;
- case NAUTILUS_UNDO_STACK_CREATE_LINK:
- label = g_strdup_printf (ngettext ("_Undo create link to %d item",
- "_Undo create link to %d items", count), count);
- break;
- case NAUTILUS_UNDO_STACK_RECURSIVE_SET_PERMISSIONS:
- label = g_strdup_printf (ngettext ("Undo recursive change permissions of %d item",
- "Undo recursive change permissions of %d items",
- count), count);
- break;
- case NAUTILUS_UNDO_STACK_SET_PERMISSIONS:
- label = g_strdup_printf (ngettext ("Undo change permissions of %d item",
- "Undo change permissions of %d items", count), count);
- break;
- case NAUTILUS_UNDO_STACK_CHANGE_GROUP:
- label = g_strdup_printf (ngettext ("Undo change group of %d item",
- "Undo change group of %d items", count), count);
- break;
- case NAUTILUS_UNDO_STACK_CHANGE_OWNER:
- label = g_strdup_printf (ngettext ("Undo change owner of %d item",
- "Undo change owner of %d items", count), count);
- break;
- default:
- break;
- }
- action->undo_label = label;
-
- return label;
-}
-
-static char *
-get_redo_label (NautilusUndoStackActionData *action)
-{
- char *label;
- guint count;
-
- g_return_val_if_fail (action != NULL, NULL);
-
- if (action->redo_label != NULL) {
- return action->redo_label;
- }
-
- label = NULL;
- count = action->count;
- switch (action->type) {
- case NAUTILUS_UNDO_STACK_COPY:
- label = g_strdup_printf (ngettext ("_Redo copy of %d item",
- "_Redo copy of %d items", count), count);
- break;
- case NAUTILUS_UNDO_STACK_DUPLICATE:
- label = g_strdup_printf (ngettext ("_Redo duplicate of %d item",
- "_Redo duplicate of %d items", count), count);
- break;
- case NAUTILUS_UNDO_STACK_MOVE:
- label = g_strdup_printf (ngettext ("_Redo move of %d item",
- "_Redo move of %d items", count), count);
- break;
- case NAUTILUS_UNDO_STACK_RENAME:
- label = g_strdup_printf (ngettext ("_Redo rename of %d item",
- "_Redo rename of %d items", count), count);
- break;
- case NAUTILUS_UNDO_STACK_CREATE_EMPTY_FILE:
- label = g_strdup_printf (_("_Redo creation of an empty file"));
- break;
- case NAUTILUS_UNDO_STACK_CREATE_FILE_FROM_TEMPLATE:
- label = g_strdup_printf (_("_Redo creation of a file from template"));
- break;
- case NAUTILUS_UNDO_STACK_CREATE_FOLDER:
- label = g_strdup_printf (ngettext ("_Redo creation of %d folder",
- "_Redo creation of %d folders", count), count);
- break;
- case NAUTILUS_UNDO_STACK_MOVE_TO_TRASH:
- label = g_strdup_printf (ngettext ("_Redo move to trash of %d item",
- "_Redo move to trash of %d items", count), count);
- break;
- case NAUTILUS_UNDO_STACK_RESTORE_FROM_TRASH:
- label = g_strdup_printf (ngettext ("_Redo restore from trash of %d item",
- "_Redo restore from trash of %d items", count), count);
- break;
- case NAUTILUS_UNDO_STACK_CREATE_LINK:
- label = g_strdup_printf (ngettext ("_Redo create link to %d item",
- "_Redo create link to %d items", count), count);
- break;
- case NAUTILUS_UNDO_STACK_RECURSIVE_SET_PERMISSIONS:
- label = g_strdup_printf (ngettext ("Redo recursive change permissions of %d item",
- "Redo recursive change permissions of %d items",
- count), count);
- break;
- case NAUTILUS_UNDO_STACK_SET_PERMISSIONS:
- label = g_strdup_printf (ngettext ("Redo change permissions of %d item",
- "Redo change permissions of %d items", count), count);
- break;
- case NAUTILUS_UNDO_STACK_CHANGE_GROUP:
- label = g_strdup_printf (ngettext ("Redo change group of %d item",
- "Redo change group of %d items", count), count);
- break;
- case NAUTILUS_UNDO_STACK_CHANGE_OWNER:
- label = g_strdup_printf (ngettext ("Redo change owner of %d item",
- "Redo change owner of %d items", count), count);
- break;
- default:
- break;
- }
-
- action->redo_label = label;
-
- return label;
-}
-
static void
undo_redo_done_transfer_callback (GHashTable * debuting_uris, gpointer data)
{
@@ -1717,7 +1374,7 @@ undo_redo_done_transfer_callback (GHashTable * debuting_uris, gpointer data)
/* If the action needed to be freed but was locked, free now */
if (action->freed) {
- free_undo_stack_action_data (action);
+ undo_stack_action_data_free (action);
} else {
action->locked = FALSE;
}
@@ -1825,12 +1482,18 @@ do_menu_update (NautilusUndoStackManager * manager)
g_mutex_lock (priv->mutex);
action = get_next_undo_action (priv);
- data->undo_label = get_undo_label (action);
- data->undo_description = get_undo_description (action);
+
+ if (action != NULL) {
+ data->undo_label = get_undo_label (action);
+ data->undo_description = get_undo_description (action);
+ }
action = get_next_redo_action (priv);
- data->redo_label = get_redo_label (action);
- data->redo_description = get_redo_description (action);
+
+ if (action != NULL) {
+ data->redo_label = get_redo_label (action);
+ data->redo_description = get_redo_description (action);
+ }
g_mutex_unlock (priv->mutex);
@@ -1944,3 +1607,429 @@ retrieve_files_to_restore (GHashTable * trashed)
return to_restore;
}
+
+static void
+copy_description_func (UndoData *action,
+ guint count,
+ gchar **labels,
+ gchar **descriptions)
+{
+ gchar *destination;
+
+ destination = g_file_get_path (action->dest_dir);
+
+ if (count != 1) {
+ descriptions[0] = g_strdup_printf (_("Delete %d copied items"), count);
+ descriptions[1] = g_strdup_printf (_("Copy %d items to '%s'"), count, destination);
+
+ labels[0] = g_strdup_printf (_("_Undo Copy %d items"), count);
+ labels[1] = g_strdup_printf (_("_Redo Copy %d items"), count);
+ } else {
+ gchar *name;
+
+ name = get_first_target_short_name (action);
+ descriptions[0] = g_strdup_printf (_("Delete '%s'"), name);
+ descriptions[1] = g_strdup_printf (_("Copy '%s' to '%s'"), name, destination);
+
+ labels[0] = g_strdup (_("_Undo Copy"));
+ labels[1] = g_strdup (_("_Redo Copy"));
+
+ g_free (name);
+ }
+}
+
+static void
+duplicate_description_func (UndoData *action,
+ guint count,
+ gchar **labels,
+ gchar **descriptions)
+{
+ gchar *destination;
+
+ destination = g_file_get_path (action->dest_dir);
+
+ if (count != 1) {
+ descriptions[0] = g_strdup_printf (_("Delete %d duplicated items"), count);
+ descriptions[1] = g_strdup_printf (_("Duplicate of %d items in '%s'"),
+ count, destination);
+
+ labels[0] = g_strdup_printf (_("_Undo Duplicate %d items"), count);
+ labels[1] = g_strdup_printf (_("_Redo Duplicate %d items"), count);
+ } else {
+ char *name;
+
+ name = get_first_target_short_name (action);
+ descriptions[0] = g_strdup_printf (_("Delete '%s'"), name);
+ descriptions[1] = g_strdup_printf (_("Duplicate '%s' in '%s'"),
+ name, destination);
+
+ labels[0] = g_strdup (_("_Undo Duplicate"));
+ labels[1] = g_strdup (_("_Redo Duplicate"));
+
+ g_free (name);
+ }
+
+}
+
+static void
+move_description_func (UndoData *action,
+ guint count,
+ gchar **labels,
+ gchar **descriptions)
+{
+ gchar *source, *destination;
+
+ source = g_file_get_path (action->src_dir);
+ destination = g_file_get_path (action->dest_dir);
+
+ if (count != 1) {
+ descriptions[0] = g_strdup_printf (_("Move %d items back to '%s'"), count, source);
+ descriptions[1] = g_strdup_printf (_("Move %d items to '%s'"), count, destination);
+
+ labels[0] = g_strdup_printf (_("_Undo Move %d items"), count);
+ labels[1] = g_strdup_printf (_("_Redo Move %d items"), count);
+ } else {
+ char *name;
+
+ name = get_first_target_short_name (action);
+ descriptions[0] = g_strdup_printf (_("Move '%s' back to '%s'"), name, source);
+ descriptions[1] = g_strdup_printf (_("Move '%s' to '%s'"), name, destination);
+
+ labels[0] = g_strdup (_("_Undo Move"));
+ labels[1] = g_strdup (_("_Redo Move"));
+
+ g_free (name);
+ }
+}
+
+static void
+rename_description_func (UndoData *action,
+ guint count,
+ gchar **labels,
+ gchar **descriptions)
+{
+ gchar *new_name, *old_name;
+
+ new_name = g_file_get_parse_name (action->new_file);
+ old_name = g_file_get_parse_name (action->old_file);
+
+ descriptions[0] = g_strdup_printf (_("Rename '%s' as '%s'"), new_name, old_name);
+ descriptions[1] = g_strdup_printf (_("Rename '%s' as '%s'"), old_name, new_name);
+
+ labels[0] = g_strdup (_("_Undo Rename"));
+ labels[1] = g_strdup (_("_Redo Rename"));
+
+ g_free (old_name);
+ g_free (new_name);
+}
+
+static void
+create_undo_common (UndoData *action,
+ guint count,
+ gchar **descriptions)
+{
+ char *name;
+
+ name = g_file_get_parse_name (action->target_file);
+ descriptions[0] = g_strdup_printf (_("Delete '%s'"), name);
+
+ g_free (name);
+}
+
+static void
+create_empty_description_func (UndoData *action,
+ guint count,
+ gchar **labels,
+ gchar **descriptions)
+{
+ gchar *name;
+
+ /* undo */
+ create_undo_common (action, count, descriptions);
+
+ name = g_file_get_parse_name (action->target_file);
+ descriptions[1] = g_strdup_printf (_("Create an empty file '%s'"), name);
+
+ labels[0] = g_strdup (_("_Undo Create Empty File"));
+ labels[1] = g_strdup (_("_Redo Create Empty File"));
+
+ g_free (name);
+}
+
+static void
+create_from_template_description_func (UndoData *action,
+ guint count,
+ gchar **labels,
+ gchar **descriptions)
+{
+ char *name;
+
+ /* undo */
+ create_undo_common (action, count, descriptions);
+
+ name = g_file_get_parse_name (action->target_file);
+ descriptions[1] = g_strdup_printf (_("Create new file '%s' from template "), name);
+ g_free (name);
+
+ labels[0] = g_strdup (_("_Undo Create from Template"));
+ labels[1] = g_strdup (_("_Redo Create from Template"));
+}
+
+static void
+create_folder_description_func (UndoData *action,
+ guint count,
+ gchar **labels,
+ gchar **descriptions)
+{
+ char *name;
+
+ /* undo */
+ create_undo_common (action, count, descriptions);
+
+ name = g_file_get_parse_name (action->target_file);
+ descriptions[1] = g_strdup_printf (_("Create a new folder '%s'"), name);
+
+ labels[0] = g_strdup (_("_Undo Create Folder"));
+ labels[1] = g_strdup (_("_Redo Create Folder"));
+
+ g_free (name);
+}
+
+static void
+trash_description_func (UndoData *action,
+ guint count,
+ gchar **labels,
+ gchar **descriptions)
+{
+ count = g_hash_table_size (action->trashed);
+
+ if (count != 1) {
+ descriptions[0] = g_strdup_printf (_("Restore %d items from trash"), count);
+ descriptions[1] = g_strdup_printf (_("Move %d items to trash"), count);
+ } else {
+ GList *keys;
+ char *name, *orig_path;
+ GFile *file;
+
+ keys = g_hash_table_get_keys (action->trashed);
+ file = g_file_new_for_commandline_arg (keys->data);
+ name = g_file_get_basename (file);
+ orig_path = g_file_get_path (file);
+ descriptions[0] = g_strdup_printf (_("Restore '%s' to '%s'"), name, orig_path);
+
+ g_free (name);
+ g_free (orig_path);
+ g_list_free (keys);
+ g_object_unref (file);
+
+ name = g_file_get_parse_name (action->target_file);
+ descriptions[1] = g_strdup_printf (_("Move '%s' to trash"), name);
+
+ g_free (name);
+
+ labels[0] = g_strdup (_("_Undo Trash"));
+ labels[1] = g_strdup (_("_Redo Trash"));
+ }
+}
+
+static void
+restore_description_func (UndoData *action,
+ guint count,
+ gchar **labels,
+ gchar **descriptions)
+{
+ if (count != 1) {
+ descriptions[0] = g_strdup_printf (_("Move %d items back to trash"), count);
+ descriptions[1] = g_strdup_printf (_("Restore %d items from trash"), count);
+ } else {
+ char *name;
+
+ name = get_first_target_short_name (action);
+ descriptions[0] = g_strdup_printf (_("Move '%s' back to trash"), name);
+ descriptions[1] = g_strdup_printf (_("Restore '%s' from trash"), name);
+
+ g_free (name);
+
+ labels[0] = g_strdup (_("_Undo Restore from Trash"));
+ labels[1] = g_strdup (_("_Redo Restore from Trash"));
+ }
+}
+
+static void
+create_link_description_func (UndoData *action,
+ guint count,
+ gchar **labels,
+ gchar **descriptions)
+{
+ if (count != 1) {
+ descriptions[0] = g_strdup_printf (_("Delete links to %d items"), count);
+ descriptions[1] = g_strdup_printf (_("Create links to %d items"), count);
+ } else {
+ char *name;
+
+ name = get_first_target_short_name (action);
+ descriptions[0] = g_strdup_printf (_("Delete link to '%s'"), name);
+ descriptions[1] = g_strdup_printf (_("Create link to '%s'"), name);
+
+ labels[0] = g_strdup (_("_Undo Create Link"));
+ labels[1] = g_strdup (_("_Redo Create Link"));
+
+ g_free (name);
+ }
+}
+
+static void
+recursive_permissions_description_func (UndoData *action,
+ guint count,
+ gchar **labels,
+ gchar **descriptions)
+{
+ char *name;
+
+ name = g_file_get_path (action->dest_dir);
+
+ descriptions[0] = g_strdup_printf (_("Restore original permissions of items enclosed in '%s'"), name);
+ descriptions[1] = g_strdup_printf (_("Set permissions of items enclosed in '%s'"), name);
+
+ labels[0] = g_strdup (_("_Undo Change Permissions"));
+ labels[1] = g_strdup (_("_Redo Change Permissions"));
+
+ g_free (name);
+}
+
+static void
+set_permissions_description_func (UndoData *action,
+ guint count,
+ gchar **labels,
+ gchar **descriptions)
+{
+ char *name;
+
+ name = g_file_get_parse_name (action->target_file);
+ descriptions[0] = g_strdup_printf (_("Restore original permissions of '%s'"), name);
+ descriptions[1] = g_strdup_printf (_("Set permissions of '%s'"), name);
+
+ labels[0] = g_strdup (_("_Undo Change Permissions"));
+ labels[1] = g_strdup (_("_Redo Change Permissions"));
+
+ g_free (name);
+}
+
+static void
+change_group_description_func (UndoData *action,
+ guint count,
+ gchar **labels,
+ gchar **descriptions)
+{
+ gchar *name;
+
+ name = g_file_get_parse_name (action->target_file);
+ descriptions[0] = g_strdup_printf (_("Restore group of '%s' to '%s'"),
+ name, action->original_name);
+ descriptions[1] = g_strdup_printf (_("Set group of '%s' to '%s'"),
+ name, action->new_name);
+
+ labels[0] = g_strdup (_("_Undo Change Group"));
+ labels[1] = g_strdup (_("_Redo Change Group"));
+
+ g_free (name);
+}
+
+static void
+change_owner_description_func (UndoData *action,
+ guint count,
+ gchar **labels,
+ gchar **descriptions)
+{
+ gchar *name;
+
+ name = g_file_get_parse_name (action->target_file);
+ descriptions[0] = g_strdup_printf (_("Restore owner of '%s' to '%s'"),
+ name, action->original_name);
+ descriptions[1] = g_strdup_printf (_("Set owner of '%s' to '%s'"),
+ name, action->new_name);
+
+ labels[0] = g_strdup (_("_Undo Change Owner"));
+ labels[1] = g_strdup (_("_Redo Change Owner"));
+
+ g_free (name);
+}
+
+static UndoData *
+create_from_type (NautilusUndoStackActionType type)
+{
+ struct {
+ void (* undo_func) (NautilusUndoStackActionData *data);
+ void (* redo_func) (NautilusUndoStackActionData *data);
+ void (* strings_func) (NautilusUndoStackActionData *data,
+ guint count,
+ gchar **labels,
+ gchar **descriptions);
+
+ } const mappings[NAUTILUS_UNDO_STACK_NUM_TYPES] = {
+ /* copy action */
+ { copy_or_link_undo_func, copy_redo_func,
+ copy_description_func },
+ /* duplicate action */
+ { copy_or_link_undo_func, duplicate_redo_func,
+ duplicate_description_func },
+ /* move action */
+ { move_undo_func, move_restore_redo_func,
+ move_description_func },
+ /* rename action */
+ { rename_undo_func, rename_redo_func,
+ rename_description_func },
+ /* create empty action */
+ { create_undo_func, create_empty_redo_func,
+ create_empty_description_func },
+ /* create from template action */
+ { create_undo_func, create_from_template_redo_func,
+ create_from_template_description_func },
+ /* create folder action */
+ { create_undo_func, create_folder_redo_func,
+ create_folder_description_func },
+ /* move to trash action */
+ { trash_undo_func, trash_redo_func,
+ trash_description_func },
+ /* restore from trash action */
+ { restore_undo_func, move_restore_redo_func,
+ restore_description_func },
+ /* create link action */
+ { create_undo_func, create_link_redo_func,
+ create_link_description_func },
+ /* recursive permissions action */
+ { recursive_permissions_undo_func, recursive_permissions_redo_func,
+ recursive_permissions_description_func },
+ /* set permissions action */
+ { set_permissions_undo_func, set_permissions_redo_func,
+ set_permissions_description_func },
+ /* change group action */
+ { change_group_undo_func, change_group_redo_func,
+ change_group_description_func },
+ /* change owner action */
+ { change_owner_undo_func, change_owner_redo_func,
+ change_owner_description_func },
+ };
+
+ UndoData *retval;
+
+ retval = g_slice_new0 (UndoData);
+ retval->undo_func = mappings[type].undo_func;
+ retval->redo_func = mappings[type].redo_func;
+ retval->strings_func = mappings[type].strings_func;
+
+ return retval;
+}
+
+NautilusUndoStackActionData *
+nautilus_undo_stack_action_data_new (NautilusUndoStackActionType type,
+ gint items_count)
+{
+ NautilusUndoStackActionData *data;
+
+ data = create_from_type (type);
+ data->type = type;
+ data->count = items_count;
+
+ return data;
+}
diff --git a/libnautilus-private/nautilus-undostack-manager.h b/libnautilus-private/nautilus-undostack-manager.h
index 2bfa47a..b90498b 100644
--- a/libnautilus-private/nautilus-undostack-manager.h
+++ b/libnautilus-private/nautilus-undostack-manager.h
@@ -50,7 +50,6 @@ typedef struct _NautilusUndoStackManagerPrivate NautilusUndoStackManagerPrivate;
NautilusUndoStackManagerClass))
typedef enum {
- NAUTILUS_UNDO_STACK_INVALID,
NAUTILUS_UNDO_STACK_COPY,
NAUTILUS_UNDO_STACK_DUPLICATE,
NAUTILUS_UNDO_STACK_MOVE,
@@ -59,23 +58,23 @@ typedef enum {
NAUTILUS_UNDO_STACK_CREATE_FILE_FROM_TEMPLATE,
NAUTILUS_UNDO_STACK_CREATE_FOLDER,
NAUTILUS_UNDO_STACK_MOVE_TO_TRASH,
- NAUTILUS_UNDO_STACK_CREATE_LINK,
NAUTILUS_UNDO_STACK_RESTORE_FROM_TRASH,
- NAUTILUS_UNDO_STACK_SET_PERMISSIONS,
+ NAUTILUS_UNDO_STACK_CREATE_LINK,
NAUTILUS_UNDO_STACK_RECURSIVE_SET_PERMISSIONS,
+ NAUTILUS_UNDO_STACK_SET_PERMISSIONS,
+ NAUTILUS_UNDO_STACK_CHANGE_GROUP,
NAUTILUS_UNDO_STACK_CHANGE_OWNER,
- NAUTILUS_UNDO_STACK_CHANGE_GROUP
+ NAUTILUS_UNDO_STACK_NUM_TYPES,
} NautilusUndoStackActionType;
typedef struct _NautilusUndoStackActionData NautilusUndoStackActionData;
-typedef struct _NautilusUndoStackMenuData NautilusUndoStackMenuData;
-struct _NautilusUndoStackMenuData {
- char *undo_label;
- char *undo_description;
- char *redo_label;
- char *redo_description;
-};
+typedef struct {
+ const char *undo_label;
+ const char *undo_description;
+ const char *redo_label;
+ const char *redo_description;
+} NautilusUndoStackMenuData;
typedef void (*NautilusUndoStackFinishCallback) (gpointer data);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]