summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Pesenti Gritti <marco@gnome.org>2003-10-06 18:07:02 +0000
committerMarco Pesenti Gritti <marco@src.gnome.org>2003-10-06 18:07:02 +0000
commitb825de03cd831b132336ee378d098d27e253c02a (patch)
tree5e423774e0df040c068cfcf0a6b53aa4b0ac7b9a
parentd8bb574f6b926502624b9be702bf87ef0e8cbaa6 (diff)
downloadepiphany-b825de03cd831b132336ee378d098d27e253c02a.tar.gz
Implement our own completion model. The big part of the new location entry
2003-10-06 Marco Pesenti Gritti <marco@gnome.org> * lib/widgets/ephy-location-entry.c: (completion_func), (match_selected_cb), (ephy_location_entry_construct_contents), (ephy_location_entry_init), (sort_func), (ephy_location_entry_set_completion): * lib/widgets/ephy-location-entry.h: * src/Makefile.am: * src/ephy-completion-model.c: (ephy_completion_model_class_init), (root_child_removed_cb), (node_iter_from_node), (get_path_real), (root_child_added_cb), (root_child_changed_cb), (connect_signals), (ephy_completion_model_init), (ephy_completion_model_get_column_type), (init_text_col), (init_action_col), (init_keywords_col), (init_relevance_col), (ephy_completion_model_get_value), (ephy_completion_model_get_iter): * src/ephy-location-action.c: (connect_proxy): Implement our own completion model. The big part of the new location entry impl is done. When gtk completion will be fixed I'll be able to merge this on head.
-rw-r--r--ChangeLog22
-rw-r--r--lib/widgets/ephy-location-entry.c116
-rw-r--r--lib/widgets/ephy-location-entry.h12
-rw-r--r--src/Makefile.am2
-rw-r--r--src/ephy-completion-model.c216
-rw-r--r--src/ephy-location-action.c26
6 files changed, 265 insertions, 129 deletions
diff --git a/ChangeLog b/ChangeLog
index 073833780..90cf0c6bd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+2003-10-06 Marco Pesenti Gritti <marco@gnome.org>
+
+ * lib/widgets/ephy-location-entry.c: (completion_func),
+ (match_selected_cb), (ephy_location_entry_construct_contents),
+ (ephy_location_entry_init), (sort_func),
+ (ephy_location_entry_set_completion):
+ * lib/widgets/ephy-location-entry.h:
+ * src/Makefile.am:
+ * src/ephy-completion-model.c: (ephy_completion_model_class_init),
+ (root_child_removed_cb), (node_iter_from_node), (get_path_real),
+ (root_child_added_cb), (root_child_changed_cb), (connect_signals),
+ (ephy_completion_model_init),
+ (ephy_completion_model_get_column_type), (init_text_col),
+ (init_action_col), (init_keywords_col), (init_relevance_col),
+ (ephy_completion_model_get_value),
+ (ephy_completion_model_get_iter):
+ * src/ephy-location-action.c: (connect_proxy):
+
+ Implement our own completion model. The big part of the
+ new location entry impl is done. When gtk completion will
+ be fixed I'll be able to merge this on head.
+
2003-10-05 Marco Pesenti Gritti <marco@gnome.org>
* lib/widgets/ephy-location-entry.c:
diff --git a/lib/widgets/ephy-location-entry.c b/lib/widgets/ephy-location-entry.c
index 2e0fda311..a2203fed6 100644
--- a/lib/widgets/ephy-location-entry.c
+++ b/lib/widgets/ephy-location-entry.c
@@ -34,13 +34,13 @@
#include <gtk/gtkwindow.h>
#include <gtk/gtkcellrenderertext.h>
#include <gtk/gtkcelllayout.h>
+#include <gtk/gtktreemodelsort.h>
#include <string.h>
#define EPHY_LOCATION_ENTRY_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_LOCATION_ENTRY, EphyLocationEntryPrivate))
struct _EphyLocationEntryPrivate
{
- GtkTreeModel *completion_model;
EphyTreeModelNode *combo_model;
GtkWidget *combo;
GtkWidget *entry;
@@ -50,13 +50,11 @@ struct _EphyLocationEntryPrivate
EphyNodeDb *combo_db;
EphyNode *combo_root;
char *xml_file;
-};
-enum
-{
- TEXT_COL,
- KEYWORDS_COL,
- ACTION_COL
+ guint text_col;
+ guint action_col;
+ guint keywords_col;
+ guint relevance_col;
};
static char *web_prefixes [] =
@@ -308,11 +306,14 @@ completion_func (GtkEntryCompletion *completion,
char *case_normalized_string, *case_normalized_keywords;
gboolean ret = FALSE;
EphyLocationEntry *le = EPHY_LOCATION_ENTRY (data);
+ GtkTreeModel *model;
- gtk_tree_model_get (le->priv->completion_model, iter,
- TEXT_COL, &item, -1);
- gtk_tree_model_get (le->priv->completion_model, iter,
- KEYWORDS_COL, &keywords, -1);
+ model = gtk_entry_completion_get_model (completion);
+
+ gtk_tree_model_get (model, iter,
+ le->priv->text_col, &item, -1);
+ gtk_tree_model_get (model, iter,
+ le->priv->keywords_col, &keywords, -1);
normalized_string = g_utf8_normalize (item, -1, G_NORMALIZE_ALL);
case_normalized_string = g_utf8_casefold (normalized_string, -1);
@@ -362,7 +363,7 @@ match_selected_cb (GtkEntryCompletion *completion,
char *item = NULL;
gtk_tree_model_get (model, iter,
- ACTION_COL, &item, -1);
+ le->priv->action_col, &item, -1);
ephy_location_entry_set_location (le, item);
g_signal_emit_by_name (le->priv->entry, "activate");
@@ -376,8 +377,6 @@ static void
ephy_location_entry_construct_contents (EphyLocationEntry *le)
{
EphyLocationEntryPrivate *p = le->priv;
- GtkEntryCompletion *completion;
- GtkCellRenderer *cell;
int combo_text_col;
LOG ("EphyLocationEntry constructing contents %p", le)
@@ -398,23 +397,6 @@ ephy_location_entry_construct_contents (EphyLocationEntry *le)
G_CALLBACK (editable_changed_cb), le);
g_signal_connect (p->entry, "activate",
G_CALLBACK (entry_activate_cb), le);
-
- p->completion_model = egg_tree_model_union_new
- (3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
-
- completion = gtk_entry_completion_new ();
- gtk_entry_completion_set_model (completion, le->priv->completion_model);
- gtk_entry_completion_set_match_func (completion, completion_func, le, NULL);
- g_signal_connect (completion, "match_selected",
- G_CALLBACK (match_selected_cb), le);
-
- cell = gtk_cell_renderer_text_new ();
- gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (completion),
- cell, TRUE);
- gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (completion),
- cell, "text", TEXT_COL);
-
- gtk_entry_set_completion (GTK_ENTRY (le->priv->entry), completion);
}
static void
@@ -429,7 +411,6 @@ ephy_location_entry_init (EphyLocationEntry *le)
p->user_changed = TRUE;
p->activation_mode = FALSE;
- p->completion_model = NULL;
p->combo_db = ephy_node_db_new ("NodeDB");
p->combo_root = ephy_node_new_with_id
(p->combo_db, LOCATION_HISTORY_NODE_ID);
@@ -500,27 +481,60 @@ ephy_location_entry_new (void)
return GTK_WIDGET (g_object_new (EPHY_TYPE_LOCATION_ENTRY, NULL));
}
+static gint
+sort_func (GtkTreeModel *model,
+ GtkTreeIter *a,
+ GtkTreeIter *b,
+ gpointer data)
+{
+ gint valuea, valueb;
+ EphyLocationEntry *le = EPHY_LOCATION_ENTRY (data);
+
+ gtk_tree_model_get (model, a,
+ le->priv->relevance_col, &valuea, -1);
+ gtk_tree_model_get (model, b,
+ le->priv->relevance_col, &valueb, -1);
+
+ return valueb - valuea;
+}
+
void
-ephy_location_entry_add_completion (EphyLocationEntry *le,
- EphyNode *root,
- guint text_property,
- guint action_property,
- guint keywords_property)
+ephy_location_entry_set_completion (EphyLocationEntry *le,
+ GtkTreeModel *model,
+ guint text_col,
+ guint action_col,
+ guint keywords_col,
+ guint relevance_col)
{
- EphyTreeModelNode *node_model;
- int action_col, text_col, keywords_col;
-
- node_model = ephy_tree_model_node_new (root, NULL);
- text_col = ephy_tree_model_node_add_prop_column
- (node_model, G_TYPE_STRING, text_property);
- action_col = ephy_tree_model_node_add_prop_column
- (node_model, G_TYPE_STRING, action_property);
- keywords_col = ephy_tree_model_node_add_prop_column
- (node_model, G_TYPE_STRING, keywords_property);
- egg_tree_model_union_append_with_mapping
- (EGG_TREE_MODEL_UNION (le->priv->completion_model),
- GTK_TREE_MODEL (node_model), text_col, keywords_col,
- action_col);
+ GtkTreeModel *sort_model;
+ GtkEntryCompletion *completion;
+ GtkCellRenderer *cell;
+
+ le->priv->text_col = text_col;
+ le->priv->action_col = action_col;
+ le->priv->keywords_col = keywords_col;
+ le->priv->relevance_col = relevance_col;
+
+ sort_model = gtk_tree_model_sort_new_with_model (model);
+ g_object_unref (model);
+ gtk_tree_sortable_set_default_sort_func
+ (GTK_TREE_SORTABLE (sort_model),
+ sort_func, le, NULL);
+
+ completion = gtk_entry_completion_new ();
+ gtk_entry_completion_set_model (completion, sort_model);
+ g_object_unref (sort_model);
+ gtk_entry_completion_set_match_func (completion, completion_func, le, NULL);
+ g_signal_connect (completion, "match_selected",
+ G_CALLBACK (match_selected_cb), le);
+
+ cell = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (completion),
+ cell, TRUE);
+ gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (completion),
+ cell, "text", text_col);
+
+ gtk_entry_set_completion (GTK_ENTRY (le->priv->entry), completion);
}
void
diff --git a/lib/widgets/ephy-location-entry.h b/lib/widgets/ephy-location-entry.h
index 4e20bc70c..f516a1ad7 100644
--- a/lib/widgets/ephy-location-entry.h
+++ b/lib/widgets/ephy-location-entry.h
@@ -26,6 +26,7 @@
#include "ephy-node.h"
#include <gtk/gtktoolitem.h>
+#include <gtk/gtktreemodel.h>
#define EPHY_TYPE_LOCATION_ENTRY (ephy_location_entry_get_type())
#define EPHY_LOCATION_ENTRY(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EPHY_TYPE_LOCATION_ENTRY,\
@@ -61,11 +62,12 @@ GtkWidget *ephy_location_entry_new (void);
GtkWidget *ephy_location_entry_get_entry (EphyLocationEntry *le);
-void ephy_location_entry_add_completion (EphyLocationEntry *le,
- EphyNode *root,
- guint text_property,
- guint action_property,
- guint keywords_property);
+void ephy_location_entry_set_completion (EphyLocationEntry *le,
+ GtkTreeModel *model,
+ guint text_col,
+ guint action_col,
+ guint keywords_col,
+ guint relevance_col);
void ephy_location_entry_set_location (EphyLocationEntry *le,
const gchar *new_location);
diff --git a/src/Makefile.am b/src/Makefile.am
index 268d6e34f..aa34a386c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -82,6 +82,8 @@ epiphany_bin_SOURCES = \
$(CORBA_SOURCE) \
$(nautilus_view_sources) \
ephy-automation.c \
+ ephy-completion-model.c \
+ ephy-completion-model.h \
ephy-encoding-menu.c \
ephy-favicon-action.c \
ephy-favorites-menu.c \
diff --git a/src/ephy-completion-model.c b/src/ephy-completion-model.c
index ccca87b7c..5a46ecd7a 100644
--- a/src/ephy-completion-model.c
+++ b/src/ephy-completion-model.c
@@ -26,7 +26,6 @@
static void ephy_completion_model_class_init (EphyCompletionModelClass *klass);
static void ephy_completion_model_init (EphyCompletionModel *model);
-static void ephy_completion_model_finalize (GObject *object);
static void ephy_completion_model_tree_model_init (GtkTreeModelIface *iface);
#define EPHY_COMPLETION_MODEL_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_COMPLETION_MODEL, EphyCompletionModelPrivate))
@@ -39,15 +38,6 @@ struct EphyCompletionModelPrivate
enum
{
- TEXT_COL,
- ACTION_COL,
- KEYWORDS_COL,
- RELEVANCE_COL,
- N_COL
-};
-
-enum
-{
HISTORY_GROUP,
BOOKMARKS_GROUP
};
@@ -100,12 +90,111 @@ ephy_completion_model_class_init (EphyCompletionModelClass *klass)
parent_class = g_type_class_peek_parent (klass);
- object_class->finalize = ephy_completion_model_finalize;
-
g_type_class_add_private (object_class, sizeof (EphyCompletionModelPrivate));
}
static void
+root_child_removed_cb (EphyNode *node,
+ EphyNode *child,
+ guint old_index,
+ EphyCompletionModel *tree_model)
+{
+ EphyCompletionModel *model = EPHY_COMPLETION_MODEL (tree_model);
+ GtkTreePath *path;
+ int real_index;
+
+ real_index = old_index;
+
+ if (node == model->priv->bookmarks)
+ {
+ real_index += ephy_node_get_n_children (model->priv->history);
+ }
+
+ path = gtk_tree_path_new ();
+ gtk_tree_path_append_index (path, real_index);
+ gtk_tree_model_row_deleted (GTK_TREE_MODEL (model), path);
+ gtk_tree_path_free (path);
+}
+
+static void
+node_iter_from_node (EphyCompletionModel *model,
+ EphyNode *node,
+ GtkTreeIter *iter)
+{
+ iter->stamp = 0;
+ iter->user_data = node;
+}
+
+static inline GtkTreePath *
+get_path_real (EphyCompletionModel *model,
+ EphyNode *node)
+{
+ GtkTreePath *retval;
+ int index;
+
+ retval = gtk_tree_path_new ();
+
+ index = ephy_node_get_child_index (model->priv->bookmarks, node);
+ if (index < 0)
+ {
+ index = ephy_node_get_child_index (model->priv->history, node);
+ }
+
+ g_return_val_if_fail (index >= 0, NULL);
+
+ gtk_tree_path_append_index (retval, index);
+
+ return retval;
+}
+
+static void
+root_child_added_cb (EphyNode *node,
+ EphyNode *child,
+ EphyCompletionModel *model)
+{
+ GtkTreePath *path;
+ GtkTreeIter iter;
+
+ node_iter_from_node (model, child, &iter);
+
+ path = get_path_real (model, child);
+ gtk_tree_model_row_inserted (GTK_TREE_MODEL (model), path, &iter);
+ gtk_tree_path_free (path);
+}
+
+static void
+root_child_changed_cb (EphyNode *node,
+ EphyNode *child,
+ EphyCompletionModel *model)
+{
+ GtkTreePath *path;
+ GtkTreeIter iter;
+
+ node_iter_from_node (model, node, &iter);
+
+ path = get_path_real (model, child);
+ gtk_tree_model_row_changed (GTK_TREE_MODEL (model), path, &iter);
+ gtk_tree_path_free (path);
+}
+
+static void
+connect_signals (EphyCompletionModel *model, EphyNode *root)
+{
+ ephy_node_signal_connect_object (root,
+ EPHY_NODE_CHILD_ADDED,
+ (EphyNodeCallback)root_child_added_cb,
+ G_OBJECT (model));
+ ephy_node_signal_connect_object (root,
+ EPHY_NODE_CHILD_REMOVED,
+ (EphyNodeCallback)root_child_removed_cb,
+ G_OBJECT (model));
+ ephy_node_signal_connect_object (root,
+ EPHY_NODE_CHILD_CHANGED,
+ (EphyNodeCallback)root_child_changed_cb,
+ G_OBJECT (model));
+}
+
+static void
ephy_completion_model_init (EphyCompletionModel *model)
{
EphyBookmarks *bookmarks;
@@ -116,17 +205,11 @@ ephy_completion_model_init (EphyCompletionModel *model)
history = ephy_embed_shell_get_global_history
(EPHY_EMBED_SHELL (ephy_shell));
model->priv->history = ephy_history_get_pages (history);
+ connect_signals (model, model->priv->history);
bookmarks = ephy_shell_get_bookmarks (ephy_shell);
model->priv->bookmarks = ephy_bookmarks_get_bookmarks (bookmarks);
-}
-
-static void
-ephy_completion_model_finalize (GObject *object)
-{
- //EphyCompletionModel *model = EPHY_COMPLETION_MODEL (object);
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
+ connect_signals (model, model->priv->bookmarks);
}
EphyCompletionModel *
@@ -156,12 +239,12 @@ ephy_completion_model_get_column_type (GtkTreeModel *tree_model,
switch (index)
{
- case TEXT_COL:
- case ACTION_COL:
- case KEYWORDS_COL:
+ case EPHY_COMPLETION_TEXT_COL:
+ case EPHY_COMPLETION_ACTION_COL:
+ case EPHY_COMPLETION_KEYWORDS_COL:
type = G_TYPE_STRING;
break;
- case RELEVANCE_COL:
+ case EPHY_COMPLETION_RELEVANCE_COL:
type = G_TYPE_INT;
break;
}
@@ -178,11 +261,11 @@ init_text_col (GValue *value, EphyNode *node, int group)
{
case BOOKMARKS_GROUP:
text = ephy_node_get_property_string
- (node, EPHY_NODE_PAGE_PROP_LOCATION);
+ (node, EPHY_NODE_PAGE_PROP_TITLE);
break;
case HISTORY_GROUP:
text = ephy_node_get_property_string
- (node, EPHY_NODE_BMK_PROP_TITLE);
+ (node, EPHY_NODE_BMK_PROP_LOCATION);
break;
default:
@@ -201,11 +284,11 @@ init_action_col (GValue *value, EphyNode *node, int group)
{
case BOOKMARKS_GROUP:
text = ephy_node_get_property_string
- (node, EPHY_NODE_PAGE_PROP_LOCATION);
+ (node, EPHY_NODE_BMK_PROP_LOCATION);
break;
case HISTORY_GROUP:
text = ephy_node_get_property_string
- (node, EPHY_NODE_BMK_PROP_LOCATION);
+ (node, EPHY_NODE_PAGE_PROP_LOCATION);
break;
default:
text = "";
@@ -214,6 +297,49 @@ init_action_col (GValue *value, EphyNode *node, int group)
g_value_set_string (value, text);
}
+static void
+init_keywords_col (GValue *value, EphyNode *node, int group)
+{
+ const char *text = NULL;
+
+ switch (group)
+ {
+ case BOOKMARKS_GROUP:
+ text = ephy_node_get_property_string
+ (node, EPHY_NODE_BMK_PROP_KEYWORDS);
+ break;
+ }
+
+ if (text == NULL)
+ {
+ text = "";
+ }
+
+ g_value_set_string (value, text);
+}
+
+static void
+init_relevance_col (GValue *value, EphyNode *node, int group)
+{
+ int relevance, visits;
+
+ switch (group)
+ {
+ case HISTORY_GROUP:
+ visits = ephy_node_get_property_int
+ (node, EPHY_NODE_PAGE_PROP_VISITS);
+ relevance = visits;
+ break;
+ case BOOKMARKS_GROUP:
+ relevance = 2000;
+ break;
+ default:
+ relevance = 0;
+ }
+
+ g_value_set_int (value, relevance);
+}
+
static EphyNode *
get_node_root (EphyCompletionModel *model, EphyNode *node)
{
@@ -276,21 +402,21 @@ ephy_completion_model_get_value (GtkTreeModel *tree_model,
switch (column)
{
- case TEXT_COL:
+ case EPHY_COMPLETION_TEXT_COL:
g_value_init (value, G_TYPE_STRING);
init_text_col (value, node, group);
break;
- case ACTION_COL:
+ case EPHY_COMPLETION_ACTION_COL:
g_value_init (value, G_TYPE_STRING);
init_action_col (value, node, group);
break;
- case KEYWORDS_COL:
+ case EPHY_COMPLETION_KEYWORDS_COL:
g_value_init (value, G_TYPE_STRING);
- g_value_set_string (value, "");
+ init_keywords_col (value, node, group);
break;
- case RELEVANCE_COL:
+ case EPHY_COMPLETION_RELEVANCE_COL:
g_value_init (value, G_TYPE_INT);
- g_value_set_int (value, 0);
+ init_relevance_col (value, node, group);
break;
}
}
@@ -329,28 +455,6 @@ ephy_completion_model_get_iter (GtkTreeModel *tree_model,
return TRUE;
}
-static inline GtkTreePath *
-get_path_real (EphyCompletionModel *model,
- EphyNode *node)
-{
- GtkTreePath *retval;
- int index;
-
- retval = gtk_tree_path_new ();
-
- index = ephy_node_get_child_index (model->priv->bookmarks, node);
- if (index < 0)
- {
- index = ephy_node_get_child_index (model->priv->history, node);
- }
-
- g_return_val_if_fail (index >= 0, NULL);
-
- gtk_tree_path_append_index (retval, index);
-
- return retval;
-}
-
static GtkTreePath *
ephy_completion_model_get_path (GtkTreeModel *tree_model,
GtkTreeIter *iter)
diff --git a/src/ephy-location-action.c b/src/ephy-location-action.c
index d132a3369..0d90e8e24 100644
--- a/src/ephy-location-action.c
+++ b/src/ephy-location-action.c
@@ -22,6 +22,7 @@
#include "ephy-location-action.h"
#include "ephy-location-entry.h"
#include "ephy-shell.h"
+#include "ephy-completion-model.h"
#include "ephy-debug.h"
#include <gtk/gtkentry.h>
@@ -216,29 +217,20 @@ add_completion_actions (GtkAction *action, GtkWidget *proxy)
static void
connect_proxy (GtkAction *action, GtkWidget *proxy)
{
- EphyLocationAction *la = EPHY_LOCATION_ACTION (action);
-
LOG ("Connect proxy")
if (EPHY_IS_LOCATION_ENTRY (proxy))
{
- EphyHistory *history;
- EphyNode *node;
+ EphyCompletionModel *model;
GtkWidget *entry;
- history = ephy_embed_shell_get_global_history
- (EPHY_EMBED_SHELL (ephy_shell));
- node = ephy_history_get_pages (history);
- ephy_location_entry_add_completion (EPHY_LOCATION_ENTRY (proxy), node,
- EPHY_NODE_PAGE_PROP_LOCATION,
- EPHY_NODE_PAGE_PROP_LOCATION,
- EPHY_NODE_PAGE_PROP_TITLE);
-
- node = ephy_bookmarks_get_bookmarks (la->priv->bookmarks);
- ephy_location_entry_add_completion (EPHY_LOCATION_ENTRY (proxy), node,
- EPHY_NODE_BMK_PROP_TITLE,
- EPHY_NODE_BMK_PROP_LOCATION,
- EPHY_NODE_BMK_PROP_KEYWORDS);
+ model = ephy_completion_model_new ();
+ ephy_location_entry_set_completion (EPHY_LOCATION_ENTRY (proxy),
+ GTK_TREE_MODEL (model),
+ EPHY_COMPLETION_TEXT_COL,
+ EPHY_COMPLETION_ACTION_COL,
+ EPHY_COMPLETION_KEYWORDS_COL,
+ EPHY_COMPLETION_RELEVANCE_COL);
add_completion_actions (action, proxy);