From 85d0142d21286ce87cd5f6c3d1e2f71aa994151f Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Mon, 2 Mar 2009 03:14:42 +0000 Subject: Move text searching UI into a new EMailSearchBar widget. svn path=/branches/kill-bonobo/; revision=37351 --- mail/e-searching-tokenizer.c | 633 ++++++++++++++++++++----------------------- 1 file changed, 287 insertions(+), 346 deletions(-) (limited to 'mail/e-searching-tokenizer.c') diff --git a/mail/e-searching-tokenizer.c b/mail/e-searching-tokenizer.c index 172a126c92..129aa0539b 100644 --- a/mail/e-searching-tokenizer.c +++ b/mail/e-searching-tokenizer.c @@ -38,77 +38,17 @@ #define d(x) +#define E_SEARCHING_TOKENIZER_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_SEARCHING_TOKENIZER, ESearchingTokenizerPrivate)) + enum { MATCH_SIGNAL, LAST_SIGNAL }; -static guint signals[LAST_SIGNAL] = { 0, }; - -static void e_searching_tokenizer_begin (HTMLTokenizer *, const char *); -static void e_searching_tokenizer_end (HTMLTokenizer *); -static char *e_searching_tokenizer_peek_token (HTMLTokenizer *); -static char *e_searching_tokenizer_next_token (HTMLTokenizer *); -static gboolean e_searching_tokenizer_has_more (HTMLTokenizer *); - -static HTMLTokenizer *e_searching_tokenizer_clone (HTMLTokenizer *); - -/* - static const gchar *space_tags[] = { "br", NULL };*/ - -static HTMLTokenizerClass *parent_class = NULL; - -/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/ - -/* ??? -typedef struct _SharedState SharedState; -struct _SharedState { - gint refs; - gchar *str_primary; - gchar *str_secondary; - gboolean case_sensitive_primary; - gboolean case_sensitive_secondary; -}; -*/ - -/* ********************************************************************** */ - - -#if 0 -static SharedState * -shared_state_new (void) -{ - SharedState *shared = g_new0 (SharedState, 1); - shared->refs = 1; - return shared; -} - -static void -shared_state_ref (SharedState *shared) -{ - g_return_if_fail (shared != NULL); - g_return_if_fail (shared->refs > 0); - ++shared->refs; -} - -static void -shared_state_unref (SharedState *shared) -{ - if (shared) { - g_return_if_fail (shared->refs > 0); - --shared->refs; - if (shared->refs == 0) { - g_free (shared->str_primary); - g_free (shared->str_secondary); - g_free (shared); - } - } -} -#endif - -/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/ - -/* ********************************************************************** */ +static gpointer parent_class; +static guint signals[LAST_SIGNAL]; /* Utility functions */ @@ -184,7 +124,7 @@ ignore_tag (const char *tag) *out = 0; for (i=0;i %p\n", p, m->ch, m->match); if (m->match) - dump_trie(m->match, d+1); + dump_trie (m->match, d+1); m = m->next; } } @@ -247,7 +187,7 @@ dump_trie(struct _state *s, int d) for a neat demo */ static inline struct _match * -g(struct _state *q, guint32 c) +g (struct _state *q, guint32 c) { struct _match *m = q->matches; @@ -258,7 +198,7 @@ g(struct _state *q, guint32 c) } static struct _trie * -build_trie(int nocase, int len, unsigned char **words) +build_trie (int nocase, int len, unsigned char **words) { struct _state *q, *qt, *r; const unsigned char *word; @@ -275,8 +215,8 @@ build_trie(int nocase, int len, unsigned char **words) trie->root.fail = NULL; trie->root.next = NULL; - trie->state_chunks = e_memchunk_new(8, sizeof(struct _state)); - trie->match_chunks = e_memchunk_new(8, sizeof(struct _match)); + trie->state_chunks = e_memchunk_new (8, sizeof(struct _state)); + trie->match_chunks = e_memchunk_new (8, sizeof(struct _match)); /* This will correspond to the length of the longest pattern */ state_depth_size = 0; @@ -294,8 +234,8 @@ build_trie(int nocase, int len, unsigned char **words) depth = 0; while ((c = camel_utf8_getc (&word))) { if (nocase) - c = g_unichar_tolower(c); - m = g(q, c); + c = g_unichar_tolower (c); + m = g (q, c); if (m == NULL) { m = e_memchunk_alloc(trie->match_chunks); m->ch = c; @@ -324,7 +264,7 @@ build_trie(int nocase, int len, unsigned char **words) } d(printf("Dumping trie:\n")); - d(dump_trie(&trie->root, 0)); + d(dump_trie (&trie->root, 0)); /* Step 2: Build failure graph */ @@ -340,14 +280,14 @@ build_trie(int nocase, int len, unsigned char **words) c = m->ch; qt = m->match; r = q->fail; - while (r && (n = g(r, c)) == NULL) + while (r && (n = g (r, c)) == NULL) r = r->fail; if (r != NULL) { qt->fail = n->match; if (qt->fail->final > qt->final) qt->final = qt->fail->final; } else { - if ((n = g(&trie->root, c))) + if ((n = g (&trie->root, c))) qt->fail = n->match; else qt->fail = &trie->root; @@ -358,10 +298,10 @@ build_trie(int nocase, int len, unsigned char **words) } } - d(printf("After failure analysis\n")); - d(dump_trie(&trie->root, 0)); + d (printf("After failure analysis\n")); + d (dump_trie (&trie->root, 0)); - g_free(state_depth); + g_free (state_depth); trie->max_depth = state_depth_size; @@ -369,12 +309,12 @@ build_trie(int nocase, int len, unsigned char **words) } static void -free_trie(struct _trie *t) +free_trie (struct _trie *t) { e_memchunk_destroy(t->match_chunks); e_memchunk_destroy(t->state_chunks); - g_free(t); + g_free (t); } /* ********************************************************************** */ @@ -444,10 +384,10 @@ searcher_new (int flags, int argc, unsigned char **argv, const char *tags, const s = g_malloc(sizeof(*s)); - s->t = build_trie((flags&SEARCH_CASE) == 0, argc, argv); + s->t = build_trie ((flags&SEARCH_CASE) == 0, argc, argv); s->words = argc; - s->tags = g_strdup(tags); - s->tage = g_strdup(tage); + s->tags = g_strdup (tags); + s->tage = g_strdup (tage); s->flags = flags; s->state = &s->t->root; s->matchcount = 0; @@ -476,20 +416,20 @@ searcher_new (int flags, int argc, unsigned char **argv, const char *tags, const } static void -searcher_free(struct _searcher *s) +searcher_free (struct _searcher *s) { struct _token *t; - while ((t = (struct _token *)e_dlist_remhead(&s->input))) - g_free(t); - while ((t = (struct _token *)e_dlist_remhead(&s->output))) - g_free(t); - g_free(s->tags); - g_free(s->tage); - g_free(s->last); - g_free(s->submatches); - free_trie(s->t); - g_free(s); + while ((t = (struct _token *)e_dlist_remhead (&s->input))) + g_free (t); + while ((t = (struct _token *)e_dlist_remhead (&s->output))) + g_free (t); + g_free (s->tags); + g_free (s->tage); + g_free (s->last); + g_free (s->submatches); + free_trie (s->t); + g_free (s); } static struct _token * append_token(EDList *list, const char *tok, int len) @@ -507,7 +447,7 @@ append_token(EDList *list, const char *tok, int len) return token; } -#define free_token(x) (g_free(x)) +#define free_token(x) (g_free (x)) static void output_token(struct _searcher *s, struct _token *token) @@ -517,10 +457,10 @@ output_token(struct _searcher *s, struct _token *token) if (token->tok[0] == TAG_ESCAPE) { if (token->offset >= s->offout) { - d(printf("moving tag token '%s' from input to output\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok)); + d (printf("moving tag token '%s' from input to output\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok)); e_dlist_addtail(&s->output, (EDListNode *)token); } else { - d(printf("discarding tag token '%s' from input\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok)); + d (printf("discarding tag token '%s' from input\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok)); free_token(token); } } else { @@ -529,12 +469,12 @@ output_token(struct _searcher *s, struct _token *token) if (left > 0) { pre = s->offout - token->offset; if (pre>0) - memmove(token->tok, token->tok+pre, left+1); - d(printf("adding partial remaining/failed '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok)); + memmove (token->tok, token->tok+pre, left+1); + d (printf("adding partial remaining/failed '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok)); s->offout = offend; e_dlist_addtail(&s->output, (EDListNode *)token); } else { - d(printf("discarding whole token '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok)); + d (printf("discarding whole token '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok)); free_token(token); } } @@ -563,30 +503,30 @@ output_match(struct _searcher *s, unsigned int start, unsigned int end) struct _token *starttoken, *endtoken; char b[8]; - d(printf("output match: %d-%d at %d\n", start, end, s->offout)); + d (printf("output match: %d-%d at %d\n", start, end, s->offout)); starttoken = find_token(s, start); endtoken = find_token(s, end); if (starttoken == NULL || endtoken == NULL) { - d(printf("Cannot find match history for match %d-%d\n", start, end)); + d (printf("Cannot find match history for match %d-%d\n", start, end)); return; } - d(printf("start in token '%s'\n", starttoken->tok[0]==TAG_ESCAPE?starttoken->tok+1:starttoken->tok)); - d(printf("end in token '%s'\n", endtoken->tok[0]==TAG_ESCAPE?endtoken->tok+1:endtoken->tok)); + d (printf("start in token '%s'\n", starttoken->tok[0]==TAG_ESCAPE?starttoken->tok+1:starttoken->tok)); + d (printf("end in token '%s'\n", endtoken->tok[0]==TAG_ESCAPE?endtoken->tok+1:endtoken->tok)); /* output pending stuff that didn't match afterall */ while ((struct _token *)s->input.head != starttoken) { - token = (struct _token *)e_dlist_remhead(&s->input); - d(printf("appending failed match '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok)); + token = (struct _token *)e_dlist_remhead (&s->input); + d (printf("appending failed match '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok)); output_token(s, token); } /* output any pre-match text */ if (s->offout < start) { token = append_token(&s->output, starttoken->tok + (s->offout-starttoken->offset), start-s->offout); - d(printf("adding pre-match text '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok)); + d (printf("adding pre-match text '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok)); s->offout = start; } @@ -598,11 +538,11 @@ output_match(struct _searcher *s, unsigned int start, unsigned int end) if (s->tags) append_token(&s->output, s->tags, -1); - /* output match node(s) */ + /* output match node (s) */ if (starttoken != endtoken) { while ((struct _token *)s->input.head != endtoken) { - token = (struct _token *)e_dlist_remhead(&s->input); - d(printf("appending (partial) match node (head) '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok)); + token = (struct _token *)e_dlist_remhead (&s->input); + d (printf("appending (partial) match node (head) '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok)); output_token(s, token); } } @@ -610,7 +550,7 @@ output_match(struct _searcher *s, unsigned int start, unsigned int end) /* any remaining partial content */ if (s->offout < end) { token = append_token(&s->output, endtoken->tok+(s->offout-endtoken->offset), end-s->offout); - d(printf("appending (partial) match node (tail) '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok)); + d (printf("appending (partial) match node (tail) '%s'\n", token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok)); s->offout = end; } @@ -627,7 +567,7 @@ output_match(struct _searcher *s, unsigned int start, unsigned int end) /* output any sub-pending blocks */ static void -output_subpending(struct _searcher *s) +output_subpending (struct _searcher *s) { int i; @@ -638,7 +578,7 @@ output_subpending(struct _searcher *s) /* returns true if a merge took place */ static int -merge_subpending(struct _searcher *s, int offstart, int offend) +merge_subpending (struct _searcher *s, int offstart, int offend) { int i; @@ -663,11 +603,11 @@ merge_subpending(struct _searcher *s, int offstart, int offend) } static void -push_subpending(struct _searcher *s, int offstart, int offend) +push_subpending (struct _searcher *s, int offstart, int offend) { /* This is really an assertion, we just ignore the last pending match instead of crashing though */ if (s->submatchp >= s->words) { - d(printf("ERROR: submatch pending stack overflow\n")); + d (printf("ERROR: submatch pending stack overflow\n")); s->submatchp = s->words-1; } @@ -678,11 +618,11 @@ push_subpending(struct _searcher *s, int offstart, int offend) /* move any (partial) tokens from input to output if they are beyond the current output position */ static void -output_pending(struct _searcher *s) +output_pending (struct _searcher *s) { struct _token *token; - while ( (token = (struct _token *)e_dlist_remhead(&s->input)) ) + while ( (token = (struct _token *)e_dlist_remhead (&s->input)) ) output_token(s, token); } @@ -706,7 +646,7 @@ flush_extra(struct _searcher *s) return; while ((struct _token *)s->input.head != starttoken) { - token = (struct _token *)e_dlist_remhead(&s->input); + token = (struct _token *)e_dlist_remhead (&s->input); output_token(s, token); } } @@ -726,8 +666,8 @@ searcher_next_token(struct _searcher *s) /* get next token */ tok = (unsigned char *)s->next_token(s->next_data); if (tok == NULL) { - output_subpending(s); - output_pending(s); + output_subpending (s); + output_pending (s); break; } @@ -736,14 +676,14 @@ searcher_next_token(struct _searcher *s) token->offset = s->offset; tok = (unsigned char *)token->tok; - d(printf("new token %d '%s'\n", token->offset, token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok)); + d (printf("new token %d '%s'\n", token->offset, token->tok[0]==TAG_ESCAPE?token->tok+1:token->tok)); /* tag test, reset state on unknown tags */ if (tok[0] == TAG_ESCAPE) { if (!ignore_tag ((char *)tok)) { /* force reset */ - output_subpending(s); - output_pending(s); + output_subpending (s); + output_pending (s); q = &t->root; } @@ -754,12 +694,12 @@ searcher_next_token(struct _searcher *s) pre_tok = stok = tok; while ((c = camel_utf8_getc (&tok))) { if ((s->flags & SEARCH_CASE) == 0) - c = g_unichar_tolower(c); - while (q && (m = g(q, c)) == NULL) + c = g_unichar_tolower (c); + while (q && (m = g (q, c)) == NULL) q = q->fail; if (q == NULL) { /* mismatch ... reset state */ - output_subpending(s); + output_subpending (s); q = &t->root; } else if (m != NULL) { /* keep track of previous offsets of utf8 chars, rotating buffer */ @@ -778,21 +718,21 @@ searcher_next_token(struct _searcher *s) if (q->matches == NULL) { if (s->submatchp == 0) { /* nothing pending, always put something in so we can try merge */ - push_subpending(s, offstart, offend); - } else if (!merge_subpending(s, offstart, offend)) { + push_subpending (s, offstart, offend); + } else if (!merge_subpending (s, offstart, offend)) { /* can't merge, output what we have, and start againt */ - output_subpending(s); - push_subpending(s, offstart, offend); + output_subpending (s); + push_subpending (s, offstart, offend); /*output_match(s, offstart, offend);*/ } else if (e_dlist_length(&s->input) > 8) { /* we're continuing to match and merge, but we have a lot of stuff waiting, so flush it out now since this is a safe point to do it */ - output_subpending(s); + output_subpending (s); } } else { /* merge/add subpending */ - if (!merge_subpending(s, offstart, offend)) - push_subpending(s, offstart, offend); + if (!merge_subpending (s, offstart, offend)) + push_subpending (s, offstart, offend); } } } @@ -809,7 +749,7 @@ searcher_next_token(struct _searcher *s) if (s->current) free_token(s->current); - s->current = token = (struct _token *)e_dlist_remhead(&s->output); + s->current = token = (struct _token *)e_dlist_remhead (&s->output); return token ? g_strdup (token->tok) : NULL; } @@ -823,7 +763,7 @@ searcher_peek_token(struct _searcher *s) tok = searcher_next_token(s); if (tok) { /* need to clear this so we dont free it while its still active */ - e_dlist_addhead(&s->output, (EDListNode *)s->current); + e_dlist_addhead (&s->output, (EDListNode *)s->current); s->current = NULL; } @@ -831,7 +771,7 @@ searcher_peek_token(struct _searcher *s) } static int -searcher_pending(struct _searcher *s) +searcher_pending (struct _searcher *s) { return !(e_dlist_empty(&s->input) && e_dlist_empty(&s->output)); } @@ -840,7 +780,7 @@ searcher_pending(struct _searcher *s) struct _search_info { GPtrArray *strv; - char *colour; + char *color; unsigned int size:8; unsigned int flags:8; }; @@ -848,12 +788,12 @@ struct _search_info { /** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/ static struct _search_info * -search_info_new(void) +search_info_new (void) { struct _search_info *s; s = g_malloc0(sizeof(struct _search_info)); - s->strv = g_ptr_array_new(); + s->strv = g_ptr_array_new (); return s; } @@ -865,14 +805,14 @@ search_info_set_flags(struct _search_info *si, unsigned int flags, unsigned int } static void -search_info_set_colour(struct _search_info *si, const char *colour) +search_info_set_color (struct _search_info *si, const char *color) { - g_free(si->colour); - si->colour = g_strdup(colour); + g_free (si->color); + si->color = g_strdup (color); } static void -search_info_add_string(struct _search_info *si, const char *s) +search_info_add_string (struct _search_info *si, const char *s) { const unsigned char *start; guint32 c; @@ -889,44 +829,44 @@ search_info_add_string(struct _search_info *si, const char *s) } /* should probably also strip trailing, but i'm lazy today */ if (start[0]) - g_ptr_array_add(si->strv, g_strdup ((char *)start)); + g_ptr_array_add (si->strv, g_strdup ((char *)start)); } } static void -search_info_clear(struct _search_info *si) +search_info_clear (struct _search_info *si) { int i; for (i=0;istrv->len;i++) - g_free(si->strv->pdata[i]); + g_free (si->strv->pdata[i]); - g_ptr_array_set_size(si->strv, 0); + g_ptr_array_set_size (si->strv, 0); } static void -search_info_free(struct _search_info *si) +search_info_free (struct _search_info *si) { int i; for (i=0;istrv->len;i++) - g_free(si->strv->pdata[i]); + g_free (si->strv->pdata[i]); - g_ptr_array_free(si->strv, TRUE); - g_free(si->colour); - g_free(si); + g_ptr_array_free (si->strv, TRUE); + g_free (si->color); + g_free (si); } static struct _search_info * -search_info_clone(struct _search_info *si) +search_info_clone (struct _search_info *si) { struct _search_info *out; int i; - out = search_info_new(); + out = search_info_new (); for (i=0;istrv->len;i++) - g_ptr_array_add(out->strv, g_strdup(si->strv->pdata[i])); - out->colour = g_strdup(si->colour); + g_ptr_array_add (out->strv, g_strdup (si->strv->pdata[i])); + out->color = g_strdup (si->color); out->flags = si->flags; out->size = si->size; @@ -934,7 +874,7 @@ search_info_clone(struct _search_info *si) } static struct _searcher * -search_info_to_searcher(struct _search_info *si) +search_info_to_searcher (struct _search_info *si) { char *tags, *tage; char *col; @@ -942,10 +882,10 @@ search_info_to_searcher(struct _search_info *si) if (si->strv->len == 0) return NULL; - if (si->colour == NULL) + if (si->color == NULL) col = "red"; else - col = si->colour; + col = si->color; tags = alloca(20+strlen(col)); sprintf(tags, "%c", TAG_ESCAPE, col); @@ -964,288 +904,289 @@ struct _ESearchingTokenizerPrivate { /** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/ -static void -e_searching_tokenizer_finalise (GObject *obj) -{ - ESearchingTokenizer *st = E_SEARCHING_TOKENIZER (obj); - struct _ESearchingTokenizerPrivate *p = st->priv; - - search_info_free (p->primary); - search_info_free (p->secondary); - if (p->engine) - searcher_free(p->engine); +/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/ - /* again wtf? - shared_state_unref (st->priv->shared); - */ +/* blah blah the htmltokeniser doesn't like being asked + for a token if it doens't hvae any! */ +static char * +get_token (HTMLTokenizer *tokenizer) +{ + HTMLTokenizerClass *class = HTML_TOKENIZER_CLASS (parent_class); - g_free (p); + if (class->has_more (tokenizer)) + return class->next_token (tokenizer); - if (G_OBJECT_CLASS (parent_class)->finalize) - G_OBJECT_CLASS (parent_class)->finalize(obj); + return NULL; } +/* proxy matched event, not sure what its for otherwise */ static void -e_searching_tokenizer_class_init (ESearchingTokenizerClass *klass) +matched (ESearchingTokenizer *tokenizer) { - GObjectClass *obj_class = (GObjectClass *) klass; - HTMLTokenizerClass *tok_class = HTML_TOKENIZER_CLASS (klass); - - parent_class = g_type_class_ref (HTML_TYPE_TOKENIZER); - - signals[MATCH_SIGNAL] = - g_signal_new ("match", - E_TYPE_SEARCHING_TOKENIZER, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ESearchingTokenizerClass, match), - NULL, - NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - obj_class->finalize = e_searching_tokenizer_finalise; - - tok_class->begin = e_searching_tokenizer_begin; - tok_class->end = e_searching_tokenizer_end; - - tok_class->peek_token = e_searching_tokenizer_peek_token; - tok_class->next_token = e_searching_tokenizer_next_token; - tok_class->has_more = e_searching_tokenizer_has_more; - tok_class->clone = e_searching_tokenizer_clone; + /*++tokenizer->priv->match_count;*/ + g_signal_emit (tokenizer, signals[MATCH_SIGNAL], 0); } +/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */ + static void -e_searching_tokenizer_init (ESearchingTokenizer *st) +searching_tokenizer_finalize (GObject *object) { - struct _ESearchingTokenizerPrivate *p; - - p = st->priv = g_new0 (struct _ESearchingTokenizerPrivate, 1); + ESearchingTokenizerPrivate *priv; - p->primary = search_info_new(); - search_info_set_flags(p->primary, SEARCH_BOLD, SEARCH_CASE|SEARCH_BOLD); - search_info_set_colour(p->primary, "red"); + priv = E_SEARCHING_TOKENIZER_GET_PRIVATE (object); - p->secondary = search_info_new(); - search_info_set_flags(p->secondary, SEARCH_BOLD, SEARCH_CASE|SEARCH_BOLD); - search_info_set_colour(p->secondary, "purple"); -} + search_info_free (priv->primary); + search_info_free (priv->secondary); -GType -e_searching_tokenizer_get_type (void) -{ - static GType type = 0; - - if (!type) { - static const GTypeInfo info = { - sizeof (ESearchingTokenizerClass), - NULL, NULL, - (GClassInitFunc) e_searching_tokenizer_class_init, - NULL, NULL, - sizeof (ESearchingTokenizer), - 0, - (GInstanceInitFunc) e_searching_tokenizer_init, - }; - - type = g_type_register_static (HTML_TYPE_TOKENIZER, "ESearchingTokenizer", &info, 0); - } + if (priv->engine != NULL) + searcher_free (priv->engine); - return type; -} - -HTMLTokenizer * -e_searching_tokenizer_new (void) -{ - return (HTMLTokenizer *) g_object_new (E_TYPE_SEARCHING_TOKENIZER, NULL); -} - -/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **/ - -/* blah blah the htmltokeniser doesn't like being asked - for a token if it doens't hvae any! */ -static char *get_token(HTMLTokenizer *t) -{ - HTMLTokenizerClass *klass = HTML_TOKENIZER_CLASS (parent_class); - - return klass->has_more(t) ? klass->next_token(t) : NULL; + /* Chain up to parent's finalize () method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); } static void -e_searching_tokenizer_begin (HTMLTokenizer *t, const char *content_type) +searching_tokenizer_begin (HTMLTokenizer *tokenizer, + const gchar *content_type) { - ESearchingTokenizer *st = E_SEARCHING_TOKENIZER (t); - struct _ESearchingTokenizerPrivate *p = st->priv; + ESearchingTokenizerPrivate *priv; + + priv = E_SEARCHING_TOKENIZER_GET_PRIVATE (tokenizer); /* reset search */ - if (p->engine) { - searcher_free(p->engine); - p->engine = NULL; + if (priv->engine != NULL) { + searcher_free (priv->engine); + priv->engine = NULL; } - if ((p->engine = search_info_to_searcher(p->primary)) - || (p->engine = search_info_to_searcher(p->secondary))) { - /*HTMLTokenizerClass *klass = HTML_TOKENIZER_CLASS (parent_class);*/ - - /*searcher_set_tokenfunc(p->engine, klass->next_token, st);*/ - searcher_set_tokenfunc(p->engine, get_token, st); + if ((priv->engine = search_info_to_searcher (priv->primary)) + || (priv->engine = search_info_to_searcher (priv->secondary))) { + searcher_set_tokenfunc(priv->engine, get_token, tokenizer); } /* else - no engine, no search active */ - HTML_TOKENIZER_CLASS (parent_class)->begin (t, content_type); + /* Chain up to parent's begin() method. */ + HTML_TOKENIZER_CLASS (parent_class)->begin (tokenizer, content_type); } -static void -e_searching_tokenizer_end (HTMLTokenizer *t) +static gchar * +searching_tokenizer_peek_token (HTMLTokenizer *tokenizer) { - /* so end gets called before any get/next tokens. - I dont get it. */ -#if 0 - ESearchingTokenizer *st = E_SEARCHING_TOKENIZER (t); - struct _ESearchingTokenizerPrivate *p = st->priv; - - /* not sure if we should reset search every time ... *shrug* */ - if (p->engine) { - searcher_free(p->engine); - p->engine = NULL; - } -#endif + ESearchingTokenizerPrivate *priv; - HTML_TOKENIZER_CLASS (parent_class)->end (t); -} + priv = E_SEARCHING_TOKENIZER_GET_PRIVATE (tokenizer); -static char * -e_searching_tokenizer_peek_token (HTMLTokenizer *tok) -{ - ESearchingTokenizer *st = E_SEARCHING_TOKENIZER (tok); + if (priv->engine != NULL) + return searcher_peek_token (priv->engine); - /* If no search is active, just use the default method. */ - if (st->priv->engine == NULL) - return HTML_TOKENIZER_CLASS (parent_class)->peek_token (tok); - - return searcher_peek_token(st->priv->engine); + /* Chain up to parent's peek_token() method. */ + return HTML_TOKENIZER_CLASS (parent_class)->peek_token (tokenizer); } -static char * -e_searching_tokenizer_next_token (HTMLTokenizer *tok) +static gchar * +searching_tokenizer_next_token (HTMLTokenizer *tokenizer) { - ESearchingTokenizer *st = E_SEARCHING_TOKENIZER (tok); + ESearchingTokenizerPrivate *priv; int oldmatched; char *token; + priv = E_SEARCHING_TOKENIZER_GET_PRIVATE (tokenizer); + /* If no search is active, just use the default method. */ - if (st->priv->engine == NULL) - return HTML_TOKENIZER_CLASS (parent_class)->next_token (tok); + if (priv->engine == NULL) + return HTML_TOKENIZER_CLASS (parent_class)->next_token (tokenizer); - oldmatched = st->priv->engine->matchcount; + oldmatched = priv->engine->matchcount; - token = searcher_next_token(st->priv->engine); + token = searcher_next_token (priv->engine); /* not sure if this has to be accurate or just say we had some matches */ - if (oldmatched != st->priv->engine->matchcount) - g_signal_emit (st, signals[MATCH_SIGNAL], 0); + if (oldmatched != priv->engine->matchcount) + g_signal_emit (tokenizer, signals[MATCH_SIGNAL], 0); return token; } static gboolean -e_searching_tokenizer_has_more (HTMLTokenizer *tok) +searching_tokenizer_has_more (HTMLTokenizer *tokenizer) { - ESearchingTokenizer *st = E_SEARCHING_TOKENIZER (tok); + ESearchingTokenizerPrivate *priv; + + priv = E_SEARCHING_TOKENIZER_GET_PRIVATE (tokenizer); - return (st->priv->engine != NULL && searcher_pending(st->priv->engine)) - || HTML_TOKENIZER_CLASS (parent_class)->has_more (tok); + return (priv->engine != NULL && searcher_pending (priv->engine)) || + HTML_TOKENIZER_CLASS (parent_class)->has_more (tokenizer); } -/* proxy matched event, not sure what its for otherwise */ +static HTMLTokenizer * +searching_tokenizer_clone (HTMLTokenizer *tokenizer) +{ + ESearchingTokenizer *orig_st; + ESearchingTokenizer *new_st; + + orig_st = E_SEARCHING_TOKENIZER (tokenizer); + new_st = e_searching_tokenizer_new (); + + search_info_free (new_st->priv->primary); + search_info_free (new_st->priv->secondary); + + new_st->priv->primary = search_info_clone (orig_st->priv->primary); + new_st->priv->secondary = search_info_clone (orig_st->priv->secondary); + + g_signal_connect_swapped ( + new_st, "match", G_CALLBACK (matched), orig_st); + + return HTML_TOKENIZER (new_st); +} static void -matched (ESearchingTokenizer *st) +searching_tokenizer_class_init (ESearchingTokenizerClass *class) { - /*++st->priv->match_count;*/ - g_signal_emit (st, signals[MATCH_SIGNAL], 0); + GObjectClass *object_class; + HTMLTokenizerClass *tokenizer_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (ESearchingTokenizerPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->finalize = searching_tokenizer_finalize; + + tokenizer_class = HTML_TOKENIZER_CLASS (class); + tokenizer_class->begin = searching_tokenizer_begin; + tokenizer_class->peek_token = searching_tokenizer_peek_token; + tokenizer_class->next_token = searching_tokenizer_next_token; + tokenizer_class->has_more = searching_tokenizer_has_more; + tokenizer_class->clone = searching_tokenizer_clone; + + signals[MATCH_SIGNAL] = g_signal_new ( + "match", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ESearchingTokenizerClass, match), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); } -static HTMLTokenizer * -e_searching_tokenizer_clone (HTMLTokenizer *tok) +static void +searching_tokenizer_init (ESearchingTokenizer *tokenizer) { - ESearchingTokenizer *orig_st = E_SEARCHING_TOKENIZER (tok); - ESearchingTokenizer *new_st = E_SEARCHING_TOKENIZER (e_searching_tokenizer_new ()); + tokenizer->priv = E_SEARCHING_TOKENIZER_GET_PRIVATE (tokenizer); + + tokenizer->priv->primary = search_info_new (); + search_info_set_flags ( + tokenizer->priv->primary, + SEARCH_BOLD, SEARCH_CASE | SEARCH_BOLD); + search_info_set_color (tokenizer->priv->primary, "red"); + + tokenizer->priv->secondary = search_info_new (); + search_info_set_flags( + tokenizer->priv->secondary, + SEARCH_BOLD, SEARCH_CASE | SEARCH_BOLD); + search_info_set_color (tokenizer->priv->secondary, "purple"); +} - search_info_free(new_st->priv->primary); - search_info_free(new_st->priv->secondary); +GType +e_searching_tokenizer_get_type (void) +{ + static GType type = 0; - new_st->priv->primary = search_info_clone(orig_st->priv->primary); - new_st->priv->secondary = search_info_clone(orig_st->priv->secondary); + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (ESearchingTokenizerClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) searching_tokenizer_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (ESearchingTokenizer), + 0, /* n_preallocs */ + (GInstanceInitFunc) searching_tokenizer_init, + NULL /* value_table */ + }; - /* what the fucking what???? */ -#if 0 - shared_state_ref (orig_st->priv->shared); - shared_state_unref (new_st->priv->shared); - new_st->priv->shared = orig_st->priv->shared; -#endif + type = g_type_register_static ( + HTML_TYPE_TOKENIZER, "ESearchingTokenizer", + &type_info, 0); + } - g_signal_connect_swapped (new_st, "match", G_CALLBACK(matched), orig_st); + return type; +} - return HTML_TOKENIZER (new_st); +ESearchingTokenizer * +e_searching_tokenizer_new (void) +{ + return g_object_new (E_TYPE_SEARCHING_TOKENIZER, NULL); } -/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */ void -e_searching_tokenizer_set_primary_search_string (ESearchingTokenizer *st, const gchar *search_str) +e_searching_tokenizer_set_primary_search_string (ESearchingTokenizer *tokenizer, + const gchar *primary_string) { - g_return_if_fail (st && E_IS_SEARCHING_TOKENIZER (st)); + g_return_if_fail (E_IS_SEARCHING_TOKENIZER (tokenizer)); - search_info_clear(st->priv->primary); - search_info_add_string(st->priv->primary, search_str); + search_info_clear (tokenizer->priv->primary); + search_info_add_string (tokenizer->priv->primary, primary_string); } void -e_searching_tokenizer_add_primary_search_string (ESearchingTokenizer *st, const gchar *search_str) +e_searching_tokenizer_add_primary_search_string (ESearchingTokenizer *tokenizer, + const gchar *primary_string) { - g_return_if_fail (st && E_IS_SEARCHING_TOKENIZER (st)); + g_return_if_fail (E_IS_SEARCHING_TOKENIZER (tokenizer)); - search_info_add_string(st->priv->primary, search_str); + search_info_add_string (tokenizer->priv->primary, primary_string); } void -e_searching_tokenizer_set_primary_case_sensitivity (ESearchingTokenizer *st, gboolean iscase) +e_searching_tokenizer_set_primary_case_sensitivity (ESearchingTokenizer *tokenizer, + gboolean case_sensitive) { - g_return_if_fail (st && E_IS_SEARCHING_TOKENIZER (st)); + g_return_if_fail (E_IS_SEARCHING_TOKENIZER (tokenizer)); - search_info_set_flags(st->priv->primary, iscase?SEARCH_CASE:0, SEARCH_CASE); + search_info_set_flags ( + tokenizer->priv->primary, + case_sensitive ? SEARCH_CASE : 0, SEARCH_CASE); } void -e_searching_tokenizer_set_secondary_search_string (ESearchingTokenizer *st, const gchar *search_str) +e_searching_tokenizer_set_secondary_search_string (ESearchingTokenizer *tokenizer, + const gchar *secondary_string) { - g_return_if_fail (st && E_IS_SEARCHING_TOKENIZER (st)); + g_return_if_fail (E_IS_SEARCHING_TOKENIZER (tokenizer)); - search_info_clear(st->priv->secondary); - search_info_add_string(st->priv->secondary, search_str); + search_info_clear (tokenizer->priv->secondary); + search_info_add_string (tokenizer->priv->secondary, secondary_string); } void -e_searching_tokenizer_add_secondary_search_string (ESearchingTokenizer *st, const gchar *search_str) +e_searching_tokenizer_add_secondary_search_string (ESearchingTokenizer *tokenizer, + const gchar *secondary_string) { - g_return_if_fail (st && E_IS_SEARCHING_TOKENIZER (st)); + g_return_if_fail (E_IS_SEARCHING_TOKENIZER (tokenizer)); - search_info_add_string(st->priv->secondary, search_str); + search_info_add_string (tokenizer->priv->secondary, secondary_string); } void -e_searching_tokenizer_set_secondary_case_sensitivity (ESearchingTokenizer *st, gboolean iscase) +e_searching_tokenizer_set_secondary_case_sensitivity (ESearchingTokenizer *tokenizer, + gboolean case_sensitive) { - g_return_if_fail (st && E_IS_SEARCHING_TOKENIZER (st)); + g_return_if_fail (E_IS_SEARCHING_TOKENIZER (tokenizer)); - search_info_set_flags(st->priv->secondary, iscase?SEARCH_CASE:0, SEARCH_CASE); + search_info_set_flags ( + tokenizer->priv->secondary, + case_sensitive ? SEARCH_CASE : 0, SEARCH_CASE); } /* Note: only returns the primary search string count */ gint -e_searching_tokenizer_match_count (ESearchingTokenizer *st) +e_searching_tokenizer_match_count (ESearchingTokenizer *tokenizer) { - g_return_val_if_fail (E_IS_SEARCHING_TOKENIZER (st), -1); + g_return_val_if_fail (E_IS_SEARCHING_TOKENIZER (tokenizer), -1); - if (st->priv->engine && st->priv->primary->strv->len) - return st->priv->engine->matchcount; + if (tokenizer->priv->engine && tokenizer->priv->primary->strv->len) + return tokenizer->priv->engine->matchcount; return 0; } -- cgit v1.2.3