diff options
author | Diego Escalante Urrelo <diegoe@src.gnome.org> | 2008-08-15 06:47:39 +0800 |
---|---|---|
committer | Diego Escalante Urrelo <diegoe@src.gnome.org> | 2008-08-15 06:47:39 +0800 |
commit | aefbb7f4a30188b281becee9d61b4b519c625a9f (patch) | |
tree | 76bb433a45c34fa885bb8398e96741bfddfefc88 | |
parent | 82a8ea1c5dbe7e892763d1f7395fe7d69c7a485d (diff) | |
download | gsoc2013-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.c | 52 | ||||
-rw-r--r-- | lib/widgets/ephy-location-entry.h | 9 | ||||
-rw-r--r-- | src/ephy-location-action.c | 135 |
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); |