2008-03-29 Cosimo Cecchi <cosimoc@gnome.org>
[nautilus.git] / libnautilus-private / nautilus-undo.c
blob29b172b6b3d001f457bcdf618569aad0d0c4e3a1
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
3 /* nautilus-undo.c - public interface for objects that implement
4 * undoable actions -- works across components
6 * Copyright (C) 2000 Eazel, Inc.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 * Boston, MA 02111-1307, USA.
23 * Author: Darin Adler <darin@bentspoon.com>
26 #include <config.h>
27 #include "nautilus-undo.h"
29 #include "nautilus-undo-private.h"
30 #include "nautilus-undo-transaction.h"
31 #include <gtk/gtksignal.h>
32 #include <gtk/gtkwindow.h>
33 #include <libgnomecanvas/gnome-canvas.h>
35 #define NAUTILUS_UNDO_MANAGER_DATA "Nautilus undo manager"
37 /* Register a simple undo action by calling nautilus_undo_register_full. */
38 void
39 nautilus_undo_register (GObject *target,
40 NautilusUndoCallback callback,
41 gpointer callback_data,
42 GDestroyNotify callback_data_destroy_notify,
43 const char *operation_name,
44 const char *undo_menu_item_label,
45 const char *undo_menu_item_hint,
46 const char *redo_menu_item_label,
47 const char *redo_menu_item_hint)
49 NautilusUndoAtom atom;
50 GList single_atom_list;
52 g_return_if_fail (G_IS_OBJECT (target));
53 g_return_if_fail (callback != NULL);
55 /* Make an atom. */
56 atom.target = target;
57 atom.callback = callback;
58 atom.callback_data = callback_data;
59 atom.callback_data_destroy_notify = callback_data_destroy_notify;
61 /* Make a single-atom list. */
62 single_atom_list.data = &atom;
63 single_atom_list.next = NULL;
64 single_atom_list.prev = NULL;
66 /* Call the full version of the registration function,
67 * using the undo target as the place to search for the
68 * undo manager.
70 nautilus_undo_register_full (&single_atom_list,
71 target,
72 operation_name,
73 undo_menu_item_label,
74 undo_menu_item_hint,
75 redo_menu_item_label,
76 redo_menu_item_hint);
79 /* Register an undo action. */
80 void
81 nautilus_undo_register_full (GList *atoms,
82 GObject *undo_manager_search_start_object,
83 const char *operation_name,
84 const char *undo_menu_item_label,
85 const char *undo_menu_item_hint,
86 const char *redo_menu_item_label,
87 const char *redo_menu_item_hint)
89 NautilusUndoTransaction *transaction;
90 GList *p;
92 g_return_if_fail (atoms != NULL);
93 g_return_if_fail (G_IS_OBJECT (undo_manager_search_start_object));
95 /* Create an undo transaction */
96 transaction = nautilus_undo_transaction_new (operation_name,
97 undo_menu_item_label,
98 undo_menu_item_hint,
99 redo_menu_item_label,
100 redo_menu_item_hint);
101 for (p = atoms; p != NULL; p = p->next) {
102 nautilus_undo_transaction_add_atom (transaction, p->data);
104 nautilus_undo_transaction_add_to_undo_manager
105 (transaction,
106 nautilus_undo_get_undo_manager (undo_manager_search_start_object));
108 /* Now we are done with the transaction.
109 * If the undo manager is holding it, then this will not destroy it.
111 g_object_unref (transaction);
114 /* Cover for forgetting about all undo relating to a particular target. */
115 void
116 nautilus_undo_unregister (GObject *target)
118 /* Perhaps this should also unregister all children if called on a
119 * GtkContainer? That might be handy.
121 nautilus_undo_transaction_unregister_object (target);
124 void
125 nautilus_undo (GObject *undo_manager_search_start_object)
127 NautilusUndoManager *manager;
129 g_return_if_fail (G_IS_OBJECT (undo_manager_search_start_object));
131 manager = nautilus_undo_get_undo_manager (undo_manager_search_start_object);
132 if (manager != NULL) {
133 nautilus_undo_manager_undo (manager);
137 NautilusUndoManager *
138 nautilus_undo_get_undo_manager (GObject *start_object)
140 NautilusUndoManager *manager;
141 GtkWidget *parent;
142 GtkWindow *transient_parent;
144 if (start_object == NULL) {
145 return CORBA_OBJECT_NIL;
148 g_return_val_if_fail (G_IS_OBJECT (start_object), NULL);
150 /* Check for an undo manager right here. */
151 manager = g_object_get_data (start_object, NAUTILUS_UNDO_MANAGER_DATA);
152 if (manager != NULL) {
153 return manager;
156 /* Check for undo manager up the parent chain. */
157 if (GTK_IS_WIDGET (start_object)) {
158 parent = GTK_WIDGET (start_object)->parent;
159 if (parent != NULL) {
160 manager = nautilus_undo_get_undo_manager (G_OBJECT (parent));
161 if (manager != NULL) {
162 return manager;
166 /* Check for undo manager in our window's parent. */
167 if (GTK_IS_WINDOW (start_object)) {
168 transient_parent = GTK_WINDOW (start_object)->transient_parent;
169 if (transient_parent != NULL) {
170 manager = nautilus_undo_get_undo_manager (G_OBJECT (transient_parent));
171 if (manager != NULL) {
172 return manager;
178 /* In the case of a canvas item, try the canvas. */
179 if (GNOME_IS_CANVAS_ITEM (start_object)) {
180 manager = nautilus_undo_get_undo_manager (G_OBJECT (GNOME_CANVAS_ITEM (start_object)->canvas));
181 if (manager != NULL) {
182 return manager;
186 /* Found nothing. I can live with that. */
187 return NULL;
190 void
191 nautilus_undo_attach_undo_manager (GObject *object,
192 NautilusUndoManager *manager)
194 g_return_if_fail (G_IS_OBJECT (object));
196 if (manager == NULL) {
197 g_object_set_data (object, NAUTILUS_UNDO_MANAGER_DATA, NULL);
198 } else {
199 g_object_ref (manager);
200 g_object_set_data_full
201 (object, NAUTILUS_UNDO_MANAGER_DATA,
202 manager, g_object_unref);
206 /* Copy a reference to the undo manager fromone object to another. */
207 void
208 nautilus_undo_share_undo_manager (GObject *destination_object,
209 GObject *source_object)
211 NautilusUndoManager *manager;
213 manager = nautilus_undo_get_undo_manager (source_object);
214 nautilus_undo_attach_undo_manager (destination_object, manager);