aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/widgets/ephy-location-entry.c104
-rw-r--r--lib/widgets/ephy-location-entry.h6
-rw-r--r--src/ephy-window.c27
-rw-r--r--src/window-commands.c40
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)