aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDiego Escalante Urrelo <diegoe@src.gnome.org>2008-08-15 06:47:39 +0800
committerDiego Escalante Urrelo <diegoe@src.gnome.org>2008-08-15 06:47:39 +0800
commitaefbb7f4a30188b281becee9d61b4b519c625a9f (patch)
tree76bb433a45c34fa885bb8398e96741bfddfefc88
parent82a8ea1c5dbe7e892763d1f7395fe7d69c7a485d (diff)
downloadgsoc2013-epiphany-aefbb7f4a30188b281becee9d61b4b519c625a9f.tar.gz
gsoc2013-epiphany-aefbb7f4a30188b281becee9d61b4b519c625a9f.tar.zst
gsoc2013-epiphany-aefbb7f4a30188b281becee9d61b4b519c625a9f.zip
Port the location bar to use GRegex.
Use a simple regex matching the input text, implements the same behaviour of the current bar, plus: - substring suggestions (closes: #151932) - unicode support (closes: #343906) - diacritics in topic keywords (closes: #328162) - completion on history items titles (closes: #534218) Also, of course, closes: #517960 - port the url bar to GRegex. svn path=/trunk/; revision=8419
-rw-r--r--lib/widgets/ephy-location-entry.c52
-rw-r--r--lib/widgets/ephy-location-entry.h9
-rw-r--r--src/ephy-location-action.c135
3 files changed, 92 insertions, 104 deletions
diff --git a/lib/widgets/ephy-location-entry.c b/lib/widgets/ephy-location-entry.c
index 5773ddaf5..6c3944e2c 100644
--- a/lib/widgets/ephy-location-entry.c
+++ b/lib/widgets/ephy-location-entry.c
@@ -54,6 +54,7 @@ struct _EphyLocationEntryPrivate
GdkColor secure_fg_colour;
GtkCellRenderer *extracell;
+ GRegex *regex;
char *before_completion;
char *saved_text;
@@ -214,6 +215,12 @@ ephy_location_entry_finalize (GObject *object)
{
g_object_unref (priv->favicon);
}
+
+ if (priv->regex)
+ {
+ g_regex_unref (priv->regex);
+ priv->regex = NULL;
+ }
parent_class->finalize (object);
}
@@ -328,6 +335,8 @@ editable_changed_cb (GtkEditable *editable,
EphyLocationEntry *entry)
{
EphyLocationEntryPrivate *priv = entry->priv;
+ const char *text;
+ char *pattern;
update_address_state (entry);
@@ -338,6 +347,25 @@ editable_changed_cb (GtkEditable *editable,
priv->user_changed = TRUE;
priv->can_redo = FALSE;
}
+
+ if (priv->regex)
+ {
+ g_regex_unref (priv->regex);
+ priv->regex = NULL;
+ }
+
+ text = gtk_entry_get_text (GTK_ENTRY (editable));
+
+ if (g_str_has_prefix (text, "re:"))
+ pattern = g_strdup (text+3);
+ else
+ pattern = g_regex_escape_string (text, -1);
+
+ priv->regex = g_regex_new (pattern,
+ G_REGEX_CASELESS | G_REGEX_OPTIMIZE,
+ G_REGEX_MATCH_NOTEMPTY, NULL);
+
+ g_free (pattern);
update_favicon (entry);
@@ -499,7 +527,7 @@ entry_drag_motion_cb (GtkWidget *widget,
{
g_signal_stop_emission_by_name (widget, "drag_motion");
}
-
+
return FALSE;
}
@@ -908,7 +936,8 @@ ephy_location_entry_init (EphyLocationEntry *le)
p->user_changed = FALSE;
p->block_update = FALSE;
p->saved_text = NULL;
-
+ p->regex = NULL;
+
ephy_location_entry_construct_contents (le);
gtk_tool_item_set_expand (GTK_TOOL_ITEM (le), TRUE);
@@ -932,8 +961,8 @@ cursor_on_match_cb (GtkEntryCompletion *completion,
gtk_tree_model_get (model, iter,
le->priv->url_col,
&item, -1);
-
entry = gtk_entry_completion_get_entry (completion);
+
gtk_entry_set_text (GTK_ENTRY (entry), item);
gtk_editable_set_position (GTK_EDITABLE (entry), -1);
@@ -972,15 +1001,16 @@ extracell_data_func (GtkCellLayout *cell_layout,
}
void
-ephy_location_entry_set_completion_func (EphyLocationEntry *le,
- GtkEntryCompletionMatchFunc completion_func,
- gpointer user_data)
+ephy_location_entry_set_match_func (EphyLocationEntry *le,
+ GtkEntryCompletionMatchFunc match_func,
+ gpointer user_data,
+ GDestroyNotify notify)
{
EphyLocationEntryPrivate *priv = le->priv;
GtkEntryCompletion *completion;
completion = gtk_entry_get_completion (GTK_ENTRY (priv->icon_entry->entry));
- gtk_entry_completion_set_match_func (completion, completion_func, user_data, NULL);
+ gtk_entry_completion_set_match_func (completion, match_func, user_data, notify);
}
void
@@ -1298,3 +1328,11 @@ ephy_location_entry_set_lock_tooltip (EphyLocationEntry *entry,
gtk_widget_set_tooltip_text (priv->lock_ebox, tooltip);
}
+
+GRegex *
+ephy_location_entry_get_regex (EphyLocationEntry *entry)
+{
+ EphyLocationEntryPrivate *priv = entry->priv;
+
+ return priv->regex;
+}
diff --git a/lib/widgets/ephy-location-entry.h b/lib/widgets/ephy-location-entry.h
index a949d949b..3c558dfa5 100644
--- a/lib/widgets/ephy-location-entry.h
+++ b/lib/widgets/ephy-location-entry.h
@@ -82,9 +82,10 @@ void ephy_location_entry_set_location (EphyLocationEntry *le,
const char *address,
const char *typed_address);
-void ephy_location_entry_set_completion_func (EphyLocationEntry *le,
- GtkEntryCompletionMatchFunc completion_func,
- gpointer user_data);
+void ephy_location_entry_set_match_func (EphyLocationEntry *le,
+ GtkEntryCompletionMatchFunc match_func,
+ gpointer user_data,
+ GDestroyNotify notify);
const char *ephy_location_entry_get_location (EphyLocationEntry *le);
@@ -92,6 +93,8 @@ gboolean ephy_location_entry_get_can_undo (EphyLocationEntry *le);
gboolean ephy_location_entry_get_can_redo (EphyLocationEntry *entry);
+GRegex * ephy_location_entry_get_regex (EphyLocationEntry *entry);
+
gboolean ephy_location_entry_reset (EphyLocationEntry *entry);
void ephy_location_entry_undo_reset (EphyLocationEntry *entry);
diff --git a/src/ephy-location-action.c b/src/ephy-location-action.c
index 5121a631d..1fdace52d 100644
--- a/src/ephy-location-action.c
+++ b/src/ephy-location-action.c
@@ -86,73 +86,35 @@ static guint signals[LAST_SIGNAL];
G_DEFINE_TYPE (EphyLocationAction, ephy_location_action, EPHY_TYPE_LINK_ACTION)
-static const struct
-{
- const char *prefix;
- int len;
-}
-web_prefixes [] =
-{
- { "http://www.", 11 },
- { "http://ftp.", 11 },
- { "http://", 7 },
- { "https://www.", 12 },
- { "https://", 8 },
- { "ftp://", 6},
- { "ftp://ftp.", 10},
- { "www.", 4 },
- { "ftp.", 4}
-};
-
-
-static gboolean
-keyword_match (const char *list,
- const char *keyword)
+typedef struct
{
- const char *p;
- gsize keyword_len;
-
- p = list;
- keyword_len = strlen (keyword);
+ EphyLocationEntry *entry;
+ EphyLocationAction *action;
+} LocationEntryAction;
- while (*p)
- {
- int i;
-
- for (i = 0; i < keyword_len; i++)
- {
- if (p[i] != keyword[i])
- {
- goto next_token;
- }
- }
-
- return TRUE;
-
- next_token:
-
- while (*p && !g_ascii_ispunct(*p) && !g_ascii_isspace(*p)) p++;
- while (*p && (g_ascii_ispunct(*p) || g_ascii_isspace(*p))) p++;
- }
-
- return FALSE;
+static void
+destroy_match_func (gpointer data)
+{
+ g_slice_free (LocationEntryAction, data);
}
static gboolean
-completion_func (GtkEntryCompletion *completion,
- const char *key,
- GtkTreeIter *iter,
- gpointer data)
+match_func (GtkEntryCompletion *completion,
+ const char *key,
+ GtkTreeIter *iter,
+ gpointer data)
{
- int i, len_key, len_prefix;
char *item = NULL;
char *url = NULL;
char *keywords = NULL;
+ char *extra = NULL;
+
gboolean ret = FALSE;
- GtkTreeModel *model;
EphyLocationActionPrivate *priv;
-
- priv = EPHY_LOCATION_ACTION (data)->priv;
+ GtkTreeModel *model;
+ GRegex *regex;
+
+ priv = EPHY_LOCATION_ACTION (((LocationEntryAction *) data)->action)->priv;
model = gtk_entry_completion_get_model (completion);
@@ -160,45 +122,24 @@ completion_func (GtkEntryCompletion *completion,
EPHY_COMPLETION_TEXT_COL, &item,
EPHY_COMPLETION_URL_COL, &url,
EPHY_COMPLETION_KEYWORDS_COL, &keywords,
+ EPHY_COMPLETION_EXTRA_COL, &extra,
-1);
-
- len_key = strlen (key);
- if (!strncasecmp (key, item, len_key))
- {
- ret = TRUE;
- }
- else if (keyword_match (keywords, key))
- {
- ret = TRUE;
- }
- else if (!strncasecmp (key, url, len_key))
- {
- ret = TRUE;
- }
- else
- {
- for (i = 0; i < G_N_ELEMENTS (web_prefixes); i++)
- {
- len_prefix = web_prefixes[i].len;
- if (!strncmp (web_prefixes[i].prefix, item, len_prefix) &&
- !strncasecmp (key, item + len_prefix, len_key))
- {
- ret = TRUE;
- break;
- }
- else if (!strncmp (web_prefixes[i].prefix, url, len_prefix) &&
- !strncasecmp (key, url + len_prefix, len_key))
- {
- ret = TRUE;
- break;
- }
-
- }
- }
+ if (!key)
+ return FALSE;
+
+ regex = ephy_location_entry_get_regex (((LocationEntryAction *) data)->entry);
+
+ ret = (g_regex_match (regex, item, G_REGEX_MATCH_NOTEMPTY, NULL)
+ || g_regex_match (regex, url, G_REGEX_MATCH_NOTEMPTY, NULL)
+ || g_regex_match (regex, keywords, G_REGEX_MATCH_NOTEMPTY, NULL)
+ || (extra && g_regex_match (regex, extra, G_REGEX_MATCH_NOTEMPTY, NULL))
+ );
+
g_free (item);
g_free (url);
g_free (keywords);
+ g_free (extra);
return ret;
}
@@ -496,6 +437,7 @@ connect_proxy (GtkAction *action, GtkWidget *proxy)
EphyLocationEntry *lentry = EPHY_LOCATION_ENTRY (proxy);
EphyCompletionModel *model;
GtkWidget *entry;
+ LocationEntryAction *lea;
model = ephy_completion_model_new ();
ephy_location_entry_set_completion (EPHY_LOCATION_ENTRY (proxy),
@@ -507,10 +449,15 @@ connect_proxy (GtkAction *action, GtkWidget *proxy)
EPHY_COMPLETION_URL_COL,
EPHY_COMPLETION_EXTRA_COL,
EPHY_COMPLETION_FAVICON_COL);
-
- ephy_location_entry_set_completion_func (EPHY_LOCATION_ENTRY (proxy),
- completion_func,
- EPHY_LOCATION_ACTION (action));
+
+ lea = g_slice_new (LocationEntryAction);
+ lea->entry = EPHY_LOCATION_ENTRY (proxy);
+ lea->action = EPHY_LOCATION_ACTION (action);
+
+ ephy_location_entry_set_match_func (EPHY_LOCATION_ENTRY (proxy),
+ match_func,
+ lea,
+ destroy_match_func);
add_completion_actions (action, proxy);