diff options
Diffstat (limited to 'src/ephy-location-action.c')
-rw-r--r-- | src/ephy-location-action.c | 211 |
1 files changed, 190 insertions, 21 deletions
diff --git a/src/ephy-location-action.c b/src/ephy-location-action.c index bd18275a7..0d90e8e24 100644 --- a/src/ephy-location-action.c +++ b/src/ephy-location-action.c @@ -22,13 +22,20 @@ #include "ephy-location-action.h" #include "ephy-location-entry.h" #include "ephy-shell.h" +#include "ephy-completion-model.h" #include "ephy-debug.h" +#include <gtk/gtkentry.h> +#include <gtk/gtkentrycompletion.h> + #define EPHY_LOCATION_ACTION_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_LOCATION_ACTION, EphyLocationActionPrivate)) struct _EphyLocationActionPrivate { + GList *actions; char *address; + EphyNode *smart_bmks; + EphyBookmarks *bookmarks; }; static void ephy_location_action_init (EphyLocationAction *action); @@ -84,32 +91,48 @@ ephy_location_action_get_type (void) } static void -location_url_activate_cb (EphyLocationEntry *entry, - const char *content, - const char *target, - EphyLocationAction *action) +action_activated_cb (GtkEntryCompletion *completion, + gint index, + EphyLocationAction *action) { - EphyBookmarks *bookmarks; + GtkWidget *entry; + char *content; - LOG ("Location url activated, content %s target %s", content, target) - - bookmarks = ephy_shell_get_bookmarks (ephy_shell); - - if (!content) - { - LOG ("Go to %s", target); - g_signal_emit (action, signals[GO_LOCATION], 0, target); - } - else + entry = gtk_entry_completion_get_entry (completion); + content = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1); + if (content) { + EphyNode *node; + const char *smart_url; char *url; + node = (EphyNode *)g_list_nth_data (action->priv->actions, index); + smart_url = ephy_node_get_property_string + (node, EPHY_NODE_BMK_PROP_LOCATION); + g_return_if_fail (smart_url != NULL); + url = ephy_bookmarks_solve_smart_url - (bookmarks, target, content); + (action->priv->bookmarks, smart_url, content); g_return_if_fail (url != NULL); - LOG ("Go to %s", url); + g_signal_emit (action, signals[GO_LOCATION], 0, url); + g_free (url); + g_free (content); + } +} + +static void +location_url_activate_cb (EphyLocationEntry *entry, + EphyLocationAction *action) +{ + char *content; + + content = gtk_editable_get_chars (GTK_EDITABLE(entry), 0, -1); + if (content) + { + g_signal_emit (action, signals[GO_LOCATION], 0, content); + g_free (content); } } @@ -142,23 +165,81 @@ sync_address (GtkAction *act, GParamSpec *pspec, GtkWidget *proxy) } static void +remove_completion_actions (GtkAction *action, GtkWidget *proxy) +{ + GtkWidget *entry; + GtkEntryCompletion *completion; + EphyLocationAction *la = EPHY_LOCATION_ACTION (action); + GList *l; + + entry = ephy_location_entry_get_entry (EPHY_LOCATION_ENTRY (proxy)); + completion = gtk_entry_get_completion (GTK_ENTRY (entry)); + + for (l = la->priv->actions; l != NULL; l = l->next) + { + int index; + + index = g_list_position (la->priv->actions, l); + gtk_entry_completion_delete_action (completion, index); + } + + g_signal_handlers_disconnect_by_func + (completion, G_CALLBACK (action_activated_cb), la); +} + +static void +add_completion_actions (GtkAction *action, GtkWidget *proxy) +{ + GtkWidget *entry; + GtkEntryCompletion *completion; + EphyLocationAction *la = EPHY_LOCATION_ACTION (action); + GList *l; + + entry = ephy_location_entry_get_entry (EPHY_LOCATION_ENTRY (proxy)); + completion = gtk_entry_get_completion (GTK_ENTRY (entry)); + + for (l = la->priv->actions; l != NULL; l = l->next) + { + EphyNode *bmk = l->data; + const char *title; + int index; + + index = g_list_position (la->priv->actions, l); + title = ephy_node_get_property_string + (bmk, EPHY_NODE_BMK_PROP_TITLE); + gtk_entry_completion_insert_action_text (completion, index, (char*)title); + } + + g_signal_connect (completion, "action_activated", + G_CALLBACK (action_activated_cb), la); +} + +static void connect_proxy (GtkAction *action, GtkWidget *proxy) { LOG ("Connect proxy") if (EPHY_IS_LOCATION_ENTRY (proxy)) { - EphyAutocompletion *ac; + EphyCompletionModel *model; + GtkWidget *entry; - ac = EPHY_AUTOCOMPLETION (ephy_shell_get_autocompletion (ephy_shell)); + model = ephy_completion_model_new (); + ephy_location_entry_set_completion (EPHY_LOCATION_ENTRY (proxy), + GTK_TREE_MODEL (model), + EPHY_COMPLETION_TEXT_COL, + EPHY_COMPLETION_ACTION_COL, + EPHY_COMPLETION_KEYWORDS_COL, + EPHY_COMPLETION_RELEVANCE_COL); - ephy_location_entry_set_autocompletion (EPHY_LOCATION_ENTRY (proxy), ac); + add_completion_actions (action, proxy); sync_address (action, NULL, proxy); g_signal_connect_object (action, "notify::address", G_CALLBACK (sync_address), proxy, 0); - g_signal_connect_object (proxy, "activated", + entry = ephy_location_entry_get_entry (EPHY_LOCATION_ENTRY (proxy)); + g_signal_connect_object (entry, "activate", G_CALLBACK (location_url_activate_cb), action, 0); g_signal_connect_object (proxy, "user_changed", @@ -274,11 +355,97 @@ ephy_location_action_class_init (EphyLocationActionClass *class) } static void +init_actions_list (EphyLocationAction *action) +{ + GPtrArray *children; + int i; + + children = ephy_node_get_children (action->priv->smart_bmks); + for (i = 0; i < children->len; i++) + { + EphyNode *kid; + + kid = g_ptr_array_index (children, i); + + action->priv->actions = g_list_append + (action->priv->actions, kid); + } +} + +static void +update_actions_list (EphyLocationAction *la) +{ + GSList *l; + GtkAction *action = GTK_ACTION (la); + + l = gtk_action_get_proxies (action); + for (; l != NULL; l = l->next) + { + remove_completion_actions (action, GTK_WIDGET (l->data)); + } + + g_list_free (la->priv->actions); + la->priv->actions = NULL; + init_actions_list (la); + + l = gtk_action_get_proxies (action); + for (; l != NULL; l = l->next) + { + add_completion_actions (action, l->data); + } +} + +static void +actions_child_removed_cb (EphyNode *node, + EphyNode *child, + guint old_index, + EphyLocationAction *action) +{ + update_actions_list (action); +} + +static void +actions_child_added_cb (EphyNode *node, + EphyNode *child, + EphyLocationAction *action) +{ + update_actions_list (action); +} + +static void +actions_child_changed_cb (EphyNode *node, + EphyNode *child, + EphyLocationAction *action) +{ + update_actions_list (action); +} + +static void ephy_location_action_init (EphyLocationAction *action) { action->priv = EPHY_LOCATION_ACTION_GET_PRIVATE (action); action->priv->address = g_strdup (""); + action->priv->actions = NULL; + + action->priv->bookmarks = ephy_shell_get_bookmarks (ephy_shell); + action->priv->smart_bmks = ephy_bookmarks_get_smart_bookmarks + (action->priv->bookmarks); + + init_actions_list (action); + + ephy_node_signal_connect_object (action->priv->smart_bmks, + EPHY_NODE_CHILD_ADDED, + (EphyNodeCallback)actions_child_added_cb, + G_OBJECT (action)); + ephy_node_signal_connect_object (action->priv->smart_bmks, + EPHY_NODE_CHILD_REMOVED, + (EphyNodeCallback)actions_child_removed_cb, + G_OBJECT (action)); + ephy_node_signal_connect_object (action->priv->smart_bmks, + EPHY_NODE_CHILD_CHANGED, + (EphyNodeCallback)actions_child_changed_cb, + G_OBJECT (action)); } static void @@ -286,6 +453,8 @@ ephy_location_action_finalize (GObject *object) { EphyLocationAction *action = EPHY_LOCATION_ACTION (object); + g_list_free (action->priv->actions); + g_free (action->priv->address); } |