Logo Search packages:      
Sourcecode: galeon version File versions

location-entry.c

/*
 *  Copyright (C) 2002  Ricardo Fernández Pascual
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2, or (at your option)
 *  any later version.
 *
 *  This program 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

/* Allow deprecated for the gnome_entry widget */
#undef GTK_DISABLE_DEPRECATED
#undef GNOME_DISABLE_DEPRECATED

#include "location-entry.h"
#include "galeon-autocompletion-window.h"
#include "galeon-marshal.h"
#include "eel-gconf-extensions.h"
#include "prefs-strings.h"
#include "galeon-debug.h"

#include <gdk/gdkkeysyms.h>
#include <gtk/gtkclipboard.h>
#include <gtk/gtkentry.h>
#include <gtk/gtkimage.h>
#include <gtk/gtkimagemenuitem.h>
#include <gtk/gtkmain.h>
#include <gtk/gtkseparatormenuitem.h>
#include <gtk/gtkstock.h>
#include <gtk/gtkwindow.h>
#include <glib/gi18n.h>
#include <libgnomeui/gnome-entry.h>
#include <string.h>

/**
 * Private data
 */
#define GALEON_LOCATION_ENTRY_GET_PRIVATE(object) (G_TYPE_INSTANCE_GET_PRIVATE ((object), \
                               GALEON_TYPE_LOCATION_ENTRY, GaleonLocationEntryPrivate))


struct _GaleonLocationEntryPrivate {
      GtkWidget *combo;
      GtkWidget *entry;
      gchar *before_completion;
      GaleonAutocompletion *autocompletion;
      GaleonAutocompletionWindow *autocompletion_window;
      gboolean autocompletion_window_visible;
      gint autocompletion_timeout;
      gint show_alternatives_timeout;
      gboolean block_set_autocompletion_key;
      gboolean hack_for_going_to_the_site_when_clicking_in_the_location_history;
      gboolean editing;

      gchar *autocompletion_key;
      gchar *last_completion;

      GtkWidget *shown_widget; /* for auto-toolbar show */
};

#define AUTOCOMPLETION_DELAY 200
#define SHOW_ALTERNATIVES_DELAY 500

#define GALEON_LOCATION_ENTRY_HISTORY_ID  "galeon-url-history"

/**
 * Private functions, only availble from this file
 */
static void       galeon_location_entry_finalize_impl (GObject *o);
static void       galeon_location_entry_build         (GaleonLocationEntry *w);
static gboolean         galeon_location_entry_key_press_event_cb (GtkWidget *entry, GdkEventKey *event,
                                                  GaleonLocationEntry *w);
static void       galeon_location_entry_activate_cb   (GtkEntry *entry, GaleonLocationEntry *w);
static void       galeon_location_entry_autocompletion_sources_changed_cb (GaleonAutocompletion *aw,
                                                             GaleonLocationEntry *w);
static gint       galeon_location_entry_autocompletion_to (GaleonLocationEntry *w);
static gint       galeon_location_entry_autocompletion_show_alternatives_to (GaleonLocationEntry *w);
static void       galeon_location_entry_autocompletion_window_url_activated_cb
/***/                                           (GaleonAutocompletionWindow *aw, 
                                                 const gchar *url, 
                                                 gboolean new_tab_or_window,
                                                 GaleonLocationEntry *w);
static void       galeon_location_entry_list_event_after_cb (GtkWidget *list,
                                                   GdkEvent *event, 
                                                   GaleonLocationEntry *e);
static void       galeon_location_entry_editable_changed_cb (GtkEditable *editable, 
                                                   GaleonLocationEntry *e);
static void       galeon_location_entry_set_autocompletion_key (GaleonLocationEntry *e);
static void       galeon_location_entry_autocompletion_show_alternatives (GaleonLocationEntry *w);
static void       galeon_location_entry_autocompletion_hide_alternatives (GaleonLocationEntry *w);
static void       galeon_location_entry_autocompletion_window_hidden_cb (GaleonAutocompletionWindow *aw, 
                                                             GaleonLocationEntry *w);





/**
 * Signals enums and ids
 */
enum GaleonLocationEntrySignalsEnum {
      GALEON_LOCATION_ENTRY_URL_ACTIVATED,
      GALEON_LOCATION_ENTRY_LAST_SIGNAL
};
static gint GaleonLocationEntrySignals[GALEON_LOCATION_ENTRY_LAST_SIGNAL];

/**
 * GaleonLocationEntry object
 */

G_DEFINE_TYPE (GaleonLocationEntry, galeon_location_entry, GTK_TYPE_HBOX);

static void
galeon_location_entry_class_init (GaleonLocationEntryClass *klass)
{
      GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);

      G_OBJECT_CLASS (klass)->finalize = galeon_location_entry_finalize_impl;

      GaleonLocationEntrySignals[GALEON_LOCATION_ENTRY_URL_ACTIVATED] = g_signal_new (
            "url-activated", G_OBJECT_CLASS_TYPE (klass),  
            G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST | G_SIGNAL_RUN_CLEANUP,
                G_STRUCT_OFFSET (GaleonLocationEntryClass, galeon_location_entry_url_activated), 
            NULL, NULL, 
            galeon_marshal_VOID__STRING_INT,
            G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_BOOLEAN);

      gtk_widget_class_install_style_property (widget_class,
                                     g_param_spec_boxed ("secure-color",
                                                     "Secure color",
                                                     "Background color to use for secure sites",
                                                     GDK_TYPE_COLOR,
                                                     G_PARAM_READABLE)); 

      g_type_class_add_private (klass, sizeof (GaleonLocationEntryPrivate));
}

static void
galeon_location_entry_activation_finished (GaleonLocationEntry *entry)
{
      if (entry->priv->shown_widget)
      {
            gtk_widget_hide (entry->priv->shown_widget);
            entry->priv->shown_widget = NULL;
      }
}

static gboolean
focus_out_event_cb (GtkWidget *entry, GdkEventFocus *event, 
                GaleonLocationEntry *w)
{
      w->priv->editing = FALSE;
      galeon_location_entry_activation_finished (w);
      return FALSE;
}

static void
entry_clear_activate_cb (GtkMenuItem *item, GtkEntry *entry)
{
      gtk_entry_set_text (entry, "");
}

static void
entry_populate_popup_cb (GtkEntry *entry, GtkMenu *menu)
{
      GtkWidget *image;
      GtkWidget *menuitem;

      menuitem = gtk_separator_menu_item_new ();
      gtk_widget_show (menuitem);
      gtk_menu_shell_prepend (GTK_MENU_SHELL(menu), menuitem);

      /* Clear and Copy mnemonics conflict, make custom menuitem */
      image = gtk_image_new_from_stock (GTK_STOCK_CLEAR, GTK_ICON_SIZE_MENU);
      /* To translators: the mnemonic shouldn't conflict with any of the
       * stock items in the GtkEntry context menu (Cut, Copy, Paste, Delete,
       * 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 (G_OBJECT(menuitem), "activate",
                    G_CALLBACK(entry_clear_activate_cb), entry);

      gtk_widget_show (image);
      gtk_widget_show (menuitem);
      gtk_menu_shell_prepend (GTK_MENU_SHELL(menu), menuitem);
}

static void 
galeon_location_entry_init (GaleonLocationEntry *w)
{
      GaleonLocationEntryPrivate *p = GALEON_LOCATION_ENTRY_GET_PRIVATE (w);
      w->priv = p;

      galeon_location_entry_build (w);

      g_signal_connect (w->priv->entry, "populate_popup",
                    G_CALLBACK (entry_populate_popup_cb), NULL);

      g_signal_connect (w->priv->entry, "focus_out_event",
                    G_CALLBACK (focus_out_event_cb), w);
}

static void
galeon_location_entry_finalize_impl (GObject *o)
{
      GaleonLocationEntry *w = GALEON_LOCATION_ENTRY (o);
      GaleonLocationEntryPrivate *p = w->priv;

      if (p->autocompletion)
      {
            g_signal_handlers_disconnect_matched (p->autocompletion, G_SIGNAL_MATCH_DATA, 0, 0, 
                                          NULL, NULL, w);

            g_signal_handlers_disconnect_matched (p->autocompletion_window, G_SIGNAL_MATCH_DATA, 0, 0, 
                                          NULL, NULL, w);

            g_object_unref (G_OBJECT (p->autocompletion));
            g_object_unref (G_OBJECT (p->autocompletion_window)); 
      }

      g_free (p->last_completion);
      g_free (p->before_completion);
      g_free (p->autocompletion_key);
      LOG ("GaleonLocationEntry finalized");

      G_OBJECT_CLASS (galeon_location_entry_parent_class)->finalize (o);
}

GaleonLocationEntry *
galeon_location_entry_new (void)
{
      return GALEON_LOCATION_ENTRY (g_object_new (GALEON_TYPE_LOCATION_ENTRY, NULL));
}

void
galeon_location_entry_clear_history (void)
{
      GtkWidget *w;

      w = gnome_entry_new (GALEON_LOCATION_ENTRY_HISTORY_ID);
      gnome_entry_clear_history (GNOME_ENTRY (w));
      gtk_widget_destroy (w);
}

static void
galeon_location_entry_build (GaleonLocationEntry *w)
{
      GaleonLocationEntryPrivate *p = w->priv;
      GtkWidget *list;

      p->combo = gnome_entry_new (GALEON_LOCATION_ENTRY_HISTORY_ID);
      p->entry = GTK_COMBO (p->combo)->entry;
      gtk_widget_show (p->combo);
      gtk_box_pack_start (GTK_BOX (w), p->combo, TRUE, TRUE, 0);

      g_signal_connect (p->entry, "key-press-event", 
                    G_CALLBACK (galeon_location_entry_key_press_event_cb), w);

      g_signal_connect (p->entry, "activate", 
                    G_CALLBACK (galeon_location_entry_activate_cb), w);

      g_signal_connect (p->entry, "changed", 
                    G_CALLBACK (galeon_location_entry_editable_changed_cb), w);

      list = GTK_COMBO (p->combo)->list;
      
      g_signal_connect_after (list, "event-after", 
                        G_CALLBACK (galeon_location_entry_list_event_after_cb), w);

}

static gint
galeon_location_entry_autocompletion_show_alternatives_to (GaleonLocationEntry *w)
{
      GaleonLocationEntryPrivate *p = w->priv;
      if (p->autocompletion)
      {
            LOG ("+galeon_location_entry_autocompletion_show_alternatives_to");
            galeon_location_entry_set_autocompletion_key (w);
            galeon_location_entry_autocompletion_show_alternatives (w);
      }
      p->show_alternatives_timeout = 0;
      return FALSE;
}

static void
galeon_location_entry_autocompletion_hide_alternatives (GaleonLocationEntry *w)
{
      GaleonLocationEntryPrivate *p = w->priv;
      if (p->autocompletion_window)
      {
            galeon_autocompletion_window_hide (p->autocompletion_window);
            p->autocompletion_window_visible = FALSE;
      }
}

static void
galeon_location_entry_autocompletion_show_alternatives (GaleonLocationEntry *w)
{
      GaleonLocationEntryPrivate *p = w->priv;
      if (p->autocompletion_window)
      {
            galeon_autocompletion_window_show (p->autocompletion_window);
            p->autocompletion_window_visible = TRUE;
      }
}

static void
galeon_location_entry_autocompletion_unselect_alternatives (GaleonLocationEntry *w)
{
      GaleonLocationEntryPrivate *p = w->priv;
      if (p->autocompletion_window)
      {
            galeon_autocompletion_window_unselect (p->autocompletion_window);
      }
}

static gint
galeon_location_entry_autocompletion_to (GaleonLocationEntry *w)
{
      GaleonLocationEntryPrivate *p = w->priv;
      gchar *text;
      gchar *common_prefix;
      
      LOG ("in galeon_location_entry_autocompletion_to");

      galeon_location_entry_set_autocompletion_key (w);

      {
            GtkEditable *editable = GTK_EDITABLE (p->entry);
            gint sstart, send;
            gint pos = gtk_editable_get_position (editable);
            const gchar *text = gtk_entry_get_text (GTK_ENTRY (p->entry));
            gint text_len = strlen (text);
            gtk_editable_get_selection_bounds (editable, &sstart, &send);
            
            if (pos != text_len
                || send != text_len)
            {
                  /* the user is editing the entry, don't mess it */
                  LOG ("The user seems editing the text: pos = %d, "
                       "strlen (text) = %d, sstart = %d, send = %d", 
                       pos, strlen (text), sstart, send);
                  p->autocompletion_timeout = 0;
                  return FALSE;
            }           
      }

      common_prefix = galeon_autocompletion_get_common_prefix (p->autocompletion);

      LOG ("common_prefix: %s", common_prefix);

      if (common_prefix && (!p->before_completion || p->before_completion[0] == '\0'))
      {
            text = galeon_location_entry_get_location (w);
            g_free (p->before_completion);
            p->before_completion = text;
      }

      if (common_prefix)
      {
            /* check original length */
            guint text_len = strlen (p->autocompletion_key);
            
            p->block_set_autocompletion_key = TRUE;

            /* set entry to completed text */
            gtk_entry_set_text (GTK_ENTRY (p->entry), common_prefix);
            
            /* move selection appropriately */
            gtk_editable_select_region (GTK_EDITABLE (p->entry), text_len, -1);
            
            p->block_set_autocompletion_key = FALSE;

            g_free (p->last_completion);
            p->last_completion = common_prefix;
      }

      p->autocompletion_timeout = 0;
      return FALSE;
}

static void
real_set_location (GaleonLocationEntry *w,
               const gchar *new_location)
{
      GaleonLocationEntryPrivate *p = w->priv;
      int pos = 0;
      int start, end;
      gchar* selection = NULL;

      /* Get the current selection, it is removed when we do the delete_text 
       * below */
      if (gtk_editable_get_selection_bounds (GTK_EDITABLE (p->entry), &start, &end))
      {
            selection = gtk_editable_get_chars (GTK_EDITABLE (p->entry), start, end);
      }

      gtk_editable_delete_text (GTK_EDITABLE (p->entry), 0, -1);
      gtk_editable_insert_text (GTK_EDITABLE (p->entry), new_location, 
                            strlen (new_location), &pos);

      /* Restore the selection into the PRIMARY clipboard as it will have just
       * been wiped */
      if (selection)
      {
            gtk_clipboard_set_text (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
                              selection, strlen (selection));
            g_free (selection);
      }
}

static void
emit_activated_signal (GaleonLocationEntry *w, const char *url, gboolean new_tab_or_window)
{
      w->priv->editing = FALSE;

      g_signal_emit (w, GaleonLocationEntrySignals[GALEON_LOCATION_ENTRY_URL_ACTIVATED], 
                       0, url, new_tab_or_window);
}


/* this is from the old location entry, need to do the autocompletion before implementing this */
static gboolean
galeon_location_entry_key_press_event_cb (GtkWidget *entry, GdkEventKey *event, GaleonLocationEntry *w)
{
      GaleonLocationEntryPrivate *p = w->priv;
        static gboolean suggest = FALSE;

        if (p->autocompletion_timeout != 0)
      {
                gtk_timeout_remove (p->autocompletion_timeout);
            p->autocompletion_timeout = 0;
      }

        if (p->show_alternatives_timeout != 0)
      {
                gtk_timeout_remove (p->show_alternatives_timeout);
            p->show_alternatives_timeout = 0;
      }
      
        /* only suggest heuristic completions if TAB is hit twice */
        if (event->keyval != GDK_Tab)
      {
                suggest = FALSE;
      }
      

      /* Handle any CTRL+Enter events */
      if ( event->state & GDK_CONTROL_MASK && 
           ( event->keyval == GDK_KP_Enter || event->keyval == GDK_Return ) )
      {
            char *url = gtk_editable_get_chars (GTK_EDITABLE(entry), 0, -1);

            LOG ("In galeon_location_key_press_cb, going to %s", url);
               
            galeon_location_entry_autocompletion_hide_alternatives (w);

            emit_activated_signal (w, url, TRUE);

            g_free (url);

            return TRUE;
      }

      /* Ingore any CTRL+<key> commands (or backspace commands) */
        if ((event->state & GDK_CONTROL_MASK) ||
            (event->state == 0 && event->keyval == GDK_BackSpace))
        {
            galeon_location_entry_autocompletion_hide_alternatives (w);
                return FALSE;
        }

        /* don't grab alt combos, thus you can still access the menus. */
        if (event->state & GDK_MOD1_MASK)
        {
            galeon_location_entry_autocompletion_hide_alternatives (w);
                return FALSE;
        }

        /* make sure the end key works at all times */ 
        if ((!((event->state & GDK_SHIFT_MASK) ||
             (event->state & GDK_CONTROL_MASK) ||
             (event->state & GDK_MOD1_MASK)) 
           && (event->keyval == GDK_End)))
        {
            galeon_location_entry_autocompletion_hide_alternatives (w);
                gtk_editable_select_region (GTK_EDITABLE (p->entry), 0, 0); 
                gtk_editable_set_position (GTK_EDITABLE (p->entry), -1);
            galeon_location_entry_autocompletion_unselect_alternatives (w);
                return TRUE;
        }

      switch (event->keyval)
        {
        case GDK_Left:
        case GDK_Right:
            galeon_location_entry_autocompletion_hide_alternatives (w);
                return FALSE;
        case GDK_Up:
        case GDK_Down:
        case GDK_Page_Up:
        case GDK_Page_Down:
            galeon_location_entry_autocompletion_hide_alternatives (w);
                /* galeon_embed_grab_focus (window->active_embed); */
                return FALSE;
        case GDK_Tab:
        {
                gchar *common_prefix = NULL;
                gchar *text;

            galeon_location_entry_set_autocompletion_key (w);

                gtk_editable_delete_selection (GTK_EDITABLE (p->entry));
                text = galeon_location_entry_get_location (w);
            galeon_location_entry_autocompletion_unselect_alternatives (w);

            /*
             * TODO: heuristic completions like in galeon1 are missing
             * common_prefix = 
             *     auto_completion_complete_url_extended (text, suggest);
             */

            if (p->autocompletion)
            {
                  common_prefix = galeon_autocompletion_get_common_prefix (p->autocompletion);
            }
                suggest = FALSE;
                if (common_prefix)
                {
                        if (!p->before_completion) 
                  {
                                p->before_completion = g_strdup (text);
                  }

                        p->block_set_autocompletion_key = TRUE;

                  gtk_entry_set_text (GTK_ENTRY (p->entry), common_prefix);
                  gtk_editable_set_position (GTK_EDITABLE (p->entry), -1);

                        p->block_set_autocompletion_key = FALSE;

                  /* show alternatives list only if there is no
                   * non-ambiguous prefix we can complete
                   */
                        if (!strcmp (common_prefix, text))
                        {
                        galeon_location_entry_autocompletion_show_alternatives (w);
                                /* really suggest something the next time */
                                suggest = TRUE; 
                        }
                  else if (p->autocompletion_window_visible)
                  {
                        /* if the alternatives list is already visible,
                         * update its contents to match the new prefix
                         */
                        galeon_location_entry_autocompletion_show_alternatives (w);
                  }
                        g_free (common_prefix);
                }
                else
                {
                  galeon_location_entry_autocompletion_hide_alternatives (w);
                }
            g_free (text);
                return TRUE;
        }
        case GDK_Escape:
            galeon_location_entry_autocompletion_hide_alternatives (w);
                if (p->before_completion)
                {
                        real_set_location (w, p->before_completion);
                        g_free (p->before_completion);
                        p->before_completion = NULL;
                  gtk_editable_set_position (GTK_EDITABLE (p->entry), -1);
                        return TRUE;
                }
                else
                {
                        /* real_set_location (w, embed->location); */
                }
                break;
        default:
            /* ignore keys that don't generate content (Shift, Ctrl, ...) */
            if (event->length <= 0) break;

            w->priv->editing = TRUE;
            galeon_location_entry_autocompletion_unselect_alternatives (w);
            if ((eel_gconf_get_boolean (CONF_COMPLETION_SHOW_LIST_AUTO))
                && (event->string[0] > 32) && (event->string[0] < 126))
                {
                        p->show_alternatives_timeout = g_timeout_add 
                                (SHOW_ALTERNATIVES_DELAY, 
                         (GSourceFunc) galeon_location_entry_autocompletion_show_alternatives_to, w);
                }
            if ((event->string[0] > 32) && (event->string[0] < 126)
                && eel_gconf_get_boolean (CONF_HISTORY_AUTOCOMP_ENABLE)
                && p->autocompletion)
            {
                  p->autocompletion_timeout = gtk_timeout_add 
                        (AUTOCOMPLETION_DELAY, 
                         (GSourceFunc) galeon_location_entry_autocompletion_to, w);
            }
                break;
        }

        return FALSE;
}

static void
galeon_location_entry_activate_cb (GtkEntry *entry, GaleonLocationEntry *w)
{
      char *url;

      url = gtk_editable_get_chars (GTK_EDITABLE(entry), 0, -1);

      galeon_location_entry_autocompletion_hide_alternatives (w);

      LOG ("In galeon_location_entry_activate_cb, going to %s", url);

      emit_activated_signal (w, url, FALSE);

      g_free (url);
}

static void
galeon_location_entry_autocompletion_sources_changed_cb (GaleonAutocompletion *aw,
                                           GaleonLocationEntry *w)
{
      GaleonLocationEntryPrivate *p = w->priv;

      LOG ("in galeon_location_entry_autocompletion_sources_changed_cb");

        if (p->autocompletion_timeout == 0
          && p->last_completion
          && !strcmp (p->last_completion, gtk_entry_get_text (GTK_ENTRY (p->entry))))
      {
            p->autocompletion_timeout = gtk_timeout_add 
                  (AUTOCOMPLETION_DELAY, 
                   (GSourceFunc) galeon_location_entry_autocompletion_to, w);
      }

        if (p->show_alternatives_timeout == 0 
          && p->autocompletion_window_visible)
      {
            p->show_alternatives_timeout = gtk_timeout_add 
                  (SHOW_ALTERNATIVES_DELAY, 
                   (GSourceFunc) galeon_location_entry_autocompletion_show_alternatives_to, w);
      }
}

void
galeon_location_entry_set_location (GaleonLocationEntry *w, 
                            const gchar *new_location)
{
      if (!w->priv->editing)
      {
            real_set_location (w, new_location);
      }
}

gchar *
galeon_location_entry_get_location (GaleonLocationEntry *w)
{
      char *location = gtk_editable_get_chars (GTK_EDITABLE (w->priv->entry), 0, -1);
      return location;
}

void
galeon_location_entry_set_autocompletion (GaleonLocationEntry *w, 
                                GaleonAutocompletion *ac)
{
      GaleonLocationEntryPrivate *p = w->priv;
      if (p->autocompletion)
      {
            g_signal_handlers_disconnect_matched (p->autocompletion, G_SIGNAL_MATCH_DATA, 0, 0, 
                                          NULL, NULL, w);

            g_signal_handlers_disconnect_matched (p->autocompletion_window, G_SIGNAL_MATCH_DATA, 0, 0, 
                                          NULL, NULL, w);

            g_object_unref (G_OBJECT (p->autocompletion));
            g_object_unref (p->autocompletion_window);
      }
      p->autocompletion = ac;
      if (p->autocompletion)
      {
            g_object_ref (G_OBJECT (p->autocompletion));
            p->autocompletion_window = galeon_autocompletion_window_new (p->autocompletion, 
                                                           p->entry);
            g_signal_connect (p->autocompletion_window, "url-activated",
                          G_CALLBACK (galeon_location_entry_autocompletion_window_url_activated_cb),
                          w);

            g_signal_connect (p->autocompletion_window, "hidden",
                          G_CALLBACK (galeon_location_entry_autocompletion_window_hidden_cb),
                          w);

            g_signal_connect (p->autocompletion, "sources-changed",
                          G_CALLBACK (galeon_location_entry_autocompletion_sources_changed_cb),
                          w);

            galeon_location_entry_set_autocompletion_key (w);
      }

}

static void
galeon_location_entry_autocompletion_window_url_activated_cb (GaleonAutocompletionWindow *aw, 
                                                const gchar *url, 
                                                gboolean new_tab_or_window,
                                                GaleonLocationEntry *w)
{
      real_set_location (w, url);

      LOG ("In location_entry_autocompletion_window_url_activated_cb, going to %s", url);

      galeon_location_entry_autocompletion_hide_alternatives (w);

      emit_activated_signal (w, url, new_tab_or_window);
}

static void
galeon_location_entry_autocompletion_window_hidden_cb (GaleonAutocompletionWindow *aw, 
                                           GaleonLocationEntry *w)
{
      GaleonLocationEntryPrivate *p = w->priv;

      LOG ("In location_entry_autocompletion_window_hidden_cb");

      p->autocompletion_window_visible = FALSE;

      if (p->show_alternatives_timeout)
      {
            g_source_remove (p->show_alternatives_timeout);
            p->show_alternatives_timeout = 0;
      }

      if (p->autocompletion_timeout)
      {
            g_source_remove (p->autocompletion_timeout);
            p->autocompletion_timeout = 0;
      }
}

void
galeon_location_entry_edit (GaleonLocationEntry *w)
{
      GtkWidget *widget;

      /* Traverse up the widget hierarchy to see if a parent
       * widget is hidden, and if it is, show it, this lets
       * that toolbar popup when the user uses Ctrl+L */
      for (widget = GTK_WIDGET (w); widget != NULL; widget = widget->parent)
      {
            if (!GTK_WIDGET_VISIBLE (widget))
            {
                  w->priv->shown_widget = widget;
                  gtk_widget_show (w->priv->shown_widget);
                  break;
            }
      }

      w->priv->editing = TRUE;
      /* gtk_editable_select_region (GTK_EDITABLE(w->priv->entry), 0, -1); */
      gtk_widget_grab_focus (w->priv->entry);
}

static void
galeon_location_entry_list_event_after_cb (GtkWidget *list,
                                 GdkEvent *event, 
                                 GaleonLocationEntry *e)
{
      if (event->type == GDK_BUTTON_PRESS
          && ((GdkEventButton *) event)->button == 1)
      {
            GaleonLocationEntryPrivate *p = e->priv;
            p->hack_for_going_to_the_site_when_clicking_in_the_location_history = TRUE;
      }
}

static void
galeon_location_entry_editable_changed_cb (GtkEditable *editable, GaleonLocationEntry *e)
{
      GaleonLocationEntryPrivate *p = e->priv;
      galeon_location_entry_set_autocompletion_key (e);

      if (p->hack_for_going_to_the_site_when_clicking_in_the_location_history)
      {
            gchar *url = galeon_location_entry_get_location (e);
            if (url && url[0] != '\0')
            {
                  p->hack_for_going_to_the_site_when_clicking_in_the_location_history = FALSE;
                  emit_activated_signal (e, url, FALSE);
                  g_free (url);
            }
      }

}

static void
galeon_location_entry_set_autocompletion_key (GaleonLocationEntry *e)
{
      GaleonLocationEntryPrivate *p = e->priv;
      if (p->autocompletion && !p->block_set_autocompletion_key)
      {
            GtkEditable *editable = GTK_EDITABLE (p->entry);
            gint sstart, send;
            gchar *text;
            gtk_editable_get_selection_bounds (editable, &sstart, &send);
            text = gtk_editable_get_chars (editable, 0, sstart);
            galeon_autocompletion_set_key (p->autocompletion, text);
            g_free (p->autocompletion_key);
            p->autocompletion_key = text;
      }
}

void
galeon_location_entry_set_is_secure (GaleonLocationEntry *entry, gboolean is_secure)
{
      GaleonLocationEntryPrivate *p = entry->priv;

      if (is_secure)
      {
            static const GdkColor fallback = { 0, 0xf7f7, 0xf7f7, 0xbebe };
            GdkColor             *secure_color = NULL;

            gtk_widget_style_get (GTK_WIDGET (entry), "secure-color", &secure_color, NULL);
            if (secure_color == NULL)
                  secure_color = (GdkColor*)&fallback;

            gtk_widget_modify_base (p->entry, GTK_STATE_NORMAL, secure_color);
            
            if (secure_color != &fallback)
                  gdk_color_free (secure_color);
      }
      else
            gtk_widget_modify_base (p->entry, GTK_STATE_NORMAL, NULL);
}

Generated by  Doxygen 1.6.0   Back to index