aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am2
-rw-r--r--src/bookmarks/ephy-bookmark-action.c8
-rw-r--r--src/bookmarks/ephy-bookmarks-export.c7
-rw-r--r--src/bookmarks/ephy-bookmarks.c114
-rw-r--r--src/bookmarks/ephy-bookmarks.h3
-rw-r--r--src/ephy-completion-model.c601
-rw-r--r--src/ephy-completion-model.h63
-rw-r--r--src/ephy-location-action.c211
-rw-r--r--src/ephy-shell.c33
-rw-r--r--src/ephy-shell.h2
10 files changed, 899 insertions, 145 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 38c1a5195..f1cc2ad3a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -81,6 +81,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/bookmarks/ephy-bookmark-action.c b/src/bookmarks/ephy-bookmark-action.c
index f805109d4..13d2e2f53 100644
--- a/src/bookmarks/ephy-bookmark-action.c
+++ b/src/bookmarks/ephy-bookmark-action.c
@@ -487,13 +487,17 @@ sync_bookmark_properties (GtkAction *action, EphyNode *bmk)
const char *tmp, *location, *icon;
char *title;
gboolean smart_url;
+ EphyBookmarks *bookmarks;
+ EphyNode *smart_bmks;
+
+ bookmarks = ephy_shell_get_bookmarks (ephy_shell);
+ smart_bmks = ephy_bookmarks_get_smart_bookmarks (bookmarks);
icon = ephy_node_get_property_string
(bmk, EPHY_NODE_BMK_PROP_ICON);
location = ephy_node_get_property_string
(bmk, EPHY_NODE_BMK_PROP_LOCATION);
- smart_url = ephy_node_get_property_boolean
- (bmk, EPHY_NODE_BMK_PROP_HAS_SMART_ADDRESS);
+ smart_url = ephy_node_has_child (smart_bmks, bmk);
tmp = ephy_node_get_property_string
(bmk, EPHY_NODE_BMK_PROP_TITLE);
title = ephy_string_double_underscores (tmp);
diff --git a/src/bookmarks/ephy-bookmarks-export.c b/src/bookmarks/ephy-bookmarks-export.c
index 97c955259..be9b97ea7 100644
--- a/src/bookmarks/ephy-bookmarks-export.c
+++ b/src/bookmarks/ephy-bookmarks-export.c
@@ -73,8 +73,7 @@ void
ephy_bookmarks_export_rdf (EphyBookmarks *bookmarks,
const char *filename)
{
- EphyNode *bmks;
- EphyNode *topics;
+ EphyNode *bmks, *topics, *smart_bmks;
xmlDocPtr doc;
xmlNodePtr root, xml_node, channel_node, channel_seq_node;
xmlNsPtr ephy_ns, rdf_ns, dc_ns;
@@ -110,6 +109,7 @@ ephy_bookmarks_export_rdf (EphyBookmarks *bookmarks,
bmks = ephy_bookmarks_get_bookmarks (bookmarks);
topics = ephy_bookmarks_get_keywords (bookmarks);
+ smart_bmks = ephy_bookmarks_get_smart_bookmarks (bookmarks);
children = ephy_node_get_children (bmks);
for (i = 0; i < children->len; i++)
@@ -123,8 +123,7 @@ ephy_bookmarks_export_rdf (EphyBookmarks *bookmarks,
kid = g_ptr_array_index (children, i);
- smart_url = ephy_node_get_property_boolean
- (kid, EPHY_NODE_BMK_PROP_HAS_SMART_ADDRESS);
+ smart_url = ephy_node_has_child (smart_bmks, kid);
url = ephy_node_get_property_string
(kid, EPHY_NODE_BMK_PROP_LOCATION);
title = ephy_node_get_property_string
diff --git a/src/bookmarks/ephy-bookmarks.c b/src/bookmarks/ephy-bookmarks.c
index 0c05e59c7..9dc4e977e 100644
--- a/src/bookmarks/ephy-bookmarks.c
+++ b/src/bookmarks/ephy-bookmarks.c
@@ -32,7 +32,6 @@
#include "ephy-toolbars-model.h"
#include "ephy-bookmarks-export.h"
#include "ephy-bookmarks-import.h"
-#include "ephy-autocompletion.h"
#include "session.h"
#include <string.h>
@@ -40,7 +39,7 @@
#include <libgnomevfs/gnome-vfs-utils.h>
#define EPHY_BOOKMARKS_XML_ROOT "ephy_bookmarks"
-#define EPHY_BOOKMARKS_XML_VERSION "1.0"
+#define EPHY_BOOKMARKS_XML_VERSION "1.01"
#define BOOKMARKS_SAVE_DELAY (3 * 1000)
#define MAX_FAVORITES_NUM 10
@@ -59,6 +58,7 @@ struct EphyBookmarksPrivate
EphyNode *keywords;
EphyNode *favorites;
EphyNode *notcategorized;
+ EphyNode *smartbookmarks;
EphyNode *lower_fav;
double lower_score;
};
@@ -112,8 +112,6 @@ static void
ephy_bookmarks_init (EphyBookmarks *tab);
static void
ephy_bookmarks_finalize (GObject *object);
-static void
-ephy_bookmarks_autocompletion_source_init (EphyAutocompletionSourceIface *iface);
static GObjectClass *parent_class = NULL;
@@ -137,79 +135,15 @@ ephy_bookmarks_get_type (void)
(GInstanceInitFunc) ephy_bookmarks_init
};
- static const GInterfaceInfo autocompletion_source_info =
- {
- (GInterfaceInitFunc) ephy_bookmarks_autocompletion_source_init,
- NULL,
- NULL
- };
-
ephy_bookmarks_type = g_type_register_static (G_TYPE_OBJECT,
"EphyBookmarks",
&our_info, 0);
-
- g_type_add_interface_static (ephy_bookmarks_type,
- EPHY_TYPE_AUTOCOMPLETION_SOURCE,
- &autocompletion_source_info);
}
return ephy_bookmarks_type;
}
static void
-ephy_bookmarks_autocompletion_source_set_basic_key (EphyAutocompletionSource *source,
- const gchar *basic_key)
-{
- /* nothing to do here */
-}
-
-static void
-ephy_bookmarks_autocompletion_source_foreach (EphyAutocompletionSource *source,
- const gchar *current_text,
- EphyAutocompletionSourceForeachFunc func,
- gpointer data)
-{
- GPtrArray *children;
- int i;
- EphyBookmarks *eb = EPHY_BOOKMARKS (source);
-
- children = ephy_node_get_children (eb->priv->bookmarks);
- for (i = 0; i < children->len; i++)
- {
- EphyNode *kid;
- const char *url, *title, *keywords;
- gboolean smart_url;
-
- kid = g_ptr_array_index (children, i);
- url = ephy_node_get_property_string
- (kid, EPHY_NODE_BMK_PROP_LOCATION);
- smart_url = ephy_node_get_property_boolean
- (kid, EPHY_NODE_BMK_PROP_HAS_SMART_ADDRESS);
- title = ephy_node_get_property_string
- (kid, EPHY_NODE_BMK_PROP_TITLE);
- keywords = ephy_node_get_property_string
- (kid, EPHY_NODE_BMK_PROP_KEYWORDS);
-
- func (source, keywords, title, url, smart_url,
- !smart_url, 0, data);
- }
- ephy_node_thaw (eb->priv->bookmarks);
-}
-
-static void
-ephy_bookmarks_emit_data_changed (EphyBookmarks *eb)
-{
- g_signal_emit_by_name (eb, "data-changed");
-}
-
-static void
-ephy_bookmarks_autocompletion_source_init (EphyAutocompletionSourceIface *iface)
-{
- iface->foreach = ephy_bookmarks_autocompletion_source_foreach;
- iface->set_basic_key = ephy_bookmarks_autocompletion_source_set_basic_key;
-}
-
-static void
ephy_bookmarks_init_defaults (EphyBookmarks *eb)
{
int i;
@@ -527,7 +461,6 @@ bookmarks_changed_cb (EphyNode *node,
EphyNode *child,
EphyBookmarks *eb)
{
- ephy_bookmarks_emit_data_changed (eb);
ephy_bookmarks_save_delayed (eb, BOOKMARKS_SAVE_DELAY);
}
@@ -537,7 +470,6 @@ bookmarks_removed_cb (EphyNode *node,
guint old_index,
EphyBookmarks *eb)
{
- ephy_bookmarks_emit_data_changed (eb);
g_signal_emit (G_OBJECT (eb), ephy_bookmarks_signals[TREE_CHANGED], 0);
ephy_bookmarks_save_delayed (eb, BOOKMARKS_SAVE_DELAY);
}
@@ -715,6 +647,10 @@ ephy_bookmarks_init (EphyBookmarks *eb)
g_value_unset (&value);
ephy_node_add_child (eb->priv->keywords, eb->priv->notcategorized);
+ /* Smart bookmarks */
+ eb->priv->smartbookmarks = ephy_node_new_with_id (db, SMARTBOOKMARKS_NODE_ID);
+ ephy_node_ref (eb->priv->smartbookmarks);
+
if (ephy_node_db_load_from_file (eb->priv->db, eb->priv->xml_file,
EPHY_BOOKMARKS_XML_ROOT,
EPHY_BOOKMARKS_XML_VERSION) == FALSE)
@@ -725,8 +661,6 @@ ephy_bookmarks_init (EphyBookmarks *eb)
}
}
- ephy_bookmarks_emit_data_changed (eb);
-
ephy_setup_history_notifiers (eb);
ephy_bookmarks_update_favorites (eb);
}
@@ -775,21 +709,32 @@ ephy_bookmarks_new ()
}
static void
-update_has_smart_address (EphyNode *bmk, const char *address)
+update_has_smart_address (EphyBookmarks *bookmarks, EphyNode *bmk, const char *address)
{
+ EphyNode *smart_bmks;
gboolean smart = FALSE;
- GValue value = { 0, };
+
+ smart_bmks = bookmarks->priv->smartbookmarks;
if (address)
{
smart = strstr (address, "%s") != NULL;
}
- g_value_init (&value, G_TYPE_BOOLEAN);
- g_value_set_boolean (&value, smart);
- ephy_node_set_property (bmk, EPHY_NODE_BMK_PROP_HAS_SMART_ADDRESS,
- &value);
- g_value_unset (&value);
+ if (smart)
+ {
+ if (!ephy_node_has_child (smart_bmks, bmk))
+ {
+ ephy_node_add_child (smart_bmks, bmk);
+ }
+ }
+ else
+ {
+ if (ephy_node_has_child (smart_bmks, bmk))
+ {
+ ephy_node_add_child (smart_bmks, bmk);
+ }
+ }
}
EphyNode *
@@ -814,12 +759,11 @@ ephy_bookmarks_add (EphyBookmarks *eb,
&value);
g_value_unset (&value);
- update_has_smart_address (bm, url);
+ update_has_smart_address (eb, bm, url);
ephy_node_add_child (eb->priv->bookmarks, bm);
ephy_node_add_child (eb->priv->notcategorized, bm);
- ephy_bookmarks_emit_data_changed (eb);
g_signal_emit (G_OBJECT (eb), ephy_bookmarks_signals[TREE_CHANGED], 0);
ephy_bookmarks_save_delayed (eb, 0);
@@ -839,7 +783,7 @@ ephy_bookmarks_set_address (EphyBookmarks *eb,
&value);
g_value_unset (&value);
- update_has_smart_address (bookmark, address);
+ update_has_smart_address (eb, bookmark, address);
}
EphyNode *
@@ -1235,6 +1179,12 @@ ephy_bookmarks_unset_keyword (EphyBookmarks *eb,
}
EphyNode *
+ephy_bookmarks_get_smart_bookmarks (EphyBookmarks *eb)
+{
+ return eb->priv->smartbookmarks;
+}
+
+EphyNode *
ephy_bookmarks_get_keywords (EphyBookmarks *eb)
{
return eb->priv->keywords;
diff --git a/src/bookmarks/ephy-bookmarks.h b/src/bookmarks/ephy-bookmarks.h
index fbbc2d1f2..8f9ae5986 100644
--- a/src/bookmarks/ephy-bookmarks.h
+++ b/src/bookmarks/ephy-bookmarks.h
@@ -42,7 +42,6 @@ enum
EPHY_NODE_BMK_PROP_LOCATION = 3,
EPHY_NODE_BMK_PROP_KEYWORDS = 4,
EPHY_NODE_KEYWORD_PROP_NAME = 5,
- EPHY_NODE_BMK_PROP_HAS_SMART_ADDRESS = 9,
EPHY_NODE_BMK_PROP_ICON = 7,
EPHY_NODE_KEYWORD_PROP_PRIORITY = 8
};
@@ -127,6 +126,8 @@ EphyNode *ephy_bookmarks_get_bookmarks (EphyBookmarks *eb);
EphyNode *ephy_bookmarks_get_not_categorized (EphyBookmarks *eb);
+EphyNode *ephy_bookmarks_get_smart_bookmarks (EphyBookmarks *eb);
+
G_END_DECLS
#endif
diff --git a/src/ephy-completion-model.c b/src/ephy-completion-model.c
new file mode 100644
index 000000000..95bfe0e69
--- /dev/null
+++ b/src/ephy-completion-model.c
@@ -0,0 +1,601 @@
+/*
+ * Copyright (C) 2002 Jorn Baayen <jorn@nl.linux.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id$
+ */
+
+#include <config.h>
+
+#include "ephy-completion-model.h"
+#include "ephy-node.h"
+#include "ephy-shell.h"
+
+static void ephy_completion_model_class_init (EphyCompletionModelClass *klass);
+static void ephy_completion_model_init (EphyCompletionModel *model);
+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))
+
+struct EphyCompletionModelPrivate
+{
+ EphyNode *history;
+ EphyNode *bookmarks;
+ int stamp;
+};
+
+enum
+{
+ HISTORY_GROUP,
+ BOOKMARKS_GROUP
+};
+
+static GObjectClass *parent_class = NULL;
+
+GType
+ephy_completion_model_get_type (void)
+{
+ static GType ephy_completion_model_type = 0;
+
+ if (ephy_completion_model_type == 0)
+ {
+ static const GTypeInfo our_info =
+ {
+ sizeof (EphyCompletionModelClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) ephy_completion_model_class_init,
+ NULL,
+ NULL,
+ sizeof (EphyCompletionModel),
+ 0,
+ (GInstanceInitFunc) ephy_completion_model_init
+ };
+
+ static const GInterfaceInfo tree_model_info =
+ {
+ (GInterfaceInitFunc) ephy_completion_model_tree_model_init,
+ NULL,
+ NULL
+ };
+
+ ephy_completion_model_type = g_type_register_static (G_TYPE_OBJECT,
+ "EphyCompletionModel",
+ &our_info, 0);
+
+ g_type_add_interface_static (ephy_completion_model_type,
+ GTK_TYPE_TREE_MODEL,
+ &tree_model_info);
+ }
+
+ return ephy_completion_model_type;
+}
+
+static void
+ephy_completion_model_class_init (EphyCompletionModelClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ 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 = model->priv->stamp;
+ 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;
+ EphyHistory *history;
+
+ model->priv = EPHY_COMPLETION_MODEL_GET_PRIVATE (model);
+ model->priv->stamp = g_random_int ();
+
+ 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);
+ connect_signals (model, model->priv->bookmarks);
+}
+
+EphyCompletionModel *
+ephy_completion_model_new (void)
+{
+ EphyCompletionModel *model;
+
+ model = EPHY_COMPLETION_MODEL (g_object_new (EPHY_TYPE_COMPLETION_MODEL,
+ NULL));
+
+ g_return_val_if_fail (model->priv != NULL, NULL);
+
+ return model;
+}
+
+static int
+ephy_completion_model_get_n_columns (GtkTreeModel *tree_model)
+{
+ return N_COL;
+}
+
+static GType
+ephy_completion_model_get_column_type (GtkTreeModel *tree_model,
+ int index)
+{
+ GType type = 0;
+
+ switch (index)
+ {
+ case EPHY_COMPLETION_TEXT_COL:
+ case EPHY_COMPLETION_ACTION_COL:
+ case EPHY_COMPLETION_KEYWORDS_COL:
+ type = G_TYPE_STRING;
+ break;
+ case EPHY_COMPLETION_RELEVANCE_COL:
+ type = G_TYPE_INT;
+ break;
+ }
+
+ return type;
+}
+
+static void
+init_text_col (GValue *value, EphyNode *node, int group)
+{
+ const char *text;
+
+ switch (group)
+ {
+ case BOOKMARKS_GROUP:
+ text = ephy_node_get_property_string
+ (node, EPHY_NODE_PAGE_PROP_TITLE);
+ break;
+ case HISTORY_GROUP:
+ text = ephy_node_get_property_string
+ (node, EPHY_NODE_BMK_PROP_LOCATION);
+ break;
+
+ default:
+ text = "";
+ }
+
+ g_value_set_string (value, text);
+}
+
+static void
+init_action_col (GValue *value, EphyNode *node, int group)
+{
+ const char *text;
+
+ switch (group)
+ {
+ case BOOKMARKS_GROUP:
+ text = ephy_node_get_property_string
+ (node, EPHY_NODE_BMK_PROP_LOCATION);
+ break;
+ case HISTORY_GROUP:
+ text = ephy_node_get_property_string
+ (node, EPHY_NODE_PAGE_PROP_LOCATION);
+ break;
+ default:
+ text = "";
+ }
+
+ 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)
+{
+ if (ephy_node_has_child (model->priv->bookmarks, node))
+ {
+ return model->priv->bookmarks;
+ }
+ else
+ {
+ return model->priv->history;
+ }
+}
+
+static int
+get_node_group (EphyCompletionModel *model, EphyNode *node)
+{
+ if (ephy_node_has_child (model->priv->bookmarks, node))
+ {
+ return BOOKMARKS_GROUP;
+ }
+ else
+ {
+ return HISTORY_GROUP;
+ }
+}
+
+static EphyNode *
+get_index_root (EphyCompletionModel *model, int *index)
+{
+ int children;
+
+ children = ephy_node_get_n_children (model->priv->history);
+
+ if (*index >= children)
+ {
+ *index = *index - children;
+ return model->priv->bookmarks;
+ }
+ else
+ {
+ return model->priv->history;
+ }
+}
+
+static void
+ephy_completion_model_get_value (GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ int column,
+ GValue *value)
+{
+ int group;
+ EphyCompletionModel *model = EPHY_COMPLETION_MODEL (tree_model);
+ EphyNode *node;
+
+ g_return_if_fail (EPHY_IS_COMPLETION_MODEL (tree_model));
+ g_return_if_fail (iter != NULL);
+ g_return_if_fail (iter->stamp == model->priv->stamp);
+
+ node = iter->user_data;
+ group = get_node_group (model, node);
+
+ switch (column)
+ {
+ case EPHY_COMPLETION_TEXT_COL:
+ g_value_init (value, G_TYPE_STRING);
+ init_text_col (value, node, group);
+ break;
+ case EPHY_COMPLETION_ACTION_COL:
+ g_value_init (value, G_TYPE_STRING);
+ init_action_col (value, node, group);
+ break;
+ case EPHY_COMPLETION_KEYWORDS_COL:
+ g_value_init (value, G_TYPE_STRING);
+ init_keywords_col (value, node, group);
+ break;
+ case EPHY_COMPLETION_RELEVANCE_COL:
+ g_value_init (value, G_TYPE_INT);
+ init_relevance_col (value, node, group);
+ break;
+ }
+}
+
+static guint
+ephy_completion_model_get_flags (GtkTreeModel *tree_model)
+{
+ return 0;
+}
+
+static gboolean
+ephy_completion_model_get_iter (GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ GtkTreePath *path)
+{
+ EphyCompletionModel *model = EPHY_COMPLETION_MODEL (tree_model);
+ EphyNode *root;
+ int i;
+
+ g_return_val_if_fail (EPHY_IS_COMPLETION_MODEL (model), FALSE);
+ g_return_val_if_fail (gtk_tree_path_get_depth (path) > 0, FALSE);
+
+ i = gtk_tree_path_get_indices (path)[0];
+
+ iter->stamp = model->priv->stamp;
+
+ root = get_index_root (model, &i);
+ iter->user_data = ephy_node_get_nth_child (root, i);
+
+ if (iter->user_data == NULL)
+ {
+ iter->stamp = 0;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static GtkTreePath *
+ephy_completion_model_get_path (GtkTreeModel *tree_model,
+ GtkTreeIter *iter)
+{
+ EphyCompletionModel *model = EPHY_COMPLETION_MODEL (tree_model);
+ EphyNode *node;
+
+ g_return_val_if_fail (EPHY_IS_COMPLETION_MODEL (tree_model), NULL);
+ g_return_val_if_fail (iter != NULL, NULL);
+ g_return_val_if_fail (iter->user_data != NULL, NULL);
+ g_return_val_if_fail (iter->stamp == model->priv->stamp, NULL);
+
+ node = iter->user_data;
+
+ if (node == model->priv->history)
+ return gtk_tree_path_new ();
+
+ return get_path_real (model, node);
+}
+
+static gboolean
+ephy_completion_model_iter_next (GtkTreeModel *tree_model,
+ GtkTreeIter *iter)
+{
+ EphyCompletionModel *model = EPHY_COMPLETION_MODEL (tree_model);
+ EphyNode *node, *next, *root;
+
+ g_return_val_if_fail (iter != NULL, FALSE);
+ g_return_val_if_fail (iter->user_data != NULL, FALSE);
+ g_return_val_if_fail (iter->stamp == model->priv->stamp, FALSE);
+
+ node = iter->user_data;
+
+ if (node == model->priv->history)
+ return FALSE;
+
+ root = get_node_root (model, node);
+ next = ephy_node_get_next_child (root, node);
+ if (next == NULL && root == model->priv->history)
+ {
+ next = ephy_node_get_nth_child (model->priv->bookmarks, 0);
+ }
+
+ iter->user_data = next;
+
+ return (iter->user_data != NULL);
+}
+
+static gboolean
+ephy_completion_model_iter_children (GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ GtkTreeIter *parent)
+{
+ EphyCompletionModel *model = EPHY_COMPLETION_MODEL (tree_model);
+
+ if (parent != NULL)
+ return FALSE;
+
+ iter->stamp = model->priv->stamp;
+ iter->user_data = model->priv->history;
+
+ return TRUE;
+}
+
+static gboolean
+ephy_completion_model_iter_has_child (GtkTreeModel *tree_model,
+ GtkTreeIter *iter)
+{
+ return FALSE;
+}
+
+static int
+ephy_completion_model_iter_n_children (GtkTreeModel *tree_model,
+ GtkTreeIter *iter)
+{
+ EphyCompletionModel *model = EPHY_COMPLETION_MODEL (tree_model);
+
+ g_return_val_if_fail (EPHY_IS_COMPLETION_MODEL (tree_model), -1);
+
+ if (iter == NULL)
+ {
+ return ephy_node_get_n_children (model->priv->history) +
+ ephy_node_get_n_children (model->priv->bookmarks);
+ }
+
+ g_return_val_if_fail (model->priv->stamp == iter->stamp, -1);
+
+ return 0;
+}
+
+static gboolean
+ephy_completion_model_iter_nth_child (GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ GtkTreeIter *parent,
+ int n)
+{
+ EphyCompletionModel *model = EPHY_COMPLETION_MODEL (tree_model);
+ EphyNode *node, *root;
+
+ g_return_val_if_fail (EPHY_IS_COMPLETION_MODEL (tree_model), FALSE);
+
+ if (parent != NULL)
+ return FALSE;
+
+ root = get_index_root (model, &n);
+ node = ephy_node_get_nth_child (root, n);
+
+ if (node != NULL)
+ {
+ iter->stamp = model->priv->stamp;
+ iter->user_data = node;
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+static gboolean
+ephy_completion_model_iter_parent (GtkTreeModel *tree_model,
+ GtkTreeIter *iter,
+ GtkTreeIter *child)
+{
+ return FALSE;
+}
+
+static void
+ephy_completion_model_tree_model_init (GtkTreeModelIface *iface)
+{
+ iface->get_flags = ephy_completion_model_get_flags;
+ iface->get_iter = ephy_completion_model_get_iter;
+ iface->get_path = ephy_completion_model_get_path;
+ iface->iter_next = ephy_completion_model_iter_next;
+ iface->iter_children = ephy_completion_model_iter_children;
+ iface->iter_has_child = ephy_completion_model_iter_has_child;
+ iface->iter_n_children = ephy_completion_model_iter_n_children;
+ iface->iter_nth_child = ephy_completion_model_iter_nth_child;
+ iface->iter_parent = ephy_completion_model_iter_parent;
+ iface->get_n_columns = ephy_completion_model_get_n_columns;
+ iface->get_column_type = ephy_completion_model_get_column_type;
+ iface->get_value = ephy_completion_model_get_value;
+}
diff --git a/src/ephy-completion-model.h b/src/ephy-completion-model.h
new file mode 100644
index 000000000..ee30f595c
--- /dev/null
+++ b/src/ephy-completion-model.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2003 Marco Pesenti Gritti <marco@gnome.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef EPHY_COMPLETION_MODEL_H
+#define EPHY_COMPLETION_MODEL_H
+
+#include <gtk/gtktreemodel.h>
+
+G_BEGIN_DECLS
+
+#define EPHY_TYPE_COMPLETION_MODEL (ephy_completion_model_get_type ())
+#define EPHY_COMPLETION_MODEL(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EPHY_TYPE_COMPLETION_MODEL, EphyCompletionModel))
+#define EPHY_COMPLETION_MODEL_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EPHY_TYPE_COMPLETION_MODEL, EphyCompletionModelClass))
+#define EPHY_IS_COMPLETION_MODEL(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EPHY_TYPE_COMPLETION_MODEL))
+#define EPHY_IS_COMPLETION_MODEL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EPHY_TYPE_COMPLETION_MODEL))
+#define EPHY_COMPLETION_MODEL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EPHY_TYPE_COMPLETION_MODEL, EphyCompletionModelClass))
+
+typedef struct EphyCompletionModelPrivate EphyCompletionModelPrivate;
+
+enum
+{
+ EPHY_COMPLETION_TEXT_COL,
+ EPHY_COMPLETION_ACTION_COL,
+ EPHY_COMPLETION_KEYWORDS_COL,
+ EPHY_COMPLETION_RELEVANCE_COL,
+ N_COL
+} EphyCompletionColumn;
+
+typedef struct
+{
+ GObject parent;
+
+ EphyCompletionModelPrivate *priv;
+} EphyCompletionModel;
+
+typedef struct
+{
+ GObjectClass parent;
+} EphyCompletionModelClass;
+
+GType ephy_completion_model_get_type (void);
+
+EphyCompletionModel *ephy_completion_model_new (void);
+
+G_END_DECLS
+
+#endif /* EPHY_COMPLETION_MODEL_H */
diff --git a/src/ephy-location-action.c b/src/ephy-location-action.c
index bd18275a7..0d90e8e24 100644
--- a/src/ephy-location-action.c
+++ b/src/ephy-location-action.c
@@ -22,13 +22,20 @@
#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>
+#include <gtk/gtkentrycompletion.h>
+
#define EPHY_LOCATION_ACTION_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_LOCATION_ACTION, EphyLocationActionPrivate))
struct _EphyLocationActionPrivate
{
+ GList *actions;
char *address;
+ EphyNode *smart_bmks;
+ EphyBookmarks *bookmarks;
};
static void ephy_location_action_init (EphyLocationAction *action);
@@ -84,32 +91,48 @@ ephy_location_action_get_type (void)
}
static void
-location_url_activate_cb (EphyLocationEntry *entry,
- const char *content,
- const char *target,
- EphyLocationAction *action)
+action_activated_cb (GtkEntryCompletion *completion,
+ gint index,
+ EphyLocationAction *action)
{
- EphyBookmarks *bookmarks;
+ GtkWidget *entry;
+ char *content;
- LOG ("Location url activated, content %s target %s", content, target)
-
- bookmarks = ephy_shell_get_bookmarks (ephy_shell);
-
- if (!content)
- {
- LOG ("Go to %s", target);
- g_signal_emit (action, signals[GO_LOCATION], 0, target);
- }
- else
+ entry = gtk_entry_completion_get_entry (completion);
+ content = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1);
+ if (content)
{
+ EphyNode *node;
+ const char *smart_url;
char *url;
+ node = (EphyNode *)g_list_nth_data (action->priv->actions, index);
+ smart_url = ephy_node_get_property_string
+ (node, EPHY_NODE_BMK_PROP_LOCATION);
+ g_return_if_fail (smart_url != NULL);
+
url = ephy_bookmarks_solve_smart_url
- (bookmarks, target, content);
+ (action->priv->bookmarks, smart_url, content);
g_return_if_fail (url != NULL);
- LOG ("Go to %s", url);
+
g_signal_emit (action, signals[GO_LOCATION], 0, url);
+
g_free (url);
+ g_free (content);
+ }
+}
+
+static void
+location_url_activate_cb (EphyLocationEntry *entry,
+ EphyLocationAction *action)
+{
+ char *content;
+
+ content = gtk_editable_get_chars (GTK_EDITABLE(entry), 0, -1);
+ if (content)
+ {
+ g_signal_emit (action, signals[GO_LOCATION], 0, content);
+ g_free (content);
}
}
@@ -142,23 +165,81 @@ sync_address (GtkAction *act, GParamSpec *pspec, GtkWidget *proxy)
}
static void
+remove_completion_actions (GtkAction *action, GtkWidget *proxy)
+{
+ GtkWidget *entry;
+ GtkEntryCompletion *completion;
+ EphyLocationAction *la = EPHY_LOCATION_ACTION (action);
+ GList *l;
+
+ entry = ephy_location_entry_get_entry (EPHY_LOCATION_ENTRY (proxy));
+ completion = gtk_entry_get_completion (GTK_ENTRY (entry));
+
+ for (l = la->priv->actions; l != NULL; l = l->next)
+ {
+ int index;
+
+ index = g_list_position (la->priv->actions, l);
+ gtk_entry_completion_delete_action (completion, index);
+ }
+
+ g_signal_handlers_disconnect_by_func
+ (completion, G_CALLBACK (action_activated_cb), la);
+}
+
+static void
+add_completion_actions (GtkAction *action, GtkWidget *proxy)
+{
+ GtkWidget *entry;
+ GtkEntryCompletion *completion;
+ EphyLocationAction *la = EPHY_LOCATION_ACTION (action);
+ GList *l;
+
+ entry = ephy_location_entry_get_entry (EPHY_LOCATION_ENTRY (proxy));
+ completion = gtk_entry_get_completion (GTK_ENTRY (entry));
+
+ for (l = la->priv->actions; l != NULL; l = l->next)
+ {
+ EphyNode *bmk = l->data;
+ const char *title;
+ int index;
+
+ index = g_list_position (la->priv->actions, l);
+ title = ephy_node_get_property_string
+ (bmk, EPHY_NODE_BMK_PROP_TITLE);
+ gtk_entry_completion_insert_action_text (completion, index, (char*)title);
+ }
+
+ g_signal_connect (completion, "action_activated",
+ G_CALLBACK (action_activated_cb), la);
+}
+
+static void
connect_proxy (GtkAction *action, GtkWidget *proxy)
{
LOG ("Connect proxy")
if (EPHY_IS_LOCATION_ENTRY (proxy))
{
- EphyAutocompletion *ac;
+ EphyCompletionModel *model;
+ GtkWidget *entry;
- ac = EPHY_AUTOCOMPLETION (ephy_shell_get_autocompletion (ephy_shell));
+ 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);
- ephy_location_entry_set_autocompletion (EPHY_LOCATION_ENTRY (proxy), ac);
+ add_completion_actions (action, proxy);
sync_address (action, NULL, proxy);
g_signal_connect_object (action, "notify::address",
G_CALLBACK (sync_address), proxy, 0);
- g_signal_connect_object (proxy, "activated",
+ entry = ephy_location_entry_get_entry (EPHY_LOCATION_ENTRY (proxy));
+ g_signal_connect_object (entry, "activate",
G_CALLBACK (location_url_activate_cb),
action, 0);
g_signal_connect_object (proxy, "user_changed",
@@ -274,11 +355,97 @@ ephy_location_action_class_init (EphyLocationActionClass *class)
}
static void
+init_actions_list (EphyLocationAction *action)
+{
+ GPtrArray *children;
+ int i;
+
+ children = ephy_node_get_children (action->priv->smart_bmks);
+ for (i = 0; i < children->len; i++)
+ {
+ EphyNode *kid;
+
+ kid = g_ptr_array_index (children, i);
+
+ action->priv->actions = g_list_append
+ (action->priv->actions, kid);
+ }
+}
+
+static void
+update_actions_list (EphyLocationAction *la)
+{
+ GSList *l;
+ GtkAction *action = GTK_ACTION (la);
+
+ l = gtk_action_get_proxies (action);
+ for (; l != NULL; l = l->next)
+ {
+ remove_completion_actions (action, GTK_WIDGET (l->data));
+ }
+
+ g_list_free (la->priv->actions);
+ la->priv->actions = NULL;
+ init_actions_list (la);
+
+ l = gtk_action_get_proxies (action);
+ for (; l != NULL; l = l->next)
+ {
+ add_completion_actions (action, l->data);
+ }
+}
+
+static void
+actions_child_removed_cb (EphyNode *node,
+ EphyNode *child,
+ guint old_index,
+ EphyLocationAction *action)
+{
+ update_actions_list (action);
+}
+
+static void
+actions_child_added_cb (EphyNode *node,
+ EphyNode *child,
+ EphyLocationAction *action)
+{
+ update_actions_list (action);
+}
+
+static void
+actions_child_changed_cb (EphyNode *node,
+ EphyNode *child,
+ EphyLocationAction *action)
+{
+ update_actions_list (action);
+}
+
+static void
ephy_location_action_init (EphyLocationAction *action)
{
action->priv = EPHY_LOCATION_ACTION_GET_PRIVATE (action);
action->priv->address = g_strdup ("");
+ action->priv->actions = NULL;
+
+ action->priv->bookmarks = ephy_shell_get_bookmarks (ephy_shell);
+ action->priv->smart_bmks = ephy_bookmarks_get_smart_bookmarks
+ (action->priv->bookmarks);
+
+ init_actions_list (action);
+
+ ephy_node_signal_connect_object (action->priv->smart_bmks,
+ EPHY_NODE_CHILD_ADDED,
+ (EphyNodeCallback)actions_child_added_cb,
+ G_OBJECT (action));
+ ephy_node_signal_connect_object (action->priv->smart_bmks,
+ EPHY_NODE_CHILD_REMOVED,
+ (EphyNodeCallback)actions_child_removed_cb,
+ G_OBJECT (action));
+ ephy_node_signal_connect_object (action->priv->smart_bmks,
+ EPHY_NODE_CHILD_CHANGED,
+ (EphyNodeCallback)actions_child_changed_cb,
+ G_OBJECT (action));
}
static void
@@ -286,6 +453,8 @@ ephy_location_action_finalize (GObject *object)
{
EphyLocationAction *action = EPHY_LOCATION_ACTION (object);
+ g_list_free (action->priv->actions);
+
g_free (action->priv->address);
}
diff --git a/src/ephy-shell.c b/src/ephy-shell.c
index fa4650b61..17adce496 100644
--- a/src/ephy-shell.c
+++ b/src/ephy-shell.c
@@ -41,7 +41,6 @@
#include "session.h"
#include "downloader-view.h"
#include "ephy-toolbars-model.h"
-#include "ephy-autocompletion.h"
#include "ephy-automation.h"
#include <string.h>
@@ -71,7 +70,6 @@ struct EphyShellPrivate
{
BonoboGenericFactory *automation_factory;
Session *session;
- EphyAutocompletion *autocompletion;
EphyBookmarks *bookmarks;
EphyToolbarsModel *toolbars_model;
EggToolbarsModel *fs_toolbars_model;
@@ -308,12 +306,6 @@ ephy_shell_finalize (GObject *object)
g_object_unref (G_OBJECT (gs->priv->session));
}
- LOG ("Unref autocompletion")
- if (gs->priv->autocompletion)
- {
- g_object_unref (gs->priv->autocompletion);
- }
-
LOG ("Unref Bookmarks Editor");
if (gs->priv->bme)
{
@@ -564,31 +556,6 @@ ephy_shell_get_session (EphyShell *gs)
return G_OBJECT (gs->priv->session);
}
-GObject *
-ephy_shell_get_autocompletion (EphyShell *gs)
-{
- EphyShellPrivate *p = gs->priv;
-
- if (!p->autocompletion)
- {
- static const gchar *prefixes[] = {
- EPHY_AUTOCOMPLETION_USUAL_WEB_PREFIXES,
- NULL
- };
-
- EphyHistory *gh = ephy_embed_shell_get_global_history (EPHY_EMBED_SHELL (gs));
- EphyBookmarks *bmk = ephy_shell_get_bookmarks (gs);
- p->autocompletion = ephy_autocompletion_new ();
- ephy_autocompletion_set_prefixes (p->autocompletion, prefixes);
-
- ephy_autocompletion_add_source (p->autocompletion,
- EPHY_AUTOCOMPLETION_SOURCE (gh));
- ephy_autocompletion_add_source (p->autocompletion,
- EPHY_AUTOCOMPLETION_SOURCE (bmk));
- }
- return G_OBJECT (p->autocompletion);
-}
-
EphyBookmarks *
ephy_shell_get_bookmarks (EphyShell *gs)
{
diff --git a/src/ephy-shell.h b/src/ephy-shell.h
index 6f0f1fd10..5c6d54899 100644
--- a/src/ephy-shell.h
+++ b/src/ephy-shell.h
@@ -93,8 +93,6 @@ EphyTab *ephy_shell_new_tab (EphyShell *shell,
GObject *ephy_shell_get_session (EphyShell *gs);
-GObject *ephy_shell_get_autocompletion (EphyShell *gs);
-
EphyBookmarks *ephy_shell_get_bookmarks (EphyShell *gs);
GObject *ephy_shell_get_toolbars_model (EphyShell *gs,