aboutsummaryrefslogtreecommitdiffstats
path: root/mail/e-searching-tokenizer.c
diff options
context:
space:
mode:
authorJon Trowbridge <trow@ximian.com>2001-05-14 13:06:16 +0800
committerJon Trowbridge <trow@src.gnome.org>2001-05-14 13:06:16 +0800
commit1f52a5d0fa5edfa1c138971100df9143ef0c0f8b (patch)
tree3c779bee030140266edf46a56c6264159837fd04 /mail/e-searching-tokenizer.c
parent9953071e22306fedaf852d018e0b5416496ababb (diff)
downloadgsoc2013-evolution-1f52a5d0fa5edfa1c138971100df9143ef0c0f8b.tar
gsoc2013-evolution-1f52a5d0fa5edfa1c138971100df9143ef0c0f8b.tar.gz
gsoc2013-evolution-1f52a5d0fa5edfa1c138971100df9143ef0c0f8b.tar.bz2
gsoc2013-evolution-1f52a5d0fa5edfa1c138971100df9143ef0c0f8b.tar.lz
gsoc2013-evolution-1f52a5d0fa5edfa1c138971100df9143ef0c0f8b.tar.xz
gsoc2013-evolution-1f52a5d0fa5edfa1c138971100df9143ef0c0f8b.tar.zst
gsoc2013-evolution-1f52a5d0fa5edfa1c138971100df9143ef0c0f8b.zip
Use secondary searches here, so that we control the interference between
2001-05-14 Jon Trowbridge <trow@ximian.com> * folder-browser.c (folder_browser_config_search): Use secondary searches here, so that we control the interference between the two bits of searching UI. 2001-05-13 Jon Trowbridge <trow@ximian.com> * mail-search.c (mail_search_construct): Destroy the MailSearch dialog if the underlying MailDisplay is destroyed. I don't like the way that label in the dialog with the message subject in it looks, so I've #ifdef-ed it out for now. Center the Matches label --- it makes the dialog look more balanced, I think. (dialog_clicked_cb): Changed to reflect adjusted ESearchingTokenizer API, using primary searches. (toggled_case_cb): Use the primary search API. * e-searching-tokenizer.c: Make searching routines utf8-friendly. Rationalize how the match begin/end markup is handled; allow for begin/end markup that varies by search. Add concept of primary and secondary matching, to disentangle possible interactions between search-bar searches and search-dialog searches. svn path=/trunk/; revision=9789
Diffstat (limited to 'mail/e-searching-tokenizer.c')
-rw-r--r--mail/e-searching-tokenizer.c207
1 files changed, 150 insertions, 57 deletions
diff --git a/mail/e-searching-tokenizer.c b/mail/e-searching-tokenizer.c
index e5b3eaf195..47266fc836 100644
--- a/mail/e-searching-tokenizer.c
+++ b/mail/e-searching-tokenizer.c
@@ -67,7 +67,13 @@ typedef struct _SearchInfo SearchInfo;
struct _SearchInfo {
gchar *search;
gchar *current;
+
gboolean case_sensitive;
+ gboolean allow_space_tags_to_match_whitespace;
+
+ gint match_size_incr;
+ gchar *match_color;
+ gboolean match_bold;
};
struct _ESearchingTokenizerPrivate {
@@ -75,12 +81,11 @@ struct _ESearchingTokenizerPrivate {
SearchInfo *search;
GList *pending;
GList *trash;
- gchar **match_begin;
- gchar **match_end;
- gchar *pending_search_string;
- gboolean pending_search_string_clear;
- gboolean pending_case_sensitivity;
+ gchar *str_primary;
+ gchar *str_secondary;
+ gboolean case_sensitive_primary;
+ gboolean case_sensitive_secondary;
};
/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/
@@ -93,6 +98,12 @@ search_info_new (void)
si = g_new0 (SearchInfo, 1);
si->case_sensitive = FALSE;
+ si->match_size_incr = 1;
+ si->match_color = g_strdup ("red");
+ si->match_bold = FALSE;
+
+ si->allow_space_tags_to_match_whitespace = TRUE;
+
return si;
}
@@ -101,6 +112,7 @@ search_info_free (SearchInfo *si)
{
if (si) {
g_free (si->search);
+ g_free (si->match_color);
g_free (si);
}
}
@@ -131,12 +143,49 @@ search_info_set_string (SearchInfo *si, const gchar *str)
}
static void
-search_info_reset (SearchInfo *si)
+search_info_set_case_sensitivity (SearchInfo *si, gboolean flag)
+{
+ g_return_if_fail (si);
+
+ si->case_sensitive = flag;
+}
+
+static void
+search_info_set_match_size_increase (SearchInfo *si, gint incr)
+{
+ g_return_if_fail (si);
+ g_return_if_fail (incr >= 0);
+
+ si->match_size_incr = incr;
+}
+
+static void
+search_info_set_match_color (SearchInfo *si, const gchar *color)
{
g_return_if_fail (si);
+
+ g_free (si->match_color);
+ si->match_color = g_strdup (color);
+}
+
+static void
+search_info_set_match_bold (SearchInfo *si, gboolean flag)
+{
+ g_return_if_fail (si);
+
+ si->match_bold = flag;
+}
+
+static void
+search_info_reset (SearchInfo *si)
+{
+ if (si == NULL)
+ return;
si->current = NULL;
}
+/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
+
static const gchar *
find_whole (SearchInfo *si, const gchar *haystack, const gchar *needle)
{
@@ -313,7 +362,8 @@ search_info_compare (SearchInfo *si, const gchar *token, gint *start_pos, gint *
}
/* "Space tags" only match whitespace in our ongoing match. */
- if (g_unichar_isspace (g_utf8_get_char (si->current))) {
+ if (si->allow_space_tags_to_match_whitespace
+ && g_unichar_isspace (g_utf8_get_char (si->current))) {
for (i=0; space_tags[i]; ++i) {
if (tag_match (token, space_tags[i])) {
si->current = g_utf8_next_char (si->current);
@@ -326,8 +376,6 @@ search_info_compare (SearchInfo *si, const gchar *token, gint *start_pos, gint *
return MATCH_FAILED;
}
-
-
s = find_partial (si, token, si->current);
if (s) {
if (start_pos)
@@ -360,8 +408,8 @@ e_searching_tokenizer_cleanup (ESearchingTokenizer *st)
}
if (st->priv->pending) {
- //g_list_foreach (st->priv->pending, (GFunc) g_free, NULL);
- //g_list_free (st->priv->pending);
+ g_list_foreach (st->priv->pending, (GFunc) g_free, NULL);
+ g_list_free (st->priv->pending);
st->priv->pending = NULL;
}
}
@@ -375,8 +423,8 @@ e_searching_tokenizer_destroy (GtkObject *obj)
search_info_free (st->priv->search);
- g_strfreev (st->priv->match_begin);
- g_strfreev (st->priv->match_end);
+ g_free (st->priv->str_primary);
+ g_free (st->priv->str_secondary);
g_free (st->priv);
st->priv = NULL;
@@ -418,13 +466,6 @@ static void
e_searching_tokenizer_init (ESearchingTokenizer *st)
{
st->priv = g_new0 (struct _ESearchingTokenizerPrivate, 1);
-
- /* For now, hard coded match markup. */
- st->priv->match_begin = g_new0 (gchar *, 2);
- st->priv->match_begin[0] = g_strdup_printf ("%c<font color=red size=+1>", TAG_ESCAPE);
-
- st->priv->match_end = g_new0 (gchar *, 2);
- st->priv->match_end[0] = g_strdup_printf ("%c</font>", TAG_ESCAPE);
}
GtkType
@@ -493,19 +534,37 @@ add_pending (ESearchingTokenizer *st, gchar *tok)
}
static void
-add_pending_match_begin (ESearchingTokenizer *st)
+add_pending_match_begin (ESearchingTokenizer *st, SearchInfo *si)
{
- gint i;
- for (i=0; st->priv->match_begin[i]; ++i)
- add_pending (st, g_strdup (st->priv->match_begin[i]));
+ gchar *size_str = NULL;
+ gchar *color_str= NULL;
+
+ if (si->match_size_incr > 0)
+ size_str = g_strdup_printf (" size=+%d", si->match_size_incr);
+ if (si->match_color)
+ color_str = g_strdup_printf (" color=%s", si->match_color);
+
+ if (size_str || color_str)
+ add_pending (st, g_strdup_printf ("%c<font%s%s>",
+ TAG_ESCAPE,
+ size_str ? size_str : "",
+ color_str ? color_str : ""));
+
+ g_free (size_str);
+ g_free (color_str);
+
+ if (si->match_bold)
+ add_pending (st, g_strdup_printf ("%c<b>", TAG_ESCAPE));
}
static void
-add_pending_match_end (ESearchingTokenizer *st)
+add_pending_match_end (ESearchingTokenizer *st, SearchInfo *si)
{
- gint i;
- for (i=0; st->priv->match_end[i]; ++i)
- add_pending (st, g_strdup (st->priv->match_end[i]));
+ if (si->match_bold)
+ add_pending (st, g_strdup_printf ("%c</b>", TAG_ESCAPE));
+
+ if (si->match_size_incr > 0 || si->match_color)
+ add_pending (st, g_strdup_printf ("%c</font>", TAG_ESCAPE));
}
static void
@@ -528,7 +587,7 @@ get_next_token (ESearchingTokenizer *st)
* the appropriate tokens.
*/
static GList *
-queue_matched (ESearchingTokenizer *st, GList *q)
+queue_matched (ESearchingTokenizer *st, SearchInfo *si, GList *q)
{
GList *qh = q;
gboolean post_start = FALSE;
@@ -536,18 +595,18 @@ queue_matched (ESearchingTokenizer *st, GList *q)
while (q != NULL) {
GList *q_next = g_list_next (q);
if (!strcmp ((gchar *) q->data, START_MAGIC)) {
- add_pending_match_begin (st);
+ add_pending_match_begin (st, si);
post_start = TRUE;
} else if (!strcmp ((gchar *) q->data, END_MAGIC)) {
- add_pending_match_end (st);
+ add_pending_match_end (st, si);
q_next = NULL;
} else {
gboolean is_tag = *((gchar *)q->data) == TAG_ESCAPE;
if (is_tag && post_start)
- add_pending_match_end (st);
+ add_pending_match_end (st, si);
add_pending (st, g_strdup ((gchar *) q->data));
if (is_tag && post_start)
- add_pending_match_begin (st);
+ add_pending_match_begin (st, si);
}
qh = g_list_remove_link (qh, q);
g_list_free_1 (q);
@@ -651,9 +710,9 @@ get_pending_tokens (ESearchingTokenizer *st)
if (start_pos != 0)
add_pending (st, g_strndup (token, start_pos));
- add_pending_match_begin (st);
+ add_pending_match_begin (st, st->priv->search);
add_pending (st, g_strndup (token+start_pos, end_pos-start_pos));
- add_pending_match_end (st);
+ add_pending_match_end (st, st->priv->search);
if (*(token+end_pos)) {
queue->data = g_strdup (token+end_pos);
add_to_trash (st, (gchar *) queue->data);
@@ -705,7 +764,7 @@ get_pending_tokens (ESearchingTokenizer *st)
add_to_trash (st, s3);
queue = g_list_remove_link (queue, q);
- queue = queue_matched (st, queue);
+ queue = queue_matched (st, st->priv->search, queue);
matched (st);
@@ -744,29 +803,42 @@ static void
e_searching_tokenizer_begin (HTMLTokenizer *t, gchar *content_type)
{
ESearchingTokenizer *st = E_SEARCHING_TOKENIZER (t);
+ SearchInfo *si;
+
+ if (st->priv->search == NULL && (st->priv->str_primary || st->priv->str_secondary)) {
+ st->priv->search = search_info_new ();
+ }
+ si = st->priv->search;
+
- if (st->priv->pending_search_string) {
+ if (st->priv->str_primary) {
- if (st->priv->search == NULL)
- st->priv->search = search_info_new ();
+ search_info_set_string (si, st->priv->str_primary);
+ search_info_set_case_sensitivity (si, st->priv->case_sensitive_primary);
- search_info_set_string (st->priv->search, st->priv->pending_search_string);
- g_free (st->priv->pending_search_string);
- st->priv->pending_search_string = NULL;
+ search_info_set_match_color (si, "red");
+ search_info_set_match_size_increase (si, 1);
+ search_info_set_match_bold (si, TRUE);
- } else if (st->priv->pending_search_string_clear) {
+ } else if (st->priv->str_secondary) {
+ search_info_set_string (si, st->priv->str_secondary);
+ search_info_set_case_sensitivity (si, st->priv->case_sensitive_secondary);
+
+ search_info_set_match_color (si, "purple");
+ search_info_set_match_size_increase (si, 1);
+ search_info_set_match_bold (si, TRUE);
+
+ } else {
+
search_info_free (st->priv->search);
st->priv->search = NULL;
- st->priv->pending_search_string_clear = FALSE;
- }
- if (st->priv->search) {
- st->priv->search->case_sensitive = st->priv->pending_case_sensitivity;
}
e_searching_tokenizer_cleanup (st);
search_info_reset (st->priv->search);
+
st->priv->match_count = 0;
HTML_TOKENIZER_CLASS (parent_class)->begin (t, content_type);
@@ -855,30 +927,51 @@ only_whitespace (const gchar *p)
}
void
-e_searching_tokenizer_set_search_string (ESearchingTokenizer *st, const gchar *search_str)
+e_searching_tokenizer_set_primary_search_string (ESearchingTokenizer *st, const gchar *search_str)
{
g_return_if_fail (st && E_IS_SEARCHING_TOKENIZER (st));
- if (search_str == NULL
- || !g_utf8_validate (search_str, -1, NULL)
- || only_whitespace (search_str)) {
+ g_free (st->priv->str_primary);
+ st->priv->str_primary = NULL;
- st->priv->pending_search_string_clear = TRUE;
+ if (search_str != NULL
+ && g_utf8_validate (search_str, -1, NULL)
+ && !only_whitespace (search_str)) {
- } else {
+ st->priv->str_primary = g_strdup (search_str);
+ }
+}
+
+void
+e_searching_tokenizer_set_primary_case_sensitivity (ESearchingTokenizer *st, gboolean is_case_sensitive)
+{
+ g_return_if_fail (st && E_IS_SEARCHING_TOKENIZER (st));
+
+ st->priv->case_sensitive_primary = is_case_sensitive;
+}
+
+void
+e_searching_tokenizer_set_secondary_search_string (ESearchingTokenizer *st, const gchar *search_str)
+{
+ g_return_if_fail (st && E_IS_SEARCHING_TOKENIZER (st));
- st->priv->pending_search_string_clear = FALSE;
- st->priv->pending_search_string = g_strdup (search_str);
+ g_free (st->priv->str_secondary);
+ st->priv->str_secondary = NULL;
+ if (search_str != NULL
+ && g_utf8_validate (search_str, -1, NULL)
+ && !only_whitespace (search_str)) {
+
+ st->priv->str_secondary = g_strdup (search_str);
}
}
void
-e_searching_tokenizer_set_case_sensitivity (ESearchingTokenizer *st, gboolean is_case_sensitive)
+e_searching_tokenizer_set_secondary_case_sensitivity (ESearchingTokenizer *st, gboolean is_case_sensitive)
{
g_return_if_fail (st && E_IS_SEARCHING_TOKENIZER (st));
- st->priv->pending_case_sensitivity = is_case_sensitive;
+ st->priv->case_sensitive_secondary = is_case_sensitive;
}
gint