/*
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;
gdouble progress;
GtkTreeModel* model;
+ GtkTreeModel* filter_model;
+ GtkTreeModel* sort_model;
+ GdkPixbuf* default_icon;
};
struct _MidoriLocationActionClass
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);
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
{
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);
}
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;
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);
}
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);
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)
GtkWidget* alignment;
GtkWidget* entry;
MidoriLocationAction* location_action;
+ GtkCellRenderer* renderer;
GTK_ACTION_CLASS (midori_location_action_parent_class)->connect_proxy (
action, proxy);
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",
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)
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
{
GSList* proxies;
GtkWidget* alignment;
+ GtkWidget* location_entry;
GtkWidget* entry;
- GtkWidget* child;
MidoriLocationEntryItem item;
g_return_if_fail (MIDORI_IS_LOCATION_ACTION (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)));
}
{
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)));
}
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
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
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)));
}
*/
#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
{
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
#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)
#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\" "
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
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:
*
{
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);
- }
-}
-