summaryrefslogtreecommitdiff
path: root/libnautilus-extensions/nautilus-undo-signal-handlers.c
diff options
context:
space:
mode:
authorGene Ragan <gzr@src.gnome.org>2000-06-12 20:29:32 +0000
committerGene Ragan <gzr@src.gnome.org>2000-06-12 20:29:32 +0000
commit822c600faefc1d8f1e38c846178683a266ff1556 (patch)
tree6cbd881a196964002e32e6151151c121cb72ff61 /libnautilus-extensions/nautilus-undo-signal-handlers.c
parent820f06eb6d24d77955b866d4dfef97950eff3c19 (diff)
downloadnautilus-822c600faefc1d8f1e38c846178683a266ff1556.tar.gz
New file and functions to handle undo in NautilusEntry and GtkEditables.
* libnautilus-extensions/nautilus-undo-signal-handlers.c: * libnautilus-extensions/nautilus-undo-signal-handlers.h: (nautilus_entry_user_changed_callback), (nautilus_undo_setup_nautilus_entry_for_undo), (nautilus_undo_teardown_nautilus_entry_for_undo), (free_editable_undo_data), (free_editable_object_data), (editable_insert_text_callback), (editable_delete_text_callback), (editable_register_edit_undo), (nautilus_undo_setup_editable_for_undo), (nautilus_undo_teardown_editable_for_undo), (restore_editable_from_undo_snapshot_callback), (editable_key_press_event), (nautilus_undo_editable_set_undo_key): New file and functions to handle undo in NautilusEntry and GtkEditables. This file is intended to contain signal handlers that enable undo for a variety of GTK widgets. Calling a setup_for_undo function will prepare the widget to handle undo functionality. * libnautilus-extensions/Makefile.am: Added entries for new files nautilus-undo-signal-handlers.c and nautilus-undo-signal-handlers.h * components/notes/nautilus-notes.c: (make_notes_view): Fixed bug #973. Add undo to notes component. * components/websearch/ntl-web-search.c: (make_obj): Changed to use new undo signal handlers. * libnautilus-extensions/nautilus-entry.c: (nautilus_entry_initialize), (nautilus_entry_key_press), (nautilus_entry_set_text), (nautilus_entry_delete_text): Removed old undo code that had been rendered obsolete by the new signal handlers mentioned above. * src/nautilus-bookmarks-window.c: (create_bookmarks_window): Changed to use new undo signal handlers. ----------------------------------
Diffstat (limited to 'libnautilus-extensions/nautilus-undo-signal-handlers.c')
-rw-r--r--libnautilus-extensions/nautilus-undo-signal-handlers.c323
1 files changed, 323 insertions, 0 deletions
diff --git a/libnautilus-extensions/nautilus-undo-signal-handlers.c b/libnautilus-extensions/nautilus-undo-signal-handlers.c
new file mode 100644
index 000000000..0d028d896
--- /dev/null
+++ b/libnautilus-extensions/nautilus-undo-signal-handlers.c
@@ -0,0 +1,323 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+
+/* Signal handlers to enable undo in Gtk Widgets.
+ *
+ * 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/gtk.h>
+
+#include <libgnome/gnome-defs.h>
+#include <libgnome/gnome-i18n.h>
+#include <libnautilus/nautilus-undo.h>
+
+#include "nautilus-gtk-macros.h"
+
+#include "nautilus-undo-signal-handlers.h"
+
+
+typedef struct {
+ char *undo_text;
+ gint position;
+ guint selection_start;
+ guint selection_end;
+} EditableUndoData;
+
+typedef struct {
+ gboolean undo_registered;
+} EditableUndoObjectData;
+
+
+static void restore_editable_from_undo_snapshot_callback (GtkObject *target,
+ gpointer callback_data);
+static void editable_register_edit_undo (GtkEditable *editable);
+static void free_editable_object_data (gpointer data);
+
+/* nautilus_undo_setup_nautilus_entry_for_undo
+ *
+ * Functions and callback methods to handle undo
+ * in a NautilusEntry
+ */
+
+static void
+nautilus_entry_user_changed_callback (NautilusEntry *entry)
+{
+ /* Register undo transaction */
+ editable_register_edit_undo (GTK_EDITABLE (entry));
+}
+
+void
+nautilus_undo_setup_nautilus_entry_for_undo (NautilusEntry *entry)
+{
+ EditableUndoObjectData *data;
+
+ if (!NAUTILUS_IS_ENTRY (entry) ) {
+ return;
+ }
+
+ data = g_new(EditableUndoObjectData, 1);
+ data->undo_registered = FALSE;
+ gtk_object_set_data_full (GTK_OBJECT (entry), "undo_registered",
+ data, free_editable_object_data);
+
+ /* Connect to entry signals */
+ gtk_signal_connect (GTK_OBJECT (entry),
+ "user_changed",
+ GTK_SIGNAL_FUNC (nautilus_entry_user_changed_callback),
+ NULL);
+}
+
+void
+nautilus_undo_teardown_nautilus_entry_for_undo (NautilusEntry *entry)
+{
+ if (!NAUTILUS_IS_ENTRY (entry) ) {
+ return;
+ }
+
+ /* Disconnect from entry signals */
+ gtk_signal_disconnect_by_func (GTK_OBJECT (entry),
+ GTK_SIGNAL_FUNC (nautilus_entry_user_changed_callback),
+ NULL);
+}
+
+/* nautilus_undo_setup_nautilus_entry_for_undo
+ *
+ * Functions and callback methods to handle undo
+ * in a NautilusEntry
+ */
+
+static void
+free_editable_undo_data (gpointer data)
+{
+ EditableUndoData *undo_data;
+
+ undo_data = (EditableUndoData *) data;
+
+ g_free (undo_data->undo_text);
+ g_free (undo_data);
+}
+
+static void
+free_editable_object_data (gpointer data)
+{
+ g_free (data);
+}
+
+
+static void
+editable_insert_text_callback (GtkEditable *editable)
+{
+ /* Register undo transaction */
+ editable_register_edit_undo (editable);
+}
+
+static void
+editable_delete_text_callback (GtkEditable *editable)
+{
+ /* Register undo transaction */
+ editable_register_edit_undo (editable);
+}
+
+static void
+editable_register_edit_undo (GtkEditable *editable)
+{
+ EditableUndoData *undo_data;
+ EditableUndoObjectData *undo_info;
+ gpointer data;
+
+ if (!GTK_IS_EDITABLE (editable) ) {
+ return;
+ }
+
+ /* Check our undo registered flag */
+ data = gtk_object_get_data (GTK_OBJECT (editable), "undo_registered");
+ if (data == NULL) {
+ return;
+ }
+
+ undo_info = (EditableUndoObjectData *)data;
+ if (undo_info->undo_registered == TRUE) {
+ return;
+ }
+
+ undo_data = g_new (EditableUndoData, 1);
+ undo_data->undo_text = g_strdup (gtk_editable_get_chars (editable, 0, -1));
+ undo_data->position = gtk_editable_get_position (editable);
+ undo_data->selection_start = editable->selection_start_pos;
+ undo_data->selection_end = editable->selection_end_pos;
+
+ nautilus_undo_register
+ (GTK_OBJECT (editable),
+ restore_editable_from_undo_snapshot_callback,
+ undo_data,
+ (GDestroyNotify) free_editable_undo_data,
+ _("Edit"),
+ _("Undo Edit"),
+ _("Undo the edit"),
+ _("Redo Edit"),
+ _("Redo the edit"));
+
+ undo_info->undo_registered = TRUE;
+}
+
+void
+nautilus_undo_setup_editable_for_undo (GtkEditable *editable)
+{
+ EditableUndoObjectData *data;
+
+ if (!GTK_IS_EDITABLE (editable) ) {
+ return;
+ }
+
+ /* Connect to editable signals */
+ gtk_signal_connect (GTK_OBJECT (editable),
+ "insert_text",
+ GTK_SIGNAL_FUNC (editable_insert_text_callback),
+ NULL);
+
+ gtk_signal_connect (GTK_OBJECT (editable),
+ "delete_text",
+ GTK_SIGNAL_FUNC (editable_delete_text_callback),
+ NULL);
+
+
+ data = g_new(EditableUndoObjectData, 1);
+ data->undo_registered = FALSE;
+ gtk_object_set_data_full (GTK_OBJECT (editable), "undo_registered",
+ data, free_editable_object_data);
+}
+
+void
+nautilus_undo_teardown_editable_for_undo (GtkEditable *editable)
+{
+ if (!GTK_IS_EDITABLE (editable) ) {
+ return;
+ }
+
+ /* Disconnect from entry signals */
+ gtk_signal_disconnect_by_func (GTK_OBJECT (editable),
+ GTK_SIGNAL_FUNC (editable_insert_text_callback),
+ NULL);
+
+ gtk_signal_disconnect_by_func (GTK_OBJECT (editable),
+ GTK_SIGNAL_FUNC (editable_delete_text_callback),
+ NULL);
+
+}
+
+/* restore_editable_from_undo_snapshot_callback
+ *
+ * Restore edited text.
+ */
+static void
+restore_editable_from_undo_snapshot_callback (GtkObject *target, gpointer callback_data)
+{
+ GtkEditable *editable;
+ GtkWindow *window;
+ EditableUndoData *undo_data;
+ EditableUndoObjectData *data;
+ gint position;
+
+ editable = GTK_EDITABLE (target);
+ undo_data = (EditableUndoData *) callback_data;
+
+ /* Check our undo registered flag */
+ data = gtk_object_get_data (target, "undo_registered");
+ if (data == NULL) {
+ return;
+ }
+
+ /* Reset the registered flag so we get a new item for future editing. */
+ data->undo_registered = FALSE;
+
+ /* Register a new undo transaction for redo. */
+ editable_register_edit_undo (editable);
+
+ /* Restore the text. */
+ position = 0;
+ gtk_editable_delete_text (editable, 0, -1);
+ gtk_editable_insert_text (editable, undo_data->undo_text,
+ strlen (undo_data->undo_text), &position);
+
+ /* Set focus to widget */
+ window = GTK_WINDOW (gtk_widget_get_toplevel ( GTK_WIDGET (target)));
+ gtk_window_set_focus (window, GTK_WIDGET (editable));
+
+ /* We have to do this call, because the previous call selects all text */
+ gtk_editable_select_region (editable, 0, 0);
+
+ /* Restore selection */
+ gtk_editable_select_region (editable, undo_data->selection_start,
+ undo_data->selection_end);
+
+ /* Set the i-beam to the saved position */
+ gtk_editable_set_position (editable, undo_data->position);
+
+ /* Reset the registered flag so we get a new item for future editing. */
+ data->undo_registered = FALSE;
+}
+
+
+/* editable_set_undo_key
+ *
+ * Allow the use of ctrl-z from within widget.
+ */
+
+static void
+editable_key_press_event (GtkEditable *editable, GdkEventKey *event, gpointer user_data)
+{
+ switch (event->keyval) {
+ /* Undo */
+ case 'z':
+ if ((event->state & GDK_CONTROL_MASK) != 0) {
+ nautilus_undo (GTK_OBJECT (editable));
+ return;
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/* editable_set_undo_key
+ *
+ * Allow the use of ctrl-z from within widget. This should only be
+ * set if there is no menu bar to use to undo the widget.
+ */
+
+void
+nautilus_undo_editable_set_undo_key (GtkEditable *editable, gboolean value)
+{
+ if (value) {
+ /* Connect to entry signals */
+ gtk_signal_connect (GTK_OBJECT (editable),
+ "key-press-event",
+ GTK_SIGNAL_FUNC (editable_key_press_event),
+ NULL);
+ }
+ else {
+ gtk_signal_disconnect_by_func (GTK_OBJECT (editable),
+ GTK_SIGNAL_FUNC (editable_key_press_event),
+ NULL);
+ }
+}