1 | /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ |
---|
2 | /* This file is part of the GtkHTML library. |
---|
3 | |
---|
4 | Copyright (C) 2000 Helix Code, Inc. |
---|
5 | Authors: Radek Doulik (rodo@helixcode.com) |
---|
6 | |
---|
7 | This library is free software; you can redistribute it and/or |
---|
8 | modify it under the terms of the GNU Library General Public |
---|
9 | License as published by the Free Software Foundation; either |
---|
10 | version 2 of the License, or (at your option) any later version. |
---|
11 | |
---|
12 | This library is distributed in the hope that it will be useful, |
---|
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
---|
15 | Library General Public License for more details. |
---|
16 | |
---|
17 | You should have received a copy of the GNU Library General Public License |
---|
18 | along with this library; see the file COPYING.LIB. If not, write to |
---|
19 | the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
---|
20 | Boston, MA 02111-1307, USA. |
---|
21 | |
---|
22 | TODO: |
---|
23 | |
---|
24 | - now we go thru the html tree without take care about vertical |
---|
25 | position of paragraph. so it is possible to find first match |
---|
26 | on bottom of page (ie. first column of table) and the second |
---|
27 | one on top (ie. top of second comlumn) |
---|
28 | [also Netscape didn't take care of it] |
---|
29 | |
---|
30 | */ |
---|
31 | |
---|
32 | #include <config.h> |
---|
33 | #include <gal/unicode/gunicode.h> |
---|
34 | #include "htmlsearch.h" |
---|
35 | #include "htmlobject.h" |
---|
36 | #include "htmlentity.h" |
---|
37 | #include "htmlengine.h" |
---|
38 | |
---|
39 | static void |
---|
40 | set_text (HTMLSearch *s, const gchar *text) |
---|
41 | { |
---|
42 | s->text = g_strdup (text); |
---|
43 | s->text_len = g_utf8_strlen (text, -1); |
---|
44 | } |
---|
45 | |
---|
46 | HTMLSearch * |
---|
47 | html_search_new (HTMLEngine *e, const gchar *text, gboolean case_sensitive, gboolean forward, gboolean regular) |
---|
48 | { |
---|
49 | HTMLSearch *ns = g_new (HTMLSearch, 1); |
---|
50 | gint i; |
---|
51 | |
---|
52 | set_text (ns, text); |
---|
53 | ns->case_sensitive = case_sensitive; |
---|
54 | ns->forward = forward; |
---|
55 | ns->found = NULL; |
---|
56 | ns->engine = e; |
---|
57 | |
---|
58 | if (html_engine_get_editable (e)) { |
---|
59 | HTMLObject *o; |
---|
60 | |
---|
61 | ns->stack = NULL; |
---|
62 | ns->start_pos = e->cursor->offset - 1; |
---|
63 | for (o = e->cursor->object; o; o = o->parent) |
---|
64 | html_search_push (ns, o); |
---|
65 | ns->stack = g_slist_reverse (ns->stack); |
---|
66 | ns->found = g_list_append (ns->found, e->cursor->object); |
---|
67 | } else { |
---|
68 | ns->stack = NULL; |
---|
69 | ns->start_pos = 0; |
---|
70 | html_search_push (ns, e->clue); |
---|
71 | } |
---|
72 | |
---|
73 | /* translate table |
---|
74 | could translate uppercase to lowercase if non case_sensitive */ |
---|
75 | ns->trans = g_new (gchar, 256); |
---|
76 | for (i=0; i<256; i++) { |
---|
77 | ns->trans [i] = (case_sensitive) ? i : ((i>='A' && i<='Z') ? i+('a'-'A') : i); |
---|
78 | } |
---|
79 | /* |
---|
80 | * FIXME translating breaks horribly |
---|
81 | * with utf8 and nonutf8 regex (see bug #24446) |
---|
82 | * so we won't do it |
---|
83 | */ |
---|
84 | /* ns->trans [ENTITY_NBSP] = ' '; */ |
---|
85 | |
---|
86 | ns->regular = regular; |
---|
87 | if (regular) { |
---|
88 | #ifdef HAVE_GNU_REGEX |
---|
89 | const gchar *rv; |
---|
90 | |
---|
91 | ns->reb = g_new0 (regex_t, 1); |
---|
92 | |
---|
93 | ns->reb->translate = ns->trans; |
---|
94 | rv = re_compile_pattern (ns->text, ns->text_len, ns->reb); |
---|
95 | if (rv) { |
---|
96 | g_warning (rv); |
---|
97 | } |
---|
98 | #else |
---|
99 | int rv_int; |
---|
100 | |
---|
101 | ns->reb = g_new0 (regex_t, 1); |
---|
102 | |
---|
103 | rv_int = regcomp (ns->reb, ns->text, (case_sensitive) ? 0 : REG_ICASE); |
---|
104 | if (rv_int) { |
---|
105 | char buf[1024]; |
---|
106 | if (regerror(rv_int, ns->reb, &buf, sizeof(buf))) { |
---|
107 | g_warning (buf); |
---|
108 | } else { |
---|
109 | g_warning ("regcomp failed, error code %d", rv_int); |
---|
110 | } |
---|
111 | } |
---|
112 | #endif |
---|
113 | } else { |
---|
114 | ns->reb = NULL; |
---|
115 | } |
---|
116 | |
---|
117 | return ns; |
---|
118 | } |
---|
119 | |
---|
120 | void |
---|
121 | html_search_destroy (HTMLSearch *search) |
---|
122 | { |
---|
123 | g_free (search->text); |
---|
124 | if (search->stack) |
---|
125 | g_slist_free (search->stack); |
---|
126 | if (search->reb) { |
---|
127 | /* FIXME why this segfault for me? regfree (search->reb); */ |
---|
128 | g_free (search->reb); |
---|
129 | } |
---|
130 | g_free (search->trans); |
---|
131 | |
---|
132 | g_free (search); |
---|
133 | } |
---|
134 | |
---|
135 | void |
---|
136 | html_search_push (HTMLSearch *search, HTMLObject *obj) |
---|
137 | { |
---|
138 | search->stack = g_slist_prepend (search->stack, obj); |
---|
139 | } |
---|
140 | |
---|
141 | HTMLObject * |
---|
142 | html_search_pop (HTMLSearch *search) |
---|
143 | { |
---|
144 | HTMLObject *obj; |
---|
145 | |
---|
146 | obj = HTML_OBJECT (search->stack->data); |
---|
147 | search->stack = g_slist_remove (search->stack, obj); |
---|
148 | |
---|
149 | return obj; |
---|
150 | } |
---|
151 | |
---|
152 | gboolean |
---|
153 | html_search_child_on_stack (HTMLSearch *search, HTMLObject *obj) |
---|
154 | { |
---|
155 | return search->stack && HTML_OBJECT (search->stack->data)->parent == obj; |
---|
156 | } |
---|
157 | |
---|
158 | gboolean |
---|
159 | html_search_next_parent (HTMLSearch *search) |
---|
160 | { |
---|
161 | return search->stack && search->stack->next |
---|
162 | ? html_object_search (HTML_OBJECT (search->stack->next->data), search) |
---|
163 | : FALSE; |
---|
164 | } |
---|
165 | |
---|
166 | void |
---|
167 | html_search_set_text (HTMLSearch *search, const gchar *text) |
---|
168 | { |
---|
169 | g_free (search->text); |
---|
170 | set_text (search, text); |
---|
171 | } |
---|
172 | |
---|
173 | void |
---|
174 | html_search_set_forward (HTMLSearch *search, gboolean forward) |
---|
175 | { |
---|
176 | if (search) |
---|
177 | search->forward = forward; |
---|
178 | } |
---|