]> spindle.queued.net Git - midori/commitdiff
Move completion logic from LocationEntry to LocationAction
authorChristian Dywan <christian@twotoasts.de>
Sun, 9 Nov 2008 18:09:35 +0000 (19:09 +0100)
committerChristian Dywan <christian@twotoasts.de>
Sun, 9 Nov 2008 18:09:35 +0000 (19:09 +0100)
This resolves various indirections, and since we are always
using the action anyway, we finally move all logic to one
place. There should be room for optimizations now.
Incidentally this also keeps the completion intact if
the entry needs to be recreated.

midori/midori-locationaction.c
midori/midori-locationaction.h
midori/midori-locationentry.c
midori/midori-locationentry.h

index 90d1ae46b9912b83b5e14da1c3ff935a11ff4a89..a0940758e746273c912c68c08f9891b799c38e52 100644 (file)
@@ -1,5 +1,6 @@
 /*
  Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
+ Copyright (C) 2008 Dale Whittaker <dayul@users.sf.net>
 
  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
 #include "midori-locationaction.h"
 
 #include "gtkiconentry.h"
+#include "sokoke.h"
 
+#include <string.h>
 #include <glib/gi18n.h>
 #include <gdk/gdkkeysyms.h>
 
+#define MAX_ITEMS 25
+
 struct _MidoriLocationAction
 {
     GtkAction parent_instance;
@@ -24,6 +29,9 @@ struct _MidoriLocationAction
     gdouble progress;
 
     GtkTreeModel* model;
+    GtkTreeModel* filter_model;
+    GtkTreeModel* sort_model;
+    GdkPixbuf* default_icon;
 };
 
 struct _MidoriLocationActionClass
@@ -53,6 +61,16 @@ enum
 
 static guint signals[LAST_SIGNAL];
 
+enum
+{
+    FAVICON_COL,
+    URI_COL,
+    TITLE_COL,
+    VISITS_COL,
+    VISIBLE_COL,
+    N_COLS
+};
+
 static void
 midori_location_action_finalize (GObject* object);
 
@@ -199,10 +217,27 @@ midori_location_action_class_init (MidoriLocationActionClass* class)
 static void
 midori_location_action_init (MidoriLocationAction* location_action)
 {
+    GtkTreeModel* liststore;
+    GtkTreeModel* sort_model;
+    GtkTreeModel* filter_model;
+
     location_action->uri = NULL;
     location_action->progress = 0.0;
 
-    location_action->model = NULL;
+    liststore = (GtkTreeModel*)gtk_list_store_new (N_COLS,
+        GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING,
+        G_TYPE_INT, G_TYPE_BOOLEAN);
+    sort_model = (GtkTreeModel*)gtk_tree_model_sort_new_with_model (liststore);
+    gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
+        VISITS_COL, GTK_SORT_DESCENDING);
+    filter_model = gtk_tree_model_filter_new (sort_model, NULL);
+    gtk_tree_model_filter_set_visible_column (
+        GTK_TREE_MODEL_FILTER (filter_model), VISIBLE_COL);
+
+    location_action->model = liststore;
+    location_action->filter_model = filter_model;
+    location_action->sort_model = sort_model;
+    location_action->default_icon = NULL;
 }
 
 static void
@@ -210,9 +245,12 @@ midori_location_action_finalize (GObject* object)
 {
     MidoriLocationAction* location_action = MIDORI_LOCATION_ACTION (object);
 
-    g_free (location_action->uri);
+    katze_assign (location_action->uri, NULL);
 
     katze_object_assign (location_action->model, NULL);
+    katze_object_assign (location_action->sort_model, NULL);
+    katze_object_assign (location_action->filter_model, NULL);
+    katze_object_assign (location_action->default_icon, NULL);
 
     G_OBJECT_CLASS (midori_location_action_parent_class)->finalize (object);
 }
@@ -228,17 +266,13 @@ midori_location_action_set_property (GObject*      object,
     switch (prop_id)
     {
     case PROP_PROGRESS:
-    {
         midori_location_action_set_progress (location_action,
             g_value_get_double (value));
         break;
-    }
     case PROP_SECONDARY_ICON:
-    {
         midori_location_action_set_secondary_icon (location_action,
             g_value_get_string (value));
         break;
-    }
     default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
         break;
@@ -276,20 +310,16 @@ static GtkWidget*
 midori_location_action_create_tool_item (GtkAction* action)
 {
     GtkWidget* toolitem;
-    GtkWidget* entry;
+    GtkWidget* location_entry;
     GtkWidget* alignment;
 
     toolitem = GTK_WIDGET (gtk_tool_item_new ());
     gtk_tool_item_set_expand (GTK_TOOL_ITEM (toolitem), TRUE);
-    entry = midori_location_entry_new ();
-    midori_location_entry_set_progress (MIDORI_LOCATION_ENTRY (entry),
-        MIDORI_LOCATION_ACTION (action)->progress);
-    gtk_icon_entry_set_icon_highlight (GTK_ICON_ENTRY (
-        gtk_bin_get_child (GTK_BIN (entry))),
-        GTK_ICON_ENTRY_SECONDARY, TRUE);
+    location_entry = midori_location_entry_new ();
+
     alignment = gtk_alignment_new (0, 0.5, 1, 0.1);
-    gtk_container_add (GTK_CONTAINER (alignment), entry);
-    gtk_widget_show (entry);
+    gtk_container_add (GTK_CONTAINER (alignment), location_entry);
+    gtk_widget_show (location_entry);
     gtk_container_add (GTK_CONTAINER (toolitem), alignment);
     gtk_widget_show (alignment);
 
@@ -297,15 +327,17 @@ midori_location_action_create_tool_item (GtkAction* action)
 }
 
 static void
-midori_location_action_active_changed_cb (GtkWidget* widget,
+midori_location_action_active_changed_cb (GtkWidget* location_entry,
                                           gint       active,
                                           GtkAction* action)
 {
     MidoriLocationAction* location_action;
+    GtkWidget* entry;
     const gchar* text;
 
     location_action = MIDORI_LOCATION_ACTION (action);
-    text = midori_location_entry_get_text (MIDORI_LOCATION_ENTRY (widget));
+    entry = gtk_bin_get_child (GTK_BIN (location_entry));
+    text = gtk_entry_get_text (GTK_ENTRY (entry));
     katze_assign (location_action->uri, g_strdup (text));
 
     g_signal_emit (action, signals[ACTIVE_CHANGED], 0, active);
@@ -359,6 +391,397 @@ midori_location_action_icon_released_cb (GtkWidget*           widget,
         g_signal_emit (action, signals[SECONDARY_ICON_RELEASED], 0, widget);
 }
 
+static void
+midori_location_entry_render_pixbuf_cb (GtkCellLayout*   layout,
+                                        GtkCellRenderer* renderer,
+                                        GtkTreeModel*    model,
+                                        GtkTreeIter*     iter,
+                                        gpointer         data)
+{
+    GdkPixbuf* pixbuf;
+
+    gtk_tree_model_get (model, iter, FAVICON_COL, &pixbuf, -1);
+    if (pixbuf)
+    {
+        g_object_set (renderer, "pixbuf", pixbuf, "yalign", 0.25, NULL);
+        g_object_unref (pixbuf);
+    }
+}
+
+static void
+midori_location_entry_render_text_cb (GtkCellLayout*   layout,
+                                      GtkCellRenderer* renderer,
+                                      GtkTreeModel*    model,
+                                      GtkTreeIter*     iter,
+                                      gpointer         data)
+{
+    gchar* uri;
+    gchar* title;
+    gchar* desc;
+    gchar* desc_uri;
+    gchar* desc_title;
+    GtkWidget* entry;
+    gchar* key;
+    gchar* temp;
+    gchar** parts;
+
+    gtk_tree_model_get (model, iter, URI_COL, &uri, TITLE_COL, &title, -1);
+
+    desc_uri = desc_title = key = NULL;
+    if (data)
+    {
+        entry = gtk_entry_completion_get_entry (GTK_ENTRY_COMPLETION (data));
+        key = g_utf8_strdown (gtk_entry_get_text (GTK_ENTRY (entry)), -1);
+    }
+    if (data && uri)
+    {
+        temp = g_utf8_strdown (uri, -1);
+        parts = g_strsplit (temp, key, 2);
+        g_free (temp);
+        if (parts && parts[0] && parts[1])
+            desc_uri = g_markup_printf_escaped ("%s<b>%s</b>%s",
+                parts[0], key, parts[1]);
+        g_strfreev (parts);
+    }
+    if (uri && !desc_uri)
+        desc_uri = g_markup_escape_text (uri, -1);
+    if (data && title)
+    {
+        temp = g_utf8_strdown (title, -1);
+        parts = g_strsplit (temp, key, 2);
+        g_free (temp);
+        if (parts && parts[0] && parts[1])
+            desc_title = g_markup_printf_escaped ("%s<b>%s</b>%s",
+                parts[0], key, parts[1]);
+        g_strfreev (parts);
+    }
+    if (title && !desc_title)
+        desc_title = g_markup_escape_text (title, -1);
+
+    if (desc_title)
+        desc = g_strdup_printf ("%s\n<span color='gray45'>%s</span>",
+                                desc_title, desc_uri);
+    else
+        desc = g_strdup_printf ("%s", desc_uri);
+
+    g_object_set (renderer, "markup", desc,
+        "ellipsize-set", TRUE, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
+
+    g_free (uri);
+    g_free (title);
+    g_free (key);
+    g_free (desc);
+    g_free (desc_uri);
+    g_free (desc_title);
+}
+
+static gboolean
+midori_location_entry_completion_match_cb (GtkEntryCompletion* completion,
+                                           const gchar*        key,
+                                           GtkTreeIter*        iter,
+                                           gpointer            data)
+{
+    GtkTreeModel* model;
+    gchar* uri;
+    gchar* title;
+    gboolean match;
+    gchar* temp;
+
+    model = gtk_entry_completion_get_model (completion);
+    gtk_tree_model_get (model, iter, URI_COL, &uri, TITLE_COL, &title, -1);
+
+    match = FALSE;
+    if (uri)
+    {
+        temp = g_utf8_casefold (uri, -1);
+        match = (strstr (temp, key) != NULL);
+        g_free (temp);
+        g_free (uri);
+
+        if (!match && title)
+        {
+            temp = g_utf8_casefold (title, -1);
+            match = (strstr (temp, key) != NULL);
+            g_free (temp);
+            g_free (title);
+        }
+    }
+
+    return match;
+}
+
+static void
+midori_location_action_set_item (MidoriLocationAction*    location_action,
+                                 GtkTreeIter*             iter,
+                                 MidoriLocationEntryItem* item)
+{
+    GtkTreeModel* model;
+    GdkPixbuf* icon;
+    GdkPixbuf* new_icon;
+
+    model = location_action->model;
+    gtk_list_store_set (GTK_LIST_STORE (model), iter,
+        URI_COL, item->uri, TITLE_COL, item->title, -1);
+
+    gtk_tree_model_get (model, iter, FAVICON_COL, &icon, -1);
+    if (item->favicon)
+        new_icon = item->favicon;
+    else if (!icon && !item->favicon)
+        new_icon = location_action->default_icon;
+    else
+        new_icon = NULL;
+    if (new_icon)
+        gtk_list_store_set (GTK_LIST_STORE (model), iter,
+            FAVICON_COL, new_icon, -1);
+}
+
+static gboolean
+midori_location_action_child_iter_to_iter (MidoriLocationAction* location_action,
+                                           GtkTreeIter*          iter,
+                                           GtkTreeIter*          child_iter)
+{
+    GtkTreeModel* filter_model;
+    GtkTreeModel* sort_model;
+    GtkTreeIter sort_iter;
+    GtkTreeIter* temp_iter;
+
+    temp_iter = child_iter;
+
+    filter_model = location_action->filter_model;
+    sort_model = location_action->sort_model;
+    gtk_tree_model_sort_convert_child_iter_to_iter
+        (GTK_TREE_MODEL_SORT (sort_model), &sort_iter, child_iter);
+    temp_iter = &sort_iter;
+
+    return gtk_tree_model_filter_convert_child_iter_to_iter
+        (GTK_TREE_MODEL_FILTER (filter_model), iter, temp_iter);
+}
+
+static void
+midori_location_action_set_active_iter (MidoriLocationAction* location_action,
+                                        GtkTreeIter*          iter)
+{
+    GdkPixbuf* pixbuf;
+    GtkTreeModel* model;
+    GSList* proxies;
+    GtkWidget* alignment;
+    GtkWidget* location_entry;
+    GtkWidget* entry;
+    GtkTreeIter parent_iter;
+
+    model = location_action->filter_model;
+
+    /* The filter iter must be set, not the child iter,
+     * but the row must first be set as visible to
+     * convert to a filter iter without error.
+     */
+    gtk_list_store_set (GTK_LIST_STORE (model), iter, VISIBLE_COL, TRUE, -1);
+
+    proxies = gtk_action_get_proxies (GTK_ACTION (location_action));
+    if (!proxies)
+        return;
+
+    do
+    if (GTK_IS_TOOL_ITEM (proxies->data))
+    {
+        alignment = gtk_bin_get_child (GTK_BIN (proxies->data));
+        location_entry = gtk_bin_get_child (GTK_BIN (alignment));
+        entry = gtk_bin_get_child (GTK_BIN (location_entry));
+
+        if (midori_location_action_child_iter_to_iter (
+            location_action, &parent_iter, iter))
+            gtk_combo_box_set_active_iter (GTK_COMBO_BOX (location_entry),
+                                           &parent_iter);
+
+        /* When setting the active iter (when adding or setting an item)
+         * the icon may have changed, so we must update the entry icon.
+         */
+        gtk_tree_model_get (model, iter, FAVICON_COL, &pixbuf, -1);
+
+        gtk_icon_entry_set_icon_from_pixbuf (GTK_ICON_ENTRY (entry),
+            GTK_ICON_ENTRY_PRIMARY, pixbuf);
+        g_object_unref (pixbuf);
+    }
+    while ((proxies = g_slist_next (proxies)));
+}
+
+/**
+ * midori_location_action_item_iter:
+ * @location_action: a #MidoriLocationAction
+ * @uri: a string
+ * @iter: a GtkTreeIter
+ *
+ * Retrieves the iter of the item matching @uri.
+ *
+ * Return value: %TRUE if @uri was found, %FALSE otherwise
+ **/
+static gboolean
+midori_location_action_item_iter (MidoriLocationAction* location_action,
+                                  const gchar*          uri,
+                                  GtkTreeIter*          iter)
+{
+    GtkTreeModel* model;
+    gchar* tmpuri;
+    gboolean found;
+
+    g_return_val_if_fail (MIDORI_IS_LOCATION_ACTION (location_action), FALSE);
+    g_return_val_if_fail (uri != NULL, FALSE);
+
+    found = FALSE;
+    model = location_action->model; // filter_model
+    if (gtk_tree_model_get_iter_first (model, iter))
+    {
+        tmpuri = NULL;
+        do
+        {
+            gtk_tree_model_get (model, iter, URI_COL, &tmpuri, -1);
+            found = !g_ascii_strcasecmp (uri, tmpuri);
+            katze_assign (tmpuri, NULL);
+
+            if (found)
+                break;
+        }
+        while (gtk_tree_model_iter_next (model, iter));
+    }
+    return found;
+}
+
+/**
+ * midori_location_action_reset:
+ * @location_action: a #MidoriLocationAction
+ *
+ * Clears the text in the entry and resets the icon.
+ **/
+static void
+midori_location_action_reset (MidoriLocationAction* location_action)
+{
+    GSList* proxies;
+    GtkWidget* alignment;
+    GtkWidget* location_entry;
+    GtkWidget* entry;
+
+    g_return_if_fail (MIDORI_IS_LOCATION_ACTION (location_action));
+
+    proxies = gtk_action_get_proxies (GTK_ACTION (location_action));
+    if (!proxies)
+        return;
+
+    do
+    if (GTK_IS_TOOL_ITEM (proxies->data))
+    {
+        alignment = gtk_bin_get_child (GTK_BIN (proxies->data));
+        location_entry = gtk_bin_get_child (GTK_BIN (alignment));
+        entry = gtk_bin_get_child (GTK_BIN (location_entry));
+
+        gtk_entry_set_text (GTK_ENTRY (entry), "");
+        gtk_icon_entry_set_icon_from_stock (GTK_ICON_ENTRY (entry),
+            GTK_ICON_ENTRY_PRIMARY, GTK_STOCK_FILE);
+    }
+    while ((proxies = g_slist_next (proxies)));
+}
+
+/**
+ * midori_location_action_set_item_from_uri:
+ * @location_action: a #MidoriLocationAction
+ * @uri: a string
+ *
+ * Finds the item from the list matching @uri
+ * and sets it as the active item.
+ * If @uri is not found it clears the active item.
+ **/
+static void
+midori_location_action_set_item_from_uri (MidoriLocationAction* location_action,
+                                          const gchar*          uri)
+{
+    GtkTreeIter iter;
+
+    g_return_if_fail (MIDORI_IS_LOCATION_ACTION (location_action));
+
+    if (midori_location_action_item_iter (location_action, uri, &iter))
+        midori_location_action_set_active_iter (location_action, &iter);
+    else
+        midori_location_action_reset (location_action);
+
+}
+
+static gboolean
+midori_location_entry_completion_selected (GtkEntryCompletion*   completion,
+                                           GtkTreeModel*         model,
+                                           GtkTreeIter*          iter,
+                                           MidoriLocationAction* location_action)
+{
+    gchar* uri;
+
+    gtk_tree_model_get (model, iter, URI_COL, &uri, -1);
+    midori_location_action_set_item_from_uri (location_action, uri);
+    g_free (uri);
+
+    return FALSE;
+}
+
+static void
+midori_location_action_completion_init (MidoriLocationAction* location_action,
+                                        GtkWidget*            location_entry)
+{
+    GtkWidget* entry;
+    GtkEntryCompletion* completion;
+    GtkCellRenderer* renderer;
+
+    entry = gtk_bin_get_child (GTK_BIN (location_entry));
+    completion = gtk_entry_completion_new ();
+
+    gtk_entry_completion_set_model (completion, location_action->sort_model);
+    gtk_entry_completion_set_text_column (completion, URI_COL);
+    gtk_cell_layout_clear (GTK_CELL_LAYOUT (completion));
+
+    renderer = gtk_cell_renderer_pixbuf_new ();
+    gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (completion), renderer, FALSE);
+    gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (completion), renderer,
+                                        midori_location_entry_render_pixbuf_cb,
+                                        NULL, NULL);
+    renderer = gtk_cell_renderer_text_new ();
+    gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (completion), renderer, TRUE);
+    gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (completion), renderer,
+                                        midori_location_entry_render_text_cb,
+                                        completion, NULL);
+    gtk_entry_completion_set_match_func (completion,
+        midori_location_entry_completion_match_cb, NULL, NULL);
+
+    gtk_entry_set_completion (GTK_ENTRY (entry), completion);
+    g_signal_connect (completion, "match-selected",
+        G_CALLBACK (midori_location_entry_completion_selected), location_entry);
+
+    g_object_unref (completion);
+}
+
+static void
+midori_location_action_entry_changed_cb (GtkComboBox*          combo_box,
+                                         MidoriLocationAction* location_action)
+{
+    GtkTreeIter iter;
+    GtkIconEntry* entry;
+    GtkTreeModel* model;
+    GdkPixbuf* pixbuf;
+
+    if (gtk_combo_box_get_active_iter (combo_box, &iter))
+    {
+        if ((entry = GTK_ICON_ENTRY (gtk_bin_get_child (GTK_BIN (combo_box)))))
+        {
+            pixbuf = NULL;
+
+            model = location_action->filter_model;
+            gtk_tree_model_get (model, &iter, FAVICON_COL, &pixbuf, -1);
+
+            gtk_icon_entry_set_icon_from_pixbuf (GTK_ICON_ENTRY (entry),
+                                                 GTK_ICON_ENTRY_PRIMARY, pixbuf);
+            g_object_unref (pixbuf);
+
+            g_signal_emit (MIDORI_LOCATION_ENTRY (combo_box),
+                signals[ACTIVE_CHANGED], 0, gtk_combo_box_get_active (combo_box));
+        }
+    }
+}
+
 static void
 midori_location_action_connect_proxy (GtkAction* action,
                                       GtkWidget* proxy)
@@ -366,6 +789,7 @@ midori_location_action_connect_proxy (GtkAction* action,
     GtkWidget* alignment;
     GtkWidget* entry;
     MidoriLocationAction* location_action;
+    GtkCellRenderer* renderer;
 
     GTK_ACTION_CLASS (midori_location_action_parent_class)->connect_proxy (
         action, proxy);
@@ -376,14 +800,30 @@ midori_location_action_connect_proxy (GtkAction* action,
         entry = gtk_bin_get_child (GTK_BIN (alignment));
 
         location_action = MIDORI_LOCATION_ACTION (action);
-        if (location_action->model)
-            gtk_combo_box_set_model (GTK_COMBO_BOX (entry),
-                                     location_action->model);
-        else
-            location_action->model = g_object_ref (gtk_combo_box_get_model (
-                                     GTK_COMBO_BOX (entry)));
-
-        g_signal_connect (entry, "active-changed",
+        midori_location_entry_set_progress (MIDORI_LOCATION_ENTRY (entry),
+            MIDORI_LOCATION_ACTION (action)->progress);
+        gtk_combo_box_set_model (GTK_COMBO_BOX (entry),
+            MIDORI_LOCATION_ACTION (action)->filter_model);
+        gtk_combo_box_entry_set_text_column (
+            GTK_COMBO_BOX_ENTRY (entry), URI_COL);
+        gtk_cell_layout_clear (GTK_CELL_LAYOUT (entry));
+
+        /* Setup the renderer for the favicon */
+        renderer = gtk_cell_renderer_pixbuf_new ();
+        gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (entry), renderer, FALSE);
+        gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (entry),
+            renderer, midori_location_entry_render_pixbuf_cb, NULL, NULL);
+        renderer = gtk_cell_renderer_text_new ();
+        gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (entry), renderer, TRUE);
+        gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (entry),
+            renderer, midori_location_entry_render_text_cb, NULL, NULL);
+
+        gtk_combo_box_set_active (GTK_COMBO_BOX (entry), -1);
+        midori_location_action_completion_init (location_action, entry);
+        g_signal_connect (entry, "changed",
+            G_CALLBACK (midori_location_action_entry_changed_cb), action);
+
+        g_signal_connect (location_action, "active-changed",
             G_CALLBACK (midori_location_action_active_changed_cb), action);
         g_object_connect (gtk_bin_get_child (GTK_BIN (entry)),
                       "signal::key-press-event",
@@ -416,18 +856,26 @@ midori_location_action_get_uri (MidoriLocationAction* location_action)
     return location_action->uri;
 }
 
-void
-midori_location_action_set_uri (MidoriLocationAction* location_action,
-                                const gchar*          uri)
+/**
+ * midori_location_action_set_text:
+ * @location_action: a #MidoriLocationAction
+ * @text: a string
+ *
+ * Sets the entry text to @text and, if applicable, updates the icon.
+ **/
+static void
+midori_location_action_set_text (MidoriLocationAction* location_action,
+                                 const gchar*          text)
 {
     GSList* proxies;
     GtkWidget* alignment;
+    GtkWidget* location_entry;
     GtkWidget* entry;
+    GtkTreeIter iter;
+    GtkTreeModel* model;
+    GdkPixbuf* icon;
 
     g_return_if_fail (MIDORI_IS_LOCATION_ACTION (location_action));
-    g_return_if_fail (uri != NULL);
-
-    katze_assign (location_action->uri, g_strdup (uri));
 
     proxies = gtk_action_get_proxies (GTK_ACTION (location_action));
     if (!proxies)
@@ -437,44 +885,139 @@ midori_location_action_set_uri (MidoriLocationAction* location_action,
     if (GTK_IS_TOOL_ITEM (proxies->data))
     {
         alignment = gtk_bin_get_child (GTK_BIN (proxies->data));
-        entry = gtk_bin_get_child (GTK_BIN (alignment));
+        location_entry = gtk_bin_get_child (GTK_BIN (alignment));
+        entry = gtk_bin_get_child (GTK_BIN (location_entry));
 
-        midori_location_entry_set_text (MIDORI_LOCATION_ENTRY (entry), uri);
+        gtk_entry_set_text (GTK_ENTRY (entry), text);
+        if (midori_location_action_item_iter (location_action, text, &iter))
+        {
+            model = location_action->model; // filter_model
+            gtk_tree_model_get (model, &iter, FAVICON_COL, &icon, -1);
+            gtk_icon_entry_set_icon_from_pixbuf (GTK_ICON_ENTRY (entry),
+                GTK_ICON_ENTRY_PRIMARY, icon);
+        }
+        /* FIXME: Due to a bug in GtkIconEntry we can't reset the icon
+        else
+            gtk_icon_entry_set_icon_from_stock (GTK_ICON_ENTRY (entry),
+                GTK_ICON_ENTRY_PRIMARY, location_action->default_icon);*/
     }
     while ((proxies = g_slist_next (proxies)));
 }
 
 void
-midori_location_action_add_uri (MidoriLocationAction* location_action,
+midori_location_action_set_uri (MidoriLocationAction* location_action,
                                 const gchar*          uri)
 {
-    GSList* proxies;
-    GtkWidget* alignment;
-    GtkWidget* entry;
-    MidoriLocationEntryItem item;
-
     g_return_if_fail (MIDORI_IS_LOCATION_ACTION (location_action));
     g_return_if_fail (uri != NULL);
 
     katze_assign (location_action->uri, g_strdup (uri));
 
-    proxies = gtk_action_get_proxies (GTK_ACTION (location_action));
-    if (!proxies)
-        return;
+    midori_location_action_set_text (location_action, uri);
+}
 
-    do
-    if (GTK_IS_TOOL_ITEM (proxies->data))
+/**
+ * midori_location_action_prepend_item:
+ * @location_action: a #MidoriLocationAction
+ * @item: a MidoriLocationItem
+ *
+ * Prepends @item if it is not already in the list.
+ * If the item already exists, it is moved before the first item.
+ * If the maximum is reached, the last item is removed.
+ **/
+static void
+midori_location_action_prepend_item (MidoriLocationAction*    location_action,
+                                     MidoriLocationEntryItem* item)
+{
+    GtkTreeModel* filter_model;
+    GtkTreeModel* model;
+    GtkTreeIter iter;
+    GtkTreeIter index;
+    gint n;
+    gint visits = 0;
+
+    g_return_if_fail (MIDORI_IS_LOCATION_ACTION (location_action));
+    g_return_if_fail (item->uri != NULL);
+
+    filter_model = location_action->filter_model;
+    model = location_action->model;
+
+    if (midori_location_action_item_iter (location_action, item->uri, &iter))
     {
-        alignment = gtk_bin_get_child (GTK_BIN (proxies->data));
-        entry = gtk_bin_get_child (GTK_BIN (alignment));
+        gtk_tree_model_get_iter_first (model, &index);
+        gtk_tree_model_get (model, &iter, VISITS_COL, &visits, -1);
+        gtk_list_store_move_before (GTK_LIST_STORE (model), &iter, &index);
+    }
+    else
+        gtk_list_store_prepend (GTK_LIST_STORE (model), &iter);
 
-        item.favicon = NULL;
-        item.uri = uri;
-        item.title = NULL;
-        midori_location_entry_prepend_item (
-            MIDORI_LOCATION_ENTRY (entry), &item);
+    n = gtk_tree_model_iter_n_children (filter_model, NULL);
+    if (n > MAX_ITEMS)
+    {
+        gtk_tree_model_iter_nth_child (model, &index, NULL, n - 1);
+        gtk_list_store_set (GTK_LIST_STORE (model),
+                            &index, VISIBLE_COL, FALSE, -1);
     }
-    while ((proxies = g_slist_next (proxies)));
+
+    /* Only increment the visits when we add the uri */
+    if (!item->title && !item->favicon)
+        gtk_list_store_set (GTK_LIST_STORE (model), &iter, VISITS_COL, ++visits,
+                            VISIBLE_COL, TRUE, -1);
+    midori_location_action_set_item (location_action, &iter, item);
+}
+
+/**
+ * midori_location_entry_append_item:
+ * @location_entry: a #MidoriLocationEntry
+ * @item: a MidoriLocationItem
+ *
+ * Appends @item if it is not already in the list.
+ * @item is not added if the maximum is reached.
+ **/
+static void
+midori_location_action_append_item (MidoriLocationAction*    location_action,
+                                    MidoriLocationEntryItem* item)
+{
+    GtkTreeModel* model;
+    GtkTreeIter iter;
+    gint n;
+    gint visits = 0;
+
+    g_return_if_fail (MIDORI_IS_LOCATION_ACTION (location_action));
+    g_return_if_fail (item->uri != NULL);
+
+    model = location_action->model;
+
+    if (!midori_location_action_item_iter (location_action, item->uri, &iter))
+    {
+        gtk_list_store_append (GTK_LIST_STORE (model), &iter);
+
+        n = gtk_tree_model_iter_n_children (model, NULL);
+        gtk_list_store_set (GTK_LIST_STORE (model), &iter, VISIBLE_COL,
+                            (n <= MAX_ITEMS), -1);
+    }
+    else
+        gtk_tree_model_get (model, &iter, VISITS_COL, &visits, -1);
+
+    gtk_list_store_set (GTK_LIST_STORE (model), &iter, VISITS_COL, ++visits, -1);
+    midori_location_action_set_item (location_action, &iter, item);
+}
+
+void
+midori_location_action_add_uri (MidoriLocationAction* location_action,
+                                const gchar*          uri)
+{
+    MidoriLocationEntryItem item;
+
+    g_return_if_fail (MIDORI_IS_LOCATION_ACTION (location_action));
+    g_return_if_fail (uri != NULL);
+
+    katze_assign (location_action->uri, g_strdup (uri));
+
+    item.favicon = NULL;
+    item.uri = uri;
+    item.title = NULL;
+    midori_location_action_prepend_item (location_action, &item);
 }
 
 void
@@ -485,8 +1028,8 @@ midori_location_action_add_item (MidoriLocationAction* location_action,
 {
     GSList* proxies;
     GtkWidget* alignment;
+    GtkWidget* location_entry;
     GtkWidget* entry;
-    GtkWidget* child;
     MidoriLocationEntryItem item;
 
     g_return_if_fail (MIDORI_IS_LOCATION_ACTION (location_action));
@@ -496,25 +1039,25 @@ midori_location_action_add_item (MidoriLocationAction* location_action,
 
     katze_assign (location_action->uri, g_strdup (uri));
 
+    item.favicon = icon;
+    item.uri = uri;
+    item.title = title;
+    midori_location_action_append_item (location_action, &item);
+
     proxies = gtk_action_get_proxies (GTK_ACTION (location_action));
     if (!proxies)
         return;
 
     do
-    if (GTK_IS_TOOL_ITEM (proxies->data))
+    if (GTK_IS_TOOL_ITEM (proxies->data) &&
+        !g_strcmp0 (location_action->uri, uri))
     {
         alignment = gtk_bin_get_child (GTK_BIN (proxies->data));
-        entry = gtk_bin_get_child (GTK_BIN (alignment));
-        child = gtk_bin_get_child (GTK_BIN (entry));
+        location_entry = gtk_bin_get_child (GTK_BIN (alignment));
+        entry = gtk_bin_get_child (GTK_BIN (location_entry));
 
-        item.favicon = icon;
-        item.uri = uri;
-        item.title = title;
-        midori_location_entry_append_item (
-            MIDORI_LOCATION_ENTRY (entry), &item);
-        if (!g_strcmp0 (location_action->uri, uri))
-            gtk_icon_entry_set_icon_from_pixbuf (GTK_ICON_ENTRY (child),
-                GTK_ICON_ENTRY_PRIMARY, icon);
+        gtk_icon_entry_set_icon_from_pixbuf (GTK_ICON_ENTRY (entry),
+            GTK_ICON_ENTRY_PRIMARY, icon);
     }
     while ((proxies = g_slist_next (proxies)));
 }
@@ -526,33 +1069,33 @@ midori_location_action_set_icon_for_uri (MidoriLocationAction* location_action,
 {
     GSList* proxies;
     GtkWidget* alignment;
+    GtkWidget* location_entry;
     GtkWidget* entry;
-    GtkWidget* child;
     MidoriLocationEntryItem item;
 
     g_return_if_fail (MIDORI_IS_LOCATION_ACTION (location_action));
     g_return_if_fail (!icon || GDK_IS_PIXBUF (icon));
     g_return_if_fail (uri != NULL);
 
+    item.favicon = icon;
+    item.uri = uri;
+    item.title = NULL;
+    midori_location_action_prepend_item (location_action, &item);
+
     proxies = gtk_action_get_proxies (GTK_ACTION (location_action));
     if (!proxies)
         return;
 
     do
-    if (GTK_IS_TOOL_ITEM (proxies->data))
+    if (GTK_IS_TOOL_ITEM (proxies->data) &&
+        !g_strcmp0 (location_action->uri, uri))
     {
         alignment = gtk_bin_get_child (GTK_BIN (proxies->data));
-        entry = gtk_bin_get_child (GTK_BIN (alignment));
-        child = gtk_bin_get_child (GTK_BIN (entry));
+        location_entry = gtk_bin_get_child (GTK_BIN (alignment));
+        entry = gtk_bin_get_child (GTK_BIN (location_entry));
 
-        item.favicon = icon;
-        item.uri = uri;
-        item.title = NULL;
-        midori_location_entry_prepend_item (
-            MIDORI_LOCATION_ENTRY (entry), &item);
-        if (!g_strcmp0 (location_action->uri, uri))
-            gtk_icon_entry_set_icon_from_pixbuf (GTK_ICON_ENTRY (child),
-                GTK_ICON_ENTRY_PRIMARY, icon);
+        gtk_icon_entry_set_icon_from_pixbuf (GTK_ICON_ENTRY (entry),
+            GTK_ICON_ENTRY_PRIMARY, icon);
     }
     while ((proxies = g_slist_next (proxies)));
 }
@@ -562,32 +1105,16 @@ midori_location_action_set_title_for_uri (MidoriLocationAction* location_action,
                                           const gchar*          title,
                                           const gchar*          uri)
 {
-    GSList* proxies;
-    GtkWidget* alignment;
-    GtkWidget* entry;
     MidoriLocationEntryItem item;
 
     g_return_if_fail (MIDORI_IS_LOCATION_ACTION (location_action));
     g_return_if_fail (title != NULL);
     g_return_if_fail (uri != NULL);
 
-    proxies = gtk_action_get_proxies (GTK_ACTION (location_action));
-    if (!proxies)
-        return;
-
-    do
-    if (GTK_IS_TOOL_ITEM (proxies->data))
-    {
-        alignment = gtk_bin_get_child (GTK_BIN (proxies->data));
-        entry = gtk_bin_get_child (GTK_BIN (alignment));
-
-        item.favicon = NULL;
-        item.uri = uri;
-        item.title = title;
-        midori_location_entry_prepend_item (
-            MIDORI_LOCATION_ENTRY (entry), &item);
-    }
-    while ((proxies = g_slist_next (proxies)));
+    item.favicon = NULL;
+    item.uri = uri;
+    item.title = title;
+    midori_location_action_prepend_item (location_action, &item);
 }
 
 gdouble
@@ -660,31 +1187,35 @@ midori_location_action_set_secondary_icon (MidoriLocationAction* location_action
     while ((proxies = g_slist_next (proxies)));
 }
 
+/**
+ * midori_location_entry_set_item_from_uri:
+ * @location_entry: a #MidoriLocationEntry
+ * @uri: a string
+ *
+ * Finds the item from the list matching @uri
+ * and removes it if it is the last instance.
+ **/
 void
 midori_location_action_delete_item_from_uri (MidoriLocationAction* location_action,
                                              const gchar*          uri)
 {
-    GSList* proxies;
-    GtkWidget* alignment;
-    GtkWidget* entry;
+    GtkTreeModel* model;
+    GtkTreeIter iter;
+    gint visits;
 
     g_return_if_fail (MIDORI_IS_LOCATION_ACTION (location_action));
     g_return_if_fail (uri != NULL);
 
-    proxies = gtk_action_get_proxies (GTK_ACTION (location_action));
-    if (!proxies)
-        return;
-
-    do
-    if (GTK_IS_TOOL_ITEM (proxies->data))
+    model = location_action->model;
+    if (midori_location_action_item_iter (location_action, uri, &iter))
     {
-        alignment = gtk_bin_get_child (GTK_BIN (proxies->data));
-        entry = gtk_bin_get_child (GTK_BIN (alignment));
-
-        midori_location_entry_delete_item_from_uri
-            (MIDORI_LOCATION_ENTRY (entry), uri);
+        gtk_tree_model_get (model, &iter, VISITS_COL, &visits, -1);
+        if (visits > 1)
+            gtk_list_store_set (GTK_LIST_STORE (model),
+                &iter, VISITS_COL, --visits, -1);
+        else
+            gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
     }
-    while ((proxies = g_slist_next (proxies)));
 }
 
 void
@@ -706,7 +1237,7 @@ midori_location_action_clear (MidoriLocationAction* location_action)
         alignment = gtk_bin_get_child (GTK_BIN (proxies->data));
         entry = gtk_bin_get_child (GTK_BIN (alignment));
 
-        midori_location_entry_clear (MIDORI_LOCATION_ENTRY (entry));
+        gtk_list_store_clear (GTK_LIST_STORE (location_action->filter_model));
     }
     while ((proxies = g_slist_next (proxies)));
 }
index 5a8f53de3ed5b2d500617f4b9c5589249e04f07a..a95301c9f23675f1b5fdc1c8937c63b827dccd84 100644 (file)
@@ -34,6 +34,13 @@ G_BEGIN_DECLS
 typedef struct _MidoriLocationAction         MidoriLocationAction;
 typedef struct _MidoriLocationActionClass    MidoriLocationActionClass;
 
+struct _MidoriLocationEntryItem
+{
+    GdkPixbuf* favicon;
+    const gchar* uri;
+    const gchar* title;
+};
+
 GType
 midori_location_action_get_type             (void);
 
index 6170c8dd90e6d56f50b180e0cfc120df837a9761..1e9a476646112749df24772a23e2913124085cf3 100644 (file)
 */
 
 #include "midori-locationentry.h"
+
 #include "gtkiconentry.h"
 #include "sokoke.h"
-
 #include <gdk/gdkkeysyms.h>
-#include <string.h>
-
-#define DEFAULT_ICON GTK_STOCK_FILE
-#define MAX_ITEMS 25
-/* #define ORDER_BY_VISITS 1 */
 
 struct _MidoriLocationEntry
 {
@@ -45,108 +40,15 @@ enum
     N_COLS
 };
 
-enum
-{
-    ACTIVE_CHANGED,
-    LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL];
-
 static gboolean
 entry_key_press_event (GtkWidget*           widget,
                        GdkEventKey*         event,
                        MidoriLocationEntry* location_entry);
 
-static void
-midori_location_entry_changed (GtkComboBox* combo_box,
-                               gpointer     user_data);
-
 static void
 midori_location_entry_class_init (MidoriLocationEntryClass* class)
 {
-    signals[ACTIVE_CHANGED] = g_signal_new ("active-changed",
-                                            G_TYPE_FROM_CLASS (class),
-                                            (GSignalFlags) (G_SIGNAL_RUN_LAST),
-                                            0,
-                                            0,
-                                            NULL,
-                                            g_cclosure_marshal_VOID__INT,
-                                            G_TYPE_NONE, 1,
-                                            G_TYPE_INT);
-}
-
-static GtkTreeModel*
-midori_location_entry_get_filter_model (MidoriLocationEntry* location_entry)
-{
-    return gtk_combo_box_get_model (GTK_COMBO_BOX (location_entry));
-}
-
-static GtkTreeModel*
-midori_location_entry_get_sort_model (MidoriLocationEntry* location_entry)
-{
-    GtkTreeModel* model;
-    GtkTreeModelFilter* filter_model;
-
-    model = midori_location_entry_get_filter_model (location_entry);
-    filter_model = GTK_TREE_MODEL_FILTER (model);
-    g_assert (filter_model);
-
-    return gtk_tree_model_filter_get_model (filter_model);
-}
-
-static GtkTreeModel*
-midori_location_entry_get_model (MidoriLocationEntry* location_entry)
-{
-
-    GtkTreeModel* model;
-#ifdef ORDER_BY_VISITS
-    GtkTreeModelSort* sort_model;
-#endif
-
-    model = midori_location_entry_get_sort_model (location_entry);
-
-#ifdef ORDER_BY_VISITS
-    sort_model = GTK_TREE_MODEL_SORT (model);
-    g_assert (sort_model);
-
-    return gtk_tree_model_sort_get_model (sort_model);
-#else
-    return GTK_IS_TREE_MODEL (model) ? model : NULL;
-#endif
-
-}
-
-static gboolean
-midori_location_entry_child_iter_to_iter (MidoriLocationEntry* location_entry,
-                                          GtkTreeIter*         iter,
-                                          GtkTreeIter*         child_iter)
-{
-    GtkTreeModel* filter_model;
-#ifdef ORDER_BY_VISITS
-    GtkTreeModel* sort_model;
-    GtkTreeIter sort_iter;
-#endif
-    GtkTreeIter* temp_iter;
-
-    temp_iter = child_iter;
-
-    filter_model = midori_location_entry_get_filter_model (location_entry);
-
-#ifdef ORDER_BY_VISITS
-    sort_model = midori_location_entry_get_sort_model (location_entry);
-
-    g_return_val_if_fail (GTK_IS_TREE_MODEL_FILTER (filter_model) &&
-                          GTK_IS_TREE_MODEL_SORT (sort_model), FALSE);
-
-    gtk_tree_model_sort_convert_child_iter_to_iter
-        (GTK_TREE_MODEL_SORT (sort_model), &sort_iter, child_iter);
 
-    temp_iter = &sort_iter;
-#endif
-
-    return gtk_tree_model_filter_convert_child_iter_to_iter
-        (GTK_TREE_MODEL_FILTER (filter_model), iter, temp_iter);
 }
 
 #define HAVE_ENTRY_PROGRESS 1
@@ -456,14 +358,6 @@ entry_expose_event (GtkWidget*           entry,
 
 #endif
 
-gdouble
-midori_location_entry_get_progress (MidoriLocationEntry* location_entry)
-{
-    g_return_val_if_fail (MIDORI_IS_LOCATION_ENTRY (location_entry), 0.0);
-
-    return location_entry->progress;
-}
-
 void
 midori_location_entry_set_progress (MidoriLocationEntry* location_entry,
                                     gdouble              progress)
@@ -483,188 +377,12 @@ midori_location_entry_set_progress (MidoriLocationEntry* location_entry,
     #endif
 }
 
-static gboolean
-midori_location_entry_completion_selected (GtkEntryCompletion*  completion,
-                                           GtkTreeModel*        model,
-                                           GtkTreeIter*         iter,
-                                           MidoriLocationEntry* location_entry)
-{
-    gchar* uri;
-
-    gtk_tree_model_get (model, iter, URI_COL, &uri, -1);
-    midori_location_entry_set_item_from_uri (location_entry, uri);
-    g_free (uri);
-
-    return FALSE;
-}
-
-static void
-midori_location_entry_render_pixbuf_cb (GtkCellLayout*   layout,
-                                        GtkCellRenderer* renderer,
-                                        GtkTreeModel*    model,
-                                        GtkTreeIter*     iter,
-                                        gpointer         data)
-{
-    GdkPixbuf* pixbuf;
-
-    gtk_tree_model_get (model, iter, FAVICON_COL, &pixbuf, -1);
-    if (pixbuf)
-    {
-        g_object_set (renderer, "pixbuf", pixbuf, "yalign", 0.25, NULL);
-        g_object_unref (pixbuf);
-    }
-}
-
-static void
-midori_location_entry_render_text_cb (GtkCellLayout*   layout,
-                                      GtkCellRenderer* renderer,
-                                      GtkTreeModel*    model,
-                                      GtkTreeIter*     iter,
-                                      gpointer         data)
-{
-    gchar* uri;
-    gchar* title;
-    gchar* desc;
-    gchar* desc_uri;
-    gchar* desc_title;
-    GtkWidget* entry;
-    gchar* key;
-    gchar* temp;
-    gchar** parts;
-
-    gtk_tree_model_get (model, iter, URI_COL, &uri, TITLE_COL, &title, -1);
-
-    desc_uri = desc_title = key = NULL;
-    if (data)
-    {
-        entry = gtk_entry_completion_get_entry (GTK_ENTRY_COMPLETION (data));
-        key = g_utf8_strdown (gtk_entry_get_text (GTK_ENTRY (entry)), -1);
-    }
-    if (data && uri)
-    {
-        temp = g_utf8_strdown (uri, -1);
-        parts = g_strsplit (temp, key, 2);
-        g_free (temp);
-        if (parts && parts[0] && parts[1])
-            desc_uri = g_markup_printf_escaped ("%s<b>%s</b>%s",
-                parts[0], key, parts[1]);
-        g_strfreev (parts);
-    }
-    if (uri && !desc_uri)
-        desc_uri = g_markup_escape_text (uri, -1);
-    if (data && title)
-    {
-        temp = g_utf8_strdown (title, -1);
-        parts = g_strsplit (temp, key, 2);
-        g_free (temp);
-        if (parts && parts[0] && parts[1])
-            desc_title = g_markup_printf_escaped ("%s<b>%s</b>%s",
-                parts[0], key, parts[1]);
-        g_strfreev (parts);
-    }
-    if (title && !desc_title)
-        desc_title = g_markup_escape_text (title, -1);
-
-    if (desc_title)
-        desc = g_strdup_printf ("%s\n<span color='gray45'>%s</span>",
-                                desc_title, desc_uri);
-    else
-        desc = g_strdup_printf ("%s", desc_uri);
-
-    g_object_set (renderer, "markup", desc,
-        "ellipsize-set", TRUE, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
-
-    g_free (uri);
-    g_free (title);
-    g_free (key);
-    g_free (desc);
-    g_free (desc_uri);
-    g_free (desc_title);
-}
-
-static gboolean
-midori_location_entry_completion_match_cb (GtkEntryCompletion* completion,
-                                           const gchar*        key,
-                                           GtkTreeIter*        iter,
-                                           gpointer            data)
-{
-    GtkTreeModel* model;
-    gchar* uri;
-    gchar* title;
-    gboolean match;
-    gchar* temp;
-
-    model = gtk_entry_completion_get_model (completion);
-    gtk_tree_model_get (model, iter, URI_COL, &uri, TITLE_COL, &title, -1);
-
-    match = FALSE;
-    if (uri)
-    {
-        temp = g_utf8_casefold (uri, -1);
-        match = (strstr (temp, key) != NULL);
-        g_free (temp);
-        g_free (uri);
-
-        if (!match && title)
-        {
-            temp = g_utf8_casefold (title, -1);
-            match = (strstr (temp, key) != NULL);
-            g_free (temp);
-            g_free (title);
-        }
-    }
-
-    return match;
-}
-
-static void
-midori_location_entry_completion_init (MidoriLocationEntry* location_entry)
-{
-    GtkWidget* entry;
-    GtkEntryCompletion* completion;
-    GtkCellRenderer* renderer;
-
-    entry = gtk_bin_get_child (GTK_BIN (location_entry));
-    completion = gtk_entry_completion_new ();
-
-    gtk_entry_completion_set_model (GTK_ENTRY_COMPLETION (completion),
-        midori_location_entry_get_sort_model (location_entry));
-    gtk_entry_completion_set_text_column (GTK_ENTRY_COMPLETION (completion),
-                                          URI_COL);
-    gtk_cell_layout_clear (GTK_CELL_LAYOUT (completion));
-
-    renderer = gtk_cell_renderer_pixbuf_new ();
-    gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (completion), renderer, FALSE);
-    gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (completion), renderer,
-                                        midori_location_entry_render_pixbuf_cb,
-                                        NULL, NULL);
-    renderer = gtk_cell_renderer_text_new ();
-    gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (completion), renderer, TRUE);
-    gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (completion), renderer,
-                                        midori_location_entry_render_text_cb,
-                                        completion, NULL);
-    gtk_entry_completion_set_match_func (completion,
-        midori_location_entry_completion_match_cb, NULL, NULL);
-
-    gtk_entry_set_completion (GTK_ENTRY (entry), completion);
-    g_signal_connect (completion, "match-selected",
-        G_CALLBACK (midori_location_entry_completion_selected), location_entry);
-
-    g_object_unref (completion);
-}
-
 static void
 midori_location_entry_init (MidoriLocationEntry* location_entry)
 {
     GtkWidget* entry;
-    GtkListStore* store;
-    GtkCellRenderer* renderer;
-    GtkTreeModel* filter_model;
-#ifdef ORDER_BY_VISITS
-    GtkTreeModel* sort_model;
-#endif
 
-    /* we want the widget to have appears-as-list applied */
+    /* We want the widget to have appears-as-list applied */
     gtk_rc_parse_string ("style \"midori-location-entry-style\" {\n"
                          "  GtkComboBox::appears-as-list = 1\n }\n"
                          "widget_class \"*MidoriLocationEntry\" "
@@ -674,57 +392,17 @@ midori_location_entry_init (MidoriLocationEntry* location_entry)
 
     entry = gtk_icon_entry_new ();
     gtk_icon_entry_set_icon_from_stock (GTK_ICON_ENTRY (entry),
-         GTK_ICON_ENTRY_PRIMARY, DEFAULT_ICON);
+         GTK_ICON_ENTRY_PRIMARY, GTK_STOCK_FILE);
+    gtk_icon_entry_set_icon_highlight (GTK_ICON_ENTRY (entry),
+         GTK_ICON_ENTRY_SECONDARY, TRUE);
     g_signal_connect_after (entry, "key-press-event",
         G_CALLBACK (entry_key_press_event), location_entry);
     #ifdef HAVE_ENTRY_PROGRESS
     g_signal_connect_after (entry, "expose-event",
         G_CALLBACK (entry_expose_event), location_entry);
     #endif
-
     gtk_widget_show (entry);
     gtk_container_add (GTK_CONTAINER (location_entry), entry);
-
-    store = gtk_list_store_new (N_COLS,
-        GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING,
-        G_TYPE_INT, G_TYPE_BOOLEAN);
-
-#ifdef ORDER_BY_VISITS
-    sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
-    gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
-        VISITS_COL, GTK_SORT_DESCENDING);
-    filter_model = gtk_tree_model_filter_new (GTK_TREE_MODEL (sort_model), NULL);
-#else
-    filter_model = gtk_tree_model_filter_new (GTK_TREE_MODEL (store), NULL);
-#endif
-
-    gtk_tree_model_filter_set_visible_column (
-        GTK_TREE_MODEL_FILTER (filter_model), VISIBLE_COL);
-    g_object_set (location_entry, "model", filter_model, NULL);
-    g_object_unref (store);
-
-    gtk_combo_box_entry_set_text_column (
-        GTK_COMBO_BOX_ENTRY (location_entry), URI_COL);
-    gtk_cell_layout_clear (GTK_CELL_LAYOUT (location_entry));
-
-    /* setup the renderer for the favicon */
-    renderer = gtk_cell_renderer_pixbuf_new ();
-    gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (location_entry),
-                                renderer, FALSE);
-    gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (location_entry),
-        renderer, midori_location_entry_render_pixbuf_cb, NULL, NULL);
-    renderer = gtk_cell_renderer_text_new ();
-    gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (location_entry),
-                                renderer, TRUE);
-    gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (location_entry),
-        renderer, midori_location_entry_render_text_cb, NULL, NULL);
-
-    gtk_combo_box_set_active (GTK_COMBO_BOX (location_entry), -1);
-
-    midori_location_entry_completion_init (location_entry);
-
-    g_signal_connect (location_entry, "changed",
-        G_CALLBACK (midori_location_entry_changed), NULL);
 }
 
 static gboolean
@@ -746,101 +424,6 @@ entry_key_press_event (GtkWidget*           widget,
     return FALSE;
 }
 
-static void
-midori_location_entry_changed (GtkComboBox* combo_box,
-                               gpointer     user_data)
-{
-    GtkTreeIter iter;
-    GtkIconEntry* entry;
-    GtkTreeModel* model;
-    GdkPixbuf* pixbuf;
-
-    if (gtk_combo_box_get_active_iter (combo_box, &iter))
-    {
-        entry = GTK_ICON_ENTRY (GTK_BIN (combo_box)->child);
-
-        if (entry)
-        {
-            pixbuf = NULL;
-
-            model = midori_location_entry_get_filter_model
-                        (MIDORI_LOCATION_ENTRY (combo_box));
-            gtk_tree_model_get (model, &iter, FAVICON_COL, &pixbuf, -1);
-
-            gtk_icon_entry_set_icon_from_pixbuf (GTK_ICON_ENTRY (entry),
-                                                 GTK_ICON_ENTRY_PRIMARY, pixbuf);
-            g_object_unref (pixbuf);
-
-            g_signal_emit (MIDORI_LOCATION_ENTRY (combo_box),
-                signals[ACTIVE_CHANGED], 0, gtk_combo_box_get_active (combo_box));
-        }
-    }
-}
-
-static void
-midori_location_entry_set_item (MidoriLocationEntry*     entry,
-                                GtkTreeIter*             iter,
-                                MidoriLocationEntryItem* item)
-{
-    GtkTreeModel* model;
-    GdkPixbuf* icon;
-    GdkPixbuf* new_icon;
-
-    model = midori_location_entry_get_model (entry);
-    gtk_list_store_set (GTK_LIST_STORE (model), iter,
-        URI_COL, item->uri, TITLE_COL, item->title, -1);
-
-    gtk_tree_model_get (model, iter, FAVICON_COL, &icon, -1);
-    if (item->favicon)
-        new_icon = g_object_ref (item->favicon);
-    else if (!icon && !item->favicon)
-        new_icon = gtk_widget_render_icon (GTK_WIDGET (entry), DEFAULT_ICON,
-                                           GTK_ICON_SIZE_MENU, NULL);
-    else
-        new_icon = NULL;
-    if (new_icon)
-    {
-        gtk_list_store_set (GTK_LIST_STORE (model), iter,
-            FAVICON_COL, new_icon, -1);
-        g_object_unref (new_icon);
-    }
-}
-
-static void
-midori_location_entry_set_active_iter (MidoriLocationEntry* location_entry,
-                                       GtkTreeIter*         iter)
-{
-    GdkPixbuf* pixbuf;
-    GtkTreeModel* model;
-    GtkWidget* entry;
-    GtkTreeIter parent_iter;
-
-    entry = gtk_bin_get_child (GTK_BIN (location_entry));
-    model = midori_location_entry_get_model (location_entry);
-
-    /* The filter iter must be set, not the child iter,
-     * but the row must first be set as visible to
-     * convert to a filter iter without error.
-     */
-    gtk_list_store_set (GTK_LIST_STORE (model), iter, VISIBLE_COL, TRUE, -1);
-    if (midori_location_entry_child_iter_to_iter (
-        location_entry, &parent_iter, iter))
-    gtk_combo_box_set_active_iter (GTK_COMBO_BOX (location_entry), &parent_iter);
-
-    /* When setting the active iter (when adding or setting an item)
-     * the favicon may have changed, so we must update the entry favicon.
-     */
-    if (entry)
-    {
-        gtk_tree_model_get (model, iter, FAVICON_COL, &pixbuf, -1);
-
-        gtk_icon_entry_set_icon_from_pixbuf (GTK_ICON_ENTRY (entry),
-            GTK_ICON_ENTRY_PRIMARY, pixbuf);
-
-        g_object_unref (pixbuf);
-    }
-}
-
 /**
  * midori_location_entry_new:
  *
@@ -853,279 +436,3 @@ midori_location_entry_new (void)
 {
     return g_object_new (MIDORI_TYPE_LOCATION_ENTRY, NULL);
 }
-
-/**
- * midori_location_entry_item_iter:
- * @location_entry: a #MidoriLocationEntry
- * @uri: a string
- * @iter: a GtkTreeIter
- *
- * Retrieves the iter of the item matching @uri.
- *
- * Return value: %TRUE if @uri was found, %FALSE otherwise
- **/
-gboolean
-midori_location_entry_item_iter (MidoriLocationEntry* location_entry,
-                                 const gchar*         uri,
-                                 GtkTreeIter*         iter)
-{
-    GtkTreeModel* model;
-    gchar* tmpuri;
-    gboolean found;
-
-    g_return_val_if_fail (MIDORI_IS_LOCATION_ENTRY (location_entry), FALSE);
-    g_return_val_if_fail (uri != NULL, FALSE);
-
-    found = FALSE;
-    model = midori_location_entry_get_model (location_entry);
-    if (gtk_tree_model_get_iter_first (model, iter))
-    {
-        tmpuri = NULL;
-        do
-        {
-            gtk_tree_model_get (model, iter, URI_COL, &tmpuri, -1);
-            found = !g_ascii_strcasecmp (uri, tmpuri);
-            katze_assign (tmpuri, NULL);
-
-            if (found)
-                break;
-        }
-        while (gtk_tree_model_iter_next (model, iter));
-    }
-    return found;
-}
-
-/**
- * midori_location_entry_get_text:
- * @location_entry: a #MidoriLocationEntry
- *
- * Retrieves the text of the embedded entry.
- *
- * Return value: a string
- **/
-const gchar*
-midori_location_entry_get_text (MidoriLocationEntry* location_entry)
-{
-    GtkWidget* entry;
-
-    g_return_val_if_fail (MIDORI_IS_LOCATION_ENTRY (location_entry), NULL);
-
-    entry = gtk_bin_get_child (GTK_BIN (location_entry));
-    g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL);
-
-    return gtk_entry_get_text (GTK_ENTRY (entry));
-}
-
-/**
- * midori_location_entry_set_text:
- * @location_entry: a #MidoriLocationEntry
- * @text: a string
- *
- * Sets the entry text to @text and, if applicable, updates the icon.
- **/
-void
-midori_location_entry_set_text (MidoriLocationEntry* location_entry,
-                                const gchar*         text)
-{
-    GtkWidget* entry;
-    GtkTreeIter iter;
-    GtkTreeModel* model;
-    GdkPixbuf* icon;
-
-    g_return_if_fail (MIDORI_IS_LOCATION_ENTRY (location_entry));
-
-    entry = gtk_bin_get_child (GTK_BIN (location_entry));
-    g_return_if_fail (GTK_IS_ENTRY (entry));
-
-    gtk_entry_set_text (GTK_ENTRY (entry), text);
-    if (midori_location_entry_item_iter (location_entry, text, &iter))
-    {
-        model = midori_location_entry_get_model (location_entry);
-        gtk_tree_model_get (model, &iter, FAVICON_COL, &icon, -1);
-        gtk_icon_entry_set_icon_from_pixbuf (GTK_ICON_ENTRY (entry),
-            GTK_ICON_ENTRY_PRIMARY, icon);
-    }
-    /* FIXME: Due to a bug in GtkIconEntry we can't reset the icon
-    else
-        gtk_icon_entry_set_icon_from_stock (GTK_ICON_ENTRY (entry),
-            GTK_ICON_ENTRY_PRIMARY, DEFAULT_ICON);*/
-}
-
-/**
- * midori_location_entry_reset:
- * @location_entry: a #MidoriLocationEntry
- *
- * Clears the entry text and resets the entry favicon.
- **/
-void
-midori_location_entry_reset (MidoriLocationEntry* location_entry)
-{
-    GtkWidget* entry;
-
-    g_return_if_fail (MIDORI_IS_LOCATION_ENTRY (location_entry));
-
-    entry = gtk_bin_get_child (GTK_BIN (location_entry));
-    g_return_if_fail (GTK_IS_ICON_ENTRY (entry));
-
-    gtk_entry_set_text (GTK_ENTRY (entry), "");
-    gtk_icon_entry_set_icon_from_stock (GTK_ICON_ENTRY (entry),
-        GTK_ICON_ENTRY_PRIMARY, DEFAULT_ICON);
-}
-
-/**
- * midori_location_entry_clear:
- * @location_entry: a #MidoriLocationEntry
- *
- * Removes all items from @location_entry
- **/
-void
-midori_location_entry_clear (MidoriLocationEntry* location_entry)
-{
-    GtkTreeModel* model;
-
-    g_return_if_fail (MIDORI_IS_LOCATION_ENTRY (location_entry));
-
-    model = midori_location_entry_get_model (location_entry);
-    gtk_list_store_clear (GTK_LIST_STORE (model));
-}
-
-/**
- * midori_location_entry_set_item_from_uri:
- * @location_entry: a #MidoriLocationEntry
- * @uri: a string
- *
- * Finds the item from the list matching @uri and sets it as the active item.
- * If @uri is not found it clears the active item.
- **/
-void
-midori_location_entry_set_item_from_uri (MidoriLocationEntry* location_entry,
-                                         const gchar*         uri)
-{
-    GtkTreeIter iter;
-
-    g_return_if_fail (MIDORI_IS_LOCATION_ENTRY (location_entry));
-
-    if (midori_location_entry_item_iter (location_entry, uri, &iter))
-        midori_location_entry_set_active_iter (location_entry, &iter);
-    else
-        midori_location_entry_reset (location_entry);
-
-}
-
-/**
- * midori_location_entry_prepend_item:
- * @location_entry: a #MidoriLocationEntry
- * @item: a MidoriLocationItem
- *
- * Prepends @item if it is not already in the list.
- * If the item already exists, it is moved before the first item.
- * If the maximum is reached, the last item is removed.
- **/
-void
-midori_location_entry_prepend_item (MidoriLocationEntry*     location_entry,
-                                    MidoriLocationEntryItem* item)
-{
-    GtkTreeModel* filter_model;
-    GtkTreeModel* model;
-    GtkTreeIter iter;
-    GtkTreeIter index;
-    gint n;
-    gint visits = 0;
-
-    g_return_if_fail (MIDORI_IS_LOCATION_ENTRY (location_entry));
-    g_return_if_fail (item->uri != NULL);
-
-    filter_model = midori_location_entry_get_filter_model (location_entry);
-    model = midori_location_entry_get_model (location_entry);
-
-    if (midori_location_entry_item_iter (location_entry, item->uri, &iter))
-    {
-        gtk_tree_model_get_iter_first (model, &index);
-        gtk_tree_model_get (model, &iter, VISITS_COL, &visits, -1);
-        gtk_list_store_move_before (GTK_LIST_STORE (model), &iter, &index);
-    }
-    else
-        gtk_list_store_prepend (GTK_LIST_STORE (model), &iter);
-
-    n = gtk_tree_model_iter_n_children (filter_model, NULL);
-    if (n > MAX_ITEMS)
-    {
-        gtk_tree_model_iter_nth_child (model, &index, NULL, n - 1);
-        gtk_list_store_set (GTK_LIST_STORE (model),
-                            &index, VISIBLE_COL, FALSE, -1);
-    }
-
-    /* Only increment the visits when we add the uri */
-    if (!item->title && !item->favicon)
-        gtk_list_store_set (GTK_LIST_STORE (model), &iter, VISITS_COL, ++visits,
-                            VISIBLE_COL, TRUE, -1);
-    midori_location_entry_set_item (location_entry, &iter, item);
-}
-
-/**
- * midori_location_entry_append_item:
- * @location_entry: a #MidoriLocationEntry
- * @item: a MidoriLocationItem
- *
- * Appends @item if it is not already in the list.
- * @item is not added if the maximum is reached.
- **/
-void
-midori_location_entry_append_item (MidoriLocationEntry*     location_entry,
-                                   MidoriLocationEntryItem* item)
-{
-    GtkTreeModel* model;
-    GtkTreeIter iter;
-    gint n;
-    gint visits = 0;
-
-    g_return_if_fail (MIDORI_IS_LOCATION_ENTRY (location_entry));
-    g_return_if_fail (item->uri != NULL);
-
-    model = midori_location_entry_get_model (location_entry);
-
-    if (!midori_location_entry_item_iter (location_entry, item->uri, &iter))
-    {
-        gtk_list_store_append (GTK_LIST_STORE (model), &iter);
-
-        n = gtk_tree_model_iter_n_children (model, NULL);
-        gtk_list_store_set (GTK_LIST_STORE (model), &iter, VISIBLE_COL,
-                            (n <= MAX_ITEMS), -1);
-    }
-    else
-        gtk_tree_model_get (model, &iter, VISITS_COL, &visits, -1);
-
-    gtk_list_store_set (GTK_LIST_STORE (model), &iter, VISITS_COL, ++visits, -1);
-    midori_location_entry_set_item (location_entry, &iter, item);
-}
-
-/**
- * midori_location_entry_set_item_from_uri:
- * @location_entry: a #MidoriLocationEntry
- * @uri: a string
- *
- * Finds the item from the list matching @uri
- * and removes it if it is the last instance.
- **/
-void
-midori_location_entry_delete_item_from_uri (MidoriLocationEntry* location_entry,
-                                            const gchar*         uri)
-{
-    GtkTreeModel* model;
-    GtkTreeIter iter;
-    gint visits = 0;
-
-    g_return_if_fail (MIDORI_IS_LOCATION_ENTRY (location_entry));
-
-    model = midori_location_entry_get_model (location_entry);
-    if (midori_location_entry_item_iter (location_entry, uri, &iter))
-    {
-        gtk_tree_model_get (model, &iter, VISITS_COL, &visits, -1);
-        if (visits > 1)
-            gtk_list_store_set (GTK_LIST_STORE (model),
-                &iter, VISITS_COL, --visits, -1);
-        else
-            gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
-    }
-}
-
index 6be5ed69fc819663d88500e1bfe9900067bf26c0..f84d0b292b939e0769586e877f164017defbbcb3 100644 (file)
@@ -27,56 +27,12 @@ typedef struct _MidoriLocationEntry         MidoriLocationEntry;
 typedef struct _MidoriLocationEntryClass    MidoriLocationEntryClass;
 typedef struct _MidoriLocationEntryItem     MidoriLocationEntryItem;
 
-struct _MidoriLocationEntryItem
-{
-    GdkPixbuf* favicon;
-    const gchar* uri;
-    const gchar* title;
-};
-
 GType
 midori_location_entry_get_type             (void);
 
 GtkWidget*
 midori_location_entry_new                  (void);
 
-gboolean
-midori_location_entry_item_iter            (MidoriLocationEntry* location_entry,
-                                            const gchar*         uri,
-                                            GtkTreeIter*         iter);
-
-const gchar*
-midori_location_entry_get_text             (MidoriLocationEntry* location_entry);
-
-void
-midori_location_entry_set_text             (MidoriLocationEntry* location_entry,
-                                            const gchar*         text);
-
-void
-midori_location_entry_reset                (MidoriLocationEntry* location_entry);
-
-void
-midori_location_entry_clear                (MidoriLocationEntry* location_entry);
-
-void
-midori_location_entry_set_item_from_uri    (MidoriLocationEntry* location_entry,
-                                            const gchar*         uri);
-
-void
-midori_location_entry_prepend_item         (MidoriLocationEntry* location_entry,
-                                            MidoriLocationEntryItem* item);
-
-void
-midori_location_entry_append_item          (MidoriLocationEntry* location_entry,
-                                            MidoriLocationEntryItem* item);
-
-void
-midori_location_entry_delete_item_from_uri (MidoriLocationEntry* location_entry,
-                                            const gchar*         uri);
-
-gdouble
-midori_location_entry_get_progress         (MidoriLocationEntry* location_entry);
-
 void
 midori_location_entry_set_progress         (MidoriLocationEntry* location_entry,
                                             gdouble              progress);