Initial import of ephy (rev# 7126) from svn
[ephy-soc.git] / src / .svn / text-base / ephy-location-action.c.svn-base
blob9c30f0dc6bb2538e7b7aafda51b1712b162257fa
1 /*
2  *  Copyright © 2003, 2004 Marco Pesenti Gritti
3  *  Copyright © 2003, 2004 Christian Persch
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  *
19  *  $Id$
20  */
22 #include "config.h"
24 #include "ephy-location-action.h"
25 #include "ephy-location-entry.h"
26 #include "ephy-shell.h"
27 #include "ephy-completion-model.h"
28 #include "ephy-link.h"
29 #include "ephy-debug.h"
31 #include <gdk/gdkkeysyms.h>
32 #include <gtk/gtkentry.h>
33 #include <gtk/gtkstock.h>
34 #include <gtk/gtkimage.h>
35 #include <gtk/gtkentrycompletion.h>
36 #include <gtk/gtkmain.h>
38 #define EPHY_LOCATION_ACTION_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_LOCATION_ACTION, EphyLocationActionPrivate))
40 struct _EphyLocationActionPrivate
42         EphyWindow *window;
43         GList *actions;
44         char *address;
45         char *typed_address;
46         EphyNode *smart_bmks;
47         EphyBookmarks *bookmarks;
48         GdkPixbuf *icon;
49         char *lock_stock_id;
50         char *lock_tooltip;
51         guint editable : 1;
52         guint show_lock : 1;
53         guint secure : 1;
56 static void ephy_location_action_init       (EphyLocationAction *action);
57 static void ephy_location_action_class_init (EphyLocationActionClass *class);
58 static void ephy_location_action_finalize   (GObject *object);
59 static void user_changed_cb                 (GtkWidget *proxy,
60                                              EphyLocationAction *action);
61 static void sync_address                    (GtkAction *action,
62                                              GParamSpec *pspec,
63                                              GtkWidget *proxy);
65 enum
67         PROP_0,
68         PROP_ADDRESS,
69         PROP_EDITABLE,
70         PROP_ICON,
71         PROP_LOCK_STOCK,
72         PROP_LOCK_TOOLTIP,
73         PROP_SECURE,
74         PROP_SHOW_LOCK,
75         PROP_WINDOW
78 enum
80         LOCK_CLICKED,
81         LAST_SIGNAL
83 static guint signals[LAST_SIGNAL] = { 0 };
85 static GObjectClass *parent_class = NULL;
87 GType
88 ephy_location_action_get_type (void)
90         static GType type = 0;
92         if (G_UNLIKELY (type == 0))
93         {
94                 const GTypeInfo type_info =
95                 {
96                         sizeof (EphyLocationActionClass),
97                         (GBaseInitFunc) NULL,
98                         (GBaseFinalizeFunc) NULL,
99                         (GClassInitFunc) ephy_location_action_class_init,
100                         (GClassFinalizeFunc) NULL,
101                         NULL,
102                         sizeof (EphyLocationAction),
103                         0, /* n_preallocs */
104                         (GInstanceInitFunc) ephy_location_action_init,
105                 };
107                 type = g_type_register_static (EPHY_TYPE_LINK_ACTION,
108                                                "EphyLocationAction",
109                                                &type_info, 0);
110         }
112         return type;
115 static void
116 action_activated_cb (GtkEntryCompletion *completion,
117                      gint index,
118                      EphyLocationAction *action)
120         GtkWidget *entry;
121         char *content;
123         entry = gtk_entry_completion_get_entry (completion);
124         content = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1);
125         if (content)
126         {
127                 EphyNode *node;
128                 const char *smart_url;
129                 char *url;
131                 node = (EphyNode *)g_list_nth_data (action->priv->actions, index);
132                 smart_url = ephy_node_get_property_string
133                         (node, EPHY_NODE_BMK_PROP_LOCATION);
134                 g_return_if_fail (smart_url != NULL);
136                 url = ephy_bookmarks_resolve_address
137                         (action->priv->bookmarks, smart_url, content);
138                 g_free (content);
139                 if (url == NULL) return;
141                 ephy_link_open (EPHY_LINK (action), url, NULL,
142                                 ephy_link_flags_from_current_event () | EPHY_LINK_ALLOW_FIXUP);
144                 g_free (url);
145         }
148 static void
149 entry_activate_cb (GtkEntry *entry,
150                    EphyLocationAction *action)
152         EphyBookmarks *bookmarks;
153         const char *content;
154         char *address;
156         content = gtk_entry_get_text (entry);
157         if (content == NULL || content[0] == '\0') return;
159         bookmarks = ephy_shell_get_bookmarks (ephy_shell_get_default ());
161         address = ephy_bookmarks_resolve_address (bookmarks, content, NULL);
162         g_return_if_fail (address != NULL);
164         ephy_link_open (EPHY_LINK (action), address, NULL, 
165                         ephy_link_flags_from_current_event () | EPHY_LINK_ALLOW_FIXUP);
167         g_free (address);
170 static void
171 user_changed_cb (GtkWidget *proxy, EphyLocationAction *action)
173         const char *address;
175         address = ephy_location_entry_get_location (EPHY_LOCATION_ENTRY (proxy));
177         LOG ("user_changed_cb, new address %s", address);
179         g_signal_handlers_block_by_func (action, G_CALLBACK (sync_address), proxy);
180         ephy_location_action_set_address (action, address, NULL);
181         g_signal_handlers_unblock_by_func (action, G_CALLBACK (sync_address), proxy);
184 static void
185 lock_clicked_cb (GtkWidget *proxy,
186                  EphyLocationAction *action)
188         g_signal_emit (action, signals[LOCK_CLICKED], 0);
191 static void
192 sync_address (GtkAction *gaction,
193               GParamSpec *pspec,
194               GtkWidget *proxy)
196         EphyLocationAction *action = EPHY_LOCATION_ACTION (gaction);
197         EphyLocationActionPrivate *priv = action->priv;
198         EphyLocationEntry *lentry = EPHY_LOCATION_ENTRY (proxy);
200         LOG ("sync_address %s", action->priv->address);
202         g_signal_handlers_block_by_func (proxy, G_CALLBACK (user_changed_cb), action);
203         ephy_location_entry_set_location (lentry, priv->address,
204                                           priv->typed_address);
205         g_signal_handlers_unblock_by_func (proxy, G_CALLBACK (user_changed_cb), action);
208 static void
209 sync_editable (GtkAction *gaction,
210                GParamSpec *pspec,
211                GtkWidget *proxy)
213         EphyLocationAction *action = EPHY_LOCATION_ACTION (gaction);
214         EphyLocationEntry *lentry = EPHY_LOCATION_ENTRY (proxy);
215         GtkWidget *entry;
217         entry = ephy_location_entry_get_entry (lentry);
218         gtk_editable_set_editable (GTK_EDITABLE (entry), action->priv->editable);
221 static void
222 sync_icon (GtkAction *gaction,
223            GParamSpec *pspec,
224            GtkWidget *proxy)
226         EphyLocationAction *action = EPHY_LOCATION_ACTION (gaction);
227         EphyLocationActionPrivate *priv = action->priv;
228         EphyLocationEntry *entry = EPHY_LOCATION_ENTRY (proxy);
230         ephy_location_entry_set_favicon (entry, priv->icon);
233 static void
234 sync_lock_stock_id (GtkAction *gaction,
235                     GParamSpec *pspec,
236                     GtkWidget *proxy)
238         EphyLocationAction *action = EPHY_LOCATION_ACTION (gaction);
239         EphyLocationActionPrivate *priv = action->priv;
240         EphyLocationEntry *entry = EPHY_LOCATION_ENTRY (proxy);
242         ephy_location_entry_set_lock_stock (entry, priv->lock_stock_id);
245 static void
246 sync_lock_tooltip (GtkAction *gaction,
247                    GParamSpec *pspec,
248                    GtkWidget *proxy)
250         EphyLocationAction *action = EPHY_LOCATION_ACTION (gaction);
251         EphyLocationActionPrivate *priv = action->priv;
252         EphyLocationEntry *entry = EPHY_LOCATION_ENTRY (proxy);
254         ephy_location_entry_set_lock_tooltip (entry, priv->lock_tooltip);
257 static void
258 sync_secure (GtkAction *gaction,
259              GParamSpec *pspec,
260              GtkWidget *proxy)
262         EphyLocationAction *action = EPHY_LOCATION_ACTION (gaction);
263         EphyLocationActionPrivate *priv = action->priv;
264         EphyLocationEntry *entry = EPHY_LOCATION_ENTRY (proxy);
266         ephy_location_entry_set_secure (entry, priv->secure);
269 static void
270 sync_show_lock (GtkAction *gaction,
271                 GParamSpec *pspec,
272                 GtkWidget *proxy)
274         EphyLocationAction *action = EPHY_LOCATION_ACTION (gaction);
275         EphyLocationActionPrivate *priv = action->priv;
276         EphyLocationEntry *entry = EPHY_LOCATION_ENTRY (proxy);
278         ephy_location_entry_set_show_lock (entry, priv->show_lock);
281 static char *
282 get_location_cb (EphyLocationEntry *entry,
283                 EphyLocationAction *action)
285         EphyLocationActionPrivate *priv = action->priv;
286         EphyTab *tab;
287         
288         tab = ephy_window_get_active_tab (priv->window);
289         g_return_val_if_fail (tab != NULL, NULL);
291         return g_strdup (ephy_tab_get_address (tab));
294 static char *
295 get_title_cb (EphyLocationEntry *entry,
296               EphyLocationAction *action)
298         EphyTab *tab;
300         tab = ephy_window_get_active_tab (action->priv->window);
302         return g_strdup (ephy_tab_get_title (tab));
305 static void
306 remove_completion_actions (GtkAction *gaction,
307                            GtkWidget *proxy)
309         EphyLocationAction *action = EPHY_LOCATION_ACTION (gaction);
310         EphyLocationEntry *lentry = EPHY_LOCATION_ENTRY (proxy);
311         GtkWidget *entry;
312         GtkEntryCompletion *completion;
313         GList *l;
315         entry = ephy_location_entry_get_entry (lentry);
316         completion = gtk_entry_get_completion (GTK_ENTRY (entry));
318         for (l = action->priv->actions; l != NULL; l = l->next)
319         {
320                 gtk_entry_completion_delete_action (completion, 0);
321         }
323         g_signal_handlers_disconnect_by_func
324                         (completion, G_CALLBACK (action_activated_cb), action);
327 static void
328 add_completion_actions (GtkAction *gaction,
329                         GtkWidget *proxy)
331         EphyLocationAction *action = EPHY_LOCATION_ACTION (gaction);
332         EphyLocationEntry *lentry = EPHY_LOCATION_ENTRY (proxy);
333         GtkWidget *entry;
334         GtkEntryCompletion *completion;
335         GList *l;
337         entry = ephy_location_entry_get_entry (lentry);
338         completion = gtk_entry_get_completion (GTK_ENTRY (entry));
340         for (l = action->priv->actions; l != NULL; l = l->next)
341         {
342                 EphyNode *bmk = l->data;
343                 const char *title;
344                 int index;
346                 index = g_list_position (action->priv->actions, l);
347                 title = ephy_node_get_property_string
348                         (bmk, EPHY_NODE_BMK_PROP_TITLE);
349                 gtk_entry_completion_insert_action_text (completion, index, (char*)title);
350         }
352         g_signal_connect (completion, "action_activated",
353                           G_CALLBACK (action_activated_cb), action);
356 static void
357 connect_proxy (GtkAction *action, GtkWidget *proxy)
359         if (EPHY_IS_LOCATION_ENTRY (proxy))
360         {
361                 EphyLocationEntry *lentry = EPHY_LOCATION_ENTRY (proxy);
362                 EphyCompletionModel *model;
363                 GtkWidget *entry;
365                 model = ephy_completion_model_new ();
366                 ephy_location_entry_set_completion (EPHY_LOCATION_ENTRY (proxy),
367                                                     GTK_TREE_MODEL (model),
368                                                     EPHY_COMPLETION_TEXT_COL,
369                                                     EPHY_COMPLETION_ACTION_COL,
370                                                     EPHY_COMPLETION_KEYWORDS_COL,
371                                                     EPHY_COMPLETION_RELEVANCE_COL,
372                                                     EPHY_COMPLETION_EXTRA_COL,
373                                                     EPHY_COMPLETION_FAVICON_COL,
374                                                     EPHY_COMPLETION_URL_COL);
376                 add_completion_actions (action, proxy);
378                 sync_address (action, NULL, proxy);
379                 g_signal_connect_object (action, "notify::address",
380                                          G_CALLBACK (sync_address), proxy, 0);
381                 sync_editable (action, NULL, proxy);
382                 g_signal_connect_object (action, "notify::editable",
383                                          G_CALLBACK (sync_editable), proxy, 0);
384                 sync_icon (action, NULL, proxy);
385                 g_signal_connect_object (action, "notify::icon",
386                                          G_CALLBACK (sync_icon), proxy, 0);
387                 sync_lock_stock_id (action, NULL, proxy);
388                 g_signal_connect_object (action, "notify::lock-stock-id",
389                                          G_CALLBACK (sync_lock_stock_id), proxy, 0);
390                 sync_lock_tooltip (action, NULL, proxy);
391                 g_signal_connect_object (action, "notify::lock-tooltip",
392                                          G_CALLBACK (sync_lock_tooltip), proxy, 0);
393                 sync_secure (action, NULL, proxy);
394                 g_signal_connect_object (action, "notify::secure",
395                                          G_CALLBACK (sync_secure), proxy, 0);
396                 sync_show_lock (action, NULL, proxy);
397                 g_signal_connect_object (action, "notify::show-lock",
398                                          G_CALLBACK (sync_show_lock), proxy, 0);
400                 entry = ephy_location_entry_get_entry (lentry);
401                 g_signal_connect_object (entry, "activate",
402                                          G_CALLBACK (entry_activate_cb),
403                                          action, 0);
404                 g_signal_connect_object (proxy, "user-changed",
405                                          G_CALLBACK (user_changed_cb), action, 0);
406                 g_signal_connect_object (proxy, "lock-clicked",
407                                          G_CALLBACK (lock_clicked_cb), action, 0);
408                 g_signal_connect_object (proxy, "get-location",
409                                          G_CALLBACK (get_location_cb), action, 0);
410                 g_signal_connect_object (proxy, "get-title",
411                                          G_CALLBACK (get_title_cb), action, 0);
412         }
414         GTK_ACTION_CLASS (parent_class)->connect_proxy (action, proxy);
417 static void
418 disconnect_proxy (GtkAction *action, GtkWidget *proxy)
420         GTK_ACTION_CLASS (parent_class)->disconnect_proxy (action, proxy);
422         if (EPHY_IS_LOCATION_ENTRY (proxy))
423         {
424                 EphyLocationEntry *lentry = EPHY_LOCATION_ENTRY (proxy);
425                 GtkWidget *entry;
427                 entry = ephy_location_entry_get_entry (lentry);
429                 g_signal_handlers_disconnect_matched (action, G_SIGNAL_MATCH_DATA,
430                                                       0, 0, NULL, NULL, proxy);
431                 g_signal_handlers_disconnect_matched (proxy, G_SIGNAL_MATCH_DATA,
432                                                       0, 0, NULL, NULL, action);
433                 g_signal_handlers_disconnect_matched (entry, G_SIGNAL_MATCH_DATA,
434                                                       0, 0, NULL, NULL, action);
435         }
438 static void
439 ephy_location_action_set_property (GObject *object,
440                                    guint prop_id,
441                                    const GValue *value,
442                                    GParamSpec *pspec)
444         EphyLocationAction *action = EPHY_LOCATION_ACTION (object);
445         EphyLocationActionPrivate *priv = action->priv;
447         switch (prop_id)
448         {
449                 case PROP_ADDRESS:
450                         ephy_location_action_set_address (action, g_value_get_string (value), NULL);
451                         break;
452                 case PROP_EDITABLE:
453                         priv->editable = g_value_get_boolean (value);
454                         break;
455                 case PROP_ICON:
456                         if (priv->icon != NULL)
457                         {
458                                 g_object_unref (priv->icon);
459                         }
460                         priv->icon = GDK_PIXBUF (g_value_dup_object (value));
461                         break;
462                 case PROP_LOCK_STOCK:
463                         g_free (priv->lock_stock_id);
464                         priv->lock_stock_id = g_value_dup_string (value);
465                         break;
466                 case PROP_LOCK_TOOLTIP:
467                         g_free (priv->lock_tooltip);
468                         priv->lock_tooltip = g_value_dup_string (value);
469                         break;
470                 case PROP_SECURE:
471                         priv->secure = g_value_get_boolean (value);
472                         break;
473                 case PROP_SHOW_LOCK:
474                         priv->show_lock = g_value_get_boolean (value);
475                         break;
476                 case PROP_WINDOW:
477                         priv->window = EPHY_WINDOW (g_value_get_object (value));
478                         break;
479         }
482 static void
483 ephy_location_action_get_property (GObject *object,
484                                    guint prop_id,
485                                    GValue *value,
486                                    GParamSpec *pspec)
488         EphyLocationAction *action = EPHY_LOCATION_ACTION (object);
489         EphyLocationActionPrivate *priv = action->priv;
491         switch (prop_id)
492         {
493                 case PROP_ADDRESS:
494                         g_value_set_string (value, ephy_location_action_get_address (action));
495                         break;
496                 case PROP_EDITABLE:
497                         g_value_set_boolean (value, priv->editable);
498                         break;
499                 case PROP_ICON:
500                         g_value_set_object (value, priv->icon);
501                         break;
502                 case PROP_LOCK_STOCK:
503                         g_value_set_string (value, priv->lock_stock_id);
504                         break;
505                 case PROP_LOCK_TOOLTIP:
506                         g_value_set_string (value, priv->lock_tooltip);
507                         break;
508                 case PROP_SECURE:
509                         g_value_set_boolean (value, priv->secure);
510                         break;
511                 case PROP_SHOW_LOCK:
512                         g_value_set_boolean (value, priv->show_lock);
513                         break;
514                 case PROP_WINDOW:
515                         /* not readable */
516                         break;
517         }
520 static void
521 ephy_location_action_class_init (EphyLocationActionClass *class)
523         GObjectClass *object_class = G_OBJECT_CLASS (class);
524         GtkActionClass *action_class = GTK_ACTION_CLASS (class);
526         parent_class = g_type_class_peek_parent (class);
528         object_class->finalize = ephy_location_action_finalize;
529         object_class->get_property = ephy_location_action_get_property;
530         object_class->set_property = ephy_location_action_set_property;
532         action_class->toolbar_item_type = EPHY_TYPE_LOCATION_ENTRY;
533         action_class->connect_proxy = connect_proxy;
534         action_class->disconnect_proxy = disconnect_proxy;
536         signals[LOCK_CLICKED] = g_signal_new (
537                 "lock-clicked",
538                 EPHY_TYPE_LOCATION_ACTION,
539                 G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST,
540                 G_STRUCT_OFFSET (EphyLocationActionClass, lock_clicked),
541                 NULL, NULL,
542                 g_cclosure_marshal_VOID__VOID,
543                 G_TYPE_NONE,
544                 0);
546         g_object_class_install_property (object_class,
547                                          PROP_ADDRESS,
548                                          g_param_spec_string ("address",
549                                                               "Address",
550                                                               "The address",
551                                                               "",
552                                                               G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
553         g_object_class_install_property (object_class,
554                                          PROP_EDITABLE,
555                                          g_param_spec_boolean ("editable",
556                                                                "Editable",
557                                                                "Editable",
558                                                                TRUE,
559                                                                G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
561         g_object_class_install_property (object_class,
562                                          PROP_ICON,
563                                          g_param_spec_object ("icon",
564                                                               "Icon",
565                                                               "The icon",
566                                                               GDK_TYPE_PIXBUF,
567                                                               G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
569         g_object_class_install_property (object_class,
570                                          PROP_LOCK_STOCK,
571                                          g_param_spec_string  ("lock-stock-id",
572                                                                "Lock Stock ID",
573                                                                "Lock Stock ID",
574                                                                NULL,
575                                                                G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
577         g_object_class_install_property (object_class,
578                                          PROP_LOCK_TOOLTIP,
579                                          g_param_spec_string  ("lock-tooltip",
580                                                                "Lock Tooltip",
581                                                                "The icon",
582                                                                NULL,
583                                                                G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
585         g_object_class_install_property (object_class,
586                                          PROP_SECURE,
587                                          g_param_spec_boolean ("secure",
588                                                                "Secure",
589                                                                "Secure",
590                                                                FALSE,
591                                                                G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
593         g_object_class_install_property (object_class,
594                                          PROP_SHOW_LOCK,
595                                          g_param_spec_boolean ("show-lock",
596                                                                "Show Lock",
597                                                                "Show Lock",
598                                                                FALSE,
599                                                                G_PARAM_READWRITE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
601         g_object_class_install_property (object_class,
602                                          PROP_WINDOW,
603                                          g_param_spec_object ("window",
604                                                               "Window",
605                                                               "The navigation window",
606                                                               G_TYPE_OBJECT,
607                                                               G_PARAM_WRITABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB |
608                                                               G_PARAM_CONSTRUCT_ONLY));
610         g_type_class_add_private (object_class, sizeof (EphyLocationActionPrivate));
613 static int
614 compare_actions (gconstpointer a,
615                  gconstpointer b)
617         EphyNode *node_a = (EphyNode *)a;
618         EphyNode *node_b = (EphyNode *)b;
619         const char *title1, *title2;
620         int retval;
622         title1 = ephy_node_get_property_string (node_a, EPHY_NODE_BMK_PROP_TITLE);
623         title2 = ephy_node_get_property_string (node_b, EPHY_NODE_BMK_PROP_TITLE);
625         if (title1 == NULL)
626         {
627                 retval = -1;
628         }
629         else if (title2 == NULL)
630         {
631                 retval = 1;
632         }
633         else
634         {
635                 char *str_a, *str_b;
637                 str_a = g_utf8_casefold (title1, -1);
638                 str_b = g_utf8_casefold (title2, -1);
639                 retval = g_utf8_collate (str_a, str_b);
640                 g_free (str_a);
641                 g_free (str_b);
642         }
644         return retval;
647 static void
648 init_actions_list (EphyLocationAction *action)
650         GPtrArray *children;
651         int i;
653         children = ephy_node_get_children (action->priv->smart_bmks);
654         for (i = 0; i < children->len; i++)
655         {
656                 EphyNode *kid;
658                 kid = g_ptr_array_index (children, i);
660                 action->priv->actions = g_list_prepend
661                         (action->priv->actions, kid);
662         }
664         action->priv->actions =
665                 g_list_sort (action->priv->actions, (GCompareFunc) compare_actions);
668 static void
669 update_actions_list (EphyLocationAction *la)
671         GSList *l;
672         GtkAction *action = GTK_ACTION (la);
674         l = gtk_action_get_proxies (action);
675         for (; l != NULL; l = l->next)
676         {
677                 remove_completion_actions (action, GTK_WIDGET (l->data));
678         }
680         g_list_free (la->priv->actions);
681         la->priv->actions = NULL;
682         init_actions_list (la);
684         l = gtk_action_get_proxies (action);
685         for (; l != NULL; l = l->next)
686         {
687                 add_completion_actions (action, l->data);
688         }
691 static void
692 actions_child_removed_cb (EphyNode *node,
693                           EphyNode *child,
694                           guint old_index,
695                           EphyLocationAction *action)
697         update_actions_list (action);
700 static void
701 actions_child_added_cb (EphyNode *node,
702                         EphyNode *child,
703                         EphyLocationAction *action)
705         update_actions_list (action);
708 static void
709 actions_child_changed_cb (EphyNode *node,
710                           EphyNode *child,
711                           guint property_id,
712                           EphyLocationAction *action)
714         update_actions_list (action);
717 static void
718 ephy_location_action_init (EphyLocationAction *action)
720         EphyLocationActionPrivate *priv;
722         priv = action->priv = EPHY_LOCATION_ACTION_GET_PRIVATE (action);
724         priv->address = g_strdup ("");
725         priv->editable = TRUE;
726         priv->bookmarks = ephy_shell_get_bookmarks (ephy_shell);
727         priv->smart_bmks = ephy_bookmarks_get_smart_bookmarks
728                 (action->priv->bookmarks);
730         init_actions_list (action);
732         ephy_node_signal_connect_object (priv->smart_bmks,
733                                          EPHY_NODE_CHILD_ADDED,
734                                          (EphyNodeCallback)actions_child_added_cb,
735                                          G_OBJECT (action));
736         ephy_node_signal_connect_object (priv->smart_bmks,
737                                          EPHY_NODE_CHILD_REMOVED,
738                                          (EphyNodeCallback)actions_child_removed_cb,
739                                          G_OBJECT (action));
740         ephy_node_signal_connect_object (priv->smart_bmks,
741                                          EPHY_NODE_CHILD_CHANGED,
742                                          (EphyNodeCallback)actions_child_changed_cb,
743                                          G_OBJECT (action));
746 static void
747 ephy_location_action_finalize (GObject *object)
749         EphyLocationAction *action = EPHY_LOCATION_ACTION (object);
750         EphyLocationActionPrivate *priv = action->priv;
752         if (priv->icon != NULL)
753         {
754                 g_object_unref (priv->icon);
755         }
757         g_list_free (priv->actions);
758         g_free (priv->address);
759         g_free (priv->typed_address);
760         g_free (priv->lock_stock_id);
761         g_free (priv->lock_tooltip);
763         G_OBJECT_CLASS (parent_class)->finalize (object);
766 const char *
767 ephy_location_action_get_address (EphyLocationAction *action)
769         g_return_val_if_fail (EPHY_IS_LOCATION_ACTION (action), "");
771         return action->priv->address;
774 void
775 ephy_location_action_set_address (EphyLocationAction *action,
776                                   const char *address,
777                                   const char *typed_address)
779         EphyLocationActionPrivate *priv;
781         g_return_if_fail (EPHY_IS_LOCATION_ACTION (action));
783         priv = action->priv;
785         LOG ("set_address %s", address);
787         g_free (priv->address);
788         priv->address = g_strdup (address);
790         g_free (priv->typed_address);
791         priv->typed_address = typed_address ? g_strdup (typed_address) : NULL;
793         g_object_notify (G_OBJECT (action), "address");