diff options
author | Marco Pesenti Gritti <marco@gnome.org> | 2003-10-06 18:07:02 +0000 |
---|---|---|
committer | Marco Pesenti Gritti <marco@src.gnome.org> | 2003-10-06 18:07:02 +0000 |
commit | b825de03cd831b132336ee378d098d27e253c02a (patch) | |
tree | 5e423774e0df040c068cfcf0a6b53aa4b0ac7b9a | |
parent | d8bb574f6b926502624b9be702bf87ef0e8cbaa6 (diff) | |
download | epiphany-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-- | ChangeLog | 22 | ||||
-rw-r--r-- | lib/widgets/ephy-location-entry.c | 116 | ||||
-rw-r--r-- | lib/widgets/ephy-location-entry.h | 12 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/ephy-completion-model.c | 216 | ||||
-rw-r--r-- | src/ephy-location-action.c | 26 |
6 files changed, 265 insertions, 129 deletions
@@ -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); |