diff options
49 files changed, 1732 insertions, 3061 deletions
@@ -1,3 +1,142 @@ +2000-06-06 Darin Adler <darin@eazel.com> + + The main change here is revamping the undo manager. + To get a complete check-out you might have to delete + the file named libnautilus/nautilus-undo.h that used + to be a generated file and is now checked-in. + + * components/help/help-method.c: (vfs_module_transform): + Removed a bogus extraneous FIXME. + + * libnautilus-extensions/Makefile.am: + Moved the undo manager into libnautilus-extensions + since it's not needed by Nautilus components. + + * libnautilus-extensions/nautilus-entry.c: + * libnautilus-extensions/nautilus-icon-text-item.c: + * libnautilus/nautilus-view.c: + * src/nautilus-application.c: + * src/nautilus-bookmarks-window.c: (create_bookmarks_window): + * src/nautilus-view-frame.c: + * src/nautilus-window-private.h: + * src/nautilus-window.c: + Updated includes and a few small function name changes. + + * libnautilus-extensions/nautilus-gtk-extensions.h: + * libnautilus-extensions/nautilus-gtk-extensions.c: + (alive_disconnecter), + (nautilus_gtk_signal_connect_full_while_alive): + Added a new function that combines the features of + gtk_signal_connect_full with gtk_signal_connect_while_alive. + + * libnautilus/nautilus-undo-context.h: [removed] + * libnautilus/nautilus-undo-context.c: [removed] + * libnautilus-extensions/nautilus-undo-context.h: + * libnautilus-extensions/nautilus-undo-context.c: + (impl_Nautilus_Undo_Context__destroy), + (impl_Nautilus_Undo_Context__create), + (impl_Nautilus_Undo_Context__get_undo_manager), + (nautilus_undo_context_new), (destroy), + (nautilus_undo_context_initialize_class): + Rewrote this class to simplify it (after moving it here). + + * libnautilus/nautilus-undo-manager.h: [removed] + * libnautilus/nautilus-undo-manager.c: [removed] + * libnautilus/nautilus-undo-manager-private.h: [removed] + * libnautilus-extensions/nautilus-undo-manager.h: + * libnautilus-extensions/nautilus-undo-manager.c: + (impl_Nautilus_Undo_Manager__destroy), + (impl_Nautilus_Undo_Manager__create), + (impl_Nautilus_Undo_Manager__append), + (impl_Nautilus_Undo_Manager__forget), + (nautilus_undo_manager_initialize), + (nautilus_undo_manager_initialize_class), + (nautilus_undo_manager_undo), + (nautilus_undo_manager_add_transaction), + (nautilus_undo_manager_forget_transaction), + (nautilus_undo_manager_set_queue_depth), + (nautilus_undo_manager_attach), + (nautilus_undo_manager_add_interface), (update_undo_menu_item), + (undo_menu_handler_connection_free), + (undo_menu_handler_connection_free_cover), + (nautilus_undo_manager_set_up_bonobo_ui_handler_undo_item): + Rewrote this class to simplify it. Got rid of many old + interfaces and added some new ones. + + * libnautilus/.cvsignore: + * libnautilus/Makefile.am: + Renamed the old nautilus-undo.idl to + nautilus-distributed-undo.idl. The IDL is only about the internal + part of the undo framework. Clients use calls that are in + nautilus-undo.h. The part that's public needs the prettier name. + + * libnautilus/nautilus-undo.idl: [removed] + * libnautilus/nautilus-distributed-undo.idl: + Updated the names of menu-item-related things to better match the + standard terminology. + + * libnautilus/nautilus-undo-private.h: + Added this new header for things needed by the undo manager that + are in libnautilus. Maybe we can eliminate this later. + + * libnautilus/nautilus-undo-transaction.h: + * libnautilus/nautilus-undo-transaction.c: + (impl_Nautilus_Undo_Transaction__destroy), + (impl_Nautilus_Undo_Transaction__create), + (impl_Nautilus_Undo_Transaction__get_undo_menu_item), + (impl_Nautilus_Undo_Transaction__get_redo_menu_item), + (impl_Nautilus_Undo_Transaction__get_operation_name), + (impl_Nautilus_Undo_Transaction__undo), + (nautilus_undo_transaction_new), + (nautilus_undo_transaction_initialize), + (remove_transaction_from_object), + (nautilus_undo_transaction_destroy), + (nautilus_undo_transaction_initialize_class), + (nautilus_undo_transaction_add_atom), + (nautilus_undo_transaction_undo), + (nautilus_undo_transaction_add_to_undo_manager), (remove_atoms), + (remove_atoms_cover), + (nautilus_undo_transaction_unregister_object), (undo_atom_free), + (undo_atom_undo_and_free), (undo_atom_free_cover), + (undo_atom_undo_and_free_cover), (undo_atom_list_free), + (undo_atom_list_undo_and_free): + Rewrote and simplified this class and got rid of all uses of + NautilusUndoable. + + * libnautilus/nautilus-undoable.h: [removed] + * libnautilus/nautilus-undoable.c: [removed] + * libnautilus/nautilus-undo.h: + * libnautilus/nautilus-undo.c: (nautilus_undo_register), + (nautilus_undo_register_full), (nautilus_undo_unregister), + (nautilus_undo), (nautilus_undo_get_undo_manager), + (undo_manager_ref), (undo_manager_unref), + (undo_manager_unref_cover), (nautilus_undo_attach_undo_manager), + (nautilus_undo_share_undo_manager), (set_up_bonobo_control), + (nautilus_undo_set_up_bonobo_control): + Added this new file with the public interface of the undo code and + most of the basic implementation. Most of this was previously in + nautilus-undoable.c. + + * nautilus-widgets/nautilus-preferences.c: + (preferences_hash_node_free), (preferences_hash_node_add_callback), + (preferences_hash_node_remove_callback), + (preferences_hash_node_check_changes_func), + (preferences_callback_node_alloc), + (preferences_callback_node_free), + (preferences_callback_node_free_func), + (preferences_callback_node_invoke_func), + (preferences_gconf_callback): + Fixed a repeated spelling error in this file. + + * src/nautilus-application.c: (nautilus_app_init): + * src/nautilus-view-frame.c: (nautilus_view_frame_load_client): + * src/nautilus-window-menus.c: (edit_menu_undo_callback), + (nautilus_window_initialize_menus): + * src/nautilus-window.c: (nautilus_window_constructed): + Changed to use public parts of the undo API instead of the old + stuff that used private secret stuff. Many places use nice new + convenient calls that do a lot of the work for you. + 2000-06-06 Pavel Cisler <pavel@eazel.com> * libnautilus-extensions/nautilus-icon-factory.c: diff --git a/components/help/help-method.c b/components/help/help-method.c index eeb3f5449..14b927e81 100644 --- a/components/help/help-method.c +++ b/components/help/help-method.c @@ -291,7 +291,7 @@ vfs_module_transform (const char *method_name, const char *args) { init_help_module (); #ifdef ALI_DEBUG - g_print ("Loading libvfs-help.so...\n"); /* FIXME: Remove me */ + g_print ("Loading libvfs-help.so...\n"); #endif return &transform; } diff --git a/libnautilus-extensions/Makefile.am b/libnautilus-extensions/Makefile.am index bb164bb86..ca4fd36af 100644 --- a/libnautilus-extensions/Makefile.am +++ b/libnautilus-extensions/Makefile.am @@ -72,6 +72,7 @@ libnautilus_extensionsinclude_HEADERS= \ nautilus-self-checks.h \ nautilus-string-list.h \ nautilus-string.h \ + nautilus-undo-manager.h \ nautilus-view-identifier.h \ nautilus-xml-extensions.h \ $(NULL) @@ -82,6 +83,7 @@ libnautilus_extensions_la_SOURCES = \ nautilus-directory-private.h \ nautilus-directory-metafile.h \ nautilus-lib-self-check-functions.h \ + nautilus-undo-context.h \ bonobo-stream-vfs.c \ nautilus-background-canvas-group.c \ nautilus-background.c \ @@ -127,6 +129,8 @@ libnautilus_extensions_la_SOURCES = \ nautilus-self-checks.c \ nautilus-string-list.c \ nautilus-string.c \ + nautilus-undo-context.c \ + nautilus-undo-manager.c \ nautilus-view-identifier.c \ nautilus-xml-extensions.c \ $(NULL) diff --git a/libnautilus-extensions/nautilus-entry.c b/libnautilus-extensions/nautilus-entry.c index de670401c..7540af06f 100644 --- a/libnautilus-extensions/nautilus-entry.c +++ b/libnautilus-extensions/nautilus-entry.c @@ -36,8 +36,6 @@ #include <libgnome/gnome-defs.h> #include <libgnome/gnome-i18n.h> -#include <libnautilus/nautilus-undo-manager.h> -#include <libnautilus/nautilus-undoable.h> #include <libnautilus/nautilus-undo.h> #include <orb/orbit.h> diff --git a/libnautilus-extensions/nautilus-gtk-extensions.c b/libnautilus-extensions/nautilus-gtk-extensions.c index 3a8d7c001..6311cea26 100644 --- a/libnautilus-extensions/nautilus-gtk-extensions.c +++ b/libnautilus-extensions/nautilus-gtk-extensions.c @@ -663,3 +663,84 @@ nautilus_gtk_widget_set_font_by_name (GtkWidget *widget, const char *font_name) nautilus_gtk_widget_set_font (widget, font); gdk_font_unref (font); } + +/* This stuff is stolen from Gtk. */ + +typedef struct DisconnectInfo { + GtkObject *object1; + guint disconnect_handler1; + guint signal_handler; + GtkObject *object2; + guint disconnect_handler2; +} DisconnectInfo; + +static guint +alive_disconnecter (GtkObject *object, DisconnectInfo *info) +{ + g_assert (info != NULL); + g_assert (GTK_IS_OBJECT (info->object1)); + g_assert (info->disconnect_handler1 != 0); + g_assert (info->signal_handler != 0); + g_assert (GTK_IS_OBJECT (info->object2)); + g_assert (info->disconnect_handler2 != 0); + g_assert (object == info->object1 || object == info->object2); + + gtk_signal_disconnect (info->object1, info->disconnect_handler1); + gtk_signal_disconnect (info->object1, info->signal_handler); + gtk_signal_disconnect (info->object2, info->disconnect_handler2); + + g_free (info); + + return 0; +} + +/** + * nautilus_gtk_signal_connect_full_while_alive + * + * Like gtk_signal_connect_while_alive, but works with full parameters. + **/ +void +nautilus_gtk_signal_connect_full_while_alive (GtkObject *object, + const gchar *name, + GtkSignalFunc func, + GtkCallbackMarshal marshal, + gpointer data, + GtkDestroyNotify destroy_func, + gboolean object_signal, + gboolean after, + GtkObject *alive_object) +{ + DisconnectInfo *info; + + g_return_if_fail (GTK_IS_OBJECT (object)); + g_return_if_fail (name != NULL); + g_return_if_fail (func != NULL); + g_return_if_fail (object_signal == FALSE || object_signal == TRUE); + g_return_if_fail (after == FALSE || after == TRUE); + g_return_if_fail (GTK_IS_OBJECT (alive_object)); + + info = g_new (DisconnectInfo, 1); + info->object1 = object; + info->object2 = alive_object; + + info->signal_handler = + gtk_signal_connect_full (object, + name, + func, + marshal, + data, + destroy_func, + object_signal, + after); + + info->disconnect_handler1 = + gtk_signal_connect (object, + "destroy", + GTK_SIGNAL_FUNC (alive_disconnecter), + info); + info->disconnect_handler2 = + gtk_signal_connect (alive_object, + "destroy", + GTK_SIGNAL_FUNC (alive_disconnecter), + info); +} diff --git a/libnautilus-extensions/nautilus-gtk-extensions.h b/libnautilus-extensions/nautilus-gtk-extensions.h index 9f7cf2418..e5a5bda23 100644 --- a/libnautilus-extensions/nautilus-gtk-extensions.h +++ b/libnautilus-extensions/nautilus-gtk-extensions.h @@ -34,56 +34,64 @@ #define NAUTILUS_DEFAULT_POPUP_MENU_DISPLACEMENT 2 /* GtkCList */ -int nautilus_gtk_clist_get_first_selected_row (GtkCList *list); -int nautilus_gtk_clist_get_last_selected_row (GtkCList *list); +int nautilus_gtk_clist_get_first_selected_row (GtkCList *list); +int nautilus_gtk_clist_get_last_selected_row (GtkCList *list); /* signals */ -guint nautilus_gtk_signal_connect_free_data (GtkObject *object, - const gchar *name, - GtkSignalFunc func, - gpointer data); - +guint nautilus_gtk_signal_connect_free_data (GtkObject *object, + const gchar *name, + GtkSignalFunc func, + gpointer data); guint nautilus_gtk_signal_connect_free_data_custom (GtkObject *object, - const gchar *name, - GtkSignalFunc func, - gpointer data, - GtkDestroyNotify destroy_func); + const gchar *name, + GtkSignalFunc func, + gpointer data, + GtkDestroyNotify destroy_func); +void nautilus_gtk_signal_connect_full_while_alive (GtkObject *object, + const gchar *name, + GtkSignalFunc func, + GtkCallbackMarshal marshal, + gpointer data, + GtkDestroyNotify destroy_func, + gboolean object_signal, + gboolean after, + GtkObject *alive_object); /* list of GtkObject */ -GList * nautilus_gtk_object_list_ref (GList *list); -void nautilus_gtk_object_list_unref (GList *list); -void nautilus_gtk_object_list_free (GList *list); -GList * nautilus_gtk_object_list_copy (GList *list); +GList * nautilus_gtk_object_list_ref (GList *list); +void nautilus_gtk_object_list_unref (GList *list); +void nautilus_gtk_object_list_free (GList *list); +GList * nautilus_gtk_object_list_copy (GList *list); /* GtkWidget */ -gboolean nautilus_point_in_allocation (const GtkAllocation *allocation, - int x, - int y); -void nautilus_gtk_widget_set_font (GtkWidget *widget, - GdkFont *font); -void nautilus_gtk_widget_set_font_by_name (GtkWidget *widget, - const char *font_name); -gboolean nautilus_point_in_widget (GtkWidget *widget, - int x, - int y); +gboolean nautilus_point_in_allocation (const GtkAllocation *allocation, + int x, + int y); +void nautilus_gtk_widget_set_font (GtkWidget *widget, + GdkFont *font); +void nautilus_gtk_widget_set_font_by_name (GtkWidget *widget, + const char *font_name); +gboolean nautilus_point_in_widget (GtkWidget *widget, + int x, + int y); /* GtkWindow */ -void nautilus_gtk_window_present (GtkWindow *window); +void nautilus_gtk_window_present (GtkWindow *window); /* selection data */ -GtkSelectionData *nautilus_gtk_selection_data_copy_deep (const GtkSelectionData *selection_data); -void nautilus_gtk_selection_data_free_deep (GtkSelectionData *selection_data); +GtkSelectionData *nautilus_gtk_selection_data_copy_deep (const GtkSelectionData *selection_data); +void nautilus_gtk_selection_data_free_deep (GtkSelectionData *selection_data); /* GtkMenu */ -void nautilus_pop_up_context_menu (GtkMenu *menu, - gint16 offset_x, - gint16 offset_y); +void nautilus_pop_up_context_menu (GtkMenu *menu, + gint16 offset_x, + gint16 offset_y); /* GtkStyle */ -void nautilus_gtk_style_set_font (GtkStyle *style, - GdkFont *font); -void nautilus_gtk_style_set_font_by_name (GtkStyle *style, - const char *font_name); +void nautilus_gtk_style_set_font (GtkStyle *style, + GdkFont *font); +void nautilus_gtk_style_set_font_by_name (GtkStyle *style, + const char *font_name); /* marshals */ diff --git a/libnautilus-extensions/nautilus-icon-text-item.c b/libnautilus-extensions/nautilus-icon-text-item.c index 8e35d5ee3..b5886ea39 100644 --- a/libnautilus-extensions/nautilus-icon-text-item.c +++ b/libnautilus-extensions/nautilus-icon-text-item.c @@ -14,7 +14,7 @@ #include "nautilus-icon-text-item.h" #include "nautilus-entry.h" -#include <libnautilus/nautilus-undoable.h> +#include <libnautilus/nautilus-undo.h> #include <math.h> #include <stdio.h> diff --git a/libnautilus-extensions/nautilus-preferences.c b/libnautilus-extensions/nautilus-preferences.c index 19974216d..b3ddf019c 100644 --- a/libnautilus-extensions/nautilus-preferences.c +++ b/libnautilus-extensions/nautilus-preferences.c @@ -93,13 +93,13 @@ static void preferences_hash_node_check_changes_func ( /* PreferencesCallbackNode functions */ -static PreferencesCallbackNode *preferneces_callback_node_alloc (NautilusPreferencesCallback callback_proc, +static PreferencesCallbackNode *preferences_callback_node_alloc (NautilusPreferencesCallback callback_proc, gpointer callback_data, const PreferencesHashNode *hash_node); -static void preferneces_callback_node_free (PreferencesCallbackNode *node); -static void preferneces_callback_node_free_func (gpointer data, +static void preferences_callback_node_free (PreferencesCallbackNode *node); +static void preferences_callback_node_free_func (gpointer data, gpointer callback_data); -static void preferneces_callback_node_invoke_func (gpointer data, +static void preferences_callback_node_invoke_func (gpointer data, gpointer callback_data); static void preferences_hash_node_add_callback (PreferencesHashNode *node, NautilusPreferencesCallback callback_proc, @@ -177,7 +177,7 @@ preferences_hash_node_free (PreferencesHashNode *node) } nautilus_g_list_free_deep_custom (node->callback_list, - preferneces_callback_node_free_func, + preferences_callback_node_free_func, NULL); node->callback_list = NULL; @@ -201,21 +201,21 @@ preferences_hash_node_add_callback (PreferencesHashNode *node, NautilusPreferencesCallback callback_proc, gpointer callback_data) { - PreferencesCallbackNode *preferneces_callback_node; + PreferencesCallbackNode *preferences_callback_node; guint i; g_assert (node != NULL); g_assert (callback_proc != NULL); - preferneces_callback_node = preferneces_callback_node_alloc (callback_proc, + preferences_callback_node = preferences_callback_node_alloc (callback_proc, callback_data, node); - g_assert (preferneces_callback_node != NULL); + g_assert (preferences_callback_node != NULL); node->callback_list = g_list_append (node->callback_list, - (gpointer) preferneces_callback_node); + (gpointer) preferences_callback_node); /* * We install only one gconf notification for each preference node. @@ -279,7 +279,7 @@ preferences_hash_node_remove_callback (PreferencesHashNode *node, node->callback_list = g_list_remove (node->callback_list, (gpointer) callback_info); - preferneces_callback_node_free (callback_info); + preferences_callback_node_free (callback_info); } } @@ -345,14 +345,14 @@ preferences_hash_node_check_changes_func (gpointer key, /* Invoke callbacks for this node */ if (node->callback_list) { g_list_foreach (node->callback_list, - preferneces_callback_node_invoke_func, + preferences_callback_node_invoke_func, (gpointer) NULL); } } } /** - * preferneces_callback_node_alloc + * preferences_callback_node_alloc * * Allocate a callback info struct from the given values. PreferencesCallbackNode * structures are used as nodes for the callbac_list member of pref hash table @@ -364,7 +364,7 @@ preferences_hash_node_check_changes_func (gpointer key, * Return value: A newly allocated node. **/ static PreferencesCallbackNode * -preferneces_callback_node_alloc (NautilusPreferencesCallback callback_proc, +preferences_callback_node_alloc (NautilusPreferencesCallback callback_proc, gpointer callback_data, const PreferencesHashNode *hash_node) { @@ -382,13 +382,13 @@ preferneces_callback_node_alloc (NautilusPreferencesCallback callback_proc, } /** - * preferneces_callback_node_free + * preferences_callback_node_free * * Free a callback info struct. - * @preferneces_callback_node: The struct to free. + * @preferences_callback_node: The struct to free. **/ static void -preferneces_callback_node_free (PreferencesCallbackNode *callback_node) +preferences_callback_node_free (PreferencesCallbackNode *callback_node) { g_assert (callback_node != NULL); @@ -399,7 +399,7 @@ preferneces_callback_node_free (PreferencesCallbackNode *callback_node) } /** - * preferneces_callback_node_free_func + * preferences_callback_node_free_func * * A function that frees a callback info struct. It is meant to be fed to * g_list_foreach () @@ -407,16 +407,16 @@ preferneces_callback_node_free (PreferencesCallbackNode *callback_node) * @callback_data: The callback_data privately maintained by the GList. **/ static void -preferneces_callback_node_free_func (gpointer data, +preferences_callback_node_free_func (gpointer data, gpointer callback_data) { g_assert (data != NULL); - preferneces_callback_node_free ((PreferencesCallbackNode *) data); + preferences_callback_node_free ((PreferencesCallbackNode *) data); } /** - * preferneces_callback_node_invoke_func + * preferences_callback_node_invoke_func * * A function that invokes a callback from the given struct. It is meant to be fed to * g_list_foreach () @@ -424,7 +424,7 @@ preferneces_callback_node_free_func (gpointer data, * @callback_data: The callback_data privately maintained by the GList. **/ static void -preferneces_callback_node_invoke_func (gpointer data, +preferences_callback_node_invoke_func (gpointer data, gpointer callback_data) { PreferencesCallbackNode *callback_node; @@ -562,7 +562,7 @@ preferences_gconf_callback (GConfClient *client, /* Invoke callbacks for this node */ if (node->callback_list) { g_list_foreach (node->callback_list, - preferneces_callback_node_invoke_func, + preferences_callback_node_invoke_func, (gpointer) NULL); } diff --git a/libnautilus-extensions/nautilus-undo-context.c b/libnautilus-extensions/nautilus-undo-context.c index ee5153e8c..f64639e59 100644 --- a/libnautilus-extensions/nautilus-undo-context.c +++ b/libnautilus-extensions/nautilus-undo-context.c @@ -1,6 +1,7 @@ /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* NautilusUndoContext +/* NautilusUndoContext - Used internally by undo machinery. + * Not public. * * Copyright (C) 2000 Eazel, Inc. * @@ -23,16 +24,11 @@ */ #include <config.h> +#include "nautilus-undo-context.h" + +#include "nautilus-gtk-macros.h" #include <gtk/gtksignal.h> -#include <gtk/gtkmain.h> #include <bonobo/bonobo-main.h> -#include <bonobo/bonobo-object.h> -#include <bonobo/bonobo-control.h> -#include <libnautilus-extensions/nautilus-gtk-macros.h> - -#include "nautilus-undo.h" - -#include "nautilus-undo-context.h" typedef struct { POA_Nautilus_Undo_Context servant; @@ -57,7 +53,7 @@ POA_Nautilus_Undo_Context__epv libnautilus_Nautilus_Undo_Context_epv = }; static PortableServer_ServantBase__epv base_epv; -static POA_Nautilus_Undo_Context__vepv impl_Nautilus_Undo_Context_vepv = +static POA_Nautilus_Undo_Context__vepv vepv = { &base_epv, NULL, @@ -65,54 +61,42 @@ static POA_Nautilus_Undo_Context__vepv impl_Nautilus_Undo_Context_vepv = }; static void -impl_Nautilus_Undo_Context__destroy (BonoboObject *obj, impl_POA_Nautilus_Undo_Context *servant) +impl_Nautilus_Undo_Context__destroy (BonoboObject *object, + PortableServer_Servant servant) { - PortableServer_ObjectId *objid; + PortableServer_ObjectId *object_id; CORBA_Environment ev; - void (*servant_destroy_func) (PortableServer_Servant servant, CORBA_Environment *ev); CORBA_exception_init (&ev); - servant_destroy_func = NAUTILUS_UNDO_CONTEXT_CLASS - (GTK_OBJECT (servant->bonobo_object)->klass)->servant_destroy_func; - objid = PortableServer_POA_servant_to_id (bonobo_poa (), servant, &ev); - PortableServer_POA_deactivate_object (bonobo_poa (), objid, &ev); - CORBA_free (objid); - obj->servant = NULL; - - (* servant_destroy_func) ((PortableServer_Servant) servant, &ev); + object_id = PortableServer_POA_servant_to_id (bonobo_poa (), servant, &ev); + PortableServer_POA_deactivate_object (bonobo_poa (), object_id, &ev); + CORBA_free (object_id); + object->servant = NULL; + POA_Nautilus_Undo_Context__fini (servant, &ev); g_free (servant); + CORBA_exception_free (&ev); } static Nautilus_Undo_Context -impl_Nautilus_Undo_Context__create (NautilusUndoContext *context, CORBA_Environment * ev) +impl_Nautilus_Undo_Context__create (NautilusUndoContext *bonobo_object, + CORBA_Environment *ev) { - Nautilus_Undo_Context retval; impl_POA_Nautilus_Undo_Context *servant; - void (*servant_init_func) (PortableServer_Servant servant, CORBA_Environment *ev); - NautilusUndoContextClass *context_class; - context_class = NAUTILUS_UNDO_CONTEXT_CLASS (GTK_OBJECT (context)->klass); - - servant_init_func = context_class->servant_init_func; servant = g_new0 (impl_POA_Nautilus_Undo_Context, 1); - servant->servant.vepv = context_class->vepv; - if (servant->servant.vepv->Bonobo_Unknown_epv == NULL) { - servant->servant.vepv->Bonobo_Unknown_epv = bonobo_object_get_epv (); - } - (* servant_init_func) ((PortableServer_Servant) servant, ev); - - servant->bonobo_object = context; + servant->servant.vepv = &vepv; + vepv.Bonobo_Unknown_epv = bonobo_object_get_epv (); + POA_Nautilus_Undo_Context__init ((PortableServer_Servant) servant, ev); - retval = bonobo_object_activate_servant (BONOBO_OBJECT (context), servant); - - gtk_signal_connect (GTK_OBJECT (context), "destroy", + gtk_signal_connect (GTK_OBJECT (bonobo_object), "destroy", GTK_SIGNAL_FUNC (impl_Nautilus_Undo_Context__destroy), servant); - return retval; + servant->bonobo_object = bonobo_object; + return bonobo_object_activate_servant (BONOBO_OBJECT (bonobo_object), servant); } static Nautilus_Undo_Manager @@ -122,23 +106,26 @@ impl_Nautilus_Undo_Context__get_undo_manager (PortableServer_Servant servant, NautilusUndoContext *context; context = ((impl_POA_Nautilus_Undo_Context *) servant)->bonobo_object; - g_assert (NAUTILUS_IS_UNDO_CONTEXT (context)); return CORBA_Object_duplicate (context->undo_manager, ev); } -/* nautilus_undo_manager_new */ NautilusUndoContext * nautilus_undo_context_new (Nautilus_Undo_Manager undo_manager) { + CORBA_Environment ev; NautilusUndoContext *context; + CORBA_exception_init (&ev); + context = gtk_type_new (nautilus_undo_context_get_type ()); - context->undo_manager = undo_manager; + context->undo_manager = CORBA_Object_duplicate (undo_manager, &ev); + + CORBA_exception_free (&ev); + return context; } -/* Object initialization function for the NautilusUndoContext */ static void nautilus_undo_context_initialize (NautilusUndoContext *context) { @@ -152,28 +139,24 @@ nautilus_undo_context_initialize (NautilusUndoContext *context) CORBA_exception_free (&ev); } -/* Class initialization function for the NautilusUndoManager. */ static void -nautilus_undo_context_initialize_class (NautilusUndoContextClass *klass) +destroy (GtkObject *object) { - GtkObjectClass *object_class; - - object_class = GTK_OBJECT_CLASS (klass); + CORBA_Environment ev; + NautilusUndoContext *context; - object_class->destroy = destroy; + CORBA_exception_init (&ev); - klass->servant_init_func = POA_Nautilus_Undo_Context__init; - klass->servant_destroy_func = POA_Nautilus_Undo_Context__fini; - klass->vepv = &impl_Nautilus_Undo_Context_vepv; + context = NAUTILUS_UNDO_CONTEXT (object); + CORBA_Object_release (context->undo_manager, &ev); + + CORBA_exception_free (&ev); + + NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object)); } -/* destroy */ static void -destroy (GtkObject *object) +nautilus_undo_context_initialize_class (NautilusUndoContextClass *klass) { - NautilusUndoContext *context; - - context = NAUTILUS_UNDO_CONTEXT (object); - - NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object)); + GTK_OBJECT_CLASS (klass)->destroy = destroy; } diff --git a/libnautilus-extensions/nautilus-undo-context.h b/libnautilus-extensions/nautilus-undo-context.h index bb4bdf2cd..2559f764e 100644 --- a/libnautilus-extensions/nautilus-undo-context.h +++ b/libnautilus-extensions/nautilus-undo-context.h @@ -1,6 +1,7 @@ /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* NautilusUndoContext +/* NautilusUndoContext - Used internally by undo machinery. + * Not public. * * Copyright (C) 2000 Eazel, Inc. * @@ -25,7 +26,8 @@ #ifndef NAUTILUS_UNDO_CONTEXT_H #define NAUTILUS_UNDO_CONTEXT_H -#include "nautilus-undo.h" +#include <bonobo/bonobo-object.h> +#include <libnautilus/nautilus-distributed-undo.h> #define NAUTILUS_TYPE_UNDO_CONTEXT \ (nautilus_undo_context_get_type ()) @@ -38,25 +40,16 @@ #define NAUTILUS_IS_UNDO_CONTEXT_CLASS(klass) \ (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_UNDO_CONTEXT)) -typedef struct NautilusUndoContext NautilusUndoContext; -typedef struct NautilusUndoContextClass NautilusUndoContextClass; - -struct NautilusUndoContext { - BonoboObject parent; +typedef struct { + BonoboObject parent_slot; Nautilus_Undo_Manager undo_manager; -}; - -struct NautilusUndoContextClass { - BonoboObjectClass parent_class; - gpointer servant_init_func, servant_destroy_func, vepv; -}; - - -/* GtkObject */ -GtkType nautilus_undo_context_get_type (void); -NautilusUndoContext *nautilus_undo_context_new (Nautilus_Undo_Manager undo_manager); +} NautilusUndoContext; -/* Prototypes */ +typedef struct { + BonoboObjectClass parent_slot; +} NautilusUndoContextClass; +GtkType nautilus_undo_context_get_type (void); +NautilusUndoContext *nautilus_undo_context_new (Nautilus_Undo_Manager undo_manager); #endif /* NAUTILUS_UNDO_CONTEXT_H */ diff --git a/libnautilus-extensions/nautilus-undo-manager.c b/libnautilus-extensions/nautilus-undo-manager.c index 15af401ff..28946d900 100644 --- a/libnautilus-extensions/nautilus-undo-manager.c +++ b/libnautilus-extensions/nautilus-undo-manager.c @@ -25,25 +25,22 @@ #include <config.h> #include "nautilus-undo-manager.h" +#include <libnautilus-extensions/nautilus-gtk-macros.h> +#include <libnautilus-extensions/nautilus-gtk-extensions.h> #include <gtk/gtksignal.h> -#include <gtk/gtkmain.h> -#include <glib.h> -#include <string.h> #include <bonobo/bonobo-main.h> -#include <bonobo/bonobo-control.h> - -#include "nautilus-undo-manager-private.h" - -#include <libnautilus-extensions/nautilus-gnome-extensions.h> -#include <libnautilus-extensions/nautilus-gtk-extensions.h> -#include <libnautilus-extensions/nautilus-gtk-macros.h> - - -/* Gloabl instance of undo manager */ -Nautilus_Undo_Manager global_undo_manager; +#include <libnautilus/nautilus-undo-private.h> +#include "nautilus-undo-context.h" + +struct NautilusUndoManagerDetails { + GList *undo_list; + GList *redo_list; + gboolean enable_redo; + gint queue_depth; +}; enum { - UNDO_TRANSACTION_OCCURRED, + CHANGED, LAST_SIGNAL }; static guint signals[LAST_SIGNAL]; @@ -53,40 +50,45 @@ typedef struct { NautilusUndoManager *bonobo_object; } impl_POA_Nautilus_Undo_Manager; +typedef struct { + BonoboUIHandler *handler; + char *path; + char *no_undo_menu_item_label; + char *no_undo_menu_item_hint; +} UndoMenuHandlerConnection; + /* GtkObject */ -static void nautilus_undo_manager_initialize_class (NautilusUndoManagerClass *class); -static void nautilus_undo_manager_initialize (NautilusUndoManager *item); -static void destroy (GtkObject *object); -static void free_undo_manager_list (GList *list); -static GList *prune_undo_manager_list (GList *list, - int items); +static void nautilus_undo_manager_initialize_class (NautilusUndoManagerClass *class); +static void nautilus_undo_manager_initialize (NautilusUndoManager *item); +static void destroy (GtkObject *object); +static void free_undo_manager_list (GList *list); +static GList *prune_undo_manager_list (GList *list, + int items); /* CORBA/Bonobo */ -static void impl_Nautilus_Undo_Manager__append (PortableServer_Servant servant, - const Nautilus_Undo_Transaction transaction, - CORBA_Environment *ev); -static void impl_Nautilus_Undo_Manager__forget (PortableServer_Servant servant, - const Nautilus_Undo_Transaction transaction, - CORBA_Environment *ev); -static void impl_Nautilus_Undo_Manager__undo (PortableServer_Servant servant, - CORBA_Environment *ev); -static void nautilus_undo_manager_add_transaction (NautilusUndoManager *manager, - Nautilus_Undo_Transaction transaction); -static void nautilus_undo_manager_forget_transaction (NautilusUndoManager *manager, - Nautilus_Undo_Transaction transaction); -static void nautilus_undo_manager_undo (NautilusUndoManager *manager); +static void impl_Nautilus_Undo_Manager__append (PortableServer_Servant servant, + Nautilus_Undo_Transaction transaction, + CORBA_Environment *ev); +static void impl_Nautilus_Undo_Manager__forget (PortableServer_Servant servant, + Nautilus_Undo_Transaction transaction, + CORBA_Environment *ev); +static void impl_Nautilus_Undo_Manager__undo (PortableServer_Servant servant, + CORBA_Environment *ev); +static void nautilus_undo_manager_add_transaction (NautilusUndoManager *manager, + Nautilus_Undo_Transaction transaction); +static void nautilus_undo_manager_forget_transaction (NautilusUndoManager *manager, + Nautilus_Undo_Transaction transaction); NAUTILUS_DEFINE_CLASS_BOILERPLATE(NautilusUndoManager, nautilus_undo_manager, BONOBO_OBJECT_TYPE) -POA_Nautilus_Undo_Manager__epv libnautilus_Nautilus_Undo_Manager_epv = +static POA_Nautilus_Undo_Manager__epv libnautilus_Nautilus_Undo_Manager_epv = { - NULL, /* _private */ + NULL, &impl_Nautilus_Undo_Manager__append, &impl_Nautilus_Undo_Manager__forget, &impl_Nautilus_Undo_Manager__undo, }; - static PortableServer_ServantBase__epv base_epv; -static POA_Nautilus_Undo_Manager__vepv impl_Nautilus_Undo_Manager_vepv = +static POA_Nautilus_Undo_Manager__vepv vepv = { &base_epv, NULL, @@ -94,53 +96,48 @@ static POA_Nautilus_Undo_Manager__vepv impl_Nautilus_Undo_Manager_vepv = }; static void -impl_Nautilus_Undo_Manager__destroy (BonoboObject *obj, impl_POA_Nautilus_Undo_Manager *servant) +impl_Nautilus_Undo_Manager__destroy (BonoboObject *object, + impl_POA_Nautilus_Undo_Manager *servant) { - PortableServer_ObjectId *objid; + PortableServer_ObjectId *object_id; CORBA_Environment ev; - void (*servant_destroy_func) (PortableServer_Servant servant, CORBA_Environment *ev); CORBA_exception_init (&ev); - servant_destroy_func = NAUTILUS_UNDO_MANAGER_CLASS (GTK_OBJECT (servant->bonobo_object)->klass)->servant_destroy_func; - objid = PortableServer_POA_servant_to_id (bonobo_poa (), servant, &ev); - PortableServer_POA_deactivate_object (bonobo_poa (), objid, &ev); - CORBA_free (objid); - obj->servant = NULL; + object_id = PortableServer_POA_servant_to_id (bonobo_poa (), servant, &ev); + PortableServer_POA_deactivate_object (bonobo_poa (), object_id, &ev); + CORBA_free (object_id); + object->servant = NULL; - servant_destroy_func ((PortableServer_Servant) servant, &ev); + POA_Nautilus_Undo_Manager__fini (servant, &ev); g_free (servant); + CORBA_exception_free (&ev); } static Nautilus_Undo_Manager -impl_Nautilus_Undo_Manager__create (NautilusUndoManager *manager, CORBA_Environment * ev) +impl_Nautilus_Undo_Manager__create (NautilusUndoManager *bonobo_object, + CORBA_Environment *ev) { - Nautilus_Undo_Manager retval; impl_POA_Nautilus_Undo_Manager *servant; - void (*servant_init_func) (PortableServer_Servant servant, CORBA_Environment *ev); - NautilusUndoManagerClass *undo_class = NAUTILUS_UNDO_MANAGER_CLASS (GTK_OBJECT(manager)->klass); - - servant_init_func = undo_class->servant_init_func; servant = g_new0 (impl_POA_Nautilus_Undo_Manager, 1); - servant->servant.vepv = undo_class->vepv; - if (!servant->servant.vepv->Bonobo_Unknown_epv) - servant->servant.vepv->Bonobo_Unknown_epv = bonobo_object_get_epv (); - servant_init_func ((PortableServer_Servant) servant, ev); - - servant->bonobo_object = manager; - retval = bonobo_object_activate_servant (BONOBO_OBJECT (manager), servant); + vepv.Bonobo_Unknown_epv = bonobo_object_get_epv (); + servant->servant.vepv = &vepv; + POA_Nautilus_Undo_Manager__init ((PortableServer_Servant) servant, ev); - gtk_signal_connect (GTK_OBJECT (manager), "destroy", GTK_SIGNAL_FUNC (impl_Nautilus_Undo_Manager__destroy), servant); + gtk_signal_connect (GTK_OBJECT (bonobo_object), "destroy", + GTK_SIGNAL_FUNC (impl_Nautilus_Undo_Manager__destroy), + servant); - return retval; + servant->bonobo_object = bonobo_object; + return bonobo_object_activate_servant (BONOBO_OBJECT (bonobo_object), servant); } static void impl_Nautilus_Undo_Manager__append (PortableServer_Servant servant, - const Nautilus_Undo_Transaction undo_transaction, + Nautilus_Undo_Transaction undo_transaction, CORBA_Environment *ev) { NautilusUndoManager *manager; @@ -153,7 +150,7 @@ impl_Nautilus_Undo_Manager__append (PortableServer_Servant servant, static void impl_Nautilus_Undo_Manager__forget (PortableServer_Servant servant, - const Nautilus_Undo_Transaction transaction, + Nautilus_Undo_Transaction transaction, CORBA_Environment *ev) { NautilusUndoManager *manager; @@ -182,8 +179,7 @@ nautilus_undo_manager_new (void) return gtk_type_new (nautilus_undo_manager_get_type ()); } -/* Object initialization function for the NautilusUndoManager */ -static void +static void nautilus_undo_manager_initialize (NautilusUndoManager *manager) { CORBA_Environment ev; @@ -192,23 +188,16 @@ nautilus_undo_manager_initialize (NautilusUndoManager *manager) manager->details = g_new0 (NautilusUndoManagerDetails, 1); - /* Create empty lists */ - manager->details->undo_list = NULL; - manager->details->redo_list = NULL; - - /* Default to no redo functionality */ - manager->details->enable_redo = FALSE; - /* Set queue depth to a single level */ manager->details->queue_depth = 1; - bonobo_object_construct (BONOBO_OBJECT (manager), impl_Nautilus_Undo_Manager__create (manager, &ev)); + bonobo_object_construct (BONOBO_OBJECT (manager), + impl_Nautilus_Undo_Manager__create (manager, &ev)); CORBA_exception_free (&ev); } -/* Class initialization function for the NautilusUndoManager. */ static void nautilus_undo_manager_initialize_class (NautilusUndoManagerClass *klass) { @@ -218,24 +207,19 @@ nautilus_undo_manager_initialize_class (NautilusUndoManagerClass *klass) object_class->destroy = destroy; - klass->servant_init_func = POA_Nautilus_Undo_Manager__init; - klass->servant_destroy_func = POA_Nautilus_Undo_Manager__fini; - klass->vepv = &impl_Nautilus_Undo_Manager_vepv; - - /* Setup signals */ - signals[UNDO_TRANSACTION_OCCURRED] - = gtk_signal_new ("undo_transaction_occurred", + signals[CHANGED] + = gtk_signal_new ("changed", GTK_RUN_LAST, object_class->type, GTK_SIGNAL_OFFSET (NautilusUndoManagerClass, - undo_transaction_occurred), + changed), gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0); gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL); } -static void +void nautilus_undo_manager_undo (NautilusUndoManager *manager) { GList *last_in_list; @@ -246,7 +230,6 @@ nautilus_undo_manager_undo (NautilusUndoManager *manager) /* Verify we have a transaction to be undone */ if (manager->details->undo_list == NULL) { - g_warning ("NautilusUndoManager has no transaction to be undone."); return; } @@ -269,8 +252,7 @@ nautilus_undo_manager_undo (NautilusUndoManager *manager) } /* Fire off signal informing that an undo transaction has occurred */ - gtk_signal_emit (GTK_OBJECT (manager), - signals[UNDO_TRANSACTION_OCCURRED]); + gtk_signal_emit (GTK_OBJECT (manager), signals[CHANGED]); CORBA_exception_free (&ev); } @@ -342,8 +324,7 @@ nautilus_undo_manager_add_transaction (NautilusUndoManager *manager, manager->details->undo_list = g_list_append (manager->details->undo_list, duplicate_transaction); /* Fire off signal informing that an undo transaction has occurred */ - gtk_signal_emit (GTK_OBJECT (manager), - signals[UNDO_TRANSACTION_OCCURRED]); + gtk_signal_emit (GTK_OBJECT (manager), signals[CHANGED]); CORBA_exception_free (&ev); } @@ -392,39 +373,13 @@ nautilus_undo_manager_forget_transaction (NautilusUndoManager *manager, if (success) { /* Fire off signal informing that a transaction has occurred */ - gtk_signal_emit (GTK_OBJECT (manager), - signals[UNDO_TRANSACTION_OCCURRED]); + gtk_signal_emit (GTK_OBJECT (manager), signals[CHANGED]); } CORBA_exception_free (&ev); } - -Nautilus_Undo_Transaction -nautilus_undo_manager_get_current_undo_transaction (NautilusUndoManager *manager) -{ - GList *last_in_list; - CORBA_Object undo_transaction; - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - /* Verify we have a transaction to be undone */ - if (manager->details->undo_list == NULL) { - g_warning ("NautilusUndoManager has no undo transaction in the queue."); - return NULL; - } - - /* Pop last transaction off undo list */ - last_in_list = g_list_last (manager->details->undo_list); - g_assert (last_in_list != NULL); - undo_transaction = last_in_list->data; - - return undo_transaction; - - CORBA_exception_free (&ev); -} - +#if 0 gboolean nautilus_undo_manager_can_undo (NautilusUndoManager *manager) @@ -441,6 +396,8 @@ nautilus_undo_manager_can_redo (NautilusUndoManager *manager) && manager->details->redo_list != NULL; } +#endif + static void destroy (GtkObject *object) { @@ -455,6 +412,8 @@ destroy (GtkObject *object) NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object)); } +#if 0 + /* nautilus_undo_manager_enable_redo * * Enable or disable redo functionality @@ -495,10 +454,11 @@ nautilus_undo_manager_set_queue_depth (NautilusUndoManager *manager, int depth) } /* Fire off signal informing that an undo transaction has occurred */ - gtk_signal_emit (GTK_OBJECT (manager), - signals[UNDO_TRANSACTION_OCCURRED]); + gtk_signal_emit (GTK_OBJECT (manager), signals[CHANGED]); } +#endif + /* free_undo_manager_list * * Clear undo data from list @@ -546,174 +506,115 @@ prune_undo_manager_list (GList *list, int items) return list; } -Nautilus_Undo_Manager -nautilus_get_undo_manager (GtkObject *start_object) -{ - Nautilus_Undo_Manager manager; - GtkWidget *parent; - GtkWindow *transient_parent; - - if (start_object == NULL) { - return NULL; - } - - g_return_val_if_fail (GTK_IS_OBJECT (start_object), NULL); - - /* Check for an undo manager right here. */ - manager = gtk_object_get_data (start_object, "Nautilus undo"); - if (manager != NULL) { - return manager; - } - - /* Check for undo manager up the parent chain. */ - if (GTK_IS_WIDGET (start_object)) { - parent = GTK_WIDGET (start_object)->parent; - if (parent != NULL) { - manager = nautilus_get_undo_manager (GTK_OBJECT (parent)); - if (manager != NULL) { - return manager; - } - } - - /* Check for undo manager in our window's parent. */ - if (GTK_IS_WINDOW (start_object)) { - transient_parent = GTK_WINDOW (start_object)->transient_parent; - if (transient_parent != NULL) { - manager = nautilus_get_undo_manager (GTK_OBJECT (transient_parent)); - if (manager != NULL) { - return manager; - } - } - } - } - - /* In the case of a canvas item, try the canvas. */ - if (GNOME_IS_CANVAS_ITEM (start_object)) { - manager = nautilus_get_undo_manager (GTK_OBJECT (GNOME_CANVAS_ITEM (start_object)->canvas)); - if (manager != NULL) { - return manager; - } - } - - /* Found nothing. I can live with that. */ - return NULL; -} - -static void -undo_manager_unref (gpointer manager) -{ - CORBA_Environment ev; - - CORBA_exception_init (&ev); - Nautilus_Undo_Manager_unref (manager, &ev); - CORBA_Object_release (manager, &ev); - CORBA_exception_free (&ev); -} - void -nautilus_attach_undo_manager (GtkObject *object, - Nautilus_Undo_Manager manager) +nautilus_undo_manager_attach (NautilusUndoManager *manager, GtkObject *target) { - CORBA_Environment ev; - Nautilus_Undo_Manager stored_manager; - - g_return_if_fail (GTK_IS_OBJECT (object)); - - if (manager == NULL) { - gtk_object_remove_data (object, "Nautilus undo"); - return; - } - - CORBA_exception_init (&ev); - Nautilus_Undo_Manager_ref (manager, &ev); - stored_manager = CORBA_Object_duplicate (manager, &ev); - CORBA_exception_free (&ev); + g_return_if_fail (NAUTILUS_IS_UNDO_MANAGER (manager)); + g_return_if_fail (GTK_IS_OBJECT (target)); - gtk_object_set_data_full - (object, "Nautilus undo", - stored_manager, undo_manager_unref); + nautilus_undo_attach_undo_manager + (target, + bonobo_object_corba_objref (BONOBO_OBJECT (manager))); } -/* This is useful because nautilus_get_undo_manager will be - * private one day. - */ void -nautilus_share_undo_manager (GtkObject *destination_object, - GtkObject *source_object) +nautilus_undo_manager_add_interface (NautilusUndoManager *manager, BonoboObject *object) { - Nautilus_Undo_Manager manager; - CORBA_Environment ev; + NautilusUndoContext *context; - manager = nautilus_get_undo_manager (source_object); - nautilus_attach_undo_manager - (destination_object, manager); + g_return_if_fail (NAUTILUS_IS_UNDO_MANAGER (manager)); + g_return_if_fail (BONOBO_IS_OBJECT (object)); - CORBA_exception_init (&ev); - CORBA_Object_release (manager, &ev); - CORBA_exception_free (&ev); + context = nautilus_undo_context_new (bonobo_object_corba_objref (BONOBO_OBJECT (manager))); + bonobo_object_add_interface (object, BONOBO_OBJECT (context)); } -/* Locates an undo manager for this bonobo control. - * The undo manager is supplied by an interface on - * the control frame. The put that undo manager on - * the Bonobo control's widget. - */ static void -set_up_bonobo_control (BonoboControl *control) +update_undo_menu_item (NautilusUndoManager *manager, + UndoMenuHandlerConnection *connection) { - Nautilus_Undo_Manager manager; - Bonobo_ControlFrame control_frame; CORBA_Environment ev; - Nautilus_Undo_Context undo_context; - GtkWidget *widget; - - g_assert (BONOBO_IS_CONTROL (control)); - - manager = CORBA_OBJECT_NIL; + Nautilus_Undo_MenuItem *menu_item; + g_assert (NAUTILUS_IS_UNDO_MANAGER (manager)); + g_assert (connection != NULL); + g_assert (BONOBO_IS_UI_HANDLER (connection->handler)); + g_assert (connection->path != NULL); + g_assert (connection->no_undo_menu_item_label != NULL); + g_assert (connection->no_undo_menu_item_hint != NULL); + CORBA_exception_init (&ev); - /* Find the undo manager. */ - control_frame = bonobo_control_get_control_frame (control); - if (!CORBA_Object_is_nil (control_frame, &ev)) { - undo_context = Bonobo_Control_query_interface - (control_frame, "IDL:Nautilus/Undo/Context:1.0", &ev); - if (!CORBA_Object_is_nil (undo_context, &ev)) { - manager = Nautilus_Undo_Context__get_undo_manager (undo_context, &ev); - } - CORBA_Object_release (undo_context, &ev); + if (manager->details->undo_list == NULL) { + menu_item = NULL; + } else { + menu_item = Nautilus_Undo_Transaction__get_undo_menu_item + (g_list_last (manager->details->undo_list)->data, &ev); } - CORBA_Object_release (control_frame, &ev); - - /* Attach the undo manager to the widget, or detach the old one. */ - widget = bonobo_control_get_widget (control); - nautilus_attach_undo_manager (GTK_OBJECT (widget), manager); - CORBA_Object_release (manager, &ev); - + + bonobo_ui_handler_menu_set_sensitivity + (connection->handler, connection->path, + menu_item != NULL); + bonobo_ui_handler_menu_set_label + (connection->handler, connection->path, + menu_item == NULL + ? connection->no_undo_menu_item_label + : menu_item->label); + bonobo_ui_handler_menu_set_hint + (connection->handler, connection->path, + menu_item == NULL + ? connection->no_undo_menu_item_hint + : menu_item->hint); + + CORBA_free (menu_item); + CORBA_exception_free (&ev); } -void -nautilus_undo_set_up_bonobo_control (BonoboControl *control) +static void +undo_menu_handler_connection_free (UndoMenuHandlerConnection *connection) { - g_return_if_fail (BONOBO_IS_CONTROL (control)); - - set_up_bonobo_control (control); - gtk_signal_connect (GTK_OBJECT (control), "set_frame", - GTK_SIGNAL_FUNC (set_up_bonobo_control), NULL); + g_assert (connection != NULL); + g_assert (BONOBO_IS_UI_HANDLER (connection->handler)); + g_assert (connection->path != NULL); + g_assert (connection->no_undo_menu_item_label != NULL); + g_assert (connection->no_undo_menu_item_hint != NULL); + + g_free (connection->path); + g_free (connection->no_undo_menu_item_label); + g_free (connection->no_undo_menu_item_hint); + g_free (connection); } - -void -nautilus_undo_manager_stash_global_undo (Nautilus_Undo_Manager undo_manager) +static void +undo_menu_handler_connection_free_cover (gpointer data) { - global_undo_manager = undo_manager; + undo_menu_handler_connection_free (data); } -Nautilus_Undo_Manager -nautilus_undo_manager_get_global_undo (void) +void +nautilus_undo_manager_set_up_bonobo_ui_handler_undo_item (NautilusUndoManager *manager, + BonoboUIHandler *handler, + const char *path, + const char *no_undo_menu_item_label, + const char *no_undo_menu_item_hint) { - return global_undo_manager; + UndoMenuHandlerConnection *connection; + + connection = g_new (UndoMenuHandlerConnection, 1); + connection->handler = handler; + connection->path = g_strdup (path); + connection->no_undo_menu_item_label = g_strdup (no_undo_menu_item_label); + connection->no_undo_menu_item_hint = g_strdup (no_undo_menu_item_hint); + + /* Set initial state of menu item. */ + update_undo_menu_item (manager, connection); + + /* Update it again whenever the changed signal is emitted. */ + nautilus_gtk_signal_connect_full_while_alive + (GTK_OBJECT (manager), "changed", + GTK_SIGNAL_FUNC (update_undo_menu_item), NULL, + connection, undo_menu_handler_connection_free_cover, + FALSE, FALSE, + GTK_OBJECT (handler)); } - - diff --git a/libnautilus-extensions/nautilus-undo-manager.h b/libnautilus-extensions/nautilus-undo-manager.h index 668733d1b..0e5deccb9 100644 --- a/libnautilus-extensions/nautilus-undo-manager.h +++ b/libnautilus-extensions/nautilus-undo-manager.h @@ -1,6 +1,7 @@ /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ /* NautilusUndoManager - Manages undo and redo transactions. + * This is the public interface used by the application. * * Copyright (C) 2000 Eazel, Inc. * @@ -25,10 +26,7 @@ #ifndef NAUTILUS_UNDO_MANAGER_H #define NAUTILUS_UNDO_MANAGER_H -#include <bonobo/bonobo-control.h> - -#include "nautilus-undo-transaction.h" -#include "nautilus-undo.h" +#include <bonobo/bonobo-ui-handler.h> #define NAUTILUS_TYPE_UNDO_MANAGER \ (nautilus_undo_manager_get_type ()) @@ -41,46 +39,36 @@ #define NAUTILUS_IS_UNDO_MANAGER_CLASS(klass) \ (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_UNDO_MANAGER)) -typedef struct NautilusUndoManagerClass NautilusUndoManagerClass; typedef struct NautilusUndoManagerDetails NautilusUndoManagerDetails; -struct NautilusUndoManager { +typedef struct { BonoboObject parent; NautilusUndoManagerDetails *details; -}; - -struct NautilusUndoManagerClass { - BonoboObjectClass parent_class; - void (* undo_transaction_occurred) (GtkObject *object, gpointer data); - gpointer servant_init_func, servant_destroy_func, vepv; -}; - - -/* GtkObject */ -GtkType nautilus_undo_manager_get_type (void); -NautilusUndoManager *nautilus_undo_manager_new (void); - -/* Prototypes */ -gboolean nautilus_undo_manager_can_undo (NautilusUndoManager *manager); -gboolean nautilus_undo_manager_can_redo (NautilusUndoManager *manager); -void nautilus_undo_manager_enable_redo (NautilusUndoManager *manager, - gboolean value); -void nautilus_undo_manager_set_queue_depth (NautilusUndoManager *manager, - gint depth); - -void nautilus_attach_undo_manager (GtkObject *object, - Nautilus_Undo_Manager manager); -void nautilus_share_undo_manager (GtkObject *destination_object, - GtkObject *source_object); -void nautilus_undo_set_up_bonobo_control (BonoboControl *control); -Nautilus_Undo_Manager nautilus_get_undo_manager (GtkObject *start_object); - -void nautilus_undo_manager_stash_global_undo (Nautilus_Undo_Manager undo_manager); -Nautilus_Undo_Manager nautilus_undo_manager_get_global_undo (void); - - -Nautilus_Undo_Transaction nautilus_undo_manager_get_current_undo_transaction (NautilusUndoManager *manager); - - - -#endif +} NautilusUndoManager; + +typedef struct { + BonoboObjectClass parent_slot; + void (* changed) (GtkObject *object, gpointer data); +} NautilusUndoManagerClass; + +GtkType nautilus_undo_manager_get_type (void); +NautilusUndoManager *nautilus_undo_manager_new (void); + +/* Undo operations. */ +void nautilus_undo_manager_undo (NautilusUndoManager *undo_manager); + +/* Connect the manager to a particular menu item. */ +void nautilus_undo_manager_set_up_bonobo_ui_handler_undo_item (NautilusUndoManager *manager, + BonoboUIHandler *handler, + const char *path, + const char *no_undo_menu_item_label, + const char *no_undo_menu_item_hint); + +/* Attach the undo manager to a Gtk object so that object and the widgets inside it can participate in undo. */ +void nautilus_undo_manager_attach (NautilusUndoManager *manager, + GtkObject *object); +/* Attach the undo manager to a Bonobo object so another component can find it. */ +void nautilus_undo_manager_add_interface (NautilusUndoManager *manager, + BonoboObject *object); + +#endif /* NAUTILUS_UNDO_MANAGER_H */ diff --git a/libnautilus-private/Makefile.am b/libnautilus-private/Makefile.am index bb164bb86..ca4fd36af 100644 --- a/libnautilus-private/Makefile.am +++ b/libnautilus-private/Makefile.am @@ -72,6 +72,7 @@ libnautilus_extensionsinclude_HEADERS= \ nautilus-self-checks.h \ nautilus-string-list.h \ nautilus-string.h \ + nautilus-undo-manager.h \ nautilus-view-identifier.h \ nautilus-xml-extensions.h \ $(NULL) @@ -82,6 +83,7 @@ libnautilus_extensions_la_SOURCES = \ nautilus-directory-private.h \ nautilus-directory-metafile.h \ nautilus-lib-self-check-functions.h \ + nautilus-undo-context.h \ bonobo-stream-vfs.c \ nautilus-background-canvas-group.c \ nautilus-background.c \ @@ -127,6 +129,8 @@ libnautilus_extensions_la_SOURCES = \ nautilus-self-checks.c \ nautilus-string-list.c \ nautilus-string.c \ + nautilus-undo-context.c \ + nautilus-undo-manager.c \ nautilus-view-identifier.c \ nautilus-xml-extensions.c \ $(NULL) diff --git a/libnautilus-private/nautilus-entry.c b/libnautilus-private/nautilus-entry.c index de670401c..7540af06f 100644 --- a/libnautilus-private/nautilus-entry.c +++ b/libnautilus-private/nautilus-entry.c @@ -36,8 +36,6 @@ #include <libgnome/gnome-defs.h> #include <libgnome/gnome-i18n.h> -#include <libnautilus/nautilus-undo-manager.h> -#include <libnautilus/nautilus-undoable.h> #include <libnautilus/nautilus-undo.h> #include <orb/orbit.h> diff --git a/libnautilus-private/nautilus-gtk-extensions.c b/libnautilus-private/nautilus-gtk-extensions.c index 3a8d7c001..6311cea26 100644 --- a/libnautilus-private/nautilus-gtk-extensions.c +++ b/libnautilus-private/nautilus-gtk-extensions.c @@ -663,3 +663,84 @@ nautilus_gtk_widget_set_font_by_name (GtkWidget *widget, const char *font_name) nautilus_gtk_widget_set_font (widget, font); gdk_font_unref (font); } + +/* This stuff is stolen from Gtk. */ + +typedef struct DisconnectInfo { + GtkObject *object1; + guint disconnect_handler1; + guint signal_handler; + GtkObject *object2; + guint disconnect_handler2; +} DisconnectInfo; + +static guint +alive_disconnecter (GtkObject *object, DisconnectInfo *info) +{ + g_assert (info != NULL); + g_assert (GTK_IS_OBJECT (info->object1)); + g_assert (info->disconnect_handler1 != 0); + g_assert (info->signal_handler != 0); + g_assert (GTK_IS_OBJECT (info->object2)); + g_assert (info->disconnect_handler2 != 0); + g_assert (object == info->object1 || object == info->object2); + + gtk_signal_disconnect (info->object1, info->disconnect_handler1); + gtk_signal_disconnect (info->object1, info->signal_handler); + gtk_signal_disconnect (info->object2, info->disconnect_handler2); + + g_free (info); + + return 0; +} + +/** + * nautilus_gtk_signal_connect_full_while_alive + * + * Like gtk_signal_connect_while_alive, but works with full parameters. + **/ +void +nautilus_gtk_signal_connect_full_while_alive (GtkObject *object, + const gchar *name, + GtkSignalFunc func, + GtkCallbackMarshal marshal, + gpointer data, + GtkDestroyNotify destroy_func, + gboolean object_signal, + gboolean after, + GtkObject *alive_object) +{ + DisconnectInfo *info; + + g_return_if_fail (GTK_IS_OBJECT (object)); + g_return_if_fail (name != NULL); + g_return_if_fail (func != NULL); + g_return_if_fail (object_signal == FALSE || object_signal == TRUE); + g_return_if_fail (after == FALSE || after == TRUE); + g_return_if_fail (GTK_IS_OBJECT (alive_object)); + + info = g_new (DisconnectInfo, 1); + info->object1 = object; + info->object2 = alive_object; + + info->signal_handler = + gtk_signal_connect_full (object, + name, + func, + marshal, + data, + destroy_func, + object_signal, + after); + + info->disconnect_handler1 = + gtk_signal_connect (object, + "destroy", + GTK_SIGNAL_FUNC (alive_disconnecter), + info); + info->disconnect_handler2 = + gtk_signal_connect (alive_object, + "destroy", + GTK_SIGNAL_FUNC (alive_disconnecter), + info); +} diff --git a/libnautilus-private/nautilus-gtk-extensions.h b/libnautilus-private/nautilus-gtk-extensions.h index 9f7cf2418..e5a5bda23 100644 --- a/libnautilus-private/nautilus-gtk-extensions.h +++ b/libnautilus-private/nautilus-gtk-extensions.h @@ -34,56 +34,64 @@ #define NAUTILUS_DEFAULT_POPUP_MENU_DISPLACEMENT 2 /* GtkCList */ -int nautilus_gtk_clist_get_first_selected_row (GtkCList *list); -int nautilus_gtk_clist_get_last_selected_row (GtkCList *list); +int nautilus_gtk_clist_get_first_selected_row (GtkCList *list); +int nautilus_gtk_clist_get_last_selected_row (GtkCList *list); /* signals */ -guint nautilus_gtk_signal_connect_free_data (GtkObject *object, - const gchar *name, - GtkSignalFunc func, - gpointer data); - +guint nautilus_gtk_signal_connect_free_data (GtkObject *object, + const gchar *name, + GtkSignalFunc func, + gpointer data); guint nautilus_gtk_signal_connect_free_data_custom (GtkObject *object, - const gchar *name, - GtkSignalFunc func, - gpointer data, - GtkDestroyNotify destroy_func); + const gchar *name, + GtkSignalFunc func, + gpointer data, + GtkDestroyNotify destroy_func); +void nautilus_gtk_signal_connect_full_while_alive (GtkObject *object, + const gchar *name, + GtkSignalFunc func, + GtkCallbackMarshal marshal, + gpointer data, + GtkDestroyNotify destroy_func, + gboolean object_signal, + gboolean after, + GtkObject *alive_object); /* list of GtkObject */ -GList * nautilus_gtk_object_list_ref (GList *list); -void nautilus_gtk_object_list_unref (GList *list); -void nautilus_gtk_object_list_free (GList *list); -GList * nautilus_gtk_object_list_copy (GList *list); +GList * nautilus_gtk_object_list_ref (GList *list); +void nautilus_gtk_object_list_unref (GList *list); +void nautilus_gtk_object_list_free (GList *list); +GList * nautilus_gtk_object_list_copy (GList *list); /* GtkWidget */ -gboolean nautilus_point_in_allocation (const GtkAllocation *allocation, - int x, - int y); -void nautilus_gtk_widget_set_font (GtkWidget *widget, - GdkFont *font); -void nautilus_gtk_widget_set_font_by_name (GtkWidget *widget, - const char *font_name); -gboolean nautilus_point_in_widget (GtkWidget *widget, - int x, - int y); +gboolean nautilus_point_in_allocation (const GtkAllocation *allocation, + int x, + int y); +void nautilus_gtk_widget_set_font (GtkWidget *widget, + GdkFont *font); +void nautilus_gtk_widget_set_font_by_name (GtkWidget *widget, + const char *font_name); +gboolean nautilus_point_in_widget (GtkWidget *widget, + int x, + int y); /* GtkWindow */ -void nautilus_gtk_window_present (GtkWindow *window); +void nautilus_gtk_window_present (GtkWindow *window); /* selection data */ -GtkSelectionData *nautilus_gtk_selection_data_copy_deep (const GtkSelectionData *selection_data); -void nautilus_gtk_selection_data_free_deep (GtkSelectionData *selection_data); +GtkSelectionData *nautilus_gtk_selection_data_copy_deep (const GtkSelectionData *selection_data); +void nautilus_gtk_selection_data_free_deep (GtkSelectionData *selection_data); /* GtkMenu */ -void nautilus_pop_up_context_menu (GtkMenu *menu, - gint16 offset_x, - gint16 offset_y); +void nautilus_pop_up_context_menu (GtkMenu *menu, + gint16 offset_x, + gint16 offset_y); /* GtkStyle */ -void nautilus_gtk_style_set_font (GtkStyle *style, - GdkFont *font); -void nautilus_gtk_style_set_font_by_name (GtkStyle *style, - const char *font_name); +void nautilus_gtk_style_set_font (GtkStyle *style, + GdkFont *font); +void nautilus_gtk_style_set_font_by_name (GtkStyle *style, + const char *font_name); /* marshals */ diff --git a/libnautilus-private/nautilus-icon-text-item.c b/libnautilus-private/nautilus-icon-text-item.c index 8e35d5ee3..b5886ea39 100644 --- a/libnautilus-private/nautilus-icon-text-item.c +++ b/libnautilus-private/nautilus-icon-text-item.c @@ -14,7 +14,7 @@ #include "nautilus-icon-text-item.h" #include "nautilus-entry.h" -#include <libnautilus/nautilus-undoable.h> +#include <libnautilus/nautilus-undo.h> #include <math.h> #include <stdio.h> diff --git a/libnautilus-private/nautilus-preferences.c b/libnautilus-private/nautilus-preferences.c index 19974216d..b3ddf019c 100644 --- a/libnautilus-private/nautilus-preferences.c +++ b/libnautilus-private/nautilus-preferences.c @@ -93,13 +93,13 @@ static void preferences_hash_node_check_changes_func ( /* PreferencesCallbackNode functions */ -static PreferencesCallbackNode *preferneces_callback_node_alloc (NautilusPreferencesCallback callback_proc, +static PreferencesCallbackNode *preferences_callback_node_alloc (NautilusPreferencesCallback callback_proc, gpointer callback_data, const PreferencesHashNode *hash_node); -static void preferneces_callback_node_free (PreferencesCallbackNode *node); -static void preferneces_callback_node_free_func (gpointer data, +static void preferences_callback_node_free (PreferencesCallbackNode *node); +static void preferences_callback_node_free_func (gpointer data, gpointer callback_data); -static void preferneces_callback_node_invoke_func (gpointer data, +static void preferences_callback_node_invoke_func (gpointer data, gpointer callback_data); static void preferences_hash_node_add_callback (PreferencesHashNode *node, NautilusPreferencesCallback callback_proc, @@ -177,7 +177,7 @@ preferences_hash_node_free (PreferencesHashNode *node) } nautilus_g_list_free_deep_custom (node->callback_list, - preferneces_callback_node_free_func, + preferences_callback_node_free_func, NULL); node->callback_list = NULL; @@ -201,21 +201,21 @@ preferences_hash_node_add_callback (PreferencesHashNode *node, NautilusPreferencesCallback callback_proc, gpointer callback_data) { - PreferencesCallbackNode *preferneces_callback_node; + PreferencesCallbackNode *preferences_callback_node; guint i; g_assert (node != NULL); g_assert (callback_proc != NULL); - preferneces_callback_node = preferneces_callback_node_alloc (callback_proc, + preferences_callback_node = preferences_callback_node_alloc (callback_proc, callback_data, node); - g_assert (preferneces_callback_node != NULL); + g_assert (preferences_callback_node != NULL); node->callback_list = g_list_append (node->callback_list, - (gpointer) preferneces_callback_node); + (gpointer) preferences_callback_node); /* * We install only one gconf notification for each preference node. @@ -279,7 +279,7 @@ preferences_hash_node_remove_callback (PreferencesHashNode *node, node->callback_list = g_list_remove (node->callback_list, (gpointer) callback_info); - preferneces_callback_node_free (callback_info); + preferences_callback_node_free (callback_info); } } @@ -345,14 +345,14 @@ preferences_hash_node_check_changes_func (gpointer key, /* Invoke callbacks for this node */ if (node->callback_list) { g_list_foreach (node->callback_list, - preferneces_callback_node_invoke_func, + preferences_callback_node_invoke_func, (gpointer) NULL); } } } /** - * preferneces_callback_node_alloc + * preferences_callback_node_alloc * * Allocate a callback info struct from the given values. PreferencesCallbackNode * structures are used as nodes for the callbac_list member of pref hash table @@ -364,7 +364,7 @@ preferences_hash_node_check_changes_func (gpointer key, * Return value: A newly allocated node. **/ static PreferencesCallbackNode * -preferneces_callback_node_alloc (NautilusPreferencesCallback callback_proc, +preferences_callback_node_alloc (NautilusPreferencesCallback callback_proc, gpointer callback_data, const PreferencesHashNode *hash_node) { @@ -382,13 +382,13 @@ preferneces_callback_node_alloc (NautilusPreferencesCallback callback_proc, } /** - * preferneces_callback_node_free + * preferences_callback_node_free * * Free a callback info struct. - * @preferneces_callback_node: The struct to free. + * @preferences_callback_node: The struct to free. **/ static void -preferneces_callback_node_free (PreferencesCallbackNode *callback_node) +preferences_callback_node_free (PreferencesCallbackNode *callback_node) { g_assert (callback_node != NULL); @@ -399,7 +399,7 @@ preferneces_callback_node_free (PreferencesCallbackNode *callback_node) } /** - * preferneces_callback_node_free_func + * preferences_callback_node_free_func * * A function that frees a callback info struct. It is meant to be fed to * g_list_foreach () @@ -407,16 +407,16 @@ preferneces_callback_node_free (PreferencesCallbackNode *callback_node) * @callback_data: The callback_data privately maintained by the GList. **/ static void -preferneces_callback_node_free_func (gpointer data, +preferences_callback_node_free_func (gpointer data, gpointer callback_data) { g_assert (data != NULL); - preferneces_callback_node_free ((PreferencesCallbackNode *) data); + preferences_callback_node_free ((PreferencesCallbackNode *) data); } /** - * preferneces_callback_node_invoke_func + * preferences_callback_node_invoke_func * * A function that invokes a callback from the given struct. It is meant to be fed to * g_list_foreach () @@ -424,7 +424,7 @@ preferneces_callback_node_free_func (gpointer data, * @callback_data: The callback_data privately maintained by the GList. **/ static void -preferneces_callback_node_invoke_func (gpointer data, +preferences_callback_node_invoke_func (gpointer data, gpointer callback_data) { PreferencesCallbackNode *callback_node; @@ -562,7 +562,7 @@ preferences_gconf_callback (GConfClient *client, /* Invoke callbacks for this node */ if (node->callback_list) { g_list_foreach (node->callback_list, - preferneces_callback_node_invoke_func, + preferences_callback_node_invoke_func, (gpointer) NULL); } diff --git a/libnautilus-private/nautilus-undo-context.c b/libnautilus-private/nautilus-undo-context.c index ee5153e8c..f64639e59 100644 --- a/libnautilus-private/nautilus-undo-context.c +++ b/libnautilus-private/nautilus-undo-context.c @@ -1,6 +1,7 @@ /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* NautilusUndoContext +/* NautilusUndoContext - Used internally by undo machinery. + * Not public. * * Copyright (C) 2000 Eazel, Inc. * @@ -23,16 +24,11 @@ */ #include <config.h> +#include "nautilus-undo-context.h" + +#include "nautilus-gtk-macros.h" #include <gtk/gtksignal.h> -#include <gtk/gtkmain.h> #include <bonobo/bonobo-main.h> -#include <bonobo/bonobo-object.h> -#include <bonobo/bonobo-control.h> -#include <libnautilus-extensions/nautilus-gtk-macros.h> - -#include "nautilus-undo.h" - -#include "nautilus-undo-context.h" typedef struct { POA_Nautilus_Undo_Context servant; @@ -57,7 +53,7 @@ POA_Nautilus_Undo_Context__epv libnautilus_Nautilus_Undo_Context_epv = }; static PortableServer_ServantBase__epv base_epv; -static POA_Nautilus_Undo_Context__vepv impl_Nautilus_Undo_Context_vepv = +static POA_Nautilus_Undo_Context__vepv vepv = { &base_epv, NULL, @@ -65,54 +61,42 @@ static POA_Nautilus_Undo_Context__vepv impl_Nautilus_Undo_Context_vepv = }; static void -impl_Nautilus_Undo_Context__destroy (BonoboObject *obj, impl_POA_Nautilus_Undo_Context *servant) +impl_Nautilus_Undo_Context__destroy (BonoboObject *object, + PortableServer_Servant servant) { - PortableServer_ObjectId *objid; + PortableServer_ObjectId *object_id; CORBA_Environment ev; - void (*servant_destroy_func) (PortableServer_Servant servant, CORBA_Environment *ev); CORBA_exception_init (&ev); - servant_destroy_func = NAUTILUS_UNDO_CONTEXT_CLASS - (GTK_OBJECT (servant->bonobo_object)->klass)->servant_destroy_func; - objid = PortableServer_POA_servant_to_id (bonobo_poa (), servant, &ev); - PortableServer_POA_deactivate_object (bonobo_poa (), objid, &ev); - CORBA_free (objid); - obj->servant = NULL; - - (* servant_destroy_func) ((PortableServer_Servant) servant, &ev); + object_id = PortableServer_POA_servant_to_id (bonobo_poa (), servant, &ev); + PortableServer_POA_deactivate_object (bonobo_poa (), object_id, &ev); + CORBA_free (object_id); + object->servant = NULL; + POA_Nautilus_Undo_Context__fini (servant, &ev); g_free (servant); + CORBA_exception_free (&ev); } static Nautilus_Undo_Context -impl_Nautilus_Undo_Context__create (NautilusUndoContext *context, CORBA_Environment * ev) +impl_Nautilus_Undo_Context__create (NautilusUndoContext *bonobo_object, + CORBA_Environment *ev) { - Nautilus_Undo_Context retval; impl_POA_Nautilus_Undo_Context *servant; - void (*servant_init_func) (PortableServer_Servant servant, CORBA_Environment *ev); - NautilusUndoContextClass *context_class; - context_class = NAUTILUS_UNDO_CONTEXT_CLASS (GTK_OBJECT (context)->klass); - - servant_init_func = context_class->servant_init_func; servant = g_new0 (impl_POA_Nautilus_Undo_Context, 1); - servant->servant.vepv = context_class->vepv; - if (servant->servant.vepv->Bonobo_Unknown_epv == NULL) { - servant->servant.vepv->Bonobo_Unknown_epv = bonobo_object_get_epv (); - } - (* servant_init_func) ((PortableServer_Servant) servant, ev); - - servant->bonobo_object = context; + servant->servant.vepv = &vepv; + vepv.Bonobo_Unknown_epv = bonobo_object_get_epv (); + POA_Nautilus_Undo_Context__init ((PortableServer_Servant) servant, ev); - retval = bonobo_object_activate_servant (BONOBO_OBJECT (context), servant); - - gtk_signal_connect (GTK_OBJECT (context), "destroy", + gtk_signal_connect (GTK_OBJECT (bonobo_object), "destroy", GTK_SIGNAL_FUNC (impl_Nautilus_Undo_Context__destroy), servant); - return retval; + servant->bonobo_object = bonobo_object; + return bonobo_object_activate_servant (BONOBO_OBJECT (bonobo_object), servant); } static Nautilus_Undo_Manager @@ -122,23 +106,26 @@ impl_Nautilus_Undo_Context__get_undo_manager (PortableServer_Servant servant, NautilusUndoContext *context; context = ((impl_POA_Nautilus_Undo_Context *) servant)->bonobo_object; - g_assert (NAUTILUS_IS_UNDO_CONTEXT (context)); return CORBA_Object_duplicate (context->undo_manager, ev); } -/* nautilus_undo_manager_new */ NautilusUndoContext * nautilus_undo_context_new (Nautilus_Undo_Manager undo_manager) { + CORBA_Environment ev; NautilusUndoContext *context; + CORBA_exception_init (&ev); + context = gtk_type_new (nautilus_undo_context_get_type ()); - context->undo_manager = undo_manager; + context->undo_manager = CORBA_Object_duplicate (undo_manager, &ev); + + CORBA_exception_free (&ev); + return context; } -/* Object initialization function for the NautilusUndoContext */ static void nautilus_undo_context_initialize (NautilusUndoContext *context) { @@ -152,28 +139,24 @@ nautilus_undo_context_initialize (NautilusUndoContext *context) CORBA_exception_free (&ev); } -/* Class initialization function for the NautilusUndoManager. */ static void -nautilus_undo_context_initialize_class (NautilusUndoContextClass *klass) +destroy (GtkObject *object) { - GtkObjectClass *object_class; - - object_class = GTK_OBJECT_CLASS (klass); + CORBA_Environment ev; + NautilusUndoContext *context; - object_class->destroy = destroy; + CORBA_exception_init (&ev); - klass->servant_init_func = POA_Nautilus_Undo_Context__init; - klass->servant_destroy_func = POA_Nautilus_Undo_Context__fini; - klass->vepv = &impl_Nautilus_Undo_Context_vepv; + context = NAUTILUS_UNDO_CONTEXT (object); + CORBA_Object_release (context->undo_manager, &ev); + + CORBA_exception_free (&ev); + + NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object)); } -/* destroy */ static void -destroy (GtkObject *object) +nautilus_undo_context_initialize_class (NautilusUndoContextClass *klass) { - NautilusUndoContext *context; - - context = NAUTILUS_UNDO_CONTEXT (object); - - NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object)); + GTK_OBJECT_CLASS (klass)->destroy = destroy; } diff --git a/libnautilus-private/nautilus-undo-context.h b/libnautilus-private/nautilus-undo-context.h index bb4bdf2cd..2559f764e 100644 --- a/libnautilus-private/nautilus-undo-context.h +++ b/libnautilus-private/nautilus-undo-context.h @@ -1,6 +1,7 @@ /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* NautilusUndoContext +/* NautilusUndoContext - Used internally by undo machinery. + * Not public. * * Copyright (C) 2000 Eazel, Inc. * @@ -25,7 +26,8 @@ #ifndef NAUTILUS_UNDO_CONTEXT_H #define NAUTILUS_UNDO_CONTEXT_H -#include "nautilus-undo.h" +#include <bonobo/bonobo-object.h> +#include <libnautilus/nautilus-distributed-undo.h> #define NAUTILUS_TYPE_UNDO_CONTEXT \ (nautilus_undo_context_get_type ()) @@ -38,25 +40,16 @@ #define NAUTILUS_IS_UNDO_CONTEXT_CLASS(klass) \ (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_UNDO_CONTEXT)) -typedef struct NautilusUndoContext NautilusUndoContext; -typedef struct NautilusUndoContextClass NautilusUndoContextClass; - -struct NautilusUndoContext { - BonoboObject parent; +typedef struct { + BonoboObject parent_slot; Nautilus_Undo_Manager undo_manager; -}; - -struct NautilusUndoContextClass { - BonoboObjectClass parent_class; - gpointer servant_init_func, servant_destroy_func, vepv; -}; - - -/* GtkObject */ -GtkType nautilus_undo_context_get_type (void); -NautilusUndoContext *nautilus_undo_context_new (Nautilus_Undo_Manager undo_manager); +} NautilusUndoContext; -/* Prototypes */ +typedef struct { + BonoboObjectClass parent_slot; +} NautilusUndoContextClass; +GtkType nautilus_undo_context_get_type (void); +NautilusUndoContext *nautilus_undo_context_new (Nautilus_Undo_Manager undo_manager); #endif /* NAUTILUS_UNDO_CONTEXT_H */ diff --git a/libnautilus-private/nautilus-undo-manager.c b/libnautilus-private/nautilus-undo-manager.c index 15af401ff..28946d900 100644 --- a/libnautilus-private/nautilus-undo-manager.c +++ b/libnautilus-private/nautilus-undo-manager.c @@ -25,25 +25,22 @@ #include <config.h> #include "nautilus-undo-manager.h" +#include <libnautilus-extensions/nautilus-gtk-macros.h> +#include <libnautilus-extensions/nautilus-gtk-extensions.h> #include <gtk/gtksignal.h> -#include <gtk/gtkmain.h> -#include <glib.h> -#include <string.h> #include <bonobo/bonobo-main.h> -#include <bonobo/bonobo-control.h> - -#include "nautilus-undo-manager-private.h" - -#include <libnautilus-extensions/nautilus-gnome-extensions.h> -#include <libnautilus-extensions/nautilus-gtk-extensions.h> -#include <libnautilus-extensions/nautilus-gtk-macros.h> - - -/* Gloabl instance of undo manager */ -Nautilus_Undo_Manager global_undo_manager; +#include <libnautilus/nautilus-undo-private.h> +#include "nautilus-undo-context.h" + +struct NautilusUndoManagerDetails { + GList *undo_list; + GList *redo_list; + gboolean enable_redo; + gint queue_depth; +}; enum { - UNDO_TRANSACTION_OCCURRED, + CHANGED, LAST_SIGNAL }; static guint signals[LAST_SIGNAL]; @@ -53,40 +50,45 @@ typedef struct { NautilusUndoManager *bonobo_object; } impl_POA_Nautilus_Undo_Manager; +typedef struct { + BonoboUIHandler *handler; + char *path; + char *no_undo_menu_item_label; + char *no_undo_menu_item_hint; +} UndoMenuHandlerConnection; + /* GtkObject */ -static void nautilus_undo_manager_initialize_class (NautilusUndoManagerClass *class); -static void nautilus_undo_manager_initialize (NautilusUndoManager *item); -static void destroy (GtkObject *object); -static void free_undo_manager_list (GList *list); -static GList *prune_undo_manager_list (GList *list, - int items); +static void nautilus_undo_manager_initialize_class (NautilusUndoManagerClass *class); +static void nautilus_undo_manager_initialize (NautilusUndoManager *item); +static void destroy (GtkObject *object); +static void free_undo_manager_list (GList *list); +static GList *prune_undo_manager_list (GList *list, + int items); /* CORBA/Bonobo */ -static void impl_Nautilus_Undo_Manager__append (PortableServer_Servant servant, - const Nautilus_Undo_Transaction transaction, - CORBA_Environment *ev); -static void impl_Nautilus_Undo_Manager__forget (PortableServer_Servant servant, - const Nautilus_Undo_Transaction transaction, - CORBA_Environment *ev); -static void impl_Nautilus_Undo_Manager__undo (PortableServer_Servant servant, - CORBA_Environment *ev); -static void nautilus_undo_manager_add_transaction (NautilusUndoManager *manager, - Nautilus_Undo_Transaction transaction); -static void nautilus_undo_manager_forget_transaction (NautilusUndoManager *manager, - Nautilus_Undo_Transaction transaction); -static void nautilus_undo_manager_undo (NautilusUndoManager *manager); +static void impl_Nautilus_Undo_Manager__append (PortableServer_Servant servant, + Nautilus_Undo_Transaction transaction, + CORBA_Environment *ev); +static void impl_Nautilus_Undo_Manager__forget (PortableServer_Servant servant, + Nautilus_Undo_Transaction transaction, + CORBA_Environment *ev); +static void impl_Nautilus_Undo_Manager__undo (PortableServer_Servant servant, + CORBA_Environment *ev); +static void nautilus_undo_manager_add_transaction (NautilusUndoManager *manager, + Nautilus_Undo_Transaction transaction); +static void nautilus_undo_manager_forget_transaction (NautilusUndoManager *manager, + Nautilus_Undo_Transaction transaction); NAUTILUS_DEFINE_CLASS_BOILERPLATE(NautilusUndoManager, nautilus_undo_manager, BONOBO_OBJECT_TYPE) -POA_Nautilus_Undo_Manager__epv libnautilus_Nautilus_Undo_Manager_epv = +static POA_Nautilus_Undo_Manager__epv libnautilus_Nautilus_Undo_Manager_epv = { - NULL, /* _private */ + NULL, &impl_Nautilus_Undo_Manager__append, &impl_Nautilus_Undo_Manager__forget, &impl_Nautilus_Undo_Manager__undo, }; - static PortableServer_ServantBase__epv base_epv; -static POA_Nautilus_Undo_Manager__vepv impl_Nautilus_Undo_Manager_vepv = +static POA_Nautilus_Undo_Manager__vepv vepv = { &base_epv, NULL, @@ -94,53 +96,48 @@ static POA_Nautilus_Undo_Manager__vepv impl_Nautilus_Undo_Manager_vepv = }; static void -impl_Nautilus_Undo_Manager__destroy (BonoboObject *obj, impl_POA_Nautilus_Undo_Manager *servant) +impl_Nautilus_Undo_Manager__destroy (BonoboObject *object, + impl_POA_Nautilus_Undo_Manager *servant) { - PortableServer_ObjectId *objid; + PortableServer_ObjectId *object_id; CORBA_Environment ev; - void (*servant_destroy_func) (PortableServer_Servant servant, CORBA_Environment *ev); CORBA_exception_init (&ev); - servant_destroy_func = NAUTILUS_UNDO_MANAGER_CLASS (GTK_OBJECT (servant->bonobo_object)->klass)->servant_destroy_func; - objid = PortableServer_POA_servant_to_id (bonobo_poa (), servant, &ev); - PortableServer_POA_deactivate_object (bonobo_poa (), objid, &ev); - CORBA_free (objid); - obj->servant = NULL; + object_id = PortableServer_POA_servant_to_id (bonobo_poa (), servant, &ev); + PortableServer_POA_deactivate_object (bonobo_poa (), object_id, &ev); + CORBA_free (object_id); + object->servant = NULL; - servant_destroy_func ((PortableServer_Servant) servant, &ev); + POA_Nautilus_Undo_Manager__fini (servant, &ev); g_free (servant); + CORBA_exception_free (&ev); } static Nautilus_Undo_Manager -impl_Nautilus_Undo_Manager__create (NautilusUndoManager *manager, CORBA_Environment * ev) +impl_Nautilus_Undo_Manager__create (NautilusUndoManager *bonobo_object, + CORBA_Environment *ev) { - Nautilus_Undo_Manager retval; impl_POA_Nautilus_Undo_Manager *servant; - void (*servant_init_func) (PortableServer_Servant servant, CORBA_Environment *ev); - NautilusUndoManagerClass *undo_class = NAUTILUS_UNDO_MANAGER_CLASS (GTK_OBJECT(manager)->klass); - - servant_init_func = undo_class->servant_init_func; servant = g_new0 (impl_POA_Nautilus_Undo_Manager, 1); - servant->servant.vepv = undo_class->vepv; - if (!servant->servant.vepv->Bonobo_Unknown_epv) - servant->servant.vepv->Bonobo_Unknown_epv = bonobo_object_get_epv (); - servant_init_func ((PortableServer_Servant) servant, ev); - - servant->bonobo_object = manager; - retval = bonobo_object_activate_servant (BONOBO_OBJECT (manager), servant); + vepv.Bonobo_Unknown_epv = bonobo_object_get_epv (); + servant->servant.vepv = &vepv; + POA_Nautilus_Undo_Manager__init ((PortableServer_Servant) servant, ev); - gtk_signal_connect (GTK_OBJECT (manager), "destroy", GTK_SIGNAL_FUNC (impl_Nautilus_Undo_Manager__destroy), servant); + gtk_signal_connect (GTK_OBJECT (bonobo_object), "destroy", + GTK_SIGNAL_FUNC (impl_Nautilus_Undo_Manager__destroy), + servant); - return retval; + servant->bonobo_object = bonobo_object; + return bonobo_object_activate_servant (BONOBO_OBJECT (bonobo_object), servant); } static void impl_Nautilus_Undo_Manager__append (PortableServer_Servant servant, - const Nautilus_Undo_Transaction undo_transaction, + Nautilus_Undo_Transaction undo_transaction, CORBA_Environment *ev) { NautilusUndoManager *manager; @@ -153,7 +150,7 @@ impl_Nautilus_Undo_Manager__append (PortableServer_Servant servant, static void impl_Nautilus_Undo_Manager__forget (PortableServer_Servant servant, - const Nautilus_Undo_Transaction transaction, + Nautilus_Undo_Transaction transaction, CORBA_Environment *ev) { NautilusUndoManager *manager; @@ -182,8 +179,7 @@ nautilus_undo_manager_new (void) return gtk_type_new (nautilus_undo_manager_get_type ()); } -/* Object initialization function for the NautilusUndoManager */ -static void +static void nautilus_undo_manager_initialize (NautilusUndoManager *manager) { CORBA_Environment ev; @@ -192,23 +188,16 @@ nautilus_undo_manager_initialize (NautilusUndoManager *manager) manager->details = g_new0 (NautilusUndoManagerDetails, 1); - /* Create empty lists */ - manager->details->undo_list = NULL; - manager->details->redo_list = NULL; - - /* Default to no redo functionality */ - manager->details->enable_redo = FALSE; - /* Set queue depth to a single level */ manager->details->queue_depth = 1; - bonobo_object_construct (BONOBO_OBJECT (manager), impl_Nautilus_Undo_Manager__create (manager, &ev)); + bonobo_object_construct (BONOBO_OBJECT (manager), + impl_Nautilus_Undo_Manager__create (manager, &ev)); CORBA_exception_free (&ev); } -/* Class initialization function for the NautilusUndoManager. */ static void nautilus_undo_manager_initialize_class (NautilusUndoManagerClass *klass) { @@ -218,24 +207,19 @@ nautilus_undo_manager_initialize_class (NautilusUndoManagerClass *klass) object_class->destroy = destroy; - klass->servant_init_func = POA_Nautilus_Undo_Manager__init; - klass->servant_destroy_func = POA_Nautilus_Undo_Manager__fini; - klass->vepv = &impl_Nautilus_Undo_Manager_vepv; - - /* Setup signals */ - signals[UNDO_TRANSACTION_OCCURRED] - = gtk_signal_new ("undo_transaction_occurred", + signals[CHANGED] + = gtk_signal_new ("changed", GTK_RUN_LAST, object_class->type, GTK_SIGNAL_OFFSET (NautilusUndoManagerClass, - undo_transaction_occurred), + changed), gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0); gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL); } -static void +void nautilus_undo_manager_undo (NautilusUndoManager *manager) { GList *last_in_list; @@ -246,7 +230,6 @@ nautilus_undo_manager_undo (NautilusUndoManager *manager) /* Verify we have a transaction to be undone */ if (manager->details->undo_list == NULL) { - g_warning ("NautilusUndoManager has no transaction to be undone."); return; } @@ -269,8 +252,7 @@ nautilus_undo_manager_undo (NautilusUndoManager *manager) } /* Fire off signal informing that an undo transaction has occurred */ - gtk_signal_emit (GTK_OBJECT (manager), - signals[UNDO_TRANSACTION_OCCURRED]); + gtk_signal_emit (GTK_OBJECT (manager), signals[CHANGED]); CORBA_exception_free (&ev); } @@ -342,8 +324,7 @@ nautilus_undo_manager_add_transaction (NautilusUndoManager *manager, manager->details->undo_list = g_list_append (manager->details->undo_list, duplicate_transaction); /* Fire off signal informing that an undo transaction has occurred */ - gtk_signal_emit (GTK_OBJECT (manager), - signals[UNDO_TRANSACTION_OCCURRED]); + gtk_signal_emit (GTK_OBJECT (manager), signals[CHANGED]); CORBA_exception_free (&ev); } @@ -392,39 +373,13 @@ nautilus_undo_manager_forget_transaction (NautilusUndoManager *manager, if (success) { /* Fire off signal informing that a transaction has occurred */ - gtk_signal_emit (GTK_OBJECT (manager), - signals[UNDO_TRANSACTION_OCCURRED]); + gtk_signal_emit (GTK_OBJECT (manager), signals[CHANGED]); } CORBA_exception_free (&ev); } - -Nautilus_Undo_Transaction -nautilus_undo_manager_get_current_undo_transaction (NautilusUndoManager *manager) -{ - GList *last_in_list; - CORBA_Object undo_transaction; - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - /* Verify we have a transaction to be undone */ - if (manager->details->undo_list == NULL) { - g_warning ("NautilusUndoManager has no undo transaction in the queue."); - return NULL; - } - - /* Pop last transaction off undo list */ - last_in_list = g_list_last (manager->details->undo_list); - g_assert (last_in_list != NULL); - undo_transaction = last_in_list->data; - - return undo_transaction; - - CORBA_exception_free (&ev); -} - +#if 0 gboolean nautilus_undo_manager_can_undo (NautilusUndoManager *manager) @@ -441,6 +396,8 @@ nautilus_undo_manager_can_redo (NautilusUndoManager *manager) && manager->details->redo_list != NULL; } +#endif + static void destroy (GtkObject *object) { @@ -455,6 +412,8 @@ destroy (GtkObject *object) NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object)); } +#if 0 + /* nautilus_undo_manager_enable_redo * * Enable or disable redo functionality @@ -495,10 +454,11 @@ nautilus_undo_manager_set_queue_depth (NautilusUndoManager *manager, int depth) } /* Fire off signal informing that an undo transaction has occurred */ - gtk_signal_emit (GTK_OBJECT (manager), - signals[UNDO_TRANSACTION_OCCURRED]); + gtk_signal_emit (GTK_OBJECT (manager), signals[CHANGED]); } +#endif + /* free_undo_manager_list * * Clear undo data from list @@ -546,174 +506,115 @@ prune_undo_manager_list (GList *list, int items) return list; } -Nautilus_Undo_Manager -nautilus_get_undo_manager (GtkObject *start_object) -{ - Nautilus_Undo_Manager manager; - GtkWidget *parent; - GtkWindow *transient_parent; - - if (start_object == NULL) { - return NULL; - } - - g_return_val_if_fail (GTK_IS_OBJECT (start_object), NULL); - - /* Check for an undo manager right here. */ - manager = gtk_object_get_data (start_object, "Nautilus undo"); - if (manager != NULL) { - return manager; - } - - /* Check for undo manager up the parent chain. */ - if (GTK_IS_WIDGET (start_object)) { - parent = GTK_WIDGET (start_object)->parent; - if (parent != NULL) { - manager = nautilus_get_undo_manager (GTK_OBJECT (parent)); - if (manager != NULL) { - return manager; - } - } - - /* Check for undo manager in our window's parent. */ - if (GTK_IS_WINDOW (start_object)) { - transient_parent = GTK_WINDOW (start_object)->transient_parent; - if (transient_parent != NULL) { - manager = nautilus_get_undo_manager (GTK_OBJECT (transient_parent)); - if (manager != NULL) { - return manager; - } - } - } - } - - /* In the case of a canvas item, try the canvas. */ - if (GNOME_IS_CANVAS_ITEM (start_object)) { - manager = nautilus_get_undo_manager (GTK_OBJECT (GNOME_CANVAS_ITEM (start_object)->canvas)); - if (manager != NULL) { - return manager; - } - } - - /* Found nothing. I can live with that. */ - return NULL; -} - -static void -undo_manager_unref (gpointer manager) -{ - CORBA_Environment ev; - - CORBA_exception_init (&ev); - Nautilus_Undo_Manager_unref (manager, &ev); - CORBA_Object_release (manager, &ev); - CORBA_exception_free (&ev); -} - void -nautilus_attach_undo_manager (GtkObject *object, - Nautilus_Undo_Manager manager) +nautilus_undo_manager_attach (NautilusUndoManager *manager, GtkObject *target) { - CORBA_Environment ev; - Nautilus_Undo_Manager stored_manager; - - g_return_if_fail (GTK_IS_OBJECT (object)); - - if (manager == NULL) { - gtk_object_remove_data (object, "Nautilus undo"); - return; - } - - CORBA_exception_init (&ev); - Nautilus_Undo_Manager_ref (manager, &ev); - stored_manager = CORBA_Object_duplicate (manager, &ev); - CORBA_exception_free (&ev); + g_return_if_fail (NAUTILUS_IS_UNDO_MANAGER (manager)); + g_return_if_fail (GTK_IS_OBJECT (target)); - gtk_object_set_data_full - (object, "Nautilus undo", - stored_manager, undo_manager_unref); + nautilus_undo_attach_undo_manager + (target, + bonobo_object_corba_objref (BONOBO_OBJECT (manager))); } -/* This is useful because nautilus_get_undo_manager will be - * private one day. - */ void -nautilus_share_undo_manager (GtkObject *destination_object, - GtkObject *source_object) +nautilus_undo_manager_add_interface (NautilusUndoManager *manager, BonoboObject *object) { - Nautilus_Undo_Manager manager; - CORBA_Environment ev; + NautilusUndoContext *context; - manager = nautilus_get_undo_manager (source_object); - nautilus_attach_undo_manager - (destination_object, manager); + g_return_if_fail (NAUTILUS_IS_UNDO_MANAGER (manager)); + g_return_if_fail (BONOBO_IS_OBJECT (object)); - CORBA_exception_init (&ev); - CORBA_Object_release (manager, &ev); - CORBA_exception_free (&ev); + context = nautilus_undo_context_new (bonobo_object_corba_objref (BONOBO_OBJECT (manager))); + bonobo_object_add_interface (object, BONOBO_OBJECT (context)); } -/* Locates an undo manager for this bonobo control. - * The undo manager is supplied by an interface on - * the control frame. The put that undo manager on - * the Bonobo control's widget. - */ static void -set_up_bonobo_control (BonoboControl *control) +update_undo_menu_item (NautilusUndoManager *manager, + UndoMenuHandlerConnection *connection) { - Nautilus_Undo_Manager manager; - Bonobo_ControlFrame control_frame; CORBA_Environment ev; - Nautilus_Undo_Context undo_context; - GtkWidget *widget; - - g_assert (BONOBO_IS_CONTROL (control)); - - manager = CORBA_OBJECT_NIL; + Nautilus_Undo_MenuItem *menu_item; + g_assert (NAUTILUS_IS_UNDO_MANAGER (manager)); + g_assert (connection != NULL); + g_assert (BONOBO_IS_UI_HANDLER (connection->handler)); + g_assert (connection->path != NULL); + g_assert (connection->no_undo_menu_item_label != NULL); + g_assert (connection->no_undo_menu_item_hint != NULL); + CORBA_exception_init (&ev); - /* Find the undo manager. */ - control_frame = bonobo_control_get_control_frame (control); - if (!CORBA_Object_is_nil (control_frame, &ev)) { - undo_context = Bonobo_Control_query_interface - (control_frame, "IDL:Nautilus/Undo/Context:1.0", &ev); - if (!CORBA_Object_is_nil (undo_context, &ev)) { - manager = Nautilus_Undo_Context__get_undo_manager (undo_context, &ev); - } - CORBA_Object_release (undo_context, &ev); + if (manager->details->undo_list == NULL) { + menu_item = NULL; + } else { + menu_item = Nautilus_Undo_Transaction__get_undo_menu_item + (g_list_last (manager->details->undo_list)->data, &ev); } - CORBA_Object_release (control_frame, &ev); - - /* Attach the undo manager to the widget, or detach the old one. */ - widget = bonobo_control_get_widget (control); - nautilus_attach_undo_manager (GTK_OBJECT (widget), manager); - CORBA_Object_release (manager, &ev); - + + bonobo_ui_handler_menu_set_sensitivity + (connection->handler, connection->path, + menu_item != NULL); + bonobo_ui_handler_menu_set_label + (connection->handler, connection->path, + menu_item == NULL + ? connection->no_undo_menu_item_label + : menu_item->label); + bonobo_ui_handler_menu_set_hint + (connection->handler, connection->path, + menu_item == NULL + ? connection->no_undo_menu_item_hint + : menu_item->hint); + + CORBA_free (menu_item); + CORBA_exception_free (&ev); } -void -nautilus_undo_set_up_bonobo_control (BonoboControl *control) +static void +undo_menu_handler_connection_free (UndoMenuHandlerConnection *connection) { - g_return_if_fail (BONOBO_IS_CONTROL (control)); - - set_up_bonobo_control (control); - gtk_signal_connect (GTK_OBJECT (control), "set_frame", - GTK_SIGNAL_FUNC (set_up_bonobo_control), NULL); + g_assert (connection != NULL); + g_assert (BONOBO_IS_UI_HANDLER (connection->handler)); + g_assert (connection->path != NULL); + g_assert (connection->no_undo_menu_item_label != NULL); + g_assert (connection->no_undo_menu_item_hint != NULL); + + g_free (connection->path); + g_free (connection->no_undo_menu_item_label); + g_free (connection->no_undo_menu_item_hint); + g_free (connection); } - -void -nautilus_undo_manager_stash_global_undo (Nautilus_Undo_Manager undo_manager) +static void +undo_menu_handler_connection_free_cover (gpointer data) { - global_undo_manager = undo_manager; + undo_menu_handler_connection_free (data); } -Nautilus_Undo_Manager -nautilus_undo_manager_get_global_undo (void) +void +nautilus_undo_manager_set_up_bonobo_ui_handler_undo_item (NautilusUndoManager *manager, + BonoboUIHandler *handler, + const char *path, + const char *no_undo_menu_item_label, + const char *no_undo_menu_item_hint) { - return global_undo_manager; + UndoMenuHandlerConnection *connection; + + connection = g_new (UndoMenuHandlerConnection, 1); + connection->handler = handler; + connection->path = g_strdup (path); + connection->no_undo_menu_item_label = g_strdup (no_undo_menu_item_label); + connection->no_undo_menu_item_hint = g_strdup (no_undo_menu_item_hint); + + /* Set initial state of menu item. */ + update_undo_menu_item (manager, connection); + + /* Update it again whenever the changed signal is emitted. */ + nautilus_gtk_signal_connect_full_while_alive + (GTK_OBJECT (manager), "changed", + GTK_SIGNAL_FUNC (update_undo_menu_item), NULL, + connection, undo_menu_handler_connection_free_cover, + FALSE, FALSE, + GTK_OBJECT (handler)); } - - diff --git a/libnautilus-private/nautilus-undo-manager.h b/libnautilus-private/nautilus-undo-manager.h index 668733d1b..0e5deccb9 100644 --- a/libnautilus-private/nautilus-undo-manager.h +++ b/libnautilus-private/nautilus-undo-manager.h @@ -1,6 +1,7 @@ /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ /* NautilusUndoManager - Manages undo and redo transactions. + * This is the public interface used by the application. * * Copyright (C) 2000 Eazel, Inc. * @@ -25,10 +26,7 @@ #ifndef NAUTILUS_UNDO_MANAGER_H #define NAUTILUS_UNDO_MANAGER_H -#include <bonobo/bonobo-control.h> - -#include "nautilus-undo-transaction.h" -#include "nautilus-undo.h" +#include <bonobo/bonobo-ui-handler.h> #define NAUTILUS_TYPE_UNDO_MANAGER \ (nautilus_undo_manager_get_type ()) @@ -41,46 +39,36 @@ #define NAUTILUS_IS_UNDO_MANAGER_CLASS(klass) \ (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_UNDO_MANAGER)) -typedef struct NautilusUndoManagerClass NautilusUndoManagerClass; typedef struct NautilusUndoManagerDetails NautilusUndoManagerDetails; -struct NautilusUndoManager { +typedef struct { BonoboObject parent; NautilusUndoManagerDetails *details; -}; - -struct NautilusUndoManagerClass { - BonoboObjectClass parent_class; - void (* undo_transaction_occurred) (GtkObject *object, gpointer data); - gpointer servant_init_func, servant_destroy_func, vepv; -}; - - -/* GtkObject */ -GtkType nautilus_undo_manager_get_type (void); -NautilusUndoManager *nautilus_undo_manager_new (void); - -/* Prototypes */ -gboolean nautilus_undo_manager_can_undo (NautilusUndoManager *manager); -gboolean nautilus_undo_manager_can_redo (NautilusUndoManager *manager); -void nautilus_undo_manager_enable_redo (NautilusUndoManager *manager, - gboolean value); -void nautilus_undo_manager_set_queue_depth (NautilusUndoManager *manager, - gint depth); - -void nautilus_attach_undo_manager (GtkObject *object, - Nautilus_Undo_Manager manager); -void nautilus_share_undo_manager (GtkObject *destination_object, - GtkObject *source_object); -void nautilus_undo_set_up_bonobo_control (BonoboControl *control); -Nautilus_Undo_Manager nautilus_get_undo_manager (GtkObject *start_object); - -void nautilus_undo_manager_stash_global_undo (Nautilus_Undo_Manager undo_manager); -Nautilus_Undo_Manager nautilus_undo_manager_get_global_undo (void); - - -Nautilus_Undo_Transaction nautilus_undo_manager_get_current_undo_transaction (NautilusUndoManager *manager); - - - -#endif +} NautilusUndoManager; + +typedef struct { + BonoboObjectClass parent_slot; + void (* changed) (GtkObject *object, gpointer data); +} NautilusUndoManagerClass; + +GtkType nautilus_undo_manager_get_type (void); +NautilusUndoManager *nautilus_undo_manager_new (void); + +/* Undo operations. */ +void nautilus_undo_manager_undo (NautilusUndoManager *undo_manager); + +/* Connect the manager to a particular menu item. */ +void nautilus_undo_manager_set_up_bonobo_ui_handler_undo_item (NautilusUndoManager *manager, + BonoboUIHandler *handler, + const char *path, + const char *no_undo_menu_item_label, + const char *no_undo_menu_item_hint); + +/* Attach the undo manager to a Gtk object so that object and the widgets inside it can participate in undo. */ +void nautilus_undo_manager_attach (NautilusUndoManager *manager, + GtkObject *object); +/* Attach the undo manager to a Bonobo object so another component can find it. */ +void nautilus_undo_manager_add_interface (NautilusUndoManager *manager, + BonoboObject *object); + +#endif /* NAUTILUS_UNDO_MANAGER_H */ diff --git a/libnautilus/.cvsignore b/libnautilus/.cvsignore index df6884d9b..41608c2b5 100644 --- a/libnautilus/.cvsignore +++ b/libnautilus/.cvsignore @@ -4,16 +4,13 @@ Makefile Makefile.in libnautilus.la -nautilus-common.c -nautilus-skels.c -nautilus-stubs.c -nautilus-undo-common.c -nautilus-undo-skels.c -nautilus-undo-stubs.c -nautilus-undo.h +nautilus-distributed-undo-common.c +nautilus-distributed-undo-skels.c +nautilus-distributed-undo-stubs.c +nautilus-distributed-undo.h nautilus-view-component-common.c nautilus-view-component-skels.c nautilus-view-component-stubs.c nautilus-view-component.h -nautilus_undo_idl_stamp +nautilus_distributed_undo_idl_stamp nautilus_view_component_idl_stamp diff --git a/libnautilus/Makefile.am b/libnautilus/Makefile.am index 9a873135b..0de21abec 100644 --- a/libnautilus/Makefile.am +++ b/libnautilus/Makefile.am @@ -27,15 +27,15 @@ nautilus_view_component_idl_sources = \ nautilus-view-component.h \ nautilus-view-component-common.c -nautilus_undo_idl_sources = \ - nautilus-undo-stubs.c \ - nautilus-undo-skels.c \ - nautilus-undo.h \ - nautilus-undo-common.c +nautilus_distributed_undo_idl_sources = \ + nautilus-distributed-undo-stubs.c \ + nautilus-distributed-undo-skels.c \ + nautilus-distributed-undo.h \ + nautilus-distributed-undo-common.c BUILT_SOURCES = \ $(nautilus_view_component_idl_sources) \ - $(nautilus_undo_idl_sources) + $(nautilus_distributed_undo_idl_sources) libnautilusincludedir=$(includedir)/libnautilus @@ -43,25 +43,22 @@ libnautilusinclude_HEADERS= \ libnautilus.h \ nautilus-bonobo-ui.h \ nautilus-clipboard.h \ + nautilus-distributed-undo.h \ nautilus-view-component.h \ nautilus-view.h \ - nautilus-undo-context.h \ - nautilus-undo-manager.h \ - nautilus-undo-transaction.h \ - nautilus-undoable.h \ + nautilus-undo.h \ + nautilus-undo-private.h \ nautilus-zoomable.h \ $(NULL) libnautilus_la_SOURCES= \ - nautilus-undo-manager-private.h \ $(nautilus_view_component_idl_sources) \ - $(nautilus_undo_idl_sources) \ + $(nautilus_distributed_undo_idl_sources) \ nautilus-clipboard.c \ - nautilus-view.c \ - nautilus-undo-context.c \ - nautilus-undo-manager.c \ nautilus-undo-transaction.c \ - nautilus-undoable.c \ + nautilus-undo-transaction.h \ + nautilus-undo.c \ + nautilus-view.c \ nautilus-zoomable.c \ $(NULL) @@ -70,17 +67,19 @@ nautilus_view_component_idl_stamp: nautilus-view-component.idl $(ORBIT_IDL) -I${datadir}/idl -I/opt/gnome/share/idl $(srcdir)/nautilus-view-component.idl touch nautilus_view_component_idl_stamp -$(nautilus_undo_idl_sources): nautilus_undo_idl_stamp -nautilus_undo_idl_stamp: nautilus-undo.idl - $(ORBIT_IDL) -I${datadir}/idl -I/opt/gnome/share/idl $(srcdir)/nautilus-undo.idl - touch nautilus_undo_idl_stamp +$(nautilus_distributed_undo_idl_sources): nautilus_distributed_undo_idl_stamp +nautilus_distributed_undo_idl_stamp: nautilus-distributed-undo.idl + $(ORBIT_IDL) -I${datadir}/idl -I/opt/gnome/share/idl $(srcdir)/nautilus-distributed-undo.idl + touch nautilus_distributed_undo_idl_stamp CLEANFILES = \ - $(nautilus_view_component_idl_sources) \ - nautilus_view_component_idl_stamp \ - $(nautilus_undo_idl_sources) \ - nautilus_undo_idl_stamp + $(nautilus_view_component_idl_sources) \ + nautilus_view_component_idl_stamp \ + $(nautilus_distributed_undo_idl_sources) \ + nautilus_distributed_undo_idl_stamp EXTRA_DIST = \ nautilus-view-component.idl \ - nautilus-undo.idl + nautilus-distributed-undo.idl \ + $(NULL) + diff --git a/libnautilus/nautilus-distributed-undo.idl b/libnautilus/nautilus-distributed-undo.idl index 49476af93..2104d189e 100644 --- a/libnautilus/nautilus-distributed-undo.idl +++ b/libnautilus/nautilus-distributed-undo.idl @@ -33,8 +33,8 @@ module Nautilus { /* The specifications for a menu item. */ struct MenuItem { - string name; - string description; + string label; + string hint; }; /* A single undoable operation is represented by a @@ -42,14 +42,14 @@ module Nautilus { * must supply for use by an undo manager. */ interface Transaction : ::Bonobo::Unknown { - /* These descriptions are used to display undo + /* These menu items are used to display undo * or redo menu items for this transaction. - * The base description is for lists of undoable + * The operation name is for lists of undoable * operations that are listed somewhere other * than an undo or redo object. */ - readonly attribute MenuItem undo_description; - readonly attribute MenuItem redo_description; + readonly attribute MenuItem undo_menu_item; + readonly attribute MenuItem redo_menu_item; readonly attribute string operation_name; /* Here's how you actually perform an undo. diff --git a/libnautilus/nautilus-undo-context.c b/libnautilus/nautilus-undo-context.c deleted file mode 100644 index ee5153e8c..000000000 --- a/libnautilus/nautilus-undo-context.c +++ /dev/null @@ -1,179 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ - -/* NautilusUndoContext - * - * Copyright (C) 2000 Eazel, Inc. - * - * Author: Gene Z. Ragan <gzr@eazel.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include <config.h> -#include <gtk/gtksignal.h> -#include <gtk/gtkmain.h> -#include <bonobo/bonobo-main.h> -#include <bonobo/bonobo-object.h> -#include <bonobo/bonobo-control.h> -#include <libnautilus-extensions/nautilus-gtk-macros.h> - -#include "nautilus-undo.h" - -#include "nautilus-undo-context.h" - -typedef struct { - POA_Nautilus_Undo_Context servant; - NautilusUndoContext *bonobo_object; -} impl_POA_Nautilus_Undo_Context; - -/* GtkObject */ -static void nautilus_undo_context_initialize_class (NautilusUndoContextClass *class); -static void nautilus_undo_context_initialize (NautilusUndoContext *item); -static void destroy (GtkObject *object); - -/* CORBA/Bonobo */ -static Nautilus_Undo_Manager impl_Nautilus_Undo_Context__get_undo_manager (PortableServer_Servant servant, - CORBA_Environment *ev); - -NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusUndoContext, nautilus_undo_context, BONOBO_OBJECT_TYPE) - -POA_Nautilus_Undo_Context__epv libnautilus_Nautilus_Undo_Context_epv = -{ - NULL, /* _private */ - &impl_Nautilus_Undo_Context__get_undo_manager, -}; - -static PortableServer_ServantBase__epv base_epv; -static POA_Nautilus_Undo_Context__vepv impl_Nautilus_Undo_Context_vepv = -{ - &base_epv, - NULL, - &libnautilus_Nautilus_Undo_Context_epv -}; - -static void -impl_Nautilus_Undo_Context__destroy (BonoboObject *obj, impl_POA_Nautilus_Undo_Context *servant) -{ - PortableServer_ObjectId *objid; - CORBA_Environment ev; - void (*servant_destroy_func) (PortableServer_Servant servant, CORBA_Environment *ev); - - CORBA_exception_init (&ev); - servant_destroy_func = NAUTILUS_UNDO_CONTEXT_CLASS - (GTK_OBJECT (servant->bonobo_object)->klass)->servant_destroy_func; - - objid = PortableServer_POA_servant_to_id (bonobo_poa (), servant, &ev); - PortableServer_POA_deactivate_object (bonobo_poa (), objid, &ev); - CORBA_free (objid); - obj->servant = NULL; - - (* servant_destroy_func) ((PortableServer_Servant) servant, &ev); - - g_free (servant); - CORBA_exception_free (&ev); -} - -static Nautilus_Undo_Context -impl_Nautilus_Undo_Context__create (NautilusUndoContext *context, CORBA_Environment * ev) -{ - Nautilus_Undo_Context retval; - impl_POA_Nautilus_Undo_Context *servant; - void (*servant_init_func) (PortableServer_Servant servant, CORBA_Environment *ev); - NautilusUndoContextClass *context_class; - - context_class = NAUTILUS_UNDO_CONTEXT_CLASS (GTK_OBJECT (context)->klass); - - servant_init_func = context_class->servant_init_func; - servant = g_new0 (impl_POA_Nautilus_Undo_Context, 1); - servant->servant.vepv = context_class->vepv; - if (servant->servant.vepv->Bonobo_Unknown_epv == NULL) { - servant->servant.vepv->Bonobo_Unknown_epv = bonobo_object_get_epv (); - } - (* servant_init_func) ((PortableServer_Servant) servant, ev); - - servant->bonobo_object = context; - - retval = bonobo_object_activate_servant (BONOBO_OBJECT (context), servant); - - gtk_signal_connect (GTK_OBJECT (context), "destroy", - GTK_SIGNAL_FUNC (impl_Nautilus_Undo_Context__destroy), - servant); - - return retval; -} - -static Nautilus_Undo_Manager -impl_Nautilus_Undo_Context__get_undo_manager (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - NautilusUndoContext *context; - - context = ((impl_POA_Nautilus_Undo_Context *) servant)->bonobo_object; - - g_assert (NAUTILUS_IS_UNDO_CONTEXT (context)); - return CORBA_Object_duplicate (context->undo_manager, ev); -} - -/* nautilus_undo_manager_new */ -NautilusUndoContext * -nautilus_undo_context_new (Nautilus_Undo_Manager undo_manager) -{ - NautilusUndoContext *context; - - context = gtk_type_new (nautilus_undo_context_get_type ()); - context->undo_manager = undo_manager; - return context; -} - -/* Object initialization function for the NautilusUndoContext */ -static void -nautilus_undo_context_initialize (NautilusUndoContext *context) -{ - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - bonobo_object_construct (BONOBO_OBJECT (context), - impl_Nautilus_Undo_Context__create (context, &ev)); - - CORBA_exception_free (&ev); -} - -/* Class initialization function for the NautilusUndoManager. */ -static void -nautilus_undo_context_initialize_class (NautilusUndoContextClass *klass) -{ - GtkObjectClass *object_class; - - object_class = GTK_OBJECT_CLASS (klass); - - object_class->destroy = destroy; - - klass->servant_init_func = POA_Nautilus_Undo_Context__init; - klass->servant_destroy_func = POA_Nautilus_Undo_Context__fini; - klass->vepv = &impl_Nautilus_Undo_Context_vepv; -} - -/* destroy */ -static void -destroy (GtkObject *object) -{ - NautilusUndoContext *context; - - context = NAUTILUS_UNDO_CONTEXT (object); - - NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object)); -} diff --git a/libnautilus/nautilus-undo-context.h b/libnautilus/nautilus-undo-context.h deleted file mode 100644 index bb4bdf2cd..000000000 --- a/libnautilus/nautilus-undo-context.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ - -/* NautilusUndoContext - * - * Copyright (C) 2000 Eazel, Inc. - * - * Author: Gene Z. Ragan <gzr@eazel.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef NAUTILUS_UNDO_CONTEXT_H -#define NAUTILUS_UNDO_CONTEXT_H - -#include "nautilus-undo.h" - -#define NAUTILUS_TYPE_UNDO_CONTEXT \ - (nautilus_undo_context_get_type ()) -#define NAUTILUS_UNDO_CONTEXT(obj) \ - (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_UNDO_CONTEXT, NautilusUndoContext)) -#define NAUTILUS_UNDO_CONTEXT_CLASS(klass) \ - (GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_UNDO_CONTEXT, NautilusUndoContextClass)) -#define NAUTILUS_IS_UNDO_CONTEXT(obj) \ - (GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_UNDO_CONTEXT)) -#define NAUTILUS_IS_UNDO_CONTEXT_CLASS(klass) \ - (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_UNDO_CONTEXT)) - -typedef struct NautilusUndoContext NautilusUndoContext; -typedef struct NautilusUndoContextClass NautilusUndoContextClass; - -struct NautilusUndoContext { - BonoboObject parent; - Nautilus_Undo_Manager undo_manager; -}; - -struct NautilusUndoContextClass { - BonoboObjectClass parent_class; - gpointer servant_init_func, servant_destroy_func, vepv; -}; - - -/* GtkObject */ -GtkType nautilus_undo_context_get_type (void); -NautilusUndoContext *nautilus_undo_context_new (Nautilus_Undo_Manager undo_manager); - -/* Prototypes */ - - -#endif /* NAUTILUS_UNDO_CONTEXT_H */ diff --git a/libnautilus/nautilus-undo-manager.c b/libnautilus/nautilus-undo-manager.c deleted file mode 100644 index 15af401ff..000000000 --- a/libnautilus/nautilus-undo-manager.c +++ /dev/null @@ -1,719 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ - -/* NautilusUndoManager - Undo/Redo transaction manager. - * - * Copyright (C) 2000 Eazel, Inc. - * - * Author: Gene Z. Ragan <gzr@eazel.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include <config.h> -#include "nautilus-undo-manager.h" - -#include <gtk/gtksignal.h> -#include <gtk/gtkmain.h> -#include <glib.h> -#include <string.h> -#include <bonobo/bonobo-main.h> -#include <bonobo/bonobo-control.h> - -#include "nautilus-undo-manager-private.h" - -#include <libnautilus-extensions/nautilus-gnome-extensions.h> -#include <libnautilus-extensions/nautilus-gtk-extensions.h> -#include <libnautilus-extensions/nautilus-gtk-macros.h> - - -/* Gloabl instance of undo manager */ -Nautilus_Undo_Manager global_undo_manager; - -enum { - UNDO_TRANSACTION_OCCURRED, - LAST_SIGNAL -}; -static guint signals[LAST_SIGNAL]; - -typedef struct { - POA_Nautilus_Undo_Manager servant; - NautilusUndoManager *bonobo_object; -} impl_POA_Nautilus_Undo_Manager; - -/* GtkObject */ -static void nautilus_undo_manager_initialize_class (NautilusUndoManagerClass *class); -static void nautilus_undo_manager_initialize (NautilusUndoManager *item); -static void destroy (GtkObject *object); -static void free_undo_manager_list (GList *list); -static GList *prune_undo_manager_list (GList *list, - int items); -/* CORBA/Bonobo */ -static void impl_Nautilus_Undo_Manager__append (PortableServer_Servant servant, - const Nautilus_Undo_Transaction transaction, - CORBA_Environment *ev); -static void impl_Nautilus_Undo_Manager__forget (PortableServer_Servant servant, - const Nautilus_Undo_Transaction transaction, - CORBA_Environment *ev); -static void impl_Nautilus_Undo_Manager__undo (PortableServer_Servant servant, - CORBA_Environment *ev); -static void nautilus_undo_manager_add_transaction (NautilusUndoManager *manager, - Nautilus_Undo_Transaction transaction); -static void nautilus_undo_manager_forget_transaction (NautilusUndoManager *manager, - Nautilus_Undo_Transaction transaction); -static void nautilus_undo_manager_undo (NautilusUndoManager *manager); - -NAUTILUS_DEFINE_CLASS_BOILERPLATE(NautilusUndoManager, nautilus_undo_manager, BONOBO_OBJECT_TYPE) - -POA_Nautilus_Undo_Manager__epv libnautilus_Nautilus_Undo_Manager_epv = -{ - NULL, /* _private */ - &impl_Nautilus_Undo_Manager__append, - &impl_Nautilus_Undo_Manager__forget, - &impl_Nautilus_Undo_Manager__undo, -}; - -static PortableServer_ServantBase__epv base_epv; -static POA_Nautilus_Undo_Manager__vepv impl_Nautilus_Undo_Manager_vepv = -{ - &base_epv, - NULL, - &libnautilus_Nautilus_Undo_Manager_epv -}; - -static void -impl_Nautilus_Undo_Manager__destroy (BonoboObject *obj, impl_POA_Nautilus_Undo_Manager *servant) -{ - PortableServer_ObjectId *objid; - CORBA_Environment ev; - void (*servant_destroy_func) (PortableServer_Servant servant, CORBA_Environment *ev); - - CORBA_exception_init (&ev); - - servant_destroy_func = NAUTILUS_UNDO_MANAGER_CLASS (GTK_OBJECT (servant->bonobo_object)->klass)->servant_destroy_func; - objid = PortableServer_POA_servant_to_id (bonobo_poa (), servant, &ev); - PortableServer_POA_deactivate_object (bonobo_poa (), objid, &ev); - CORBA_free (objid); - obj->servant = NULL; - - servant_destroy_func ((PortableServer_Servant) servant, &ev); - g_free (servant); - CORBA_exception_free (&ev); -} - -static Nautilus_Undo_Manager -impl_Nautilus_Undo_Manager__create (NautilusUndoManager *manager, CORBA_Environment * ev) -{ - Nautilus_Undo_Manager retval; - impl_POA_Nautilus_Undo_Manager *servant; - void (*servant_init_func) (PortableServer_Servant servant, CORBA_Environment *ev); - - NautilusUndoManagerClass *undo_class = NAUTILUS_UNDO_MANAGER_CLASS (GTK_OBJECT(manager)->klass); - - servant_init_func = undo_class->servant_init_func; - servant = g_new0 (impl_POA_Nautilus_Undo_Manager, 1); - servant->servant.vepv = undo_class->vepv; - if (!servant->servant.vepv->Bonobo_Unknown_epv) - servant->servant.vepv->Bonobo_Unknown_epv = bonobo_object_get_epv (); - servant_init_func ((PortableServer_Servant) servant, ev); - - servant->bonobo_object = manager; - - retval = bonobo_object_activate_servant (BONOBO_OBJECT (manager), servant); - - gtk_signal_connect (GTK_OBJECT (manager), "destroy", GTK_SIGNAL_FUNC (impl_Nautilus_Undo_Manager__destroy), servant); - - return retval; -} - -static void -impl_Nautilus_Undo_Manager__append (PortableServer_Servant servant, - const Nautilus_Undo_Transaction undo_transaction, - CORBA_Environment *ev) -{ - NautilusUndoManager *manager; - - manager = ((impl_POA_Nautilus_Undo_Manager *) servant)->bonobo_object; - g_assert (NAUTILUS_IS_UNDO_MANAGER (manager)); - - nautilus_undo_manager_add_transaction (manager, undo_transaction); -} - -static void -impl_Nautilus_Undo_Manager__forget (PortableServer_Servant servant, - const Nautilus_Undo_Transaction transaction, - CORBA_Environment *ev) -{ - NautilusUndoManager *manager; - - manager = ((impl_POA_Nautilus_Undo_Manager *) servant)->bonobo_object; - g_assert (NAUTILUS_IS_UNDO_MANAGER (manager)); - - nautilus_undo_manager_forget_transaction (manager, transaction); -} - -static void -impl_Nautilus_Undo_Manager__undo (PortableServer_Servant servant, - CORBA_Environment *ev) -{ - NautilusUndoManager *manager; - - manager = ((impl_POA_Nautilus_Undo_Manager *) servant)->bonobo_object; - g_assert (NAUTILUS_IS_UNDO_MANAGER (manager)); - - nautilus_undo_manager_undo (manager); -} - -NautilusUndoManager * -nautilus_undo_manager_new (void) -{ - return gtk_type_new (nautilus_undo_manager_get_type ()); -} - -/* Object initialization function for the NautilusUndoManager */ -static void -nautilus_undo_manager_initialize (NautilusUndoManager *manager) -{ - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - manager->details = g_new0 (NautilusUndoManagerDetails, 1); - - /* Create empty lists */ - manager->details->undo_list = NULL; - manager->details->redo_list = NULL; - - /* Default to no redo functionality */ - manager->details->enable_redo = FALSE; - - /* Set queue depth to a single level */ - manager->details->queue_depth = 1; - - bonobo_object_construct (BONOBO_OBJECT (manager), impl_Nautilus_Undo_Manager__create (manager, &ev)); - - CORBA_exception_free (&ev); -} - - -/* Class initialization function for the NautilusUndoManager. */ -static void -nautilus_undo_manager_initialize_class (NautilusUndoManagerClass *klass) -{ - GtkObjectClass *object_class; - - object_class = GTK_OBJECT_CLASS (klass); - - object_class->destroy = destroy; - - klass->servant_init_func = POA_Nautilus_Undo_Manager__init; - klass->servant_destroy_func = POA_Nautilus_Undo_Manager__fini; - klass->vepv = &impl_Nautilus_Undo_Manager_vepv; - - /* Setup signals */ - signals[UNDO_TRANSACTION_OCCURRED] - = gtk_signal_new ("undo_transaction_occurred", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusUndoManagerClass, - undo_transaction_occurred), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); - - gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL); -} - -static void -nautilus_undo_manager_undo (NautilusUndoManager *manager) -{ - GList *last_in_list; - CORBA_Object undo_transaction; - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - /* Verify we have a transaction to be undone */ - if (manager->details->undo_list == NULL) { - g_warning ("NautilusUndoManager has no transaction to be undone."); - return; - } - - /* Pop last transaction off undo list */ - last_in_list = g_list_last (manager->details->undo_list); - g_assert (last_in_list != NULL); - undo_transaction = last_in_list->data; - manager->details->undo_list = g_list_remove (manager->details->undo_list, undo_transaction); - - /* Undo transaction */ - Nautilus_Undo_Transaction_undo (undo_transaction, &ev); - - /* Place transaction into redo list */ - if (manager->details->enable_redo) { - /* FIXME: Implement redo. */ - /* nautilus_undo_manager_add_redo_transaction (undo_transaction); */ - } else { - /* Purge transaction */ - Nautilus_Undo_Transaction_unref (undo_transaction, &ev); - } - - /* Fire off signal informing that an undo transaction has occurred */ - gtk_signal_emit (GTK_OBJECT (manager), - signals[UNDO_TRANSACTION_OCCURRED]); - - CORBA_exception_free (&ev); -} - -#if 0 -static void -nautilus_undo_manager_redo (NautilusUndoManager *manager) -{ - GList *list; - CORBA_Object redo_transaction; - CORBA_Object undo_transaction; - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - /* Are we allowing redo operations? */ - if (manager->details->enable_redo) { - g_warning ("NautilusUndoManager is not configure to allow redo operations."); - return; - } - - /* Verify we have a transaction to be redone */ - if (manager->details->redo_list == NULL) { - g_warning ("NautilusUndoManager has no transaction to be redone."); - return; - } - - /* Pop last transaction off redo list */ - list = g_list_last (manager->details->redo_list); - g_assert(list); - redo_transaction = list->data; - - Nautilus_Undo_Transaction_undo (redo_transaction, &ev); - - /* Place transaction into undo list */ - undo_transaction = bonobo_object_corba_objref (BONOBO_OBJECT (redo_transaction)); - nautilus_undo_manager_add_transaction (manager, undo_transaction); - - CORBA_exception_free (&ev); -} -#endif - -static void -nautilus_undo_manager_add_transaction (NautilusUndoManager *manager, - Nautilus_Undo_Transaction transaction) -{ - int length; - Nautilus_Undo_Transaction duplicate_transaction; - CORBA_Environment ev; - - g_return_if_fail (NAUTILUS_IS_UNDO_MANAGER (manager)); - g_return_if_fail (transaction != CORBA_OBJECT_NIL); - - CORBA_exception_init (&ev); - - /* Check and see if we are over our queue limit */ - length = g_list_length (manager->details->undo_list); - if (length >= manager->details->queue_depth) { - manager->details->undo_list = prune_undo_manager_list - (manager->details->undo_list, - (length - manager->details->queue_depth) + 1); - } - - /* Perform refs on the transaction */ - duplicate_transaction = CORBA_Object_duplicate (transaction, &ev); - Nautilus_Undo_Transaction_ref (duplicate_transaction, &ev); - - /* Add transaction to undo list */ - manager->details->undo_list = g_list_append (manager->details->undo_list, duplicate_transaction); - - /* Fire off signal informing that an undo transaction has occurred */ - gtk_signal_emit (GTK_OBJECT (manager), - signals[UNDO_TRANSACTION_OCCURRED]); - - CORBA_exception_free (&ev); -} - - -static void -nautilus_undo_manager_forget_transaction (NautilusUndoManager *manager, - Nautilus_Undo_Transaction transaction) -{ - GList *list; - int index, length; - CORBA_Environment ev; - gboolean success; - - CORBA_exception_init (&ev); - - success = FALSE; - - /* Check undo list */ - length = g_list_length (manager->details->undo_list); - for (index = 0; index < length; index++) { - list = g_list_nth (manager->details->undo_list, index); - if (list) { - transaction = list->data; - manager->details->undo_list = - g_list_remove (manager->details->undo_list, transaction); - Nautilus_Undo_Transaction_unref (transaction, &ev); - success = TRUE; - index--; - } - } - - /* Check redo list */ - length = g_list_length (manager->details->redo_list); - for (index = 0; index < length; index++) { - list = g_list_nth (manager->details->redo_list, index); - if (list) { - transaction = list->data; - manager->details->redo_list = - g_list_remove (manager->details->redo_list, transaction); - Nautilus_Undo_Transaction_unref (transaction, &ev); - success = TRUE; - index--; - } - } - - if (success) { - /* Fire off signal informing that a transaction has occurred */ - gtk_signal_emit (GTK_OBJECT (manager), - signals[UNDO_TRANSACTION_OCCURRED]); - } - - CORBA_exception_free (&ev); -} - - -Nautilus_Undo_Transaction -nautilus_undo_manager_get_current_undo_transaction (NautilusUndoManager *manager) -{ - GList *last_in_list; - CORBA_Object undo_transaction; - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - /* Verify we have a transaction to be undone */ - if (manager->details->undo_list == NULL) { - g_warning ("NautilusUndoManager has no undo transaction in the queue."); - return NULL; - } - - /* Pop last transaction off undo list */ - last_in_list = g_list_last (manager->details->undo_list); - g_assert (last_in_list != NULL); - undo_transaction = last_in_list->data; - - return undo_transaction; - - CORBA_exception_free (&ev); -} - - -gboolean -nautilus_undo_manager_can_undo (NautilusUndoManager *manager) -{ - return manager != NULL - && manager->details->undo_list != NULL; -} - -gboolean -nautilus_undo_manager_can_redo (NautilusUndoManager *manager) -{ - return manager != NULL - && manager->details->enable_redo - && manager->details->redo_list != NULL; -} - -static void -destroy (GtkObject *object) -{ - NautilusUndoManager *manager; - - manager = NAUTILUS_UNDO_MANAGER (object); - - /* Clear lists */ - free_undo_manager_list (manager->details->undo_list); - free_undo_manager_list (manager->details->redo_list); - - NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object)); -} - -/* nautilus_undo_manager_enable_redo - * - * Enable or disable redo functionality - */ -void -nautilus_undo_manager_enable_redo (NautilusUndoManager *manager, gboolean value) -{ - g_return_if_fail (NAUTILUS_IS_UNDO_MANAGER (manager)); - g_return_if_fail (value == FALSE || value == TRUE); - - manager->details->enable_redo = value; - - /* Flush and free redo queue */ - free_undo_manager_list (manager->details->redo_list); - manager->details->redo_list = NULL; -} - -void -nautilus_undo_manager_set_queue_depth (NautilusUndoManager *manager, int depth) -{ - int length; - - g_return_if_fail (NAUTILUS_IS_UNDO_MANAGER (manager)); - g_return_if_fail (depth > 0); - - manager->details->queue_depth = depth; - - /* Prune lists */ - length = g_list_length (manager->details->undo_list); - if (length > depth) { - manager->details->undo_list = prune_undo_manager_list (manager->details->undo_list, - length - depth); - } - length = g_list_length (manager->details->redo_list); - if (length > depth) { - manager->details->undo_list = prune_undo_manager_list (manager->details->redo_list, - length - depth); - } - - /* Fire off signal informing that an undo transaction has occurred */ - gtk_signal_emit (GTK_OBJECT (manager), - signals[UNDO_TRANSACTION_OCCURRED]); -} - -/* free_undo_manager_list - * - * Clear undo data from list - */ -static void -free_undo_manager_list (GList *list) -{ - GList *p; - Nautilus_Undo_Transaction transaction; - CORBA_Environment ev; - - CORBA_exception_init (&ev); - for (p = list; p != NULL; p = p->next) { - transaction = p->data; - - Nautilus_Undo_Transaction_unref (transaction, &ev); - } - CORBA_exception_free (&ev); - - g_list_free (list); -} - - -/* prune_undo_manager_list - * - * Prune n items from start of list - */ -static GList * -prune_undo_manager_list (GList *list, int items) -{ - int i; - Nautilus_Undo_Transaction transaction; - CORBA_Environment ev; - - CORBA_exception_init (&ev); - for (i = 0; i < items; i++) { - if (list != NULL) { - transaction = list->data; - list = g_list_remove (list, transaction); - Nautilus_Undo_Transaction_unref (transaction, &ev); - } - } - CORBA_exception_free (&ev); - - return list; -} - -Nautilus_Undo_Manager -nautilus_get_undo_manager (GtkObject *start_object) -{ - Nautilus_Undo_Manager manager; - GtkWidget *parent; - GtkWindow *transient_parent; - - if (start_object == NULL) { - return NULL; - } - - g_return_val_if_fail (GTK_IS_OBJECT (start_object), NULL); - - /* Check for an undo manager right here. */ - manager = gtk_object_get_data (start_object, "Nautilus undo"); - if (manager != NULL) { - return manager; - } - - /* Check for undo manager up the parent chain. */ - if (GTK_IS_WIDGET (start_object)) { - parent = GTK_WIDGET (start_object)->parent; - if (parent != NULL) { - manager = nautilus_get_undo_manager (GTK_OBJECT (parent)); - if (manager != NULL) { - return manager; - } - } - - /* Check for undo manager in our window's parent. */ - if (GTK_IS_WINDOW (start_object)) { - transient_parent = GTK_WINDOW (start_object)->transient_parent; - if (transient_parent != NULL) { - manager = nautilus_get_undo_manager (GTK_OBJECT (transient_parent)); - if (manager != NULL) { - return manager; - } - } - } - } - - /* In the case of a canvas item, try the canvas. */ - if (GNOME_IS_CANVAS_ITEM (start_object)) { - manager = nautilus_get_undo_manager (GTK_OBJECT (GNOME_CANVAS_ITEM (start_object)->canvas)); - if (manager != NULL) { - return manager; - } - } - - /* Found nothing. I can live with that. */ - return NULL; -} - -static void -undo_manager_unref (gpointer manager) -{ - CORBA_Environment ev; - - CORBA_exception_init (&ev); - Nautilus_Undo_Manager_unref (manager, &ev); - CORBA_Object_release (manager, &ev); - CORBA_exception_free (&ev); -} - -void -nautilus_attach_undo_manager (GtkObject *object, - Nautilus_Undo_Manager manager) -{ - CORBA_Environment ev; - Nautilus_Undo_Manager stored_manager; - - g_return_if_fail (GTK_IS_OBJECT (object)); - - if (manager == NULL) { - gtk_object_remove_data (object, "Nautilus undo"); - return; - } - - CORBA_exception_init (&ev); - Nautilus_Undo_Manager_ref (manager, &ev); - stored_manager = CORBA_Object_duplicate (manager, &ev); - CORBA_exception_free (&ev); - - gtk_object_set_data_full - (object, "Nautilus undo", - stored_manager, undo_manager_unref); -} - -/* This is useful because nautilus_get_undo_manager will be - * private one day. - */ -void -nautilus_share_undo_manager (GtkObject *destination_object, - GtkObject *source_object) -{ - Nautilus_Undo_Manager manager; - CORBA_Environment ev; - - manager = nautilus_get_undo_manager (source_object); - nautilus_attach_undo_manager - (destination_object, manager); - - CORBA_exception_init (&ev); - CORBA_Object_release (manager, &ev); - CORBA_exception_free (&ev); -} - -/* Locates an undo manager for this bonobo control. - * The undo manager is supplied by an interface on - * the control frame. The put that undo manager on - * the Bonobo control's widget. - */ -static void -set_up_bonobo_control (BonoboControl *control) -{ - Nautilus_Undo_Manager manager; - Bonobo_ControlFrame control_frame; - CORBA_Environment ev; - Nautilus_Undo_Context undo_context; - GtkWidget *widget; - - g_assert (BONOBO_IS_CONTROL (control)); - - manager = CORBA_OBJECT_NIL; - - CORBA_exception_init (&ev); - - /* Find the undo manager. */ - control_frame = bonobo_control_get_control_frame (control); - if (!CORBA_Object_is_nil (control_frame, &ev)) { - undo_context = Bonobo_Control_query_interface - (control_frame, "IDL:Nautilus/Undo/Context:1.0", &ev); - if (!CORBA_Object_is_nil (undo_context, &ev)) { - manager = Nautilus_Undo_Context__get_undo_manager (undo_context, &ev); - } - CORBA_Object_release (undo_context, &ev); - } - CORBA_Object_release (control_frame, &ev); - - /* Attach the undo manager to the widget, or detach the old one. */ - widget = bonobo_control_get_widget (control); - nautilus_attach_undo_manager (GTK_OBJECT (widget), manager); - CORBA_Object_release (manager, &ev); - - CORBA_exception_free (&ev); -} - -void -nautilus_undo_set_up_bonobo_control (BonoboControl *control) -{ - g_return_if_fail (BONOBO_IS_CONTROL (control)); - - set_up_bonobo_control (control); - gtk_signal_connect (GTK_OBJECT (control), "set_frame", - GTK_SIGNAL_FUNC (set_up_bonobo_control), NULL); -} - - -void -nautilus_undo_manager_stash_global_undo (Nautilus_Undo_Manager undo_manager) -{ - global_undo_manager = undo_manager; -} - -Nautilus_Undo_Manager -nautilus_undo_manager_get_global_undo (void) -{ - return global_undo_manager; -} - - diff --git a/libnautilus/nautilus-undo-manager.h b/libnautilus/nautilus-undo-manager.h deleted file mode 100644 index 668733d1b..000000000 --- a/libnautilus/nautilus-undo-manager.h +++ /dev/null @@ -1,86 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ - -/* NautilusUndoManager - Manages undo and redo transactions. - * - * Copyright (C) 2000 Eazel, Inc. - * - * Author: Gene Z. Ragan <gzr@eazel.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef NAUTILUS_UNDO_MANAGER_H -#define NAUTILUS_UNDO_MANAGER_H - -#include <bonobo/bonobo-control.h> - -#include "nautilus-undo-transaction.h" -#include "nautilus-undo.h" - -#define NAUTILUS_TYPE_UNDO_MANAGER \ - (nautilus_undo_manager_get_type ()) -#define NAUTILUS_UNDO_MANAGER(obj) \ - (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_UNDO_MANAGER, NautilusUndoManager)) -#define NAUTILUS_UNDO_MANAGER_CLASS(klass) \ - (GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_UNDO_MANAGER, NautilusUndoManagerClass)) -#define NAUTILUS_IS_UNDO_MANAGER(obj) \ - (GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_UNDO_MANAGER)) -#define NAUTILUS_IS_UNDO_MANAGER_CLASS(klass) \ - (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_UNDO_MANAGER)) - -typedef struct NautilusUndoManagerClass NautilusUndoManagerClass; -typedef struct NautilusUndoManagerDetails NautilusUndoManagerDetails; - -struct NautilusUndoManager { - BonoboObject parent; - NautilusUndoManagerDetails *details; -}; - -struct NautilusUndoManagerClass { - BonoboObjectClass parent_class; - void (* undo_transaction_occurred) (GtkObject *object, gpointer data); - gpointer servant_init_func, servant_destroy_func, vepv; -}; - - -/* GtkObject */ -GtkType nautilus_undo_manager_get_type (void); -NautilusUndoManager *nautilus_undo_manager_new (void); - -/* Prototypes */ -gboolean nautilus_undo_manager_can_undo (NautilusUndoManager *manager); -gboolean nautilus_undo_manager_can_redo (NautilusUndoManager *manager); -void nautilus_undo_manager_enable_redo (NautilusUndoManager *manager, - gboolean value); -void nautilus_undo_manager_set_queue_depth (NautilusUndoManager *manager, - gint depth); - -void nautilus_attach_undo_manager (GtkObject *object, - Nautilus_Undo_Manager manager); -void nautilus_share_undo_manager (GtkObject *destination_object, - GtkObject *source_object); -void nautilus_undo_set_up_bonobo_control (BonoboControl *control); -Nautilus_Undo_Manager nautilus_get_undo_manager (GtkObject *start_object); - -void nautilus_undo_manager_stash_global_undo (Nautilus_Undo_Manager undo_manager); -Nautilus_Undo_Manager nautilus_undo_manager_get_global_undo (void); - - -Nautilus_Undo_Transaction nautilus_undo_manager_get_current_undo_transaction (NautilusUndoManager *manager); - - - -#endif diff --git a/libnautilus/nautilus-undo-manager-private.h b/libnautilus/nautilus-undo-private.h index 43da69c3a..235c60331 100644 --- a/libnautilus/nautilus-undo-manager-private.h +++ b/libnautilus/nautilus-undo-private.h @@ -1,5 +1,6 @@ /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* nautulus-undo-manager-private.h + +/* xxx * * Copyright (C) 2000 Eazel, Inc. * @@ -21,22 +22,14 @@ * Boston, MA 02111-1307, USA. */ +#ifndef NAUTILUS_UNDO_PRIVATE_H +#define NAUTILUS_UNDO_PRIVATE_H -#ifndef NAUTILUS_UNDO_MANAGER_PRIVATE_H -#define NAUTILUS_UNDO_MANAGER_PRIVATE_H - -#include <glib.h> -#include <bonobo.h> - -#include "nautilus-undo-transaction.h" - -/* Private data */ +#include "nautilus-distributed-undo.h" +#include <gtk/gtkobject.h> -struct NautilusUndoManagerDetails { - GList *undo_list; - GList *redo_list; - gboolean enable_redo; - gint queue_depth; -}; +Nautilus_Undo_Manager nautilus_undo_get_undo_manager (GtkObject *attached_object); +void nautilus_undo_attach_undo_manager (GtkObject *object, + Nautilus_Undo_Manager manager); -#endif /* NAUTILUS_UNDO_MANAGER_PRIVATE_H */
\ No newline at end of file +#endif /* NAUTILUS_UNDO_PRIVATE_H */ diff --git a/libnautilus/nautilus-undo-transaction.c b/libnautilus/nautilus-undo-transaction.c index 1d0ce5cea..5fc84eff5 100644 --- a/libnautilus/nautilus-undo-transaction.c +++ b/libnautilus/nautilus-undo-transaction.c @@ -1,6 +1,8 @@ /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* NautilusUndoTransaction - An object for an undoable transcation. +/* NautilusUndoTransaction - An object for an undoable transaction. + * Used internally by undo machinery. + * Not public. * * Copyright (C) 2000 Eazel, Inc. * @@ -23,330 +25,398 @@ */ #include <config.h> +#include "nautilus-undo-transaction.h" -#include <string.h> -#include <glib.h> -#include <gtk/gtksignal.h> -#include <gtk/gtkmain.h> #include <bonobo/bonobo-main.h> -#include <bonobo/bonobo-control.h> #include <libnautilus-extensions/nautilus-gtk-macros.h> +#include "nautilus-undo-private.h" -#include "nautilus-undo-transaction.h" +#define NAUTILUS_UNDO_TRANSACTION_LIST_DATA "Nautilus undo transaction list" typedef struct { - POA_Nautilus_Undo_Transaction servant; - gpointer bonobo_object; - - NautilusUndoTransaction *undo_transaction; + POA_Nautilus_Undo_Transaction servant; + NautilusUndoTransaction *bonobo_object; } impl_POA_Nautilus_Undo_Transaction; -/* GtkObject */ -static void nautilus_undo_transaction_initialize_class (NautilusUndoTransactionClass *class); -static void nautilus_undo_transaction_initialize (NautilusUndoTransaction *item); -static void nautilus_undo_transaction_destroy (GtkObject *object); -static void nautilus_undo_transaction_undo (NautilusUndoTransaction *transaction); - +static void nautilus_undo_transaction_initialize_class (NautilusUndoTransactionClass *class); +static void nautilus_undo_transaction_initialize (NautilusUndoTransaction *item); +static void nautilus_undo_transaction_destroy (GtkObject *object); +static void nautilus_undo_transaction_undo (NautilusUndoTransaction *transaction); /* CORBA/Bonobo */ -static Nautilus_Undo_MenuItem *impl_Nautilus_Undo_Transaction__get_undo_description (impl_POA_Nautilus_Undo_Transaction *servant, - CORBA_Environment *ev); -static Nautilus_Undo_MenuItem *impl_Nautilus_Undo_Transaction__get_redo_description (impl_POA_Nautilus_Undo_Transaction *servant, - CORBA_Environment *ev); -static CORBA_char *impl_Nautilus_Undo_Transaction__get_operation_name (impl_POA_Nautilus_Undo_Transaction *servant, - CORBA_Environment *ev); -static void impl_Nautilus_Undo_Transaction__undo (impl_POA_Nautilus_Undo_Transaction *servant, - CORBA_Environment *ev); - +static Nautilus_Undo_MenuItem *impl_Nautilus_Undo_Transaction__get_undo_menu_item (PortableServer_Servant servant, + CORBA_Environment *ev); +static Nautilus_Undo_MenuItem *impl_Nautilus_Undo_Transaction__get_redo_menu_item (PortableServer_Servant servant, + CORBA_Environment *ev); +static CORBA_char * impl_Nautilus_Undo_Transaction__get_operation_name (PortableServer_Servant servant, + CORBA_Environment *ev); +static void impl_Nautilus_Undo_Transaction__undo (PortableServer_Servant servant, + CORBA_Environment *ev); + +/* undo atoms */ +static void undo_atom_list_free (GList *list); +static void undo_atom_list_undo_and_free (GList *list); NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusUndoTransaction, nautilus_undo_transaction, BONOBO_OBJECT_TYPE) POA_Nautilus_Undo_Transaction__epv libnautilus_Nautilus_Undo_Transaction_epv = { - NULL, /* _private */ - - (gpointer) &impl_Nautilus_Undo_Transaction__get_undo_description, - (gpointer) &impl_Nautilus_Undo_Transaction__get_redo_description, - (gpointer) &impl_Nautilus_Undo_Transaction__get_operation_name, - (gpointer) &impl_Nautilus_Undo_Transaction__undo + NULL, + &impl_Nautilus_Undo_Transaction__get_undo_menu_item, + &impl_Nautilus_Undo_Transaction__get_redo_menu_item, + &impl_Nautilus_Undo_Transaction__get_operation_name, + &impl_Nautilus_Undo_Transaction__undo }; -static PortableServer_ServantBase__epv base_epv = { NULL, NULL, NULL }; - -static POA_Nautilus_Undo_Transaction__vepv impl_Nautilus_Undo_Transaction_vepv = +static PortableServer_ServantBase__epv base_epv; +static POA_Nautilus_Undo_Transaction__vepv vepv = { &base_epv, NULL, &libnautilus_Nautilus_Undo_Transaction_epv }; - static void -impl_Nautilus_Undo_Transaction__destroy(BonoboObject *obj, impl_POA_Nautilus_Undo_Transaction *servant) +impl_Nautilus_Undo_Transaction__destroy (BonoboObject *object, + PortableServer_Servant servant) { - PortableServer_ObjectId *objid; + PortableServer_ObjectId *object_id; CORBA_Environment ev; - void (*servant_destroy_func) (PortableServer_Servant servant, CORBA_Environment *ev); CORBA_exception_init (&ev); - servant_destroy_func = NAUTILUS_UNDO_TRANSACTION_CLASS (GTK_OBJECT (servant->undo_transaction)->klass)->servant_destroy_func; - objid = PortableServer_POA_servant_to_id (bonobo_poa (), servant, &ev); - PortableServer_POA_deactivate_object (bonobo_poa (), objid, &ev); - CORBA_free (objid); - obj->servant = NULL; + object_id = PortableServer_POA_servant_to_id (bonobo_poa (), servant, &ev); + PortableServer_POA_deactivate_object (bonobo_poa (), object_id, &ev); + CORBA_free (object_id); + object->servant = NULL; - servant_destroy_func ((PortableServer_Servant) servant, &ev); + POA_Nautilus_Undo_Transaction__fini (servant, &ev); g_free (servant); - CORBA_exception_free(&ev); -} + CORBA_exception_free (&ev); +} static Nautilus_Undo_Transaction -impl_Nautilus_Undo_Transaction__create (NautilusUndoTransaction *transaction, CORBA_Environment *ev) +impl_Nautilus_Undo_Transaction__create (NautilusUndoTransaction *bonobo_object, + CORBA_Environment *ev) { - Nautilus_Undo_Transaction retval; impl_POA_Nautilus_Undo_Transaction *servant; - void (*servant_init_func) (PortableServer_Servant servant, CORBA_Environment *ev); - NautilusUndoTransactionClass *transaction_class = NAUTILUS_UNDO_TRANSACTION_CLASS (GTK_OBJECT (transaction)->klass); - - servant_init_func = transaction_class->servant_init_func; servant = g_new0 (impl_POA_Nautilus_Undo_Transaction, 1); - servant->servant.vepv = transaction_class->vepv; - if (!servant->servant.vepv->Bonobo_Unknown_epv) - servant->servant.vepv->Bonobo_Unknown_epv = bonobo_object_get_epv (); - servant_init_func ((PortableServer_Servant) servant, ev); - - servant->undo_transaction = transaction; - retval = bonobo_object_activate_servant (BONOBO_OBJECT (transaction), servant); + vepv.Bonobo_Unknown_epv = bonobo_object_get_epv (); + servant->servant.vepv = &vepv; + POA_Nautilus_Undo_Transaction__init ((PortableServer_Servant) servant, ev); - gtk_signal_connect (GTK_OBJECT (transaction), "destroy", GTK_SIGNAL_FUNC (impl_Nautilus_Undo_Transaction__destroy), servant); + gtk_signal_connect (GTK_OBJECT (bonobo_object), "destroy", + GTK_SIGNAL_FUNC (impl_Nautilus_Undo_Transaction__destroy), + servant); - return retval; + servant->bonobo_object = bonobo_object; + return bonobo_object_activate_servant (BONOBO_OBJECT (bonobo_object), servant); } - static Nautilus_Undo_MenuItem * -impl_Nautilus_Undo_Transaction__get_undo_description (impl_POA_Nautilus_Undo_Transaction *servant, - CORBA_Environment *ev) +impl_Nautilus_Undo_Transaction__get_undo_menu_item (PortableServer_Servant servant, + CORBA_Environment *ev) { - Nautilus_Undo_MenuItem *item; NautilusUndoTransaction *transaction; + Nautilus_Undo_MenuItem *item; - CORBA_exception_init(ev); - - transaction = servant->undo_transaction; + transaction = ((impl_POA_Nautilus_Undo_Transaction *) servant)->bonobo_object; - item = ORBit_alloc (sizeof (Nautilus_Undo_MenuItem), NULL, NULL); - - item->name = ORBit_alloc (strlen (transaction->undo_menu_item_name) * sizeof (CORBA_char), NULL, NULL); - strcpy (item->name, transaction->undo_menu_item_name); - - item->description = ORBit_alloc (strlen (transaction->undo_menu_item_description) * sizeof (CORBA_char), NULL, NULL); - strcpy (item->description, transaction->undo_menu_item_description); - - CORBA_exception_free(ev); + item = Nautilus_Undo_MenuItem__alloc (); + item->label = CORBA_string_dup (transaction->undo_menu_item_label); + item->hint = CORBA_string_dup (transaction->undo_menu_item_hint); return item; } static Nautilus_Undo_MenuItem * -impl_Nautilus_Undo_Transaction__get_redo_description (impl_POA_Nautilus_Undo_Transaction *servant, - CORBA_Environment *ev) +impl_Nautilus_Undo_Transaction__get_redo_menu_item (PortableServer_Servant servant, + CORBA_Environment *ev) { - Nautilus_Undo_MenuItem *item; NautilusUndoTransaction *transaction; + Nautilus_Undo_MenuItem *item; - CORBA_exception_init(ev); - - transaction = servant->undo_transaction; + transaction = ((impl_POA_Nautilus_Undo_Transaction *) servant)->bonobo_object; - item = ORBit_alloc (sizeof (Nautilus_Undo_MenuItem), NULL, NULL); - - item->name = ORBit_alloc (strlen (transaction->redo_menu_item_name) * sizeof (CORBA_char), NULL, NULL); - strcpy (item->name, transaction->redo_menu_item_name); - - item->description = ORBit_alloc (strlen (transaction->redo_menu_item_description) * sizeof (CORBA_char), NULL, NULL); - strcpy (item->description, transaction->redo_menu_item_description); - - CORBA_exception_free(ev); + item = Nautilus_Undo_MenuItem__alloc (); + item->label = CORBA_string_dup (transaction->redo_menu_item_label); + item->hint = CORBA_string_dup (transaction->redo_menu_item_hint); return item; - } - + static CORBA_char * -impl_Nautilus_Undo_Transaction__get_operation_name (impl_POA_Nautilus_Undo_Transaction *servant, - CORBA_Environment *ev) +impl_Nautilus_Undo_Transaction__get_operation_name (PortableServer_Servant servant, + CORBA_Environment *ev) { NautilusUndoTransaction *transaction; - CORBA_char *operation_name; - CORBA_exception_init(ev); + transaction = ((impl_POA_Nautilus_Undo_Transaction *) servant)->bonobo_object; + return CORBA_string_dup (transaction->operation_name); +} - transaction = servant->undo_transaction; - - operation_name = ORBit_alloc (strlen (transaction->operation_name) * sizeof (CORBA_char), NULL, NULL); - strcpy (operation_name, transaction->operation_name); - - CORBA_exception_free(ev); +static void +impl_Nautilus_Undo_Transaction__undo (PortableServer_Servant servant, + CORBA_Environment *ev) +{ + NautilusUndoTransaction *transaction; - return operation_name; + transaction = ((impl_POA_Nautilus_Undo_Transaction *) servant)->bonobo_object; + nautilus_undo_transaction_undo (transaction); } - -static void -impl_Nautilus_Undo_Transaction__undo (impl_POA_Nautilus_Undo_Transaction *servant, CORBA_Environment *ev) -{ - nautilus_undo_transaction_undo (servant->undo_transaction); -} -/* nautilus_undo_transaction_new */ NautilusUndoTransaction * -nautilus_undo_transaction_new (const char *operation_name, const char *undo_menu_item_name, - const char *undo_menu_item_description, const char *redo_menu_item_name, - const char *redo_menu_item_description) +nautilus_undo_transaction_new (const char *operation_name, + const char *undo_menu_item_label, + const char *undo_menu_item_hint, + const char *redo_menu_item_label, + const char *redo_menu_item_hint) { NautilusUndoTransaction *transaction; transaction = gtk_type_new (nautilus_undo_transaction_get_type ()); transaction->operation_name = g_strdup (operation_name); - transaction->undo_menu_item_name = g_strdup (undo_menu_item_name); - transaction->undo_menu_item_description = g_strdup (undo_menu_item_description); - transaction->redo_menu_item_name = g_strdup (redo_menu_item_name); - transaction->redo_menu_item_description = g_strdup (redo_menu_item_description); + transaction->undo_menu_item_label = g_strdup (undo_menu_item_label); + transaction->undo_menu_item_hint = g_strdup (undo_menu_item_hint); + transaction->redo_menu_item_label = g_strdup (redo_menu_item_label); + transaction->redo_menu_item_hint = g_strdup (redo_menu_item_hint); return transaction; } - -/* Object initialization function for NautilusUndoTransaction */ static void nautilus_undo_transaction_initialize (NautilusUndoTransaction *transaction) { CORBA_Environment ev; - CORBA_exception_init(&ev); - - /* Create empty lists */ - transaction->transaction_list = NULL; + CORBA_exception_init (&ev); bonobo_object_construct (BONOBO_OBJECT (transaction), impl_Nautilus_Undo_Transaction__create (transaction, &ev)); + CORBA_exception_free (&ev); +} - CORBA_exception_free(&ev); +static void +remove_transaction_from_object (gpointer list_data, gpointer callback_data) +{ + NautilusUndoAtom *atom; + NautilusUndoTransaction *transaction; + GList *list; + + g_assert (list_data != NULL); + atom = list_data; + transaction = NAUTILUS_UNDO_TRANSACTION (callback_data); + + /* Remove the transaction from the list on the atom. */ + list = gtk_object_get_data (atom->target, NAUTILUS_UNDO_TRANSACTION_LIST_DATA); + list = g_list_remove (list, transaction); + gtk_object_set_data (atom->target, NAUTILUS_UNDO_TRANSACTION_LIST_DATA, list); } -/* nautilus_undo_transaction_destroy */ static void nautilus_undo_transaction_destroy (GtkObject *object) { NautilusUndoTransaction *transaction; - - g_return_if_fail (NAUTILUS_IS_UNDO_TRANSACTION (object)); + CORBA_Environment ev; transaction = NAUTILUS_UNDO_TRANSACTION (object); - /* Empty list */ - g_list_free(transaction->transaction_list); - - g_free(transaction->operation_name); - g_free(transaction->undo_menu_item_name); - g_free(transaction->undo_menu_item_description); - g_free(transaction->redo_menu_item_name); - g_free(transaction->redo_menu_item_description); + g_list_foreach (transaction->atom_list, + remove_transaction_from_object, + transaction); + undo_atom_list_free (transaction->atom_list); + + g_free (transaction->operation_name); + g_free (transaction->undo_menu_item_label); + g_free (transaction->undo_menu_item_hint); + g_free (transaction->redo_menu_item_label); + g_free (transaction->redo_menu_item_hint); + + CORBA_exception_init (&ev); + CORBA_Object_release (transaction->owner, &ev); + CORBA_exception_free (&ev); NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object)); } -/* Class initialization function for the NautilusUndoable item. */ static void nautilus_undo_transaction_initialize_class (NautilusUndoTransactionClass *klass) { - GtkObjectClass *object_class; + GTK_OBJECT_CLASS (klass)->destroy = nautilus_undo_transaction_destroy; +} - object_class = GTK_OBJECT_CLASS (klass); +void +nautilus_undo_transaction_add_atom (NautilusUndoTransaction *transaction, + const NautilusUndoAtom *atom) +{ + GList *list; + + g_return_if_fail (NAUTILUS_IS_UNDO_TRANSACTION (transaction)); + g_return_if_fail (atom != NULL); + g_return_if_fail (GTK_IS_OBJECT (atom->target)); - object_class->destroy = nautilus_undo_transaction_destroy; + /* Add the atom to the atom list in the transaction. */ + transaction->atom_list = g_list_append + (transaction->atom_list, g_memdup (atom, sizeof (*atom))); - klass->servant_init_func = POA_Nautilus_Undo_Transaction__init; - klass->servant_destroy_func = POA_Nautilus_Undo_Transaction__fini; - klass->vepv = &impl_Nautilus_Undo_Transaction_vepv; + /* Add the transaction to the list on the atom. */ + list = gtk_object_get_data (atom->target, NAUTILUS_UNDO_TRANSACTION_LIST_DATA); + if (g_list_find (list, transaction) != NULL) { + return; + } + + /* If it's not already on that atom, this object is new. */ + list = g_list_prepend (list, transaction); + gtk_object_set_data (atom->target, NAUTILUS_UNDO_TRANSACTION_LIST_DATA, list); + + /* Connect a signal handler to the atom so it will unregister + * itself when it's destroyed. + */ + gtk_signal_connect (atom->target, "destroy", + GTK_SIGNAL_FUNC (nautilus_undo_transaction_unregister_object), + NULL); } -/* nautilus_undo_transaction_add_undoable */ -gboolean -nautilus_undo_transaction_add_undoable (NautilusUndoTransaction *transaction, - NautilusUndoable *undoable) -{ - if (transaction == NULL) { - g_warning ("Cannot add undoable to a NULL transaction"); - return FALSE; +void +nautilus_undo_transaction_undo (NautilusUndoTransaction *transaction) +{ + g_return_if_fail (NAUTILUS_IS_UNDO_TRANSACTION (transaction)); + + undo_atom_list_undo_and_free (transaction->atom_list); + transaction->atom_list = NULL; +} + +void +nautilus_undo_transaction_add_to_undo_manager (NautilusUndoTransaction *transaction, + Nautilus_Undo_Manager manager) +{ + CORBA_Environment ev; + + g_return_if_fail (NAUTILUS_IS_UNDO_TRANSACTION (transaction)); + g_return_if_fail (transaction->owner == CORBA_OBJECT_NIL); + + CORBA_exception_init (&ev); + + if (!CORBA_Object_is_nil (manager, &ev)) { + Nautilus_Undo_Manager_append + (manager, + bonobo_object_corba_objref (BONOBO_OBJECT (transaction)), + &ev); + transaction->owner = CORBA_Object_duplicate (manager, &ev); + } + + CORBA_exception_free (&ev); +} + +static void +remove_atoms (NautilusUndoTransaction *transaction, + GtkObject *object) +{ + CORBA_Environment ev; + GList *p, *next; + NautilusUndoAtom *atom; + + g_assert (NAUTILUS_IS_UNDO_TRANSACTION (transaction)); + g_assert (GTK_IS_OBJECT (object)); + + CORBA_exception_init (&ev); + + /* Destroy any atoms for this object. */ + for (p = transaction->atom_list; p != NULL; p = next) { + atom = p->data; + next = p->next; + + if (atom->target == object) { + transaction->atom_list = g_list_remove_link + (transaction->atom_list, p); + undo_atom_list_free (p); + } } - if (undoable == NULL) { - g_warning ("Cannot add a NULL undoable to a transaction"); - return FALSE; + /* If all the atoms are gone, forget this transaction. + * This may end up freeing the transaction. + */ + if (transaction->atom_list == NULL) { + Nautilus_Undo_Manager_forget + (transaction->owner, + bonobo_object_corba_objref (BONOBO_OBJECT (transaction)), + &ev); } - transaction->transaction_list = g_list_append (transaction->transaction_list, undoable); - - return TRUE; + CORBA_exception_free (&ev); } +static void +remove_atoms_cover (gpointer list_data, gpointer callback_data) +{ + remove_atoms (NAUTILUS_UNDO_TRANSACTION (list_data), GTK_OBJECT (callback_data)); +} +void +nautilus_undo_transaction_unregister_object (GtkObject *object) +{ + GList *list; -/* nautilus_undo_transaction_undo - * Parse transaction and send undo signals to undoable objects stored in transaction - */ + g_return_if_fail (GTK_IS_OBJECT (object)); -void -nautilus_undo_transaction_undo (NautilusUndoTransaction *transaction) + /* Remove atoms from each transaction on the list. */ + list = gtk_object_get_data (object, NAUTILUS_UNDO_TRANSACTION_LIST_DATA); + g_list_foreach (list, remove_atoms_cover, object); + g_list_free (list); + gtk_object_remove_data (object, NAUTILUS_UNDO_TRANSACTION_LIST_DATA); +} + +static void +undo_atom_free (NautilusUndoAtom *atom) { - NautilusUndoable *undoable; - guint index; - - if (transaction == NULL) { - return; + /* Call the destroy-notify function if it's present. */ + if (atom->callback_data_destroy_notify != NULL) { + (* atom->callback_data_destroy_notify) (atom->callback_data); } - for ( index = 0; index < g_list_length (transaction->transaction_list); index++) { + /* Free the atom storage. */ + g_free (atom); +} - /* Get pointer to undoable */ - undoable = g_list_nth_data (transaction->transaction_list, index); +static void +undo_atom_undo_and_free (NautilusUndoAtom *atom) +{ + /* Call the function that does the actual undo. */ + (* atom->callback) (atom->target, atom->callback_data); - /* Send object restore from undo signal */ - if (undoable != NULL) { - nautilus_undoable_restore_from_undo_snapshot (undoable); - } - } + /* Get rid of the atom now that it's spent. */ + undo_atom_free (atom); } +static void +undo_atom_free_cover (gpointer atom, gpointer callback_data) +{ + g_assert (atom != NULL); + g_assert (callback_data == NULL); + undo_atom_free (atom); +} -/* nautilus_undo_transaction_contains_object - * - * Return TRUE if object is contained by transaction - */ -gboolean -nautilus_undo_transaction_contains_object (NautilusUndoTransaction *transaction, - GtkObject *object) +static void +undo_atom_undo_and_free_cover (gpointer atom, gpointer callback_data) { - NautilusUndoable *undoable; - gint index; - - g_return_val_if_fail(transaction != NULL, FALSE); - - for ( index = 0; index < g_list_length(transaction->transaction_list); index++) { - - /* Get pointer to undoable */ - undoable = g_list_nth_data(transaction->transaction_list, index); - - /* Check and see if we have a target object match */ - if (undoable != NULL && undoable->undo_target_class == object) { - return TRUE; - } - } + g_assert (atom != NULL); + g_assert (callback_data == NULL); + undo_atom_undo_and_free (atom); +} - return FALSE; +static void +undo_atom_list_free (GList *list) +{ + g_list_foreach (list, undo_atom_free_cover, NULL); + g_list_free (list); +} + +static void +undo_atom_list_undo_and_free (GList *list) +{ + g_list_foreach (list, undo_atom_undo_and_free_cover, NULL); + g_list_free (list); } diff --git a/libnautilus/nautilus-undo-transaction.h b/libnautilus/nautilus-undo-transaction.h index 2e46ef7e6..6c8345af4 100644 --- a/libnautilus/nautilus-undo-transaction.h +++ b/libnautilus/nautilus-undo-transaction.h @@ -1,6 +1,8 @@ /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* NautilusUndoTransaction - An object for an undoable transcation. +/* NautilusUndoTransaction - An object for an undoable transaction. + * Used internally by undo machinery. + * Not public. * * Copyright (C) 2000 Eazel, Inc. * @@ -25,10 +27,8 @@ #ifndef NAUTILUS_UNDO_TRANSACTION_H #define NAUTILUS_UNDO_TRANSACTION_H -#include <glib.h> -#include <bonobo/bonobo-object.h> -#include "nautilus-undoable.h" #include "nautilus-undo.h" +#include "nautilus-distributed-undo.h" #define NAUTILUS_TYPE_UNDO_TRANSACTION \ (nautilus_undo_transaction_get_type ()) @@ -41,32 +41,33 @@ #define NAUTILUS_IS_UNDO_TRANSACTION_CLASS(klass) \ (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_UNDO_TRANSACTION)) -typedef struct NautilusUndoTransactionClass NautilusUndoTransactionClass; +typedef struct { + BonoboObject parent_slot; - -struct NautilusUndoTransaction { - BonoboObject parent; char *operation_name; - char *undo_menu_item_name; - char *undo_menu_item_description; - char *redo_menu_item_name; - char *redo_menu_item_description; - GList *transaction_list; -}; + char *undo_menu_item_label; + char *undo_menu_item_hint; + char *redo_menu_item_label; + char *redo_menu_item_hint; + GList *atom_list; -struct NautilusUndoTransactionClass { - BonoboObjectClass parent_class; - gpointer servant_init_func, servant_destroy_func, vepv; -}; + Nautilus_Undo_Manager owner; +} NautilusUndoTransaction; -GtkType nautilus_undo_transaction_get_type (void); -NautilusUndoTransaction *nautilus_undo_transaction_new (const char *operation_name, - const char *undo_menu_item_name, - const char *undo_menu_item_description, - const char *redo_menu_item_name, - const char *redo_menu_item_description); -gboolean nautilus_undo_transaction_add_undoable (NautilusUndoTransaction *transaction, - NautilusUndoable *undoable); -gboolean nautilus_undo_transaction_contains_object (NautilusUndoTransaction *transaction, - GtkObject *object); -#endif +typedef struct { + BonoboObjectClass parent_slot; +} NautilusUndoTransactionClass; + +GtkType nautilus_undo_transaction_get_type (void); +NautilusUndoTransaction *nautilus_undo_transaction_new (const char *operation_name, + const char *undo_menu_item_label, + const char *undo_menu_item_hint, + const char *redo_menu_item_label, + const char *redo_menu_item_hint); +void nautilus_undo_transaction_add_atom (NautilusUndoTransaction *transaction, + const NautilusUndoAtom *atom); +void nautilus_undo_transaction_add_to_undo_manager (NautilusUndoTransaction *transaction, + Nautilus_Undo_Manager manager); +void nautilus_undo_transaction_unregister_object (GtkObject *atom_target); + +#endif /* NAUTILUS_UNDO_TRANSACTION_H */ diff --git a/libnautilus/nautilus-undo.c b/libnautilus/nautilus-undo.c new file mode 100644 index 000000000..f5cc24e13 --- /dev/null +++ b/libnautilus/nautilus-undo.c @@ -0,0 +1,305 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* nautilus-undo.c - public interface for objects that implement + * undoable actions -- works across components + * + * Copyright (C) 2000 Eazel, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Darin Adler <darin@eazel.com> + */ + +#include <config.h> +#include "nautilus-undo.h" + +#include "nautilus-undo-private.h" +#include "nautilus-undo-transaction.h" +#include <libgnomeui/gnome-canvas.h> + +#define NAUTILUS_UNDO_MANAGER_DATA "Nautilus undo manager" + +/* Register a simple undo action by calling nautilus_undo_register_full. */ +void +nautilus_undo_register (GtkObject *target, + NautilusUndoCallback callback, + gpointer callback_data, + GDestroyNotify callback_data_destroy_notify, + const char *operation_name, + const char *undo_menu_item_label, + const char *undo_menu_item_hint, + const char *redo_menu_item_label, + const char *redo_menu_item_hint) +{ + NautilusUndoAtom atom; + GList single_atom_list; + + g_return_if_fail (GTK_IS_OBJECT (target)); + g_return_if_fail (callback != NULL); + + /* Make an atom. */ + atom.target = target; + atom.callback = callback; + atom.callback_data = callback_data; + atom.callback_data_destroy_notify = callback_data_destroy_notify; + + /* Make a single-atom list. */ + single_atom_list.data = &atom; + single_atom_list.next = NULL; + single_atom_list.prev = NULL; + + /* Call the full version of the registration function, + * using the undo target as the place to search for the + * undo manager. + */ + nautilus_undo_register_full (&single_atom_list, + target, + operation_name, + undo_menu_item_label, + undo_menu_item_hint, + redo_menu_item_label, + redo_menu_item_hint); +} + +/* Register an undo action. */ +void +nautilus_undo_register_full (GList *atoms, + GtkObject *undo_manager_search_start_object, + const char *operation_name, + const char *undo_menu_item_label, + const char *undo_menu_item_hint, + const char *redo_menu_item_label, + const char *redo_menu_item_hint) +{ + NautilusUndoTransaction *transaction; + GList *p; + + g_return_if_fail (atoms != NULL); + g_return_if_fail (GTK_IS_OBJECT (undo_manager_search_start_object)); + + /* Create an undo transaction */ + transaction = nautilus_undo_transaction_new (operation_name, + undo_menu_item_label, + undo_menu_item_hint, + redo_menu_item_label, + redo_menu_item_hint); + for (p = atoms; p != NULL; p = p->next) { + nautilus_undo_transaction_add_atom (transaction, p->data); + } + nautilus_undo_transaction_add_to_undo_manager + (transaction, + nautilus_undo_get_undo_manager (undo_manager_search_start_object)); + + /* Now we are done with the transaction. + * If the undo manager is holding it, then this will not destroy it. + */ + bonobo_object_unref (BONOBO_OBJECT (transaction)); +} + +/* Cover for forgetting about all undo relating to a particular target. */ +void +nautilus_undo_unregister (GtkObject *target) +{ + /* Perhaps this should also unregister all children if called on a + * GtkContainer? That might be handy. + */ + nautilus_undo_transaction_unregister_object (target); +} + +void +nautilus_undo (GtkObject *undo_manager_search_start_object) +{ + Nautilus_Undo_Manager manager; + CORBA_Environment ev; + + g_return_if_fail (GTK_IS_OBJECT (undo_manager_search_start_object)); + + CORBA_exception_init (&ev); + + manager = nautilus_undo_get_undo_manager (undo_manager_search_start_object); + if (!CORBA_Object_is_nil (manager, &ev)) { + Nautilus_Undo_Manager_undo (manager, &ev); + } + + CORBA_exception_free (&ev); +} + +Nautilus_Undo_Manager +nautilus_undo_get_undo_manager (GtkObject *start_object) +{ + Nautilus_Undo_Manager manager; + GtkWidget *parent; + GtkWindow *transient_parent; + + if (start_object == NULL) { + return CORBA_OBJECT_NIL; + } + + g_return_val_if_fail (GTK_IS_OBJECT (start_object), NULL); + + /* Check for an undo manager right here. */ + manager = gtk_object_get_data (start_object, NAUTILUS_UNDO_MANAGER_DATA); + if (manager != NULL) { + return manager; + } + + /* Check for undo manager up the parent chain. */ + if (GTK_IS_WIDGET (start_object)) { + parent = GTK_WIDGET (start_object)->parent; + if (parent != NULL) { + manager = nautilus_undo_get_undo_manager (GTK_OBJECT (parent)); + if (manager != NULL) { + return manager; + } + } + + /* Check for undo manager in our window's parent. */ + if (GTK_IS_WINDOW (start_object)) { + transient_parent = GTK_WINDOW (start_object)->transient_parent; + if (transient_parent != NULL) { + manager = nautilus_undo_get_undo_manager (GTK_OBJECT (transient_parent)); + if (manager != NULL) { + return manager; + } + } + } + } + + /* In the case of a canvas item, try the canvas. */ + if (GNOME_IS_CANVAS_ITEM (start_object)) { + manager = nautilus_undo_get_undo_manager (GTK_OBJECT (GNOME_CANVAS_ITEM (start_object)->canvas)); + if (manager != NULL) { + return manager; + } + } + + /* Found nothing. I can live with that. */ + return CORBA_OBJECT_NIL; +} + +static Nautilus_Undo_Manager +undo_manager_ref (Nautilus_Undo_Manager manager) +{ + CORBA_Environment ev; + Nautilus_Undo_Manager result; + + CORBA_exception_init (&ev); + Nautilus_Undo_Manager_ref (manager, &ev); + result = CORBA_Object_duplicate (manager, &ev); + CORBA_exception_free (&ev); + + return result; +} + +static void +undo_manager_unref (Nautilus_Undo_Manager manager) +{ + CORBA_Environment ev; + + CORBA_exception_init (&ev); + Nautilus_Undo_Manager_unref (manager, &ev); + CORBA_Object_release (manager, &ev); + CORBA_exception_free (&ev); +} + +static void +undo_manager_unref_cover (gpointer manager) +{ + undo_manager_unref (manager); +} + +void +nautilus_undo_attach_undo_manager (GtkObject *object, + Nautilus_Undo_Manager manager) +{ + g_return_if_fail (GTK_IS_OBJECT (object)); + + if (manager == NULL) { + gtk_object_remove_data (object, NAUTILUS_UNDO_MANAGER_DATA); + } else { + gtk_object_set_data_full + (object, NAUTILUS_UNDO_MANAGER_DATA, + undo_manager_ref (manager), undo_manager_unref_cover); + } +} + +/* Copy a reference to the undo manager fromone object to another. */ +void +nautilus_undo_share_undo_manager (GtkObject *destination_object, + GtkObject *source_object) +{ + Nautilus_Undo_Manager manager; + CORBA_Environment ev; + + manager = nautilus_undo_get_undo_manager (source_object); + + nautilus_undo_attach_undo_manager + (destination_object, manager); + + CORBA_exception_init (&ev); + CORBA_Object_release (manager, &ev); + CORBA_exception_free (&ev); +} + +/* Locates an undo manager for this bonobo control. + * The undo manager is supplied by an interface on + * the control frame. The put that undo manager on + * the Bonobo control's widget. + */ +static void +set_up_bonobo_control (BonoboControl *control) +{ + Nautilus_Undo_Manager manager; + Bonobo_ControlFrame control_frame; + CORBA_Environment ev; + Nautilus_Undo_Context undo_context; + GtkWidget *widget; + + g_assert (BONOBO_IS_CONTROL (control)); + + manager = CORBA_OBJECT_NIL; + + CORBA_exception_init (&ev); + + /* Find the undo manager. */ + control_frame = bonobo_control_get_control_frame (control); + if (!CORBA_Object_is_nil (control_frame, &ev)) { + undo_context = Bonobo_Control_query_interface + (control_frame, "IDL:Nautilus/Undo/Context:1.0", &ev); + if (!CORBA_Object_is_nil (undo_context, &ev)) { + manager = Nautilus_Undo_Context__get_undo_manager (undo_context, &ev); + } + CORBA_Object_release (undo_context, &ev); + } + CORBA_Object_release (control_frame, &ev); + + /* Attach the undo manager to the widget, or detach the old one. */ + widget = bonobo_control_get_widget (control); + nautilus_undo_attach_undo_manager (GTK_OBJECT (widget), manager); + CORBA_Object_release (manager, &ev); + + CORBA_exception_free (&ev); +} + +void +nautilus_undo_set_up_bonobo_control (BonoboControl *control) +{ + g_return_if_fail (BONOBO_IS_CONTROL (control)); + + set_up_bonobo_control (control); + gtk_signal_connect (GTK_OBJECT (control), "set_frame", + GTK_SIGNAL_FUNC (set_up_bonobo_control), NULL); +} diff --git a/libnautilus/nautilus-undo.h b/libnautilus/nautilus-undo.h new file mode 100644 index 000000000..76f684a8d --- /dev/null +++ b/libnautilus/nautilus-undo.h @@ -0,0 +1,74 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ + +/* nautilus-undo.h - public interface for objects that implement + * undoable actions -- works across components + * + * Copyright (C) 2000 Eazel, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Darin Adler <darin@eazel.com> + */ + +#ifndef NAUTILUS_UNDO_H +#define NAUTILUS_UNDO_H + +#include <bonobo/bonobo-control.h> + +/* The basic undoable operation. */ +typedef void (* NautilusUndoCallback) (GtkObject *target, gpointer callback_data); + +/* Recipe for undo of a bit of work on an object. + * Create these atoms when you want to register more + * than one as a single undoable operation. + */ +typedef struct { + GtkObject *target; + NautilusUndoCallback callback; + gpointer callback_data; + GDestroyNotify callback_data_destroy_notify; +} NautilusUndoAtom; + +/* Registering something that can be undone. */ +void nautilus_undo_register (GtkObject *target, + NautilusUndoCallback callback, + gpointer callback_data, + GDestroyNotify callback_data_destroy_notify, + const char *operation_name, + const char *undo_menu_item_label, + const char *undo_menu_item_hint, + const char *redo_menu_item_label, + const char *redo_menu_item_hint); +void nautilus_undo_register_full (GList *atoms, + GtkObject *undo_manager_search_start_object, + const char *operation_name, + const char *undo_menu_item_label, + const char *undo_menu_item_hint, + const char *redo_menu_item_label, + const char *redo_menu_item_hint); +void nautilus_undo_unregister (GtkObject *target); + +/* Performing an undo explicitly. Only for use by objects "out in the field". + * The menu bar itself uses a richer API in the undo manager. + */ +void nautilus_undo (GtkObject *undo_manager_search_start_object); + +/* Connecting an undo manager. */ +void nautilus_undo_share_undo_manager (GtkObject *destination_object, + GtkObject *source_object); +void nautilus_undo_set_up_bonobo_control (BonoboControl *control); + +#endif /* NAUTILUS_UNDO_H */ diff --git a/libnautilus/nautilus-undo.idl b/libnautilus/nautilus-undo.idl deleted file mode 100644 index 49476af93..000000000 --- a/libnautilus/nautilus-undo.idl +++ /dev/null @@ -1,102 +0,0 @@ -/* -*- Mode: IDL; tab-width: 8; indent-tabs-mode: 8; c-basic-offset: 8 -*- */ - -/* nautilus-undo.idl - Interface for view components that - * support undo, used internally by the - * undo support classes. - * - * Copyright (C) 2000 Eazel, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef NAUTUILUS_UNDO_IDL_INCLUDED -#define NAUTUILUS_UNDO_IDL_INCLUDED - -#include <Bonobo.idl> - -module Nautilus { - - module Undo { - - /* The specifications for a menu item. */ - struct MenuItem { - string name; - string description; - }; - - /* A single undoable operation is represented by a - * transaction. This is the interface a transaction - * must supply for use by an undo manager. - */ - interface Transaction : ::Bonobo::Unknown { - /* These descriptions are used to display undo - * or redo menu items for this transaction. - * The base description is for lists of undoable - * operations that are listed somewhere other - * than an undo or redo object. - */ - readonly attribute MenuItem undo_description; - readonly attribute MenuItem redo_description; - readonly attribute string operation_name; - - /* Here's how you actually perform an undo. - * Once it's performed, calling this again is - * safe; it's guaranteed to do nothing. - */ - void undo (); - }; - - /* An undo manager deals with a list of transactions - * for a particular application or window. This is the - * interface of the manager from the transaction's - * point of view only. - */ - interface Manager : ::Bonobo::Unknown { - /* Add a new transaction. This is normally called - * by the code that creates the transaction. - */ - void append (in Transaction transaction); - - /* Forget a transaction. This is typically called - * when the operation that the transaction does - * undo for no longer makes sense. - */ - void forget (in Transaction transaction); - - /* Sometimes an undo has to be "forced" from the - * client side when it recognizes an undo key - * equivalent. - */ - void undo (); - - /* FIXME: We may need additional interface so the - * client can include an appropriate undo item in - * a contextual menu. - */ - }; - - /* To locate the appropriate manager, a view component - * can query for this interface on its Bonobo control - * frame. This is done automatically by functions in - * the undo manager. - */ - interface Context : ::Bonobo::Unknown { - readonly attribute Manager undo_manager; - }; - }; -}; - -#endif /* NAUTUILUS_UNDO_IDL_INCLUDED */ diff --git a/libnautilus/nautilus-undoable.c b/libnautilus/nautilus-undoable.c deleted file mode 100644 index 2bbdab4e4..000000000 --- a/libnautilus/nautilus-undoable.c +++ /dev/null @@ -1,392 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ - -/* NautilusUndoable - A container for an undoable object . - * - * Copyright (C) 2000 Eazel, Inc. - * - * Author: Gene Z. Ragan <gzr@eazel.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include <config.h> -#include "nautilus-undoable.h" - -#include <gtk/gtksignal.h> -#include <gtk/gtkmain.h> -#include <glib.h> - -#include <libnautilus-extensions/nautilus-gnome-extensions.h> -#include <libnautilus-extensions/nautilus-gtk-extensions.h> -#include <libnautilus-extensions/nautilus-gtk-macros.h> -#include <libnautilus-extensions/nautilus-gtk-macros.h> -#include <libnautilus/nautilus-undo.h> - -#include "nautilus-undo-manager.h" - -enum { - SAVE_UNDO_SNAPSHOT, - RESTORE_FROM_UNDO_SNAPSHOT, - LAST_SIGNAL -}; -static guint signals[LAST_SIGNAL]; - - -/* GtkObject */ -static void nautilus_undoable_initialize_class (NautilusUndoableClass *class); -static void nautilus_undoable_initialize (NautilusUndoable *item); -static void destroy (GtkObject *object); - -NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusUndoable, nautilus_undoable, GTK_TYPE_OBJECT) - - -/* Class initialization function for the NautilusUndoable item. */ -static void -nautilus_undoable_initialize_class (NautilusUndoableClass *class) -{ - GtkObjectClass *object_class; - - object_class = GTK_OBJECT_CLASS (class); - - object_class->destroy = destroy; - - signals[SAVE_UNDO_SNAPSHOT] - = gtk_signal_new ("save_undo_snapshot", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusUndoableClass, - save_undo_snapshot), - gtk_marshal_NONE__POINTER, - GTK_TYPE_NONE, 1, - GTK_TYPE_POINTER); - - signals[RESTORE_FROM_UNDO_SNAPSHOT] - = gtk_signal_new ("restore_from_undo_snapshot", - GTK_RUN_LAST, - object_class->type, - GTK_SIGNAL_OFFSET (NautilusUndoableClass, - restore_from_undo_snapshot), - gtk_marshal_NONE__POINTER, - GTK_TYPE_NONE, 1, - GTK_TYPE_POINTER); - - gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL); -} - -/* Object initialization function for the NautilusUndoable. */ -static void -nautilus_undoable_initialize (NautilusUndoable *undoable) -{ - g_datalist_init(&undoable->undo_data); -} - - -GtkObject * -nautilus_undoable_new (void) -{ - GtkObject *new; - - new = gtk_type_new (nautilus_undoable_get_type ()); - - return new; -} - - - -/* destroy */ -static void -destroy (GtkObject *object) -{ - NautilusUndoable *undoable; - - g_return_if_fail (NAUTILUS_IS_UNDOABLE (object)); - - undoable = NAUTILUS_UNDOABLE(object); - - g_datalist_clear(&undoable->undo_data); - - NAUTILUS_CALL_PARENT_CLASS (GTK_OBJECT_CLASS, destroy, (object)); -} - - -/* nautilus_undoable_save_undo_snapshot */ -void -nautilus_undoable_save_undo_snapshot (NautilusUndoTransaction *transaction, GtkObject *target, - GtkSignalFunc save_func, GtkSignalFunc restore_func) -{ - gboolean result; - NautilusUndoable *undoable; - GList *transaction_list; - - /* Init Undoable */ - undoable = NAUTILUS_UNDOABLE(nautilus_undoable_new()); - - /* Set target */ - undoable->undo_target_class = target; - - /* Connect signals to target object */ - gtk_signal_connect_while_alive (GTK_OBJECT (undoable), "save_undo_snapshot", save_func, target, target); - gtk_signal_connect_while_alive (GTK_OBJECT (undoable), "restore_from_undo_snapshot", restore_func, target, target); - - /* Add undoable to current transaction */ - result = nautilus_undo_transaction_add_undoable (transaction, undoable); - - /* Add transaction to objects transaction list */ - transaction_list = gtk_object_get_data (target, NAUTILUS_UNDO_TRANSACTION_LIST_NAME); - if (transaction_list == NULL) { - /* Create list and add to object */ - transaction_list = g_list_alloc(); - transaction_list = NULL; - gtk_object_set_data (target, NAUTILUS_UNDO_TRANSACTION_LIST_NAME, transaction_list); - } - transaction_list = g_list_append (transaction_list, undoable); - - /* Fire SAVE_UNDO_SNAPSHOT signal */ - gtk_signal_emit (GTK_OBJECT (undoable), - signals[SAVE_UNDO_SNAPSHOT], - undoable); -} - - -/* nautilus_undoable_restore_from_undo_snapshot */ -void -nautilus_undoable_restore_from_undo_snapshot (NautilusUndoable *undoable) -{ - gtk_signal_emit (GTK_OBJECT (undoable), - signals[RESTORE_FROM_UNDO_SNAPSHOT], - undoable); -} - -/* Register a simple undo action by calling nautilus_undo_register_full. */ -void -nautilus_undo_register (GtkObject *target, - NautilusUndoCallback callback, - gpointer callback_data, - GDestroyNotify callback_data_destroy_notify, - const char *operation_name, - const char *undo_menu_item_name, - const char *undo_menu_item_description, - const char *redo_menu_item_name, - const char *redo_menu_item_description) -{ - NautilusUndoAtom atom; - GList single_atom_list; - - g_return_if_fail (GTK_IS_OBJECT (target)); - g_return_if_fail (callback != NULL); - - /* Make an atom. */ - atom.target = target; - atom.callback = callback; - atom.callback_data = callback_data; - atom.callback_data_destroy_notify = callback_data_destroy_notify; - - /* Make a single-atom list. */ - single_atom_list.data = &atom; - single_atom_list.next = NULL; - single_atom_list.prev = NULL; - - /* Call the full version of the registration function, - * using the undo target as the place to search for the - * undo manager. - */ - nautilus_undo_register_full (&single_atom_list, - target, - operation_name, - undo_menu_item_name, - undo_menu_item_description, - redo_menu_item_name, - redo_menu_item_description); -} - -static void -undo_atom_destroy_callback_data (NautilusUndoAtom *atom) -{ - if (atom->callback_data_destroy_notify != NULL) { - (* atom->callback_data_destroy_notify) (atom->callback_data); - } -} - -static void -undo_atom_destroy (NautilusUndoAtom *atom) -{ - undo_atom_destroy_callback_data (atom); - g_free (atom); -} - -static void -undo_atom_destroy_notify_cover (gpointer data) -{ - undo_atom_destroy (data); -} - -static void -undo_atom_destroy_callback_data_g_func_cover (gpointer data, gpointer callback_data) -{ - undo_atom_destroy_callback_data (data); -} - -/* This is a temporary hack to make things work with NautilusUndoable. */ -static NautilusUndoAtom *atom_global_hack; - -/* The saving has already been done. - * We just use the save callback as a way to connect the atom to the - * undoable object that's created. - */ -static void -save_callback (NautilusUndoable *undoable) -{ - gtk_object_set_data_full (GTK_OBJECT (undoable), - "Nautilus undo atom", - atom_global_hack, - undo_atom_destroy_notify_cover); -} - -static void -restore_callback (NautilusUndoable *undoable) -{ - NautilusUndoAtom *atom; - - atom = gtk_object_get_data (GTK_OBJECT (undoable), - "Nautilus undo atom"); - (* atom->callback) (atom->target, atom->callback_data); -} - -/* Register an undo action. */ -void -nautilus_undo_register_full (GList *atoms, - GtkObject *undo_manager_search_start_object, - const char *operation_name, - const char *undo_menu_item_name, - const char *undo_menu_item_description, - const char *redo_menu_item_name, - const char *redo_menu_item_description) -{ - Nautilus_Undo_Manager manager; - NautilusUndoTransaction *transaction; - Nautilus_Undo_Transaction corba_transaction; - NautilusUndoAtom *atom; - GList *p; - CORBA_Environment ev; - - g_return_if_fail (atoms != NULL); - g_return_if_fail (GTK_IS_OBJECT (undo_manager_search_start_object)); - - CORBA_exception_init (&ev); - - /* Note that this is just a hack in terms of the existing stuff. - * A lot of things could be simplified and we can probably get rid of - * NautilusUndoable entirely (maybe replace it with NautilusUndoAtom). - */ - manager = nautilus_get_undo_manager (undo_manager_search_start_object); - if (CORBA_Object_is_nil (manager, &ev)) { - g_list_foreach (atoms, undo_atom_destroy_callback_data_g_func_cover, NULL); - CORBA_exception_free (&ev); - return; - } - - /* Create an undo transaction */ - transaction = nautilus_undo_transaction_new (operation_name, undo_menu_item_name, - undo_menu_item_description, - redo_menu_item_name, - redo_menu_item_description); - for (p = atoms; p != NULL; p = p->next) { - atom = p->data; - - atom_global_hack = g_memdup (atom, sizeof (*atom)); - nautilus_undoable_save_undo_snapshot - (transaction, atom->target, - GTK_SIGNAL_FUNC (save_callback), - GTK_SIGNAL_FUNC (restore_callback)); - - /* Connect a signal handler so this object will unregister - * itself when it's destroyed. - */ - gtk_signal_connect - (atom->target, "destroy", - GTK_SIGNAL_FUNC (nautilus_undo_unregister), NULL); - } - - /* Get CORBA object and add to undo manager. */ - corba_transaction = bonobo_object_corba_objref (BONOBO_OBJECT (transaction)); - Nautilus_Undo_Manager_append (manager, corba_transaction, &ev); - - /* Now we are done with the transaction. */ - bonobo_object_unref (BONOBO_OBJECT (transaction)); - - CORBA_exception_free (&ev); -} - -/* Cover for forgetting about all undo relating to a particular target. */ -void -nautilus_undo_unregister (GtkObject *target) -{ - Nautilus_Undo_Manager manager; - GList *transaction_list, *p; - CORBA_Environment ev; - Nautilus_Undo_Transaction transaction; - - g_return_if_fail (GTK_IS_OBJECT (target)); - - /* Perhaps this should also unregister all children if called on a - * GtkContainer? That might be handy. - */ - - CORBA_exception_init (&ev); - - manager = nautilus_get_undo_manager (GTK_OBJECT (target)); - if (CORBA_Object_is_nil (manager, &ev)) { - CORBA_exception_free (&ev); - return; - } - - transaction_list = gtk_object_get_data (target, NAUTILUS_UNDO_TRANSACTION_LIST_NAME); - if (transaction_list == NULL) { - CORBA_exception_free (&ev); - return; - } - - for (p = transaction_list; p != NULL; p = p->next) { - /* Get pointer to transaction */ - transaction = p->data; - if (!CORBA_Object_is_nil (transaction, &ev)) { - Nautilus_Undo_Manager_forget (manager, transaction, &ev); - } - } - - gtk_object_remove_data (target, NAUTILUS_UNDO_TRANSACTION_LIST_NAME); - g_list_free (transaction_list); - - CORBA_exception_free (&ev); -} - -void -nautilus_undo (GtkObject *undo_manager_search_start_object) -{ - Nautilus_Undo_Manager manager; - CORBA_Environment ev; - - g_return_if_fail (GTK_IS_OBJECT (undo_manager_search_start_object)); - - CORBA_exception_init (&ev); - - manager = nautilus_get_undo_manager (undo_manager_search_start_object); - if (!CORBA_Object_is_nil (manager, &ev)) { - Nautilus_Undo_Manager_undo (manager, &ev); - } - - CORBA_exception_free (&ev); -} diff --git a/libnautilus/nautilus-undoable.h b/libnautilus/nautilus-undoable.h deleted file mode 100644 index 1230cf1df..000000000 --- a/libnautilus/nautilus-undoable.h +++ /dev/null @@ -1,113 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ - -/* NautilusUndoable - A container for an undoable object . - * - * Copyright (C) 2000 Eazel, Inc. - * - * Author: Gene Z. Ragan <gzr@eazel.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifndef NAUTILUS_UNDOABLE_H -#define NAUTILUS_UNDOABLE_H - -#include <libgnome/gnome-defs.h> -#include <gtk/gtksignal.h> -#include <gtk/gtkmain.h> - -#define NAUTILUS_UNDO_TRANSACTION_LIST_NAME "nautilus_undo_transaction_list" - -#define NAUTILUS_TYPE_UNDOABLE \ - (nautilus_undoable_get_type ()) -#define NAUTILUS_UNDOABLE(obj) \ - (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_UNDOABLE, NautilusUndoable)) -#define NAUTILUS_UNDOABLE_CLASS(klass) \ - (GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_UNDOABLE, NautilusUndoableClass)) -#define NAUTILUS_IS_UNDOABLE(obj) \ - (GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_UNDOABLE)) -#define NAUTILUS_IS_UNDOABLE_CLASS(klass) \ - (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_UNDOABLE)) - -typedef struct NautilusUndoable NautilusUndoable; -typedef struct NautilusUndoableClass NautilusUndoableClass; - -typedef struct NautilusUndoManager NautilusUndoManager; -typedef struct NautilusUndoTransaction NautilusUndoTransaction; - -struct NautilusUndoable { - GtkObject parent; - NautilusUndoManager *undo_manager; - GtkObject *undo_target_class; - GData *undo_data; -}; - -struct NautilusUndoableClass { - GtkObjectClass parent_class; - - void (* save_undo_snapshot) (GtkObject *object, - gpointer data); - void (* restore_from_undo_snapshot) (GtkObject *object, - gpointer data); -}; - -/* GtkObject */ -GtkType nautilus_undoable_get_type (void); -GtkObject *nautilus_undoable_new (void); - -/* Basic operations. */ -void nautilus_undoable_save_undo_snapshot (NautilusUndoTransaction *transaction, - GtkObject *target, - GtkSignalFunc save_function, - GtkSignalFunc restore_function); -void nautilus_undoable_restore_from_undo_snapshot (NautilusUndoable *undoable); - -typedef void (* NautilusUndoCallback) (GtkObject *target, gpointer callback_data); - -/* Recipe for undo of a bit of work on an object. */ -typedef struct { - GtkObject *target; - NautilusUndoCallback callback; - gpointer callback_data; - GDestroyNotify callback_data_destroy_notify; -} NautilusUndoAtom; - -/* Registering something that can be undone. */ -void nautilus_undo_register (GtkObject *target, - NautilusUndoCallback callback, - gpointer callback_data, - GDestroyNotify callback_data_destroy_notify, - const char *operation_name, - const char *undo_menu_item_name, - const char *undo_menu_item_description, - const char *redo_menu_item_name, - const char *redo_menu_item_description); -void nautilus_undo_register_full (GList *atoms, - GtkObject *undo_manager_search_start_object, - const char *operation_name, - const char *undo_menu_item_name, - const char *undo_menu_item_description, - const char *redo_menu_item_name, - const char *redo_menu_item_description); - -void nautilus_undo_unregister (GtkObject *target); - -/* Performing an undo explicitly. Only for use by objects "out in the field". - * The menu bar itself uses a richer API in the undo manager. - */ -void nautilus_undo (GtkObject *undo_manager_search_start_object); - -#endif diff --git a/libnautilus/nautilus-view.c b/libnautilus/nautilus-view.c index 1c8944191..746833de0 100644 --- a/libnautilus/nautilus-view.c +++ b/libnautilus/nautilus-view.c @@ -34,8 +34,7 @@ #include <bonobo/bonobo-main.h> #include <bonobo/bonobo-control.h> #include <libnautilus-extensions/nautilus-gtk-macros.h> -#include <libnautilus/nautilus-undo-context.h> -#include <libnautilus/nautilus-undo-manager.h> +#include "nautilus-undo.h" enum { NOTIFY_LOCATION_CHANGE, diff --git a/nautilus-widgets/nautilus-preferences.c b/nautilus-widgets/nautilus-preferences.c index 19974216d..b3ddf019c 100644 --- a/nautilus-widgets/nautilus-preferences.c +++ b/nautilus-widgets/nautilus-preferences.c @@ -93,13 +93,13 @@ static void preferences_hash_node_check_changes_func ( /* PreferencesCallbackNode functions */ -static PreferencesCallbackNode *preferneces_callback_node_alloc (NautilusPreferencesCallback callback_proc, +static PreferencesCallbackNode *preferences_callback_node_alloc (NautilusPreferencesCallback callback_proc, gpointer callback_data, const PreferencesHashNode *hash_node); -static void preferneces_callback_node_free (PreferencesCallbackNode *node); -static void preferneces_callback_node_free_func (gpointer data, +static void preferences_callback_node_free (PreferencesCallbackNode *node); +static void preferences_callback_node_free_func (gpointer data, gpointer callback_data); -static void preferneces_callback_node_invoke_func (gpointer data, +static void preferences_callback_node_invoke_func (gpointer data, gpointer callback_data); static void preferences_hash_node_add_callback (PreferencesHashNode *node, NautilusPreferencesCallback callback_proc, @@ -177,7 +177,7 @@ preferences_hash_node_free (PreferencesHashNode *node) } nautilus_g_list_free_deep_custom (node->callback_list, - preferneces_callback_node_free_func, + preferences_callback_node_free_func, NULL); node->callback_list = NULL; @@ -201,21 +201,21 @@ preferences_hash_node_add_callback (PreferencesHashNode *node, NautilusPreferencesCallback callback_proc, gpointer callback_data) { - PreferencesCallbackNode *preferneces_callback_node; + PreferencesCallbackNode *preferences_callback_node; guint i; g_assert (node != NULL); g_assert (callback_proc != NULL); - preferneces_callback_node = preferneces_callback_node_alloc (callback_proc, + preferences_callback_node = preferences_callback_node_alloc (callback_proc, callback_data, node); - g_assert (preferneces_callback_node != NULL); + g_assert (preferences_callback_node != NULL); node->callback_list = g_list_append (node->callback_list, - (gpointer) preferneces_callback_node); + (gpointer) preferences_callback_node); /* * We install only one gconf notification for each preference node. @@ -279,7 +279,7 @@ preferences_hash_node_remove_callback (PreferencesHashNode *node, node->callback_list = g_list_remove (node->callback_list, (gpointer) callback_info); - preferneces_callback_node_free (callback_info); + preferences_callback_node_free (callback_info); } } @@ -345,14 +345,14 @@ preferences_hash_node_check_changes_func (gpointer key, /* Invoke callbacks for this node */ if (node->callback_list) { g_list_foreach (node->callback_list, - preferneces_callback_node_invoke_func, + preferences_callback_node_invoke_func, (gpointer) NULL); } } } /** - * preferneces_callback_node_alloc + * preferences_callback_node_alloc * * Allocate a callback info struct from the given values. PreferencesCallbackNode * structures are used as nodes for the callbac_list member of pref hash table @@ -364,7 +364,7 @@ preferences_hash_node_check_changes_func (gpointer key, * Return value: A newly allocated node. **/ static PreferencesCallbackNode * -preferneces_callback_node_alloc (NautilusPreferencesCallback callback_proc, +preferences_callback_node_alloc (NautilusPreferencesCallback callback_proc, gpointer callback_data, const PreferencesHashNode *hash_node) { @@ -382,13 +382,13 @@ preferneces_callback_node_alloc (NautilusPreferencesCallback callback_proc, } /** - * preferneces_callback_node_free + * preferences_callback_node_free * * Free a callback info struct. - * @preferneces_callback_node: The struct to free. + * @preferences_callback_node: The struct to free. **/ static void -preferneces_callback_node_free (PreferencesCallbackNode *callback_node) +preferences_callback_node_free (PreferencesCallbackNode *callback_node) { g_assert (callback_node != NULL); @@ -399,7 +399,7 @@ preferneces_callback_node_free (PreferencesCallbackNode *callback_node) } /** - * preferneces_callback_node_free_func + * preferences_callback_node_free_func * * A function that frees a callback info struct. It is meant to be fed to * g_list_foreach () @@ -407,16 +407,16 @@ preferneces_callback_node_free (PreferencesCallbackNode *callback_node) * @callback_data: The callback_data privately maintained by the GList. **/ static void -preferneces_callback_node_free_func (gpointer data, +preferences_callback_node_free_func (gpointer data, gpointer callback_data) { g_assert (data != NULL); - preferneces_callback_node_free ((PreferencesCallbackNode *) data); + preferences_callback_node_free ((PreferencesCallbackNode *) data); } /** - * preferneces_callback_node_invoke_func + * preferences_callback_node_invoke_func * * A function that invokes a callback from the given struct. It is meant to be fed to * g_list_foreach () @@ -424,7 +424,7 @@ preferneces_callback_node_free_func (gpointer data, * @callback_data: The callback_data privately maintained by the GList. **/ static void -preferneces_callback_node_invoke_func (gpointer data, +preferences_callback_node_invoke_func (gpointer data, gpointer callback_data) { PreferencesCallbackNode *callback_node; @@ -562,7 +562,7 @@ preferences_gconf_callback (GConfClient *client, /* Invoke callbacks for this node */ if (node->callback_list) { g_list_foreach (node->callback_list, - preferneces_callback_node_invoke_func, + preferences_callback_node_invoke_func, (gpointer) NULL); } diff --git a/src/nautilus-application.c b/src/nautilus-application.c index 4c4c926bd..73381c896 100644 --- a/src/nautilus-application.c +++ b/src/nautilus-application.c @@ -37,7 +37,7 @@ #include <libnautilus-extensions/nautilus-file-utilities.h> #include <libnautilus-extensions/nautilus-string-list.h> #include <libnautilus-extensions/nautilus-gnome-extensions.h> -#include <libnautilus/nautilus-undo-manager.h> +#include <libnautilus-extensions/nautilus-undo-manager.h> #include <liboaf/liboaf.h> #include "nautilus-desktop-window.h" @@ -222,7 +222,6 @@ nautilus_app_init (NautilusApp *app) { CORBA_Environment ev; CORBA_Object objref; - Nautilus_Undo_Manager undo_manager; CORBA_exception_init (&ev); @@ -231,15 +230,12 @@ nautilus_app_init (NautilusApp *app) objref); bonobo_object_construct (BONOBO_OBJECT(app), objref); - /* Init undo manager */ + /* Create an undo manager */ app->undo_manager = BONOBO_OBJECT (nautilus_undo_manager_new ()); - undo_manager = bonobo_object_corba_objref (BONOBO_OBJECT (app->undo_manager)); - /* Stash a global reference to the object */ - nautilus_undo_manager_stash_global_undo (undo_manager); - - /* Add it to the application object */ - nautilus_attach_undo_manager (GTK_OBJECT (app), undo_manager); + /* Attach undo manager to application so windows can use share_undo_manager. */ + nautilus_undo_manager_attach (NAUTILUS_UNDO_MANAGER (app->undo_manager), + GTK_OBJECT (app)); CORBA_exception_free (&ev); } diff --git a/src/nautilus-bookmarks-window.c b/src/nautilus-bookmarks-window.c index c1369891c..ac168ce34 100644 --- a/src/nautilus-bookmarks-window.c +++ b/src/nautilus-bookmarks-window.c @@ -24,7 +24,7 @@ #include <config.h> #include "nautilus-bookmarks-window.h" -#include <libnautilus/nautilus-undo-manager.h> +#include <libnautilus/nautilus-undo.h> #include <libnautilus-extensions/nautilus-entry.h> #include <libnautilus-extensions/nautilus-icon-factory.h> #include <gnome.h> @@ -125,7 +125,7 @@ create_bookmarks_window (NautilusBookmarkList *list, GtkObject *undo_manager_sou bookmarks = list; window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - nautilus_share_undo_manager (GTK_OBJECT (window), undo_manager_source); + nautilus_undo_share_undo_manager (GTK_OBJECT (window), undo_manager_source); gtk_container_set_border_width (GTK_CONTAINER (window), GNOME_PAD); gtk_window_set_title (GTK_WINDOW (window), _("Nautilus: Bookmarks")); gtk_widget_set_usize (window, diff --git a/src/nautilus-navigation-window-menus.c b/src/nautilus-navigation-window-menus.c index 020313907..1cca28abb 100644 --- a/src/nautilus-navigation-window-menus.c +++ b/src/nautilus-navigation-window-menus.c @@ -32,7 +32,7 @@ #include "nautilus-window-private.h" #include "nautilus-property-browser.h" -#include <libnautilus/nautilus-undo-manager.h> +#include <libnautilus-extensions/nautilus-undo-manager.h> #include <libnautilus/nautilus-bonobo-ui.h> #include <libnautilus-extensions/nautilus-bonobo-extensions.h> #include <libnautilus-extensions/nautilus-glib-extensions.h> @@ -56,7 +56,6 @@ static void clear_appended_bookmark_items (Nau static NautilusBookmarkList *get_bookmark_list (void); static void refresh_bookmarks_in_go_menu (NautilusWindow *window); static void refresh_bookmarks_in_bookmarks_menu (NautilusWindow *window); -static void update_undo_menu_item (NautilusWindow *window); static void edit_bookmarks (NautilusWindow *window); @@ -134,18 +133,8 @@ edit_menu_undo_callback (BonoboUIHandler *ui_handler, gpointer user_data, const char *path) { - Nautilus_Undo_Manager undo_manager; - CORBA_Environment ev; - - CORBA_exception_init(&ev); - - g_assert (NAUTILUS_IS_WINDOW (user_data)); - - /* Locate undo manager */ - undo_manager = nautilus_get_undo_manager (GTK_OBJECT (user_data)); - Nautilus_Undo_Manager_undo (undo_manager, &ev); - - CORBA_exception_free(&ev); + nautilus_undo_manager_undo + (NAUTILUS_UNDO_MANAGER (NAUTILUS_APP (NAUTILUS_WINDOW (user_data)->app)->undo_manager)); } static void @@ -155,9 +144,7 @@ edit_menu_cut_callback (BonoboUIHandler *ui_handler, { GtkWindow *main_window; - g_assert (GTK_IS_WINDOW (user_data)); - main_window=GTK_WINDOW (user_data); - + main_window = GTK_WINDOW (user_data); if (GTK_IS_EDITABLE (main_window->focus_widget)) { gtk_editable_cut_clipboard (GTK_EDITABLE (main_window->focus_widget)); } @@ -171,9 +158,7 @@ edit_menu_copy_callback (BonoboUIHandler *ui_handler, { GtkWindow *main_window; - g_assert (GTK_IS_WINDOW (user_data)); - main_window=GTK_WINDOW (user_data); - + main_window = GTK_WINDOW (user_data); if (GTK_IS_EDITABLE (main_window->focus_widget)) { gtk_editable_copy_clipboard (GTK_EDITABLE (main_window->focus_widget)); } @@ -188,7 +173,7 @@ edit_menu_paste_callback (BonoboUIHandler *ui_handler, { GtkWindow *main_window; - main_window=GTK_WINDOW (user_data); + main_window = GTK_WINDOW (user_data); if (GTK_IS_EDITABLE (main_window->focus_widget)) { gtk_editable_paste_clipboard (GTK_EDITABLE (main_window->focus_widget)); } @@ -202,7 +187,8 @@ edit_menu_clear_callback (BonoboUIHandler *ui_handler, const char *path) { GtkWindow *main_window; - main_window=GTK_WINDOW (user_data); + + main_window = GTK_WINDOW (user_data); if (GTK_IS_EDITABLE (main_window->focus_widget)) { /* A negative index deletes until the end of the string */ gtk_editable_delete_text (GTK_EDITABLE (main_window->focus_widget),0, -1); @@ -215,7 +201,6 @@ go_menu_back_callback (BonoboUIHandler *ui_handler, gpointer user_data, const char *path) { - g_assert (NAUTILUS_IS_WINDOW (user_data)); nautilus_window_go_back (NAUTILUS_WINDOW (user_data)); } @@ -224,7 +209,6 @@ go_menu_forward_callback (BonoboUIHandler *ui_handler, gpointer user_data, const char *path) { - g_assert (NAUTILUS_IS_WINDOW (user_data)); nautilus_window_go_forward (NAUTILUS_WINDOW (user_data)); } @@ -233,7 +217,6 @@ go_menu_up_callback (BonoboUIHandler *ui_handler, gpointer user_data, const char *path) { - g_assert (NAUTILUS_IS_WINDOW (user_data)); nautilus_window_go_up (NAUTILUS_WINDOW (user_data)); } @@ -242,7 +225,6 @@ go_menu_home_callback (BonoboUIHandler *ui_handler, gpointer user_data, const char *path) { - g_assert (NAUTILUS_IS_WINDOW (user_data)); nautilus_window_go_home (NAUTILUS_WINDOW (user_data)); } @@ -251,8 +233,6 @@ bookmarks_menu_add_bookmark_callback (BonoboUIHandler *ui_handler, gpointer user_data, const char *path) { - g_return_if_fail (NAUTILUS_IS_WINDOW (user_data)); - nautilus_window_add_bookmark_for_current_location (NAUTILUS_WINDOW (user_data)); } @@ -261,8 +241,6 @@ bookmarks_menu_edit_bookmarks_callback (BonoboUIHandler *ui_handler, gpointer user_data, const char *path) { - g_return_if_fail (NAUTILUS_IS_WINDOW (user_data)); - edit_bookmarks (NAUTILUS_WINDOW (user_data)); } @@ -275,9 +253,7 @@ settings_menu_user_level_radio_group_callback (BonoboUIHandler *ui_handler, guint old_user_level; guint new_user_level; - g_return_if_fail (user_data != NULL); - g_return_if_fail (NAUTILUS_IS_WINDOW (user_data)); - g_return_if_fail (path != NULL); + g_assert (path != NULL); window = NAUTILUS_WINDOW (user_data); @@ -608,7 +584,6 @@ void nautilus_window_initialize_menus (NautilusWindow *window) { BonoboUIHandler *ui_handler; - NautilusUndoManager *undo_manager; ui_handler = window->uih; g_assert (ui_handler != NULL); @@ -913,14 +888,11 @@ nautilus_window_initialize_menus (NautilusWindow *window) NAUTILUS_MENU_PATH_SELECT_ALL_ITEM, FALSE); - /* Set inital state of undo menu */ - update_undo_menu_item (window); - - /* Connect to UndoManager so that we are notified when an undo transcation has occurred */ - undo_manager = NAUTILUS_UNDO_MANAGER (NAUTILUS_APP (window->app)->undo_manager); - gtk_signal_connect_object_while_alive - (GTK_OBJECT (undo_manager), "undo_transaction_occurred", - update_undo_menu_item, GTK_OBJECT (window)); + /* Connect to undo manager so it will handle the menu item. */ + nautilus_undo_manager_set_up_bonobo_ui_handler_undo_item + (NAUTILUS_UNDO_MANAGER (NAUTILUS_APP (window->app)->undo_manager), + ui_handler, NAUTILUS_MENU_PATH_UNDO_ITEM, + _("_Undo"), _("Undo the last text change")); nautilus_window_initialize_bookmarks_menu (window); nautilus_window_initialize_go_menu (window); @@ -1002,47 +974,6 @@ refresh_bookmarks_in_go_menu (NautilusWindow *window) } } -/* Toggle sensitivity based on undo manager state */ -static void -update_undo_menu_item (NautilusWindow *window) -{ - NautilusUndoManager *local_manager; - Nautilus_Undo_Manager undo_transaction; - Nautilus_Undo_MenuItem *menu_item; - gboolean update; - CORBA_Environment ev; - - g_assert (NAUTILUS_IS_WINDOW (window)); - - local_manager = NAUTILUS_UNDO_MANAGER (NAUTILUS_APP (window->app)->undo_manager); - if (local_manager != NULL) { - update = nautilus_undo_manager_can_undo (local_manager); - - bonobo_ui_handler_menu_set_sensitivity(window->uih, NAUTILUS_MENU_PATH_UNDO_ITEM, update); - - if (update) { - /* Get undo transaction name */ - CORBA_exception_init(&ev); - - undo_transaction = nautilus_undo_manager_get_current_undo_transaction (local_manager); - menu_item = Nautilus_Undo_Transaction__get_undo_description (undo_transaction, &ev); - - bonobo_ui_handler_menu_set_label (window->uih, NAUTILUS_MENU_PATH_UNDO_ITEM, menu_item->name); - - CORBA_free (menu_item); - - CORBA_exception_free(&ev); - } - else { - bonobo_ui_handler_menu_set_label (window->uih, NAUTILUS_MENU_PATH_UNDO_ITEM, _("Undo")); - } - - } else { - bonobo_ui_handler_menu_set_sensitivity(window->uih, NAUTILUS_MENU_PATH_UNDO_ITEM, - FALSE); - } -} - static void user_level_changed_callback (GtkObject *user_level_manager, gpointer user_data) diff --git a/src/nautilus-navigation-window.c b/src/nautilus-navigation-window.c index 080f28c94..13d0de945 100644 --- a/src/nautilus-navigation-window.c +++ b/src/nautilus-navigation-window.c @@ -53,7 +53,7 @@ #include <libnautilus-extensions/nautilus-string.h> #include <libnautilus-extensions/nautilus-mini-icon.h> #include <libnautilus-extensions/nautilus-generous-bin.h> -#include <libnautilus/nautilus-undo-manager.h> +#include <libnautilus/nautilus-undo.h> #include "nautilus-zoom-control.h" #include <ctype.h> #include <libgnomevfs/gnome-vfs-uri.h> @@ -349,8 +349,6 @@ nautilus_window_constructed (NautilusWindow *window) GtkWidget *temp_frame; GnomeDockItemBehavior behavior; int sidebar_width; - NautilusUndoManager *app_undo_manager; - Nautilus_Undo_Manager undo_manager; app = GNOME_APP(window); @@ -465,10 +463,7 @@ nautilus_window_constructed (NautilusWindow *window) nautilus_window_allow_stop (window, FALSE); /* Set up undo manager */ - app_undo_manager = NAUTILUS_UNDO_MANAGER (NAUTILUS_APP (window->app)->undo_manager); - g_assert (app_undo_manager != NULL); - undo_manager = bonobo_object_corba_objref (BONOBO_OBJECT (app_undo_manager)); - nautilus_attach_undo_manager (GTK_OBJECT (window), undo_manager); + nautilus_undo_share_undo_manager (GTK_OBJECT (window), GTK_OBJECT (window->app)); } static void diff --git a/src/nautilus-object-window.c b/src/nautilus-object-window.c index 080f28c94..13d0de945 100644 --- a/src/nautilus-object-window.c +++ b/src/nautilus-object-window.c @@ -53,7 +53,7 @@ #include <libnautilus-extensions/nautilus-string.h> #include <libnautilus-extensions/nautilus-mini-icon.h> #include <libnautilus-extensions/nautilus-generous-bin.h> -#include <libnautilus/nautilus-undo-manager.h> +#include <libnautilus/nautilus-undo.h> #include "nautilus-zoom-control.h" #include <ctype.h> #include <libgnomevfs/gnome-vfs-uri.h> @@ -349,8 +349,6 @@ nautilus_window_constructed (NautilusWindow *window) GtkWidget *temp_frame; GnomeDockItemBehavior behavior; int sidebar_width; - NautilusUndoManager *app_undo_manager; - Nautilus_Undo_Manager undo_manager; app = GNOME_APP(window); @@ -465,10 +463,7 @@ nautilus_window_constructed (NautilusWindow *window) nautilus_window_allow_stop (window, FALSE); /* Set up undo manager */ - app_undo_manager = NAUTILUS_UNDO_MANAGER (NAUTILUS_APP (window->app)->undo_manager); - g_assert (app_undo_manager != NULL); - undo_manager = bonobo_object_corba_objref (BONOBO_OBJECT (app_undo_manager)); - nautilus_attach_undo_manager (GTK_OBJECT (window), undo_manager); + nautilus_undo_share_undo_manager (GTK_OBJECT (window), GTK_OBJECT (window->app)); } static void diff --git a/src/nautilus-spatial-window.c b/src/nautilus-spatial-window.c index 080f28c94..13d0de945 100644 --- a/src/nautilus-spatial-window.c +++ b/src/nautilus-spatial-window.c @@ -53,7 +53,7 @@ #include <libnautilus-extensions/nautilus-string.h> #include <libnautilus-extensions/nautilus-mini-icon.h> #include <libnautilus-extensions/nautilus-generous-bin.h> -#include <libnautilus/nautilus-undo-manager.h> +#include <libnautilus/nautilus-undo.h> #include "nautilus-zoom-control.h" #include <ctype.h> #include <libgnomevfs/gnome-vfs-uri.h> @@ -349,8 +349,6 @@ nautilus_window_constructed (NautilusWindow *window) GtkWidget *temp_frame; GnomeDockItemBehavior behavior; int sidebar_width; - NautilusUndoManager *app_undo_manager; - Nautilus_Undo_Manager undo_manager; app = GNOME_APP(window); @@ -465,10 +463,7 @@ nautilus_window_constructed (NautilusWindow *window) nautilus_window_allow_stop (window, FALSE); /* Set up undo manager */ - app_undo_manager = NAUTILUS_UNDO_MANAGER (NAUTILUS_APP (window->app)->undo_manager); - g_assert (app_undo_manager != NULL); - undo_manager = bonobo_object_corba_objref (BONOBO_OBJECT (app_undo_manager)); - nautilus_attach_undo_manager (GTK_OBJECT (window), undo_manager); + nautilus_undo_share_undo_manager (GTK_OBJECT (window), GTK_OBJECT (window->app)); } static void diff --git a/src/nautilus-view-frame.c b/src/nautilus-view-frame.c index 26c1d7821..cb23a7100 100644 --- a/src/nautilus-view-frame.c +++ b/src/nautilus-view-frame.c @@ -30,13 +30,13 @@ #include <config.h> #include "nautilus-view-frame-private.h" +#include "nautilus-application.h" #include "nautilus-window.h" #include <libnautilus-extensions/nautilus-gtk-extensions.h> #include <libnautilus-extensions/nautilus-gtk-macros.h> #include <gtk/gtksignal.h> #include <gtk/gtk.h> -#include <libnautilus/nautilus-undo-manager.h> -#include <libnautilus/nautilus-undo-context.h> +#include <libnautilus-extensions/nautilus-undo-manager.h> enum { REQUEST_LOCATION_CHANGE, @@ -288,8 +288,6 @@ nautilus_view_frame_load_client(NautilusViewFrame *view, const char *iid) { CORBA_Object obj; CORBA_Object zoomable; - Nautilus_Undo_Manager undo_manager; - NautilusUndoContext *undo_context; CORBA_Environment ev; int i; @@ -317,10 +315,9 @@ nautilus_view_frame_load_client(NautilusViewFrame *view, const char *iid) view->zoomable_frame = impl_Nautilus_ZoomableFrame__create(view, &ev); /* Add undo manager to component */ - undo_manager = nautilus_undo_manager_get_global_undo (); - g_assert (undo_manager); - undo_context = nautilus_undo_context_new (undo_manager); - bonobo_object_add_interface (BONOBO_OBJECT (view->view_frame), BONOBO_OBJECT (undo_context)); + nautilus_undo_manager_add_interface + (NAUTILUS_UNDO_MANAGER (NAUTILUS_APP (NAUTILUS_WINDOW (view->main_window)->app)->undo_manager), + BONOBO_OBJECT (view->view_frame)); /* Now figure out which type of embedded object it is: */ for(i = 0; component_types[i] && !view->component_class; i++) diff --git a/src/nautilus-window-menus.c b/src/nautilus-window-menus.c index 020313907..1cca28abb 100644 --- a/src/nautilus-window-menus.c +++ b/src/nautilus-window-menus.c @@ -32,7 +32,7 @@ #include "nautilus-window-private.h" #include "nautilus-property-browser.h" -#include <libnautilus/nautilus-undo-manager.h> +#include <libnautilus-extensions/nautilus-undo-manager.h> #include <libnautilus/nautilus-bonobo-ui.h> #include <libnautilus-extensions/nautilus-bonobo-extensions.h> #include <libnautilus-extensions/nautilus-glib-extensions.h> @@ -56,7 +56,6 @@ static void clear_appended_bookmark_items (Nau static NautilusBookmarkList *get_bookmark_list (void); static void refresh_bookmarks_in_go_menu (NautilusWindow *window); static void refresh_bookmarks_in_bookmarks_menu (NautilusWindow *window); -static void update_undo_menu_item (NautilusWindow *window); static void edit_bookmarks (NautilusWindow *window); @@ -134,18 +133,8 @@ edit_menu_undo_callback (BonoboUIHandler *ui_handler, gpointer user_data, const char *path) { - Nautilus_Undo_Manager undo_manager; - CORBA_Environment ev; - - CORBA_exception_init(&ev); - - g_assert (NAUTILUS_IS_WINDOW (user_data)); - - /* Locate undo manager */ - undo_manager = nautilus_get_undo_manager (GTK_OBJECT (user_data)); - Nautilus_Undo_Manager_undo (undo_manager, &ev); - - CORBA_exception_free(&ev); + nautilus_undo_manager_undo + (NAUTILUS_UNDO_MANAGER (NAUTILUS_APP (NAUTILUS_WINDOW (user_data)->app)->undo_manager)); } static void @@ -155,9 +144,7 @@ edit_menu_cut_callback (BonoboUIHandler *ui_handler, { GtkWindow *main_window; - g_assert (GTK_IS_WINDOW (user_data)); - main_window=GTK_WINDOW (user_data); - + main_window = GTK_WINDOW (user_data); if (GTK_IS_EDITABLE (main_window->focus_widget)) { gtk_editable_cut_clipboard (GTK_EDITABLE (main_window->focus_widget)); } @@ -171,9 +158,7 @@ edit_menu_copy_callback (BonoboUIHandler *ui_handler, { GtkWindow *main_window; - g_assert (GTK_IS_WINDOW (user_data)); - main_window=GTK_WINDOW (user_data); - + main_window = GTK_WINDOW (user_data); if (GTK_IS_EDITABLE (main_window->focus_widget)) { gtk_editable_copy_clipboard (GTK_EDITABLE (main_window->focus_widget)); } @@ -188,7 +173,7 @@ edit_menu_paste_callback (BonoboUIHandler *ui_handler, { GtkWindow *main_window; - main_window=GTK_WINDOW (user_data); + main_window = GTK_WINDOW (user_data); if (GTK_IS_EDITABLE (main_window->focus_widget)) { gtk_editable_paste_clipboard (GTK_EDITABLE (main_window->focus_widget)); } @@ -202,7 +187,8 @@ edit_menu_clear_callback (BonoboUIHandler *ui_handler, const char *path) { GtkWindow *main_window; - main_window=GTK_WINDOW (user_data); + + main_window = GTK_WINDOW (user_data); if (GTK_IS_EDITABLE (main_window->focus_widget)) { /* A negative index deletes until the end of the string */ gtk_editable_delete_text (GTK_EDITABLE (main_window->focus_widget),0, -1); @@ -215,7 +201,6 @@ go_menu_back_callback (BonoboUIHandler *ui_handler, gpointer user_data, const char *path) { - g_assert (NAUTILUS_IS_WINDOW (user_data)); nautilus_window_go_back (NAUTILUS_WINDOW (user_data)); } @@ -224,7 +209,6 @@ go_menu_forward_callback (BonoboUIHandler *ui_handler, gpointer user_data, const char *path) { - g_assert (NAUTILUS_IS_WINDOW (user_data)); nautilus_window_go_forward (NAUTILUS_WINDOW (user_data)); } @@ -233,7 +217,6 @@ go_menu_up_callback (BonoboUIHandler *ui_handler, gpointer user_data, const char *path) { - g_assert (NAUTILUS_IS_WINDOW (user_data)); nautilus_window_go_up (NAUTILUS_WINDOW (user_data)); } @@ -242,7 +225,6 @@ go_menu_home_callback (BonoboUIHandler *ui_handler, gpointer user_data, const char *path) { - g_assert (NAUTILUS_IS_WINDOW (user_data)); nautilus_window_go_home (NAUTILUS_WINDOW (user_data)); } @@ -251,8 +233,6 @@ bookmarks_menu_add_bookmark_callback (BonoboUIHandler *ui_handler, gpointer user_data, const char *path) { - g_return_if_fail (NAUTILUS_IS_WINDOW (user_data)); - nautilus_window_add_bookmark_for_current_location (NAUTILUS_WINDOW (user_data)); } @@ -261,8 +241,6 @@ bookmarks_menu_edit_bookmarks_callback (BonoboUIHandler *ui_handler, gpointer user_data, const char *path) { - g_return_if_fail (NAUTILUS_IS_WINDOW (user_data)); - edit_bookmarks (NAUTILUS_WINDOW (user_data)); } @@ -275,9 +253,7 @@ settings_menu_user_level_radio_group_callback (BonoboUIHandler *ui_handler, guint old_user_level; guint new_user_level; - g_return_if_fail (user_data != NULL); - g_return_if_fail (NAUTILUS_IS_WINDOW (user_data)); - g_return_if_fail (path != NULL); + g_assert (path != NULL); window = NAUTILUS_WINDOW (user_data); @@ -608,7 +584,6 @@ void nautilus_window_initialize_menus (NautilusWindow *window) { BonoboUIHandler *ui_handler; - NautilusUndoManager *undo_manager; ui_handler = window->uih; g_assert (ui_handler != NULL); @@ -913,14 +888,11 @@ nautilus_window_initialize_menus (NautilusWindow *window) NAUTILUS_MENU_PATH_SELECT_ALL_ITEM, FALSE); - /* Set inital state of undo menu */ - update_undo_menu_item (window); - - /* Connect to UndoManager so that we are notified when an undo transcation has occurred */ - undo_manager = NAUTILUS_UNDO_MANAGER (NAUTILUS_APP (window->app)->undo_manager); - gtk_signal_connect_object_while_alive - (GTK_OBJECT (undo_manager), "undo_transaction_occurred", - update_undo_menu_item, GTK_OBJECT (window)); + /* Connect to undo manager so it will handle the menu item. */ + nautilus_undo_manager_set_up_bonobo_ui_handler_undo_item + (NAUTILUS_UNDO_MANAGER (NAUTILUS_APP (window->app)->undo_manager), + ui_handler, NAUTILUS_MENU_PATH_UNDO_ITEM, + _("_Undo"), _("Undo the last text change")); nautilus_window_initialize_bookmarks_menu (window); nautilus_window_initialize_go_menu (window); @@ -1002,47 +974,6 @@ refresh_bookmarks_in_go_menu (NautilusWindow *window) } } -/* Toggle sensitivity based on undo manager state */ -static void -update_undo_menu_item (NautilusWindow *window) -{ - NautilusUndoManager *local_manager; - Nautilus_Undo_Manager undo_transaction; - Nautilus_Undo_MenuItem *menu_item; - gboolean update; - CORBA_Environment ev; - - g_assert (NAUTILUS_IS_WINDOW (window)); - - local_manager = NAUTILUS_UNDO_MANAGER (NAUTILUS_APP (window->app)->undo_manager); - if (local_manager != NULL) { - update = nautilus_undo_manager_can_undo (local_manager); - - bonobo_ui_handler_menu_set_sensitivity(window->uih, NAUTILUS_MENU_PATH_UNDO_ITEM, update); - - if (update) { - /* Get undo transaction name */ - CORBA_exception_init(&ev); - - undo_transaction = nautilus_undo_manager_get_current_undo_transaction (local_manager); - menu_item = Nautilus_Undo_Transaction__get_undo_description (undo_transaction, &ev); - - bonobo_ui_handler_menu_set_label (window->uih, NAUTILUS_MENU_PATH_UNDO_ITEM, menu_item->name); - - CORBA_free (menu_item); - - CORBA_exception_free(&ev); - } - else { - bonobo_ui_handler_menu_set_label (window->uih, NAUTILUS_MENU_PATH_UNDO_ITEM, _("Undo")); - } - - } else { - bonobo_ui_handler_menu_set_sensitivity(window->uih, NAUTILUS_MENU_PATH_UNDO_ITEM, - FALSE); - } -} - static void user_level_changed_callback (GtkObject *user_level_manager, gpointer user_data) diff --git a/src/nautilus-window-private.h b/src/nautilus-window-private.h index 96c6d91eb..371025cce 100644 --- a/src/nautilus-window-private.h +++ b/src/nautilus-window-private.h @@ -3,7 +3,7 @@ #include "nautilus-window.h" #include <libnautilus/libnautilus.h> -#include <libnautilus/nautilus-undo-manager.h> +#include <libnautilus-extensions/nautilus-undo-manager.h> #include <gtk/gtk.h> typedef enum { diff --git a/src/nautilus-window.c b/src/nautilus-window.c index 080f28c94..13d0de945 100644 --- a/src/nautilus-window.c +++ b/src/nautilus-window.c @@ -53,7 +53,7 @@ #include <libnautilus-extensions/nautilus-string.h> #include <libnautilus-extensions/nautilus-mini-icon.h> #include <libnautilus-extensions/nautilus-generous-bin.h> -#include <libnautilus/nautilus-undo-manager.h> +#include <libnautilus/nautilus-undo.h> #include "nautilus-zoom-control.h" #include <ctype.h> #include <libgnomevfs/gnome-vfs-uri.h> @@ -349,8 +349,6 @@ nautilus_window_constructed (NautilusWindow *window) GtkWidget *temp_frame; GnomeDockItemBehavior behavior; int sidebar_width; - NautilusUndoManager *app_undo_manager; - Nautilus_Undo_Manager undo_manager; app = GNOME_APP(window); @@ -465,10 +463,7 @@ nautilus_window_constructed (NautilusWindow *window) nautilus_window_allow_stop (window, FALSE); /* Set up undo manager */ - app_undo_manager = NAUTILUS_UNDO_MANAGER (NAUTILUS_APP (window->app)->undo_manager); - g_assert (app_undo_manager != NULL); - undo_manager = bonobo_object_corba_objref (BONOBO_OBJECT (app_undo_manager)); - nautilus_attach_undo_manager (GTK_OBJECT (window), undo_manager); + nautilus_undo_share_undo_manager (GTK_OBJECT (window), GTK_OBJECT (window->app)); } static void |