diff options
author | Cosimo Cecchi <cosimoc@src.gnome.org> | 2008-02-15 09:10:36 +0800 |
---|---|---|
committer | Cosimo Cecchi <cosimoc@src.gnome.org> | 2008-02-15 09:10:36 +0800 |
commit | 7411f596afe064f52e49e778f81d0e88f0b13d3c (patch) | |
tree | f2e59f258b0fe768a9283e66917580f7c95ebce3 | |
parent | 3bb5f859cf406cec4e562c17afe276db2ef92b4b (diff) | |
download | gsoc2013-epiphany-7411f596afe064f52e49e778f81d0e88f0b13d3c.tar gsoc2013-epiphany-7411f596afe064f52e49e778f81d0e88f0b13d3c.tar.gz gsoc2013-epiphany-7411f596afe064f52e49e778f81d0e88f0b13d3c.tar.bz2 gsoc2013-epiphany-7411f596afe064f52e49e778f81d0e88f0b13d3c.tar.lz gsoc2013-epiphany-7411f596afe064f52e49e778f81d0e88f0b13d3c.tar.xz gsoc2013-epiphany-7411f596afe064f52e49e778f81d0e88f0b13d3c.tar.zst gsoc2013-epiphany-7411f596afe064f52e49e778f81d0e88f0b13d3c.zip |
Add Undo/Redo commands to the location entry, both in the context menu
and linked to the main window commands. Bug #171179.
svn path=/trunk/; revision=7945
-rw-r--r-- | lib/widgets/ephy-location-entry.c | 104 | ||||
-rw-r--r-- | lib/widgets/ephy-location-entry.h | 6 | ||||
-rw-r--r-- | src/ephy-window.c | 27 | ||||
-rw-r--r-- | src/window-commands.c | 40 |
4 files changed, 151 insertions, 26 deletions
diff --git a/lib/widgets/ephy-location-entry.c b/lib/widgets/ephy-location-entry.c index 2dcd5386f..6bd3af9ef 100644 --- a/lib/widgets/ephy-location-entry.c +++ b/lib/widgets/ephy-location-entry.c @@ -73,6 +73,7 @@ struct _EphyLocationEntryPrivate GtkCellRenderer *extracell; char *before_completion; + char *saved_text; guint text_col; guint action_col; @@ -85,6 +86,8 @@ struct _EphyLocationEntryPrivate guint hash; guint user_changed : 1; + guint can_redo : 1; + guint block_update : 1; guint original_address : 1; guint secure : 1; guint apply_colours : 1; @@ -221,6 +224,8 @@ ephy_location_entry_finalize (GObject *object) { EphyLocationEntry *entry = EPHY_LOCATION_ENTRY (object); EphyLocationEntryPrivate *priv = entry->priv; + + g_free (priv->saved_text); if (priv->favicon != NULL) { @@ -343,7 +348,13 @@ editable_changed_cb (GtkEditable *editable, update_address_state (entry); - if (priv->user_changed == FALSE) return; + if (priv->block_update == TRUE) + return; + else + { + priv->user_changed = TRUE; + priv->can_redo = FALSE; + } update_favicon (entry); @@ -424,6 +435,8 @@ entry_activate_after_cb (GtkEntry *entry, EphyLocationEntry *lentry) { EphyLocationEntryPrivate *priv = lentry->priv; + + priv->user_changed = FALSE; if (priv->needs_reset) { @@ -528,19 +541,34 @@ entry_clear_activate_cb (GtkMenuItem *item, { EphyLocationEntryPrivate *priv = entry->priv; - priv->user_changed = FALSE; + priv->block_update = TRUE; gtk_entry_set_text (GTK_ENTRY (priv->icon_entry->entry), ""); + priv->block_update = FALSE; priv->user_changed = TRUE; } static void +entry_redo_activate_cb (GtkMenuItem *item, + EphyLocationEntry *entry) +{ + ephy_location_entry_undo_reset (entry); +} + +static void +entry_undo_activate_cb (GtkMenuItem *item, + EphyLocationEntry *entry) +{ + ephy_location_entry_reset_internal (entry, FALSE); +} + +static void entry_populate_popup_cb (GtkEntry *entry, GtkMenu *menu, EphyLocationEntry *lentry) { EphyLocationEntryPrivate *priv = lentry->priv; GtkWidget *image; - GtkWidget *menuitem; + GtkWidget *clear_menuitem, *undo_menuitem, *redo_menuitem, *separator; GList *children, *item; int pos = 0, sep = 0; gboolean is_editable; @@ -553,13 +581,13 @@ entry_populate_popup_cb (GtkEntry *entry, * standard items in the GtkEntry context menu (Cut, Copy, Paste, Delete, * Select All, Input Methods and Insert Unicode control character.) */ - menuitem = gtk_image_menu_item_new_with_mnemonic (_("Cl_ear")); - gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM(menuitem), image); - g_signal_connect (menuitem , "activate", + clear_menuitem = gtk_image_menu_item_new_with_mnemonic (_("Cl_ear")); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (clear_menuitem), image); + g_signal_connect (clear_menuitem , "activate", G_CALLBACK (entry_clear_activate_cb), lentry); is_editable = gtk_editable_get_editable (GTK_EDITABLE (priv->icon_entry->entry)); - gtk_widget_set_sensitive (menuitem, is_editable); - gtk_widget_show (menuitem); + gtk_widget_set_sensitive (clear_menuitem, is_editable); + gtk_widget_show (clear_menuitem); /* search for the 2nd separator (the one after Select All) in the context * menu, and insert this menu item before it. @@ -571,7 +599,25 @@ entry_populate_popup_cb (GtkEntry *entry, if (GTK_IS_SEPARATOR_MENU_ITEM (item->data)) sep++; } - gtk_menu_shell_insert (GTK_MENU_SHELL (menu), menuitem, pos - 1); + gtk_menu_shell_insert (GTK_MENU_SHELL (menu), clear_menuitem, pos - 1); + + undo_menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_UNDO, NULL); + gtk_widget_set_sensitive (undo_menuitem, priv->user_changed); + g_signal_connect (undo_menuitem, "activate", + G_CALLBACK (entry_undo_activate_cb), lentry); + gtk_widget_show (undo_menuitem); + gtk_menu_shell_insert (GTK_MENU_SHELL (menu), undo_menuitem, 0); + + redo_menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_REDO, NULL); + gtk_widget_set_sensitive (redo_menuitem, priv->can_redo); + g_signal_connect (redo_menuitem, "activate", + G_CALLBACK (entry_redo_activate_cb), lentry); + gtk_widget_show (redo_menuitem); + gtk_menu_shell_insert (GTK_MENU_SHELL (menu), redo_menuitem, 1); + + separator = gtk_separator_menu_item_new (); + gtk_widget_show (separator); + gtk_menu_shell_insert (GTK_MENU_SHELL (menu), separator, 2); } static void @@ -876,7 +922,9 @@ ephy_location_entry_init (EphyLocationEntry *le) p = EPHY_LOCATION_ENTRY_GET_PRIVATE (le); le->priv = p; - p->user_changed = TRUE; + p->user_changed = FALSE; + p->block_update = FALSE; + p->saved_text = NULL; ephy_location_entry_construct_contents (le); @@ -1095,9 +1143,9 @@ ephy_location_entry_set_location (EphyLocationEntry *entry, /* First record the new hash, then update the entry text */ priv->hash = g_str_hash (address); - priv->user_changed = FALSE; + priv->block_update = TRUE; gtk_entry_set_text (GTK_ENTRY (priv->icon_entry->entry), text); - priv->user_changed = TRUE; + priv->block_update = FALSE; /* We need to call update_address_state() here, as the 'changed' signal * may not get called if the user has typed in the exact correct url */ @@ -1115,6 +1163,22 @@ ephy_location_entry_set_location (EphyLocationEntry *entry, } } +gboolean +ephy_location_entry_get_can_undo (EphyLocationEntry *entry) +{ + EphyLocationEntryPrivate *priv = entry->priv; + + return priv->user_changed; +} + +gboolean +ephy_location_entry_get_can_redo (EphyLocationEntry *entry) +{ + EphyLocationEntryPrivate *priv = entry->priv; + + return priv->can_redo; +} + const char * ephy_location_entry_get_location (EphyLocationEntry *entry) { @@ -1137,6 +1201,10 @@ ephy_location_entry_reset_internal (EphyLocationEntry *entry, old_text = gtk_entry_get_text (GTK_ENTRY (priv->icon_entry->entry)); old_text = old_text != NULL ? old_text : ""; + g_free (priv->saved_text); + priv->saved_text = g_strdup (old_text); + priv->can_redo = TRUE; + retval = g_str_hash (text) != g_str_hash (old_text); ephy_location_entry_set_location (entry, text, NULL); @@ -1146,10 +1214,22 @@ ephy_location_entry_reset_internal (EphyLocationEntry *entry, { g_signal_emit (entry, signals[USER_CHANGED], 0); } + + priv->user_changed = FALSE; return retval; } +void +ephy_location_entry_undo_reset (EphyLocationEntry *entry) +{ + EphyLocationEntryPrivate *priv = entry->priv; + + gtk_entry_set_text (GTK_ENTRY (priv->icon_entry->entry), priv->saved_text); + priv->can_redo = FALSE; + priv->user_changed = TRUE; +} + gboolean ephy_location_entry_reset (EphyLocationEntry *entry) { diff --git a/lib/widgets/ephy-location-entry.h b/lib/widgets/ephy-location-entry.h index 0833bedf4..de6d35e57 100644 --- a/lib/widgets/ephy-location-entry.h +++ b/lib/widgets/ephy-location-entry.h @@ -87,8 +87,14 @@ void ephy_location_entry_set_completion_func (EphyLocationEntry *le, const char *ephy_location_entry_get_location (EphyLocationEntry *le); +gboolean ephy_location_entry_get_can_undo (EphyLocationEntry *le); + +gboolean ephy_location_entry_get_can_redo (EphyLocationEntry *entry); + gboolean ephy_location_entry_reset (EphyLocationEntry *entry); +void ephy_location_entry_undo_reset (EphyLocationEntry *entry); + void ephy_location_entry_activate (EphyLocationEntry *le); GtkWidget *ephy_location_entry_get_entry (EphyLocationEntry *entry); diff --git a/src/ephy-window.c b/src/ephy-window.c index 93f9f16f7..46da33704 100644 --- a/src/ephy-window.c +++ b/src/ephy-window.c @@ -57,6 +57,7 @@ #include "ephy-find-toolbar.h" #include "ephy-embed-persist.h" #include "ephy-embed-factory.h" +#include "ephy-location-entry.h" #include <string.h> #include <glib/gi18n.h> @@ -1133,15 +1134,35 @@ update_edit_actions_sensitivity (EphyWindow *window, gboolean hide) if (GTK_IS_EDITABLE (widget)) { gboolean has_selection; - + GtkActionGroup *action_group; + GtkAction *location_action; + GSList *proxies; + GtkWidget *proxy; + + action_group = ephy_toolbar_get_action_group (window->priv->toolbar); + location_action = gtk_action_group_get_action (action_group, + "Location"); + proxies = gtk_action_get_proxies (location_action); + proxy = GTK_WIDGET (proxies->data); + has_selection = gtk_editable_get_selection_bounds (GTK_EDITABLE (widget), NULL, NULL); can_copy = has_selection; can_cut = has_selection; can_paste = TRUE; - can_undo = FALSE; - can_redo = FALSE; + if (proxy != NULL && + EPHY_IS_LOCATION_ENTRY (proxy) && + widget == ephy_location_entry_get_entry (EPHY_LOCATION_ENTRY (proxy))) + { + can_undo = ephy_location_entry_get_can_undo (EPHY_LOCATION_ENTRY (proxy)); + can_redo = ephy_location_entry_get_can_redo (EPHY_LOCATION_ENTRY (proxy)); + } + else + { + can_undo = FALSE; + can_redo = FALSE; + } } else { diff --git a/src/window-commands.c b/src/window-commands.c index 9bc698a67..dd5bd634d 100644 --- a/src/window-commands.c +++ b/src/window-commands.c @@ -355,14 +355,24 @@ window_cmd_edit_undo (GtkAction *action, { GtkWidget *widget; GtkWidget *embed; + GtkWidget *location_entry; widget = gtk_window_get_focus (GTK_WINDOW (window)); - embed = gtk_widget_get_ancestor (widget, EPHY_TYPE_EMBED); - - if (embed) + location_entry = gtk_widget_get_ancestor (widget, EPHY_TYPE_LOCATION_ENTRY); + + if (location_entry) + { + ephy_location_entry_reset (EPHY_LOCATION_ENTRY (location_entry)); + } + else { - ephy_command_manager_do_command (EPHY_COMMAND_MANAGER (embed), - "cmd_undo"); + embed = gtk_widget_get_ancestor (widget, EPHY_TYPE_EMBED); + + if (embed) + { + ephy_command_manager_do_command (EPHY_COMMAND_MANAGER (embed), + "cmd_undo"); + } } } @@ -372,17 +382,25 @@ window_cmd_edit_redo (GtkAction *action, { GtkWidget *widget; GtkWidget *embed; + GtkWidget *location_entry; widget = gtk_window_get_focus (GTK_WINDOW (window)); - embed = gtk_widget_get_ancestor (widget, EPHY_TYPE_EMBED); - - if (embed) + location_entry = gtk_widget_get_ancestor (widget, EPHY_TYPE_LOCATION_ENTRY); + + if (location_entry) { - ephy_command_manager_do_command (EPHY_COMMAND_MANAGER (embed), - "cmd_redo"); + ephy_location_entry_undo_reset (EPHY_LOCATION_ENTRY (location_entry)); + } + else + { + embed = gtk_widget_get_ancestor (widget, EPHY_TYPE_EMBED); + if (embed) + { + ephy_command_manager_do_command (EPHY_COMMAND_MANAGER (embed), + "cmd_redo"); + } } } - void window_cmd_edit_cut (GtkAction *action, EphyWindow *window) |