Mercurial > pidgin.yaz
annotate src/gtkimhtml.c @ 7353:dc35b4a42fea
[gaim-migrate @ 7944]
This gets rid of the gtk critical warning regarding clipboards and fixes the
broken highlighting (when highlighting text with no smileys... I'm not sure
how to get that to work when there are smileys... but I'll work on it.)
committer: Tailor Script <tailor@pidgin.im>
author | Sean Egan <seanegan@gmail.com> |
---|---|
date | Mon, 27 Oct 2003 19:47:57 +0000 |
parents | 15155dbc768a |
children | 5a35881e9e89 |
rev | line source |
---|---|
1428 | 1 /* |
2 * GtkIMHtml | |
3 * | |
4 * Copyright (C) 2000, Eric Warmenhoven <warmenhoven@yahoo.com> | |
5 * | |
6 * This program is free software; you can redistribute it and/or modify | |
7 * under the terms of the GNU General Public License as published by | |
8 * the Free Software Foundation; either version 2 of the License, or | |
9 * (at your option) any later version. | |
10 * | |
11 * This program is distributed in the hope that it will be useful, | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 * GNU General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU General Public License | |
17 * along with this program; if not, write to the Free Software | |
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
19 * | |
20 */ | |
21 | |
2541
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2365
diff
changeset
|
22 #ifdef HAVE_CONFIG_H |
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2365
diff
changeset
|
23 #include <config.h> |
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2365
diff
changeset
|
24 #endif |
1428 | 25 #include "gtkimhtml.h" |
26 #include <gtk/gtk.h> | |
4895 | 27 #include <glib/gerror.h> |
4046 | 28 #include <gdk/gdkkeysyms.h> |
1428 | 29 #include <string.h> |
30 #include <ctype.h> | |
31 #include <stdio.h> | |
4629 | 32 #include <stdlib.h> |
1428 | 33 #include <math.h> |
2541
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2365
diff
changeset
|
34 #ifdef HAVE_LANGINFO_CODESET |
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2365
diff
changeset
|
35 #include <langinfo.h> |
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2365
diff
changeset
|
36 #include <locale.h> |
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2365
diff
changeset
|
37 #endif |
1428 | 38 |
4417 | 39 #ifdef ENABLE_NLS |
40 # include <libintl.h> | |
41 # define _(x) gettext(x) | |
42 # ifdef gettext_noop | |
43 # define N_(String) gettext_noop (String) | |
44 # else | |
45 # define N_(String) (String) | |
46 # endif | |
47 #else | |
48 # define N_(String) (String) | |
49 # define _(x) (x) | |
50 #endif | |
51 | |
4735 | 52 #include <pango/pango-font.h> |
53 | |
5105 | 54 /* GTK+ < 2.2.2 hack, see ui.h for details. */ |
55 #ifndef GTK_WRAP_WORD_CHAR | |
56 #define GTK_WRAP_WORD_CHAR GTK_WRAP_WORD | |
57 #endif | |
58 | |
4735 | 59 #define TOOLTIP_TIMEOUT 500 |
60 | |
3922 | 61 /* POINT_SIZE converts from AIM font sizes to point sizes. It probably should be redone in such a |
62 * way that it base the sizes off the default font size rather than using arbitrary font sizes. */ | |
63 #define MAX_FONT_SIZE 7 | |
5367 | 64 #define POINT_SIZE(x) (options & GTK_IMHTML_USE_POINTSIZE ? x : _point_sizes [MIN ((x), MAX_FONT_SIZE) - 1]) |
3928 | 65 static gint _point_sizes [] = { 8, 10, 12, 14, 20, 30, 40 }; |
2349
60c716c32c40
[gaim-migrate @ 2362]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2348
diff
changeset
|
66 |
4032 | 67 static GtkSmileyTree* |
68 gtk_smiley_tree_new () | |
69 { | |
70 return g_new0 (GtkSmileyTree, 1); | |
71 } | |
72 | |
73 static void | |
74 gtk_smiley_tree_insert (GtkSmileyTree *tree, | |
4263 | 75 GtkIMHtmlSmiley *smiley) |
4032 | 76 { |
77 GtkSmileyTree *t = tree; | |
4263 | 78 const gchar *x = smiley->smile; |
4032 | 79 |
80 if (!strlen (x)) | |
81 return; | |
82 | |
83 while (*x) { | |
84 gchar *pos; | |
85 gint index; | |
86 | |
87 if (!t->values) | |
88 t->values = g_string_new (""); | |
89 | |
90 pos = strchr (t->values->str, *x); | |
91 if (!pos) { | |
92 t->values = g_string_append_c (t->values, *x); | |
93 index = t->values->len - 1; | |
94 t->children = g_realloc (t->children, t->values->len * sizeof (GtkSmileyTree *)); | |
95 t->children [index] = g_new0 (GtkSmileyTree, 1); | |
96 } else | |
6478
338147ea6896
[gaim-migrate @ 6991]
Christian Hammond <chipx86@chipx86.com>
parents:
6162
diff
changeset
|
97 index = (int) pos - GPOINTER_TO_INT(t->values->str); |
4032 | 98 |
99 t = t->children [index]; | |
100 | |
101 x++; | |
102 } | |
103 | |
4263 | 104 t->image = smiley; |
4032 | 105 } |
4041 | 106 |
4263 | 107 |
4264 | 108 void gtk_smiley_tree_destroy (GtkSmileyTree *tree) |
4032 | 109 { |
110 GSList *list = g_slist_append (NULL, tree); | |
111 | |
112 while (list) { | |
113 GtkSmileyTree *t = list->data; | |
114 gint i; | |
115 list = g_slist_remove(list, t); | |
116 if (t->values) { | |
117 for (i = 0; i < t->values->len; i++) | |
118 list = g_slist_append (list, t->children [i]); | |
119 g_string_free (t->values, TRUE); | |
120 g_free (t->children); | |
121 } | |
122 g_free (t); | |
123 } | |
124 } | |
125 | |
5967 | 126 static gboolean gtk_size_allocate_cb(GtkIMHtml *widget, GtkAllocation *alloc, gpointer user_data) |
127 { | |
128 GdkRectangle rect; | |
129 | |
130 gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(widget), &rect); | |
131 if(widget->old_rect.width != rect.width || widget->old_rect.height != rect.height){ | |
132 GList *iter = GTK_IMHTML(widget)->scalables; | |
133 | |
134 while(iter){ | |
135 GtkIMHtmlScalable *scale = GTK_IMHTML_SCALABLE(iter->data); | |
136 scale->scale(scale, rect.width, rect.height); | |
137 | |
138 iter = iter->next; | |
139 } | |
140 } | |
141 | |
142 widget->old_rect = rect; | |
143 return FALSE; | |
144 } | |
145 | |
146 static gint | |
147 gtk_imhtml_tip_paint (GtkIMHtml *imhtml) | |
148 { | |
149 PangoLayout *layout; | |
150 | |
151 g_return_val_if_fail(GTK_IS_IMHTML(imhtml), FALSE); | |
152 | |
153 layout = gtk_widget_create_pango_layout(imhtml->tip_window, imhtml->tip); | |
154 | |
155 gtk_paint_flat_box (imhtml->tip_window->style, imhtml->tip_window->window, | |
156 GTK_STATE_NORMAL, GTK_SHADOW_OUT, NULL, imhtml->tip_window, | |
157 "tooltip", 0, 0, -1, -1); | |
158 | |
159 gtk_paint_layout (imhtml->tip_window->style, imhtml->tip_window->window, GTK_STATE_NORMAL, | |
160 FALSE, NULL, imhtml->tip_window, NULL, 4, 4, layout); | |
161 | |
162 g_object_unref(layout); | |
163 return FALSE; | |
164 } | |
165 | |
166 static gint | |
167 gtk_imhtml_tip (gpointer data) | |
168 { | |
169 GtkIMHtml *imhtml = data; | |
170 PangoFontMetrics *font; | |
171 PangoLayout *layout; | |
172 | |
173 gint gap, x, y, h, w, scr_w, baseline_skip; | |
174 | |
175 g_return_val_if_fail(GTK_IS_IMHTML(imhtml), FALSE); | |
176 | |
177 if (!imhtml->tip || !GTK_WIDGET_DRAWABLE (GTK_WIDGET(imhtml))) { | |
178 imhtml->tip_timer = 0; | |
179 return FALSE; | |
180 } | |
181 | |
182 if (imhtml->tip_window){ | |
183 gtk_widget_destroy (imhtml->tip_window); | |
184 imhtml->tip_window = NULL; | |
185 } | |
186 | |
187 imhtml->tip_timer = 0; | |
188 imhtml->tip_window = gtk_window_new (GTK_WINDOW_POPUP); | |
189 gtk_widget_set_app_paintable (imhtml->tip_window, TRUE); | |
190 gtk_window_set_resizable (GTK_WINDOW (imhtml->tip_window), FALSE); | |
191 gtk_widget_set_name (imhtml->tip_window, "gtk-tooltips"); | |
192 g_signal_connect_swapped (G_OBJECT (imhtml->tip_window), "expose_event", | |
193 G_CALLBACK (gtk_imhtml_tip_paint), imhtml); | |
194 | |
195 gtk_widget_ensure_style (imhtml->tip_window); | |
196 layout = gtk_widget_create_pango_layout(imhtml->tip_window, imhtml->tip); | |
197 font = pango_font_get_metrics(pango_context_load_font(pango_layout_get_context(layout), | |
198 imhtml->tip_window->style->font_desc), | |
199 NULL); | |
200 | |
201 | |
202 pango_layout_get_pixel_size(layout, &scr_w, NULL); | |
203 gap = PANGO_PIXELS((pango_font_metrics_get_ascent(font) + | |
204 pango_font_metrics_get_descent(font))/ 4); | |
205 | |
206 if (gap < 2) | |
207 gap = 2; | |
208 baseline_skip = PANGO_PIXELS(pango_font_metrics_get_ascent(font) + | |
209 pango_font_metrics_get_descent(font)); | |
210 w = 8 + scr_w; | |
211 h = 8 + baseline_skip; | |
212 | |
213 gdk_window_get_pointer (NULL, &x, &y, NULL); | |
214 if (GTK_WIDGET_NO_WINDOW (GTK_WIDGET(imhtml))) | |
215 y += GTK_WIDGET(imhtml)->allocation.y; | |
216 | |
217 scr_w = gdk_screen_width(); | |
218 | |
219 x -= ((w >> 1) + 4); | |
220 | |
221 if ((x + w) > scr_w) | |
222 x -= (x + w) - scr_w; | |
223 else if (x < 0) | |
224 x = 0; | |
225 | |
226 y = y + PANGO_PIXELS(pango_font_metrics_get_ascent(font) + | |
227 pango_font_metrics_get_descent(font)); | |
228 | |
229 gtk_widget_set_size_request (imhtml->tip_window, w, h); | |
230 gtk_widget_show (imhtml->tip_window); | |
231 gtk_window_move (GTK_WINDOW(imhtml->tip_window), x, y); | |
232 | |
233 pango_font_metrics_unref(font); | |
234 g_object_unref(layout); | |
235 | |
236 return FALSE; | |
237 } | |
238 | |
239 gboolean gtk_motion_event_notify(GtkWidget *imhtml, GdkEventMotion *event, gpointer data) | |
240 { | |
241 GtkTextIter iter; | |
242 GdkWindow *win = event->window; | |
243 int x, y; | |
244 char *tip = NULL; | |
245 GSList *tags = NULL, *templist = NULL; | |
246 gdk_window_get_pointer(GTK_WIDGET(imhtml)->window, NULL, NULL, NULL); | |
247 gtk_text_view_window_to_buffer_coords(GTK_TEXT_VIEW(imhtml), GTK_TEXT_WINDOW_WIDGET, | |
248 event->x, event->y, &x, &y); | |
249 gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(imhtml), &iter, x, y); | |
250 tags = gtk_text_iter_get_tags(&iter); | |
251 | |
252 templist = tags; | |
253 while (templist) { | |
254 GtkTextTag *tag = templist->data; | |
255 tip = g_object_get_data(G_OBJECT(tag), "link_url"); | |
256 if (tip) | |
257 break; | |
258 templist = templist->next; | |
259 } | |
260 | |
261 if (GTK_IMHTML(imhtml)->tip) { | |
262 if ((tip == GTK_IMHTML(imhtml)->tip)) { | |
263 return FALSE; | |
264 } | |
265 /* We've left the cell. Remove the timeout and create a new one below */ | |
266 if (GTK_IMHTML(imhtml)->tip_window) { | |
267 gtk_widget_destroy(GTK_IMHTML(imhtml)->tip_window); | |
268 GTK_IMHTML(imhtml)->tip_window = NULL; | |
269 } | |
270 gdk_window_set_cursor(win, GTK_IMHTML(imhtml)->arrow_cursor); | |
271 if (GTK_IMHTML(imhtml)->tip_timer) | |
272 g_source_remove(GTK_IMHTML(imhtml)->tip_timer); | |
273 GTK_IMHTML(imhtml)->tip_timer = 0; | |
274 } | |
275 | |
276 if(tip){ | |
277 gdk_window_set_cursor(win, GTK_IMHTML(imhtml)->hand_cursor); | |
278 GTK_IMHTML(imhtml)->tip_timer = g_timeout_add (TOOLTIP_TIMEOUT, | |
279 gtk_imhtml_tip, imhtml); | |
280 } | |
281 | |
282 GTK_IMHTML(imhtml)->tip = tip; | |
283 g_slist_free(tags); | |
284 return FALSE; | |
285 } | |
286 | |
287 gboolean gtk_leave_event_notify(GtkWidget *imhtml, GdkEventCrossing *event, gpointer data) | |
288 { | |
289 /* when leaving the widget, clear any current & pending tooltips and restore the cursor */ | |
290 if (GTK_IMHTML(imhtml)->tip_window) { | |
291 gtk_widget_destroy(GTK_IMHTML(imhtml)->tip_window); | |
292 GTK_IMHTML(imhtml)->tip_window = NULL; | |
293 } | |
294 if (GTK_IMHTML(imhtml)->tip_timer) { | |
295 g_source_remove(GTK_IMHTML(imhtml)->tip_timer); | |
296 GTK_IMHTML(imhtml)->tip_timer = 0; | |
297 } | |
298 gdk_window_set_cursor(event->window, GTK_IMHTML(imhtml)->arrow_cursor); | |
299 | |
300 /* propogate the event normally */ | |
301 return FALSE; | |
302 } | |
303 | |
6066 | 304 /* |
305 * XXX - This should be removed eventually. | |
306 * | |
307 * This function exists to work around a gross bug in GtkTextView. | |
308 * Basically, we short circuit ctrl+a and ctrl+end because they make | |
309 * el program go boom. | |
310 * | |
311 * It's supposed to be fixed in gtk2.2. You can view the bug report at | |
312 * http://bugzilla.gnome.org/show_bug.cgi?id=107939 | |
313 */ | |
314 gboolean gtk_key_pressed_cb(GtkWidget *imhtml, GdkEventKey *event, gpointer data) | |
315 { | |
316 if (event->state & GDK_CONTROL_MASK) | |
317 switch (event->keyval) { | |
318 case 'a': | |
319 return TRUE; | |
320 break; | |
321 | |
322 case GDK_Home: | |
323 return TRUE; | |
324 break; | |
325 | |
326 case GDK_End: | |
327 return TRUE; | |
328 break; | |
329 } | |
330 | |
331 return FALSE; | |
332 } | |
333 | |
7346 | 334 static GtkIMHtmlCopyable *gtk_imhtml_copyable_new(GtkIMHtml *imhtml, GtkTextMark *mark, const gchar *text) |
335 { | |
336 GtkIMHtmlCopyable *copy = g_malloc(sizeof(GtkIMHtmlCopyable)); | |
337 copy->mark = mark; | |
338 copy->text = g_strdup(text); | |
339 imhtml->copyables = g_slist_append(imhtml->copyables, copy); | |
340 return copy; | |
341 } | |
342 | |
343 static void copy_clipboard_cb(GtkIMHtml *imhtml, GtkClipboard *clipboard) | |
344 { | |
345 GtkTextMark *sel = gtk_text_buffer_get_selection_bound(imhtml->text_buffer); | |
346 GtkTextMark *ins = gtk_text_buffer_get_insert(imhtml->text_buffer); | |
347 GtkTextIter start, end, smiley, last; | |
348 GString *str = g_string_new(NULL); | |
349 char *text; | |
350 | |
351 GSList *copyables; | |
352 | |
353 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &start, sel); | |
354 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &end, ins); | |
355 | |
356 if (gtk_text_iter_equal(&start, &end)) | |
357 return; | |
358 | |
359 gtk_text_iter_order(&start, &end); | |
360 last = start; | |
361 | |
362 for (copyables = imhtml->copyables; copyables != NULL; copyables = copyables->next) { | |
363 GtkIMHtmlCopyable *copy = GTK_IMHTML_COPYABLE(copyables->data); | |
364 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &smiley, copy->mark); | |
365 if (gtk_text_iter_compare(&end, &smiley) < 0) { | |
366 break; | |
367 } | |
368 if (gtk_text_iter_compare(&last, &smiley) <= 0) { | |
369 text = gtk_text_buffer_get_text(imhtml->text_buffer, &last, &smiley, FALSE); | |
370 str = g_string_append(str, text); | |
371 str = g_string_append(str, copy->text); | |
372 last = smiley; | |
373 g_free(text); | |
374 } | |
375 } | |
376 text = gtk_text_buffer_get_text(imhtml->text_buffer, &last, &end, FALSE); | |
377 str = g_string_append(str, text); | |
378 g_free(text); | |
7353 | 379 |
380 if (!gtk_text_iter_equal(&start, &last); | |
381 gtk_clipboard_set_text(clipboard ? clipboard : | |
382 gtk_widget_get_clipboard(GTK_WIDGET(imhtml), GDK_SELECTION_CLIPBOARD), | |
383 str->str, str->len); | |
7346 | 384 g_string_free(str, TRUE); |
385 } | |
386 | |
387 static gboolean button_release_cb(GtkIMHtml *imhtml, GdkEventButton event, gpointer the_foibles_of_man) | |
388 { | |
389 copy_clipboard_cb(imhtml, gtk_widget_get_clipboard(GTK_WIDGET(imhtml), GDK_SELECTION_PRIMARY)); | |
390 return FALSE; | |
391 } | |
5967 | 392 |
4263 | 393 |
4032 | 394 static GtkTextViewClass *parent_class = NULL; |
395 | |
3922 | 396 /* GtkIMHtml has one signal--URL_CLICKED */ |
1428 | 397 enum { |
398 URL_CLICKED, | |
399 LAST_SIGNAL | |
400 }; | |
401 static guint signals [LAST_SIGNAL] = { 0 }; | |
402 | |
4032 | 403 static void |
404 gtk_imhtml_finalize (GObject *object) | |
405 { | |
406 GtkIMHtml *imhtml = GTK_IMHTML(object); | |
4895 | 407 GList *scalables; |
7346 | 408 GSList *copyables; |
409 | |
4138 | 410 g_hash_table_destroy(imhtml->smiley_data); |
4032 | 411 gtk_smiley_tree_destroy(imhtml->default_smilies); |
4138 | 412 gdk_cursor_unref(imhtml->hand_cursor); |
413 gdk_cursor_unref(imhtml->arrow_cursor); | |
4735 | 414 if(imhtml->tip_window){ |
415 gtk_widget_destroy(imhtml->tip_window); | |
416 } | |
417 if(imhtml->tip_timer) | |
418 gtk_timeout_remove(imhtml->tip_timer); | |
419 | |
4895 | 420 for(scalables = imhtml->scalables; scalables; scalables = scalables->next) { |
421 GtkIMHtmlScalable *scale = GTK_IMHTML_SCALABLE(scalables->data); | |
422 scale->free(scale); | |
423 } | |
7346 | 424 |
425 for (copyables = imhtml->copyables; copyables; copyables = copyables->next) { | |
426 GtkIMHtmlCopyable *copy = GTK_IMHTML_COPYABLE(copyables->data); | |
427 g_free(copy->text); | |
428 g_free(copy); | |
429 } | |
430 | |
4895 | 431 g_list_free(imhtml->scalables); |
4032 | 432 G_OBJECT_CLASS(parent_class)->finalize (object); |
433 } | |
1428 | 434 |
3922 | 435 /* Boring GTK stuff */ |
436 static void gtk_imhtml_class_init (GtkIMHtmlClass *class) | |
1428 | 437 { |
3922 | 438 GtkObjectClass *object_class; |
4032 | 439 GObjectClass *gobject_class; |
3922 | 440 object_class = (GtkObjectClass*) class; |
4032 | 441 gobject_class = (GObjectClass*) class; |
442 parent_class = gtk_type_class(GTK_TYPE_TEXT_VIEW); | |
4417 | 443 signals[URL_CLICKED] = g_signal_new("url_clicked", |
444 G_TYPE_FROM_CLASS(gobject_class), | |
445 G_SIGNAL_RUN_FIRST, | |
446 G_STRUCT_OFFSET(GtkIMHtmlClass, url_clicked), | |
447 NULL, | |
448 0, | |
449 g_cclosure_marshal_VOID__POINTER, | |
450 G_TYPE_NONE, 1, | |
451 G_TYPE_POINTER); | |
4032 | 452 gobject_class->finalize = gtk_imhtml_finalize; |
1428 | 453 } |
454 | |
3922 | 455 static void gtk_imhtml_init (GtkIMHtml *imhtml) |
1428 | 456 { |
3922 | 457 GtkTextIter iter; |
458 imhtml->text_buffer = gtk_text_buffer_new(NULL); | |
459 gtk_text_buffer_get_end_iter (imhtml->text_buffer, &iter); | |
460 imhtml->end = gtk_text_buffer_create_mark(imhtml->text_buffer, NULL, &iter, FALSE); | |
461 gtk_text_view_set_buffer(GTK_TEXT_VIEW(imhtml), imhtml->text_buffer); | |
5105 | 462 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(imhtml), GTK_WRAP_WORD_CHAR); |
3922 | 463 gtk_text_view_set_editable(GTK_TEXT_VIEW(imhtml), FALSE); |
464 gtk_text_view_set_pixels_below_lines(GTK_TEXT_VIEW(imhtml), 5); | |
465 gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(imhtml), FALSE); | |
466 /*gtk_text_view_set_justification(GTK_TEXT_VIEW(imhtml), GTK_JUSTIFY_FILL);*/ | |
3465 | 467 |
3922 | 468 /* These tags will be used often and can be reused--we create them on init and then apply them by name |
469 * other tags (color, size, face, etc.) will have to be created and applied dynamically */ | |
470 gtk_text_buffer_create_tag(imhtml->text_buffer, "BOLD", "weight", PANGO_WEIGHT_BOLD, NULL); | |
471 gtk_text_buffer_create_tag(imhtml->text_buffer, "ITALICS", "style", PANGO_STYLE_ITALIC, NULL); | |
472 gtk_text_buffer_create_tag(imhtml->text_buffer, "UNDERLINE", "underline", PANGO_UNDERLINE_SINGLE, NULL); | |
473 gtk_text_buffer_create_tag(imhtml->text_buffer, "STRIKE", "strikethrough", TRUE, NULL); | |
474 gtk_text_buffer_create_tag(imhtml->text_buffer, "SUB", "rise", -5000, NULL); | |
475 gtk_text_buffer_create_tag(imhtml->text_buffer, "SUP", "rise", 5000, NULL); | |
476 gtk_text_buffer_create_tag(imhtml->text_buffer, "PRE", "family", "Monospace", NULL); | |
7295 | 477 gtk_text_buffer_create_tag(imhtml->text_buffer, "search", "background", "#22ff00", "weight", "bold", NULL); |
478 | |
3922 | 479 /* When hovering over a link, we show the hand cursor--elsewhere we show the plain ol' pointer cursor */ |
480 imhtml->hand_cursor = gdk_cursor_new (GDK_HAND2); | |
481 imhtml->arrow_cursor = gdk_cursor_new (GDK_LEFT_PTR); | |
2993 | 482 |
4253 | 483 imhtml->show_smileys = TRUE; |
6124 | 484 imhtml->show_comments = TRUE; |
4253 | 485 |
4892 | 486 imhtml->smiley_data = g_hash_table_new_full(g_str_hash, g_str_equal, |
4902 | 487 g_free, (GDestroyNotify)gtk_smiley_tree_destroy); |
4032 | 488 imhtml->default_smilies = gtk_smiley_tree_new(); |
4735 | 489 |
4944 | 490 g_signal_connect(G_OBJECT(imhtml), "size-allocate", G_CALLBACK(gtk_size_allocate_cb), NULL); |
4735 | 491 g_signal_connect(G_OBJECT(imhtml), "motion-notify-event", G_CALLBACK(gtk_motion_event_notify), NULL); |
4944 | 492 g_signal_connect(G_OBJECT(imhtml), "leave-notify-event", G_CALLBACK(gtk_leave_event_notify), NULL); |
6066 | 493 g_signal_connect(G_OBJECT(imhtml), "key_press_event", G_CALLBACK(gtk_key_pressed_cb), NULL); |
7353 | 494 g_signal_connect(G_OBJECT(imhtml), "copy-clipboard", G_CALLBACK(copy_clipboard_cb), NULL); |
7346 | 495 g_signal_connect(G_OBJECT(imhtml), "button-release-event", G_CALLBACK(button_release_cb), imhtml); |
4944 | 496 gtk_widget_add_events(GTK_WIDGET(imhtml), GDK_LEAVE_NOTIFY_MASK); |
4735 | 497 |
498 imhtml->tip = NULL; | |
499 imhtml->tip_timer = 0; | |
500 imhtml->tip_window = NULL; | |
4895 | 501 |
502 imhtml->scalables = NULL; | |
7346 | 503 imhtml->copyables = NULL; |
2993 | 504 } |
505 | |
3922 | 506 GtkWidget *gtk_imhtml_new(void *a, void *b) |
1428 | 507 { |
4635 | 508 return GTK_WIDGET(g_object_new(gtk_imhtml_get_type(), NULL)); |
1428 | 509 } |
510 | |
4635 | 511 GType gtk_imhtml_get_type() |
1428 | 512 { |
4635 | 513 static GType imhtml_type = 0; |
1428 | 514 |
515 if (!imhtml_type) { | |
4635 | 516 static const GTypeInfo imhtml_info = { |
517 sizeof(GtkIMHtmlClass), | |
518 NULL, | |
519 NULL, | |
520 (GClassInitFunc) gtk_imhtml_class_init, | |
521 NULL, | |
522 NULL, | |
1428 | 523 sizeof (GtkIMHtml), |
4635 | 524 0, |
525 (GInstanceInitFunc) gtk_imhtml_init | |
1428 | 526 }; |
4635 | 527 |
528 imhtml_type = g_type_register_static(gtk_text_view_get_type(), | |
529 "GtkIMHtml", &imhtml_info, 0); | |
1428 | 530 } |
531 | |
532 return imhtml_type; | |
533 } | |
534 | |
4417 | 535 struct url_data { |
536 GObject *object; | |
537 gchar *url; | |
538 }; | |
539 | |
540 static void url_open(GtkWidget *w, struct url_data *data) { | |
541 if(!data) return; | |
542 | |
543 g_signal_emit(data->object, signals[URL_CLICKED], 0, data->url); | |
544 | |
545 g_object_unref(data->object); | |
546 g_free(data->url); | |
547 g_free(data); | |
548 } | |
5582 | 549 |
4417 | 550 static void url_copy(GtkWidget *w, gchar *url) { |
551 GtkClipboard *clipboard; | |
552 | |
5293
ead927e2543f
[gaim-migrate @ 5665]
Christian Hammond <chipx86@chipx86.com>
parents:
5282
diff
changeset
|
553 clipboard = gtk_clipboard_get(GDK_SELECTION_PRIMARY); |
4417 | 554 gtk_clipboard_set_text(clipboard, url, -1); |
5582 | 555 |
556 clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); | |
557 gtk_clipboard_set_text(clipboard, url, -1); | |
4417 | 558 } |
559 | |
560 /* The callback for an event on a link tag. */ | |
5091 | 561 gboolean tag_event(GtkTextTag *tag, GObject *imhtml, GdkEvent *event, GtkTextIter *arg2, char *url) { |
4417 | 562 GdkEventButton *event_button = (GdkEventButton *) event; |
563 | |
3922 | 564 if (event->type == GDK_BUTTON_RELEASE) { |
4417 | 565 if (event_button->button == 1) { |
566 GtkTextIter start, end; | |
567 /* we shouldn't open a URL if the user has selected something: */ | |
568 gtk_text_buffer_get_selection_bounds( | |
569 gtk_text_iter_get_buffer(arg2), &start, &end); | |
570 if(gtk_text_iter_get_offset(&start) != | |
571 gtk_text_iter_get_offset(&end)) | |
572 return FALSE; | |
573 | |
574 /* A link was clicked--we emit the "url_clicked" signal | |
575 * with the URL as the argument */ | |
5091 | 576 g_signal_emit(imhtml, signals[URL_CLICKED], 0, url); |
4417 | 577 return FALSE; |
578 } else if(event_button->button == 3) { | |
4745 | 579 GtkWidget *img, *item, *menu; |
4417 | 580 struct url_data *tempdata = g_new(struct url_data, 1); |
5091 | 581 tempdata->object = g_object_ref(imhtml); |
4417 | 582 tempdata->url = g_strdup(url); |
4745 | 583 |
5091 | 584 /* Don't want the tooltip around if user right-clicked on link */ |
585 if (GTK_IMHTML(imhtml)->tip_window) { | |
586 gtk_widget_destroy(GTK_IMHTML(imhtml)->tip_window); | |
587 GTK_IMHTML(imhtml)->tip_window = NULL; | |
588 } | |
589 if (GTK_IMHTML(imhtml)->tip_timer) { | |
590 g_source_remove(GTK_IMHTML(imhtml)->tip_timer); | |
591 GTK_IMHTML(imhtml)->tip_timer = 0; | |
592 } | |
593 gdk_window_set_cursor(event_button->window, GTK_IMHTML(imhtml)->arrow_cursor); | |
4417 | 594 menu = gtk_menu_new(); |
4745 | 595 |
4417 | 596 /* buttons and such */ |
597 | |
7140
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
598 if (!strncmp(url, "mailto:", 7)) |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
599 { |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
600 /* Copy E-Mail Address */ |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
601 img = gtk_image_new_from_stock(GTK_STOCK_COPY, |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
602 GTK_ICON_SIZE_MENU); |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
603 item = gtk_image_menu_item_new_with_mnemonic( |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
604 _("_Copy E-Mail Address")); |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
605 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), img); |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
606 g_signal_connect(G_OBJECT(item), "activate", |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
607 G_CALLBACK(url_copy), url + 7); |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
608 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
609 } |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
610 else |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
611 { |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
612 /* Copy Link Location */ |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
613 img = gtk_image_new_from_stock(GTK_STOCK_COPY, |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
614 GTK_ICON_SIZE_MENU); |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
615 item = gtk_image_menu_item_new_with_mnemonic( |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
616 _("_Copy Link Location")); |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
617 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), img); |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
618 g_signal_connect(G_OBJECT(item), "activate", |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
619 G_CALLBACK(url_copy), url); |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
620 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
621 |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
622 /* Open Link in Browser */ |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
623 img = gtk_image_new_from_stock(GTK_STOCK_JUMP_TO, |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
624 GTK_ICON_SIZE_MENU); |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
625 item = gtk_image_menu_item_new_with_mnemonic( |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
626 _("_Open Link in Browser")); |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
627 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), img); |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
628 g_signal_connect(G_OBJECT(item), "activate", |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
629 G_CALLBACK(url_open), tempdata); |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
630 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
631 } |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
632 |
4756 | 633 |
4417 | 634 gtk_widget_show_all(menu); |
4756 | 635 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, |
636 event_button->button, event_button->time); | |
4745 | 637 |
4417 | 638 return TRUE; |
639 } | |
1428 | 640 } |
4417 | 641 if(event->type == GDK_BUTTON_PRESS && event_button->button == 3) |
642 return TRUE; /* Clicking the right mouse button on a link shouldn't | |
643 be caught by the regular GtkTextView menu */ | |
644 else | |
645 return FALSE; /* Let clicks go through if we didn't catch anything */ | |
1428 | 646 } |
647 | |
4298 | 648 /* this isn't used yet |
4032 | 649 static void |
4263 | 650 gtk_smiley_tree_remove (GtkSmileyTree *tree, |
651 GtkIMHtmlSmiley *smiley) | |
4032 | 652 { |
653 GtkSmileyTree *t = tree; | |
4263 | 654 const gchar *x = smiley->smile; |
4032 | 655 gint len = 0; |
656 | |
657 while (*x) { | |
658 gchar *pos; | |
659 | |
660 if (!t->values) | |
661 return; | |
662 | |
663 pos = strchr (t->values->str, *x); | |
664 if (pos) | |
665 t = t->children [(int) pos - (int) t->values->str]; | |
666 else | |
667 return; | |
668 | |
669 x++; len++; | |
670 } | |
671 | |
4141
ccec4fde84f4
[gaim-migrate @ 4359]
Christian Hammond <chipx86@chipx86.com>
parents:
4140
diff
changeset
|
672 if (t->image) { |
4032 | 673 t->image = NULL; |
4141
ccec4fde84f4
[gaim-migrate @ 4359]
Christian Hammond <chipx86@chipx86.com>
parents:
4140
diff
changeset
|
674 } |
4032 | 675 } |
4298 | 676 */ |
677 | |
4032 | 678 |
679 static gint | |
680 gtk_smiley_tree_lookup (GtkSmileyTree *tree, | |
681 const gchar *text) | |
682 { | |
683 GtkSmileyTree *t = tree; | |
684 const gchar *x = text; | |
685 gint len = 0; | |
686 | |
687 while (*x) { | |
688 gchar *pos; | |
689 | |
690 if (!t->values) | |
691 break; | |
692 | |
693 pos = strchr (t->values->str, *x); | |
694 if (pos) | |
6478
338147ea6896
[gaim-migrate @ 6991]
Christian Hammond <chipx86@chipx86.com>
parents:
6162
diff
changeset
|
695 t = t->children [(int) pos - GPOINTER_TO_INT(t->values->str)]; |
4032 | 696 else |
697 break; | |
698 | |
699 x++; len++; | |
700 } | |
701 | |
702 if (t->image) | |
703 return len; | |
704 | |
705 return 0; | |
706 } | |
707 | |
708 void | |
4263 | 709 gtk_imhtml_associate_smiley (GtkIMHtml *imhtml, |
710 gchar *sml, | |
711 GtkIMHtmlSmiley *smiley) | |
4032 | 712 { |
713 GtkSmileyTree *tree; | |
714 g_return_if_fail (imhtml != NULL); | |
715 g_return_if_fail (GTK_IS_IMHTML (imhtml)); | |
4263 | 716 |
4032 | 717 if (sml == NULL) |
718 tree = imhtml->default_smilies; | |
719 else if ((tree = g_hash_table_lookup(imhtml->smiley_data, sml))) { | |
720 } else { | |
721 tree = gtk_smiley_tree_new(); | |
4892 | 722 g_hash_table_insert(imhtml->smiley_data, g_strdup(sml), tree); |
4032 | 723 } |
724 | |
4263 | 725 gtk_smiley_tree_insert (tree, smiley); |
4032 | 726 } |
727 | |
728 static gboolean | |
729 gtk_imhtml_is_smiley (GtkIMHtml *imhtml, | |
730 GSList *fonts, | |
731 const gchar *text, | |
732 gint *len) | |
733 { | |
734 GtkSmileyTree *tree; | |
5967 | 735 GtkIMHtmlFontDetail *font; |
4032 | 736 char *sml = NULL; |
737 | |
738 if (fonts) { | |
739 font = fonts->data; | |
740 sml = font->sml; | |
741 } | |
742 | |
743 if (sml == NULL) | |
744 tree = imhtml->default_smilies; | |
745 else { | |
746 tree = g_hash_table_lookup(imhtml->smiley_data, sml); | |
747 } | |
748 if (tree == NULL) | |
749 return FALSE; | |
750 | |
751 *len = gtk_smiley_tree_lookup (tree, text); | |
752 return (*len > 0); | |
753 } | |
754 | |
6814
782907a6ae65
[gaim-migrate @ 7354]
Christian Hammond <chipx86@chipx86.com>
parents:
6648
diff
changeset
|
755 GdkPixbufAnimation * |
4032 | 756 gtk_smiley_tree_image (GtkIMHtml *imhtml, |
757 const gchar *sml, | |
758 const gchar *text) | |
759 { | |
760 GtkSmileyTree *t; | |
761 const gchar *x = text; | |
762 if (sml == NULL) | |
763 t = imhtml->default_smilies; | |
764 else | |
765 t = g_hash_table_lookup(imhtml->smiley_data, sml); | |
766 | |
767 | |
768 if (t == NULL) | |
769 return sml ? gtk_smiley_tree_image(imhtml, NULL, text) : NULL; | |
770 | |
771 while (*x) { | |
772 gchar *pos; | |
773 | |
774 if (!t->values) { | |
775 return sml ? gtk_smiley_tree_image(imhtml, NULL, text) : NULL; | |
776 } | |
777 | |
778 pos = strchr (t->values->str, *x); | |
779 if (pos) { | |
6478
338147ea6896
[gaim-migrate @ 6991]
Christian Hammond <chipx86@chipx86.com>
parents:
6162
diff
changeset
|
780 t = t->children [(int) pos - GPOINTER_TO_INT(t->values->str)]; |
4032 | 781 } else { |
782 return sml ? gtk_smiley_tree_image(imhtml, NULL, text) : NULL; | |
783 } | |
784 x++; | |
785 } | |
786 | |
4263 | 787 if (!t->image->icon) |
6814
782907a6ae65
[gaim-migrate @ 7354]
Christian Hammond <chipx86@chipx86.com>
parents:
6648
diff
changeset
|
788 t->image->icon = gdk_pixbuf_animation_new_from_file(t->image->file, NULL); |
4263 | 789 |
790 return t->image->icon; | |
4032 | 791 } |
4793 | 792 #define VALID_TAG(x) if (!g_ascii_strncasecmp (string, x ">", strlen (x ">"))) { \ |
3922 | 793 *tag = g_strndup (string, strlen (x)); \ |
794 *len = strlen (x) + 1; \ | |
795 return TRUE; \ | |
796 } \ | |
797 (*type)++ | |
1428 | 798 |
4793 | 799 #define VALID_OPT_TAG(x) if (!g_ascii_strncasecmp (string, x " ", strlen (x " "))) { \ |
3922 | 800 const gchar *c = string + strlen (x " "); \ |
801 gchar e = '"'; \ | |
802 gboolean quote = FALSE; \ | |
803 while (*c) { \ | |
804 if (*c == '"' || *c == '\'') { \ | |
805 if (quote && (*c == e)) \ | |
806 quote = !quote; \ | |
807 else if (!quote) { \ | |
808 quote = !quote; \ | |
809 e = *c; \ | |
810 } \ | |
811 } else if (!quote && (*c == '>')) \ | |
812 break; \ | |
813 c++; \ | |
814 } \ | |
815 if (*c) { \ | |
816 *tag = g_strndup (string, c - string); \ | |
817 *len = c - string + 1; \ | |
818 return TRUE; \ | |
819 } \ | |
820 } \ | |
821 (*type)++ | |
1428 | 822 |
823 | |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
824 static gboolean |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
825 gtk_imhtml_is_amp_escape (const gchar *string, |
7280 | 826 gchar **replace, |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
827 gint *length) |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
828 { |
7287 | 829 static char buf[7]; |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
830 g_return_val_if_fail (string != NULL, FALSE); |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
831 g_return_val_if_fail (replace != NULL, FALSE); |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
832 g_return_val_if_fail (length != NULL, FALSE); |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
833 |
4793 | 834 if (!g_ascii_strncasecmp (string, "&", 5)) { |
7280 | 835 *replace = "&"; |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
836 *length = 5; |
4793 | 837 } else if (!g_ascii_strncasecmp (string, "<", 4)) { |
7280 | 838 *replace = "<"; |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
839 *length = 4; |
4793 | 840 } else if (!g_ascii_strncasecmp (string, ">", 4)) { |
7280 | 841 *replace = ">"; |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
842 *length = 4; |
4793 | 843 } else if (!g_ascii_strncasecmp (string, " ", 6)) { |
7280 | 844 *replace = " "; |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
845 *length = 6; |
4793 | 846 } else if (!g_ascii_strncasecmp (string, "©", 6)) { |
7280 | 847 *replace = "©"; |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
848 *length = 6; |
4793 | 849 } else if (!g_ascii_strncasecmp (string, """, 6)) { |
7280 | 850 *replace = "\""; |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
851 *length = 6; |
4793 | 852 } else if (!g_ascii_strncasecmp (string, "®", 5)) { |
7280 | 853 *replace = "®"; |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
854 *length = 5; |
5093 | 855 } else if (!g_ascii_strncasecmp (string, "'", 6)) { |
7280 | 856 *replace = "\'"; |
5093 | 857 *length = 6; |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
858 } else if (*(string + 1) == '#') { |
2022
199ba82faacb
[gaim-migrate @ 2032]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2002
diff
changeset
|
859 guint pound = 0; |
3004 | 860 if ((sscanf (string, "&#%u;", £) == 1) && pound != 0) { |
7287 | 861 int buflen; |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
862 if (*(string + 3 + (gint)log10 (pound)) != ';') |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
863 return FALSE; |
7287 | 864 buflen = g_unichar_to_utf8((gunichar)pound, buf); |
865 buf[buflen] = '\0'; | |
7280 | 866 *replace = buf; |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
867 *length = 2; |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
868 while (isdigit ((gint) string [*length])) (*length)++; |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
869 if (string [*length] == ';') (*length)++; |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
870 } else { |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
871 return FALSE; |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
872 } |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
873 } else { |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
874 return FALSE; |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
875 } |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
876 |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
877 return TRUE; |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
878 } |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
879 |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
880 static gboolean |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
881 gtk_imhtml_is_tag (const gchar *string, |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
882 gchar **tag, |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
883 gint *len, |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
884 gint *type) |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
885 { |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
886 *type = 1; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
887 |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
888 if (!strchr (string, '>')) |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
889 return FALSE; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
890 |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
891 VALID_TAG ("B"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
892 VALID_TAG ("BOLD"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
893 VALID_TAG ("/B"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
894 VALID_TAG ("/BOLD"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
895 VALID_TAG ("I"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
896 VALID_TAG ("ITALIC"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
897 VALID_TAG ("/I"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
898 VALID_TAG ("/ITALIC"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
899 VALID_TAG ("U"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
900 VALID_TAG ("UNDERLINE"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
901 VALID_TAG ("/U"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
902 VALID_TAG ("/UNDERLINE"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
903 VALID_TAG ("S"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
904 VALID_TAG ("STRIKE"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
905 VALID_TAG ("/S"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
906 VALID_TAG ("/STRIKE"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
907 VALID_TAG ("SUB"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
908 VALID_TAG ("/SUB"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
909 VALID_TAG ("SUP"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
910 VALID_TAG ("/SUP"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
911 VALID_TAG ("PRE"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
912 VALID_TAG ("/PRE"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
913 VALID_TAG ("TITLE"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
914 VALID_TAG ("/TITLE"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
915 VALID_TAG ("BR"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
916 VALID_TAG ("HR"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
917 VALID_TAG ("/FONT"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
918 VALID_TAG ("/A"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
919 VALID_TAG ("P"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
920 VALID_TAG ("/P"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
921 VALID_TAG ("H3"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
922 VALID_TAG ("/H3"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
923 VALID_TAG ("HTML"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
924 VALID_TAG ("/HTML"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
925 VALID_TAG ("BODY"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
926 VALID_TAG ("/BODY"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
927 VALID_TAG ("FONT"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
928 VALID_TAG ("HEAD"); |
2993 | 929 VALID_TAG ("/HEAD"); |
930 VALID_TAG ("BINARY"); | |
931 VALID_TAG ("/BINARY"); | |
5093 | 932 |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
933 VALID_OPT_TAG ("HR"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
934 VALID_OPT_TAG ("FONT"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
935 VALID_OPT_TAG ("BODY"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
936 VALID_OPT_TAG ("A"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
937 VALID_OPT_TAG ("IMG"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
938 VALID_OPT_TAG ("P"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
939 VALID_OPT_TAG ("H3"); |
5093 | 940 VALID_OPT_TAG ("HTML"); |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
941 |
5101 | 942 VALID_TAG ("CITE"); |
943 VALID_TAG ("/CITE"); | |
944 VALID_TAG ("EM"); | |
945 VALID_TAG ("/EM"); | |
946 VALID_TAG ("STRONG"); | |
947 VALID_TAG ("/STRONG"); | |
948 | |
5104 | 949 VALID_OPT_TAG ("SPAN"); |
950 VALID_TAG ("/SPAN"); | |
5174 | 951 VALID_TAG ("BR/"); /* hack until gtkimhtml handles things better */ |
6982 | 952 VALID_TAG ("IMG"); |
5104 | 953 |
4793 | 954 if (!g_ascii_strncasecmp(string, "!--", strlen ("!--"))) { |
2954
f6c4f2187c08
[gaim-migrate @ 2967]
Christian Hammond <chipx86@chipx86.com>
parents:
2898
diff
changeset
|
955 gchar *e = strstr (string + strlen("!--"), "-->"); |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
956 if (e) { |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
957 *len = e - string + strlen ("-->"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
958 *tag = g_strndup (string + strlen ("!--"), *len - strlen ("!---->")); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
959 return TRUE; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
960 } |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
961 } |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
962 |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
963 return FALSE; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
964 } |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
965 |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
966 static gchar* |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
967 gtk_imhtml_get_html_opt (gchar *tag, |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
968 const gchar *opt) |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
969 { |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
970 gchar *t = tag; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
971 gchar *e, *a; |
5177 | 972 gchar *val; |
973 gint len; | |
7280 | 974 gchar *c; |
5177 | 975 GString *ret; |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
976 |
4793 | 977 while (g_ascii_strncasecmp (t, opt, strlen (opt))) { |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
978 gboolean quote = FALSE; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
979 if (*t == '\0') break; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
980 while (*t && !((*t == ' ') && !quote)) { |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
981 if (*t == '\"') |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
982 quote = ! quote; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
983 t++; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
984 } |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
985 while (*t && (*t == ' ')) t++; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
986 } |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
987 |
4793 | 988 if (!g_ascii_strncasecmp (t, opt, strlen (opt))) { |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
989 t += strlen (opt); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
990 } else { |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
991 return NULL; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
992 } |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
993 |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
994 if ((*t == '\"') || (*t == '\'')) { |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
995 e = a = ++t; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
996 while (*e && (*e != *(t - 1))) e++; |
2993 | 997 if (*e == '\0') { |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
998 return NULL; |
5177 | 999 } else |
1000 val = g_strndup(a, e - a); | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1001 } else { |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1002 e = a = t; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1003 while (*e && !isspace ((gint) *e)) e++; |
5177 | 1004 val = g_strndup(a, e - a); |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1005 } |
5177 | 1006 |
1007 ret = g_string_new(""); | |
1008 e = val; | |
1009 while(*e) { | |
1010 if(gtk_imhtml_is_amp_escape(e, &c, &len)) { | |
7280 | 1011 ret = g_string_append(ret, c); |
5177 | 1012 e += len; |
1013 } else { | |
1014 ret = g_string_append_c(ret, *e); | |
1015 e++; | |
1016 } | |
1017 } | |
1018 | |
1019 g_free(val); | |
1020 val = ret->str; | |
1021 g_string_free(ret, FALSE); | |
1022 return val; | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1023 } |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1024 |
3922 | 1025 |
1026 | |
1027 #define NEW_TEXT_BIT 0 | |
4343 | 1028 #define NEW_COMMENT_BIT 2 |
4895 | 1029 #define NEW_SCALABLE_BIT 1 |
3922 | 1030 #define NEW_BIT(x) ws [wpos] = '\0'; \ |
1031 mark2 = gtk_text_buffer_create_mark(imhtml->text_buffer, NULL, &iter, TRUE); \ | |
1032 gtk_text_buffer_insert(imhtml->text_buffer, &iter, ws, -1); \ | |
4895 | 1033 gtk_text_buffer_get_end_iter(imhtml->text_buffer, &iter); \ |
3922 | 1034 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &siter, mark2); \ |
1035 gtk_text_buffer_delete_mark(imhtml->text_buffer, mark2); \ | |
1036 if (bold) \ | |
1037 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "BOLD", &siter, &iter); \ | |
4895 | 1038 if (italics) \ |
3922 | 1039 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "ITALICS", &siter, &iter); \ |
1040 if (underline) \ | |
1041 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "UNDERLINE", &siter, &iter); \ | |
1042 if (strike) \ | |
1043 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "STRIKE", &siter, &iter); \ | |
1044 if (sub) \ | |
1045 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "SUB", &siter, &iter); \ | |
1046 if (sup) \ | |
1047 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "SUP", &siter, &iter); \ | |
1048 if (pre) \ | |
1049 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "PRE", &siter, &iter); \ | |
1050 if (bg) { \ | |
1051 texttag = gtk_text_buffer_create_tag(imhtml->text_buffer, NULL, "background", bg, NULL); \ | |
1052 gtk_text_buffer_apply_tag(imhtml->text_buffer, texttag, &siter, &iter); \ | |
1053 } \ | |
1054 if (fonts) { \ | |
5967 | 1055 GtkIMHtmlFontDetail *fd = fonts->data; \ |
3922 | 1056 if (fd->fore) { \ |
1057 texttag = gtk_text_buffer_create_tag(imhtml->text_buffer, NULL, "foreground", fd->fore, NULL); \ | |
1058 gtk_text_buffer_apply_tag(imhtml->text_buffer, texttag, &siter, &iter); \ | |
1059 } \ | |
1060 if (fd->back) { \ | |
1061 texttag = gtk_text_buffer_create_tag(imhtml->text_buffer, NULL, "background", fd->back, NULL); \ | |
1062 gtk_text_buffer_apply_tag(imhtml->text_buffer, texttag, &siter, &iter); \ | |
1063 } \ | |
1064 if (fd->face) { \ | |
6648 | 1065 texttag = gtk_text_buffer_create_tag(imhtml->text_buffer, NULL, "family", fd->face, NULL); \ |
3922 | 1066 gtk_text_buffer_apply_tag(imhtml->text_buffer, texttag, &siter, &iter); \ |
1067 } \ | |
1068 if (fd->size) { \ | |
5118 | 1069 texttag = gtk_text_buffer_create_tag(imhtml->text_buffer, NULL, "size-points", (double)POINT_SIZE(fd->size), NULL); \ |
3922 | 1070 gtk_text_buffer_apply_tag(imhtml->text_buffer, texttag, &siter, &iter); \ |
1071 } \ | |
1072 } \ | |
1073 if (url) { \ | |
1074 texttag = gtk_text_buffer_create_tag(imhtml->text_buffer, NULL, "foreground", "blue", "underline", PANGO_UNDERLINE_SINGLE, NULL); \ | |
5012 | 1075 g_signal_connect(G_OBJECT(texttag), "event", G_CALLBACK(tag_event), g_strdup(url)); \ |
3922 | 1076 gtk_text_buffer_apply_tag(imhtml->text_buffer, texttag, &siter, &iter); \ |
4735 | 1077 texttag = gtk_text_buffer_create_tag(imhtml->text_buffer, NULL, NULL); \ |
1078 g_object_set_data(G_OBJECT(texttag), "link_url", g_strdup(url)); \ | |
1079 gtk_text_buffer_apply_tag(imhtml->text_buffer, texttag, &siter, &iter); \ | |
3922 | 1080 } \ |
1081 wpos = 0; \ | |
1082 ws[0] = 0; \ | |
1083 gtk_text_buffer_get_end_iter(imhtml->text_buffer, &iter); \ | |
4895 | 1084 if (x == NEW_SCALABLE_BIT) { \ |
1085 GdkRectangle rect; \ | |
1086 gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(imhtml), &rect); \ | |
1087 scalable->add_to(scalable, imhtml, &iter); \ | |
1088 scalable->scale(scalable, rect.width, rect.height); \ | |
1089 imhtml->scalables = g_list_append(imhtml->scalables, scalable); \ | |
1090 gtk_text_buffer_get_end_iter(imhtml->text_buffer, &iter); \ | |
4343 | 1091 } \ |
3922 | 1092 |
4895 | 1093 |
1094 | |
6982 | 1095 GString* gtk_imhtml_append_text_with_images (GtkIMHtml *imhtml, |
1096 const gchar *text, | |
1097 GtkIMHtmlOptions options, | |
1098 GSList *images) | |
1428 | 1099 { |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1100 gint pos = 0; |
3922 | 1101 GString *str = NULL; |
1102 GtkTextIter iter, siter; | |
1103 GtkTextMark *mark, *mark2; | |
1104 GtkTextTag *texttag; | |
1105 gchar *ws; | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1106 gchar *tag; |
3922 | 1107 gchar *url = NULL; |
1108 gchar *bg = NULL; | |
6982 | 1109 gint len; |
4032 | 1110 gint tlen, smilelen, wpos=0; |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1111 gint type; |
3922 | 1112 const gchar *c; |
7280 | 1113 gchar *amp; |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1114 |
1428 | 1115 guint bold = 0, |
1116 italics = 0, | |
1117 underline = 0, | |
1118 strike = 0, | |
1119 sub = 0, | |
1120 sup = 0, | |
1691
d802b115800f
[gaim-migrate @ 1701]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1647
diff
changeset
|
1121 title = 0, |
3922 | 1122 pre = 0; |
1428 | 1123 |
3922 | 1124 GSList *fonts = NULL; |
1428 | 1125 |
4612 | 1126 GdkRectangle rect; |
1127 int y, height; | |
1128 | |
4895 | 1129 GtkIMHtmlScalable *scalable = NULL; |
1130 | |
1428 | 1131 g_return_val_if_fail (imhtml != NULL, NULL); |
1132 g_return_val_if_fail (GTK_IS_IMHTML (imhtml), NULL); | |
1133 g_return_val_if_fail (text != NULL, NULL); | |
6982 | 1134 |
3922 | 1135 c = text; |
6982 | 1136 len = strlen(text); |
3922 | 1137 ws = g_malloc(len + 1); |
1138 ws[0] = 0; | |
1428 | 1139 |
1140 if (options & GTK_IMHTML_RETURN_LOG) | |
3922 | 1141 str = g_string_new(""); |
1428 | 1142 |
3922 | 1143 gtk_text_buffer_get_end_iter(imhtml->text_buffer, &iter); |
1144 mark = gtk_text_buffer_create_mark (imhtml->text_buffer, NULL, &iter, /* right grav */ FALSE); | |
4612 | 1145 |
1146 gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(imhtml), &rect); | |
1147 gtk_text_view_get_line_yrange(GTK_TEXT_VIEW(imhtml), &iter, &y, &height); | |
1148 | |
1149 if(((y + height) - (rect.y + rect.height)) > height | |
1150 && gtk_text_buffer_get_char_count(imhtml->text_buffer)){ | |
1151 options |= GTK_IMHTML_NO_SCROLL; | |
1152 } | |
1153 | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1154 while (pos < len) { |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1155 if (*c == '<' && gtk_imhtml_is_tag (c + 1, &tag, &tlen, &type)) { |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1156 c++; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1157 pos++; |
3922 | 1158 switch (type) |
1159 { | |
1160 case 1: /* B */ | |
1161 case 2: /* BOLD */ | |
5101 | 1162 case 54: /* STRONG */ |
3922 | 1163 NEW_BIT (NEW_TEXT_BIT); |
1164 bold++; | |
1165 break; | |
1166 case 3: /* /B */ | |
1167 case 4: /* /BOLD */ | |
5101 | 1168 case 55: /* /STRONG */ |
3922 | 1169 NEW_BIT (NEW_TEXT_BIT); |
1170 if (bold) | |
1171 bold--; | |
1172 break; | |
1173 case 5: /* I */ | |
1174 case 6: /* ITALIC */ | |
5101 | 1175 case 52: /* EM */ |
3922 | 1176 NEW_BIT (NEW_TEXT_BIT); |
1177 italics++; | |
1178 break; | |
1179 case 7: /* /I */ | |
1180 case 8: /* /ITALIC */ | |
5101 | 1181 case 53: /* /EM */ |
3922 | 1182 NEW_BIT (NEW_TEXT_BIT); |
1183 if (italics) | |
1184 italics--; | |
1185 break; | |
1186 case 9: /* U */ | |
1187 case 10: /* UNDERLINE */ | |
1188 NEW_BIT (NEW_TEXT_BIT); | |
1189 underline++; | |
1190 break; | |
1191 case 11: /* /U */ | |
1192 case 12: /* /UNDERLINE */ | |
1193 NEW_BIT (NEW_TEXT_BIT); | |
1194 if (underline) | |
1195 underline--; | |
1196 break; | |
1197 case 13: /* S */ | |
1198 case 14: /* STRIKE */ | |
1199 NEW_BIT (NEW_TEXT_BIT); | |
1200 strike++; | |
1201 break; | |
1202 case 15: /* /S */ | |
1203 case 16: /* /STRIKE */ | |
1204 NEW_BIT (NEW_TEXT_BIT); | |
1205 if (strike) | |
1206 strike--; | |
1207 break; | |
1208 case 17: /* SUB */ | |
1209 NEW_BIT (NEW_TEXT_BIT); | |
1210 sub++; | |
1211 break; | |
1212 case 18: /* /SUB */ | |
1213 NEW_BIT (NEW_TEXT_BIT); | |
1214 if (sub) | |
1215 sub--; | |
1216 break; | |
1217 case 19: /* SUP */ | |
1218 NEW_BIT (NEW_TEXT_BIT); | |
1219 sup++; | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1220 break; |
3922 | 1221 case 20: /* /SUP */ |
1222 NEW_BIT (NEW_TEXT_BIT); | |
1223 if (sup) | |
1224 sup--; | |
1225 break; | |
1226 case 21: /* PRE */ | |
1227 NEW_BIT (NEW_TEXT_BIT); | |
1228 pre++; | |
1229 break; | |
1230 case 22: /* /PRE */ | |
1231 NEW_BIT (NEW_TEXT_BIT); | |
1232 if (pre) | |
1233 pre--; | |
1234 break; | |
1235 case 23: /* TITLE */ | |
1236 NEW_BIT (NEW_TEXT_BIT); | |
1237 title++; | |
1238 break; | |
1239 case 24: /* /TITLE */ | |
1240 if (title) { | |
1241 if (options & GTK_IMHTML_NO_TITLE) { | |
1242 wpos = 0; | |
1243 ws [wpos] = '\0'; | |
1244 } | |
1245 title--; | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1246 } |
3922 | 1247 break; |
1248 case 25: /* BR */ | |
5174 | 1249 case 58: /* BR/ */ |
3922 | 1250 ws[wpos] = '\n'; |
1251 wpos++; | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1252 NEW_BIT (NEW_TEXT_BIT); |
6982 | 1253 break; |
3922 | 1254 case 26: /* HR */ |
1255 case 42: /* HR (opt) */ | |
1256 ws[wpos++] = '\n'; | |
5967 | 1257 scalable = gtk_imhtml_hr_new(); |
4895 | 1258 NEW_BIT(NEW_SCALABLE_BIT); |
4343 | 1259 ws[wpos++] = '\n'; |
3922 | 1260 break; |
1261 case 27: /* /FONT */ | |
1262 if (fonts) { | |
5967 | 1263 GtkIMHtmlFontDetail *font = fonts->data; |
3922 | 1264 NEW_BIT (NEW_TEXT_BIT); |
1265 fonts = g_slist_remove (fonts, font); | |
1266 if (font->face) | |
1267 g_free (font->face); | |
1268 if (font->fore) | |
1269 g_free (font->fore); | |
1270 if (font->back) | |
1271 g_free (font->back); | |
4032 | 1272 if (font->sml) |
1273 g_free (font->sml); | |
3922 | 1274 g_free (font); |
1275 } | |
1276 break; | |
1277 case 28: /* /A */ | |
1278 if (url) { | |
1279 NEW_BIT(NEW_TEXT_BIT); | |
1280 g_free(url); | |
1281 url = NULL; | |
2993 | 1282 break; |
1283 } | |
3922 | 1284 case 29: /* P */ |
1285 case 30: /* /P */ | |
1286 case 31: /* H3 */ | |
1287 case 32: /* /H3 */ | |
1288 case 33: /* HTML */ | |
1289 case 34: /* /HTML */ | |
1290 case 35: /* BODY */ | |
1291 case 36: /* /BODY */ | |
1292 case 37: /* FONT */ | |
1293 case 38: /* HEAD */ | |
1294 case 39: /* /HEAD */ | |
6982 | 1295 case 40: /* BINARY */ |
1296 case 41: /* /BINARY */ | |
3922 | 1297 break; |
1298 case 43: /* FONT (opt) */ | |
1299 { | |
4032 | 1300 gchar *color, *back, *face, *size, *sml; |
5967 | 1301 GtkIMHtmlFontDetail *font, *oldfont = NULL; |
3922 | 1302 color = gtk_imhtml_get_html_opt (tag, "COLOR="); |
1303 back = gtk_imhtml_get_html_opt (tag, "BACK="); | |
1304 face = gtk_imhtml_get_html_opt (tag, "FACE="); | |
1305 size = gtk_imhtml_get_html_opt (tag, "SIZE="); | |
4032 | 1306 sml = gtk_imhtml_get_html_opt (tag, "SML="); |
1307 if (!(color || back || face || size || sml)) | |
3922 | 1308 break; |
1309 | |
1310 NEW_BIT (NEW_TEXT_BIT); | |
1311 | |
5967 | 1312 font = g_new0 (GtkIMHtmlFontDetail, 1); |
3922 | 1313 if (fonts) |
1314 oldfont = fonts->data; | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1315 |
3922 | 1316 if (color && !(options & GTK_IMHTML_NO_COLOURS)) |
1317 font->fore = color; | |
1318 else if (oldfont && oldfont->fore) | |
1319 font->fore = g_strdup(oldfont->fore); | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1320 |
3922 | 1321 if (back && !(options & GTK_IMHTML_NO_COLOURS)) |
1322 font->back = back; | |
1323 else if (oldfont && oldfont->back) | |
1324 font->back = g_strdup(oldfont->back); | |
1325 | |
1326 if (face && !(options & GTK_IMHTML_NO_FONTS)) | |
1327 font->face = face; | |
1328 else if (oldfont && oldfont->face) | |
1329 font->face = g_strdup(oldfont->face); | |
4629 | 1330 if (font->face && (atoi(font->face) > 100)) { |
1331 g_free(font->face); | |
1332 font->face = g_strdup("100"); | |
1333 } | |
4032 | 1334 |
1335 if (sml) | |
1336 font->sml = sml; | |
1337 else if (oldfont && oldfont->sml) | |
1338 font->sml = g_strdup(oldfont->sml); | |
1339 | |
3922 | 1340 if (size && !(options & GTK_IMHTML_NO_SIZES)) { |
1341 if (*size == '+') { | |
1342 sscanf (size + 1, "%hd", &font->size); | |
1343 font->size += 3; | |
1344 } else if (*size == '-') { | |
1345 sscanf (size + 1, "%hd", &font->size); | |
1346 font->size = MAX (0, 3 - font->size); | |
1347 } else if (isdigit (*size)) { | |
1348 sscanf (size, "%hd", &font->size); | |
1349 } | |
6042 | 1350 if (font->size > 100) |
1351 font->size = 100; | |
3922 | 1352 } else if (oldfont) |
1353 font->size = oldfont->size; | |
1354 g_free(size); | |
1355 fonts = g_slist_prepend (fonts, font); | |
1356 } | |
1357 break; | |
1358 case 44: /* BODY (opt) */ | |
1359 if (!(options & GTK_IMHTML_NO_COLOURS)) { | |
1360 char *bgcolor = gtk_imhtml_get_html_opt (tag, "BGCOLOR="); | |
1361 if (bgcolor) { | |
1362 NEW_BIT(NEW_TEXT_BIT); | |
1363 if (bg) | |
1364 g_free(bg); | |
1365 bg = bgcolor; | |
2885
f72efa29c109
[gaim-migrate @ 2898]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2871
diff
changeset
|
1366 } |
1428 | 1367 } |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1368 break; |
3922 | 1369 case 45: /* A (opt) */ |
1370 { | |
1371 gchar *href = gtk_imhtml_get_html_opt (tag, "HREF="); | |
1372 if (href) { | |
1373 NEW_BIT (NEW_TEXT_BIT); | |
1374 if (url) | |
1375 g_free (url); | |
1376 url = href; | |
1377 } | |
2993 | 1378 } |
3922 | 1379 break; |
4895 | 1380 case 46: /* IMG (opt) */ |
6982 | 1381 case 59: /* IMG */ |
4895 | 1382 { |
6982 | 1383 GdkPixbuf *img = NULL; |
1384 const gchar *filename = NULL; | |
4895 | 1385 |
6982 | 1386 if (images && images->data) { |
1387 img = images->data; | |
1388 images = images->next; | |
1389 filename = g_object_get_data(G_OBJECT(img), "filename"); | |
1390 g_object_ref(G_OBJECT(img)); | |
1391 } else { | |
1392 img = gtk_widget_render_icon(GTK_WIDGET(imhtml), | |
1393 GTK_STOCK_MISSING_IMAGE, GTK_ICON_SIZE_BUTTON, | |
1394 "gtkimhtml-missing-image"); | |
1395 } | |
4895 | 1396 |
6982 | 1397 scalable = gtk_imhtml_image_new(img, filename); |
1398 NEW_BIT(NEW_SCALABLE_BIT); | |
1399 g_object_unref(G_OBJECT(img)); | |
4895 | 1400 } |
3922 | 1401 case 47: /* P (opt) */ |
1402 case 48: /* H3 (opt) */ | |
5093 | 1403 case 49: /* HTML (opt) */ |
5101 | 1404 case 50: /* CITE */ |
1405 case 51: /* /CITE */ | |
5104 | 1406 case 56: /* SPAN */ |
1407 case 57: /* /SPAN */ | |
2993 | 1408 break; |
6982 | 1409 case 60: /* comment */ |
3922 | 1410 NEW_BIT (NEW_TEXT_BIT); |
6124 | 1411 if (imhtml->show_comments) |
1412 wpos = g_snprintf (ws, len, "%s", tag); | |
3922 | 1413 NEW_BIT (NEW_COMMENT_BIT); |
1414 break; | |
1415 default: | |
6882 | 1416 break; |
2993 | 1417 } |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1418 c += tlen; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1419 pos += tlen; |
4138 | 1420 if(tag) |
1421 g_free(tag); /* This was allocated back in VALID_TAG() */ | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1422 } else if (*c == '&' && gtk_imhtml_is_amp_escape (c, &, &tlen)) { |
7280 | 1423 while(*amp) { |
1424 ws [wpos++] = *amp++; | |
1425 } | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1426 c += tlen; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1427 pos += tlen; |
1428 | 1428 } else if (*c == '\n') { |
1429 if (!(options & GTK_IMHTML_NO_NEWLINE)) { | |
3922 | 1430 ws[wpos] = '\n'; |
1431 wpos++; | |
1428 | 1432 NEW_BIT (NEW_TEXT_BIT); |
1433 } | |
1434 c++; | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1435 pos++; |
4253 | 1436 } else if (imhtml->show_smileys && (gtk_imhtml_is_smiley (imhtml, fonts, c, &smilelen) || gtk_imhtml_is_smiley(imhtml, NULL, c, &smilelen))) { |
6814
782907a6ae65
[gaim-migrate @ 7354]
Christian Hammond <chipx86@chipx86.com>
parents:
6648
diff
changeset
|
1437 GtkTextChildAnchor *anchor; |
6882 | 1438 GtkWidget *icon = NULL; |
7344 | 1439 GtkTextIter copy; |
6882 | 1440 GdkPixbufAnimation *annipixbuf = NULL; |
1441 GdkPixbuf *pixbuf = NULL; | |
5967 | 1442 GtkIMHtmlFontDetail *fd; |
7346 | 1443 |
4032 | 1444 gchar *sml = NULL; |
1445 if (fonts) { | |
1446 fd = fonts->data; | |
1447 sml = fd->sml; | |
1448 } | |
1449 NEW_BIT (NEW_TEXT_BIT); | |
1450 wpos = g_snprintf (ws, smilelen + 1, "%s", c); | |
6814
782907a6ae65
[gaim-migrate @ 7354]
Christian Hammond <chipx86@chipx86.com>
parents:
6648
diff
changeset
|
1451 anchor = gtk_text_buffer_create_child_anchor(imhtml->text_buffer, &iter); |
6882 | 1452 annipixbuf = gtk_smiley_tree_image(imhtml, sml, ws); |
1453 if(annipixbuf) { | |
1454 if(gdk_pixbuf_animation_is_static_image(annipixbuf)) { | |
1455 pixbuf = gdk_pixbuf_animation_get_static_image(annipixbuf); | |
1456 if(pixbuf) | |
1457 icon = gtk_image_new_from_pixbuf(pixbuf); | |
1458 } else { | |
1459 icon = gtk_image_new_from_animation(annipixbuf); | |
1460 } | |
1461 } | |
1462 | |
1463 if (icon) { | |
6839
bdc4e73f354d
[gaim-migrate @ 7384]
Christian Hammond <chipx86@chipx86.com>
parents:
6814
diff
changeset
|
1464 gtk_widget_show(icon); |
bdc4e73f354d
[gaim-migrate @ 7384]
Christian Hammond <chipx86@chipx86.com>
parents:
6814
diff
changeset
|
1465 gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), icon, anchor); |
7346 | 1466 gtk_imhtml_copyable_new(imhtml, |
1467 gtk_text_buffer_create_mark(imhtml->text_buffer, NULL, &iter, TRUE), | |
1468 ws); | |
6839
bdc4e73f354d
[gaim-migrate @ 7384]
Christian Hammond <chipx86@chipx86.com>
parents:
6814
diff
changeset
|
1469 } |
7344 | 1470 |
1471 copy = iter; | |
1472 gtk_text_iter_backward_char(©); | |
1473 if (bg) { | |
1474 texttag = gtk_text_buffer_create_tag(imhtml->text_buffer, NULL, "background", bg, NULL); | |
1475 gtk_text_buffer_apply_tag(imhtml->text_buffer, texttag, &iter, ©); | |
1476 } | |
1477 if (fonts) { | |
1478 GtkIMHtmlFontDetail *fd = fonts->data; | |
1479 if (fd->back) { | |
1480 texttag = gtk_text_buffer_create_tag(imhtml->text_buffer, NULL, "background", fd->back, NULL); | |
1481 gtk_text_buffer_apply_tag(imhtml->text_buffer, texttag, &iter, ©); | |
1482 } | |
1483 } | |
4032 | 1484 c += smilelen; |
1485 pos += smilelen; | |
1486 wpos = 0; | |
1487 ws[0] = 0; | |
1488 } else if (*c) { | |
1428 | 1489 ws [wpos++] = *c++; |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1490 pos++; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1491 } else { |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1492 break; |
1428 | 1493 } |
1494 } | |
3922 | 1495 |
1496 NEW_BIT(NEW_TEXT_BIT); | |
1428 | 1497 if (url) { |
1498 g_free (url); | |
3922 | 1499 if (str) |
1500 str = g_string_append (str, "</A>"); | |
1428 | 1501 } |
3922 | 1502 |
4032 | 1503 while (fonts) { |
5967 | 1504 GtkIMHtmlFontDetail *font = fonts->data; |
4032 | 1505 fonts = g_slist_remove (fonts, font); |
1506 if (font->face) | |
1507 g_free (font->face); | |
1508 if (font->fore) | |
1509 g_free (font->fore); | |
1510 if (font->back) | |
1511 g_free (font->back); | |
1512 if (font->sml) | |
1513 g_free (font->sml); | |
1514 g_free (font); | |
1515 if (str) | |
1516 str = g_string_append (str, "</FONT>"); | |
1517 } | |
1518 | |
3922 | 1519 if (str) { |
1428 | 1520 while (bold) { |
3922 | 1521 str = g_string_append (str, "</B>"); |
1428 | 1522 bold--; |
1523 } | |
1524 while (italics) { | |
3922 | 1525 str = g_string_append (str, "</I>"); |
1428 | 1526 italics--; |
1527 } | |
1528 while (underline) { | |
3922 | 1529 str = g_string_append (str, "</U>"); |
1428 | 1530 underline--; |
1531 } | |
1532 while (strike) { | |
3922 | 1533 str = g_string_append (str, "</S>"); |
1428 | 1534 strike--; |
1535 } | |
1536 while (sub) { | |
3922 | 1537 str = g_string_append (str, "</SUB>"); |
1428 | 1538 sub--; |
1539 } | |
1540 while (sup) { | |
3922 | 1541 str = g_string_append (str, "</SUP>"); |
1428 | 1542 sup--; |
1543 } | |
1544 while (title) { | |
3922 | 1545 str = g_string_append (str, "</TITLE>"); |
1428 | 1546 title--; |
1547 } | |
1691
d802b115800f
[gaim-migrate @ 1701]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1647
diff
changeset
|
1548 while (pre) { |
3922 | 1549 str = g_string_append (str, "</PRE>"); |
1691
d802b115800f
[gaim-migrate @ 1701]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1647
diff
changeset
|
1550 pre--; |
d802b115800f
[gaim-migrate @ 1701]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1647
diff
changeset
|
1551 } |
1428 | 1552 } |
4032 | 1553 g_free (ws); |
4630 | 1554 if(bg) |
1555 g_free(bg); | |
4032 | 1556 if (!(options & GTK_IMHTML_NO_SCROLL)) |
1557 gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (imhtml), mark, | |
1558 0, TRUE, 0.0, 1.0); | |
3922 | 1559 gtk_text_buffer_delete_mark (imhtml->text_buffer, mark); |
1560 return str; | |
1561 } | |
1562 | |
4892 | 1563 void gtk_imhtml_remove_smileys(GtkIMHtml *imhtml) |
1564 { | |
4288 | 1565 g_hash_table_destroy(imhtml->smiley_data); |
1566 gtk_smiley_tree_destroy(imhtml->default_smilies); | |
4892 | 1567 imhtml->smiley_data = g_hash_table_new_full(g_str_hash, g_str_equal, |
4902 | 1568 g_free, (GDestroyNotify)gtk_smiley_tree_destroy); |
4288 | 1569 imhtml->default_smilies = gtk_smiley_tree_new(); |
1570 } | |
3922 | 1571 void gtk_imhtml_show_smileys (GtkIMHtml *imhtml, |
4253 | 1572 gboolean show) |
1573 { | |
1574 imhtml->show_smileys = show; | |
1575 } | |
3922 | 1576 |
1577 void gtk_imhtml_show_comments (GtkIMHtml *imhtml, | |
4253 | 1578 gboolean show) |
1579 { | |
6124 | 1580 imhtml->show_comments = show; |
4253 | 1581 } |
1780
d7cbedd1d651
[gaim-migrate @ 1790]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1738
diff
changeset
|
1582 |
d7cbedd1d651
[gaim-migrate @ 1790]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1738
diff
changeset
|
1583 void |
d7cbedd1d651
[gaim-migrate @ 1790]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1738
diff
changeset
|
1584 gtk_imhtml_clear (GtkIMHtml *imhtml) |
d7cbedd1d651
[gaim-migrate @ 1790]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1738
diff
changeset
|
1585 { |
3922 | 1586 GtkTextIter start, end; |
2993 | 1587 |
3922 | 1588 gtk_text_buffer_get_start_iter(imhtml->text_buffer, &start); |
1589 gtk_text_buffer_get_end_iter(imhtml->text_buffer, &end); | |
1590 gtk_text_buffer_delete(imhtml->text_buffer, &start, &end); | |
1780
d7cbedd1d651
[gaim-migrate @ 1790]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1738
diff
changeset
|
1591 } |
2363
08c66712364c
[gaim-migrate @ 2376]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2349
diff
changeset
|
1592 |
4046 | 1593 void gtk_imhtml_page_up (GtkIMHtml *imhtml) |
1594 { | |
5282 | 1595 GdkRectangle rect; |
1596 GtkTextIter iter; | |
4046 | 1597 |
5282 | 1598 gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(imhtml), &rect); |
1599 gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(imhtml), &iter, rect.x, | |
1600 rect.y - rect.height); | |
1601 gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(imhtml), &iter, 0, TRUE, 0, 0); | |
1602 | |
4046 | 1603 } |
5282 | 1604 void gtk_imhtml_page_down (GtkIMHtml *imhtml) |
1605 { | |
1606 GdkRectangle rect; | |
1607 GtkTextIter iter; | |
1608 | |
1609 gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(imhtml), &rect); | |
1610 gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(imhtml), &iter, rect.x, | |
1611 rect.y + rect.height); | |
1612 gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(imhtml), &iter, 0, TRUE, 0, 0); | |
1613 } | |
4735 | 1614 |
5967 | 1615 /* GtkIMHtmlScalable, gtk_imhtml_image, gtk_imhtml_hr */ |
6982 | 1616 GtkIMHtmlScalable *gtk_imhtml_image_new(GdkPixbuf *img, const gchar *filename) |
4735 | 1617 { |
5967 | 1618 GtkIMHtmlImage *im_image = g_malloc(sizeof(GtkIMHtmlImage)); |
5012 | 1619 GtkImage *image = GTK_IMAGE(gtk_image_new_from_pixbuf(img)); |
4895 | 1620 |
5967 | 1621 GTK_IMHTML_SCALABLE(im_image)->scale = gtk_imhtml_image_scale; |
1622 GTK_IMHTML_SCALABLE(im_image)->add_to = gtk_imhtml_image_add_to; | |
1623 GTK_IMHTML_SCALABLE(im_image)->free = gtk_imhtml_image_free; | |
5046 | 1624 |
1625 im_image->pixbuf = img; | |
5012 | 1626 im_image->image = image; |
4895 | 1627 im_image->width = gdk_pixbuf_get_width(img); |
1628 im_image->height = gdk_pixbuf_get_height(img); | |
1629 im_image->mark = NULL; | |
6982 | 1630 im_image->filename = filename ? g_strdup(filename) : NULL; |
4895 | 1631 |
5046 | 1632 g_object_ref(img); |
4895 | 1633 return GTK_IMHTML_SCALABLE(im_image); |
1634 } | |
1635 | |
5967 | 1636 void gtk_imhtml_image_scale(GtkIMHtmlScalable *scale, int width, int height) |
4895 | 1637 { |
5967 | 1638 GtkIMHtmlImage *image = (GtkIMHtmlImage *)scale; |
4895 | 1639 |
1640 if(image->width > width || image->height > height){ | |
1641 GdkPixbuf *new_image = NULL; | |
1642 float factor; | |
1643 int new_width = image->width, new_height = image->height; | |
1644 | |
1645 if(image->width > width){ | |
1646 factor = (float)(width)/image->width; | |
1647 new_width = width; | |
1648 new_height = image->height * factor; | |
1649 } | |
1650 if(new_height > height){ | |
1651 factor = (float)(height)/new_height; | |
1652 new_height = height; | |
1653 new_width = new_width * factor; | |
1654 } | |
1655 | |
5046 | 1656 new_image = gdk_pixbuf_scale_simple(image->pixbuf, new_width, new_height, GDK_INTERP_BILINEAR); |
5012 | 1657 gtk_image_set_from_pixbuf(image->image, new_image); |
4895 | 1658 g_object_unref(G_OBJECT(new_image)); |
1659 } | |
1660 } | |
1661 | |
5012 | 1662 static void write_img_to_file(GtkWidget *w, GtkFileSelection *sel) |
1663 { | |
1664 const gchar *filename = gtk_file_selection_get_filename(sel); | |
5967 | 1665 gchar *dirname; |
1666 GtkIMHtmlImage *image = g_object_get_data(G_OBJECT(sel), "GtkIMHtmlImage"); | |
5012 | 1667 gchar *type = NULL; |
5019 | 1668 GError *error = NULL; |
5015 | 1669 #if GTK_CHECK_VERSION(2,2,0) |
5012 | 1670 GSList *formats = gdk_pixbuf_get_formats(); |
6162 | 1671 #else |
1672 char *basename = g_path_get_basename(filename); | |
1673 char *ext = strrchr(basename, '.'); | |
5959 | 1674 #endif |
5012 | 1675 |
5967 | 1676 if (g_file_test(filename, G_FILE_TEST_IS_DIR)) { |
1677 /* append a / if needed */ | |
1678 if (filename[strlen(filename) - 1] != '/') { | |
1679 dirname = g_strconcat(filename, "/", NULL); | |
1680 } else { | |
1681 dirname = g_strdup(filename); | |
1682 } | |
1683 gtk_file_selection_set_filename(sel, dirname); | |
1684 g_free(dirname); | |
5959 | 1685 return; |
5967 | 1686 } |
5959 | 1687 |
1688 #if GTK_CHECK_VERSION(2,2,0) | |
5012 | 1689 while(formats){ |
1690 GdkPixbufFormat *format = formats->data; | |
1691 gchar **extensions = gdk_pixbuf_format_get_extensions(format); | |
1692 gpointer p = extensions; | |
1693 | |
1694 while(gdk_pixbuf_format_is_writable(format) && extensions && extensions[0]){ | |
1695 gchar *fmt_ext = extensions[0]; | |
1696 const gchar* file_ext = filename + strlen(filename) - strlen(fmt_ext); | |
1697 | |
1698 if(!strcmp(fmt_ext, file_ext)){ | |
1699 type = gdk_pixbuf_format_get_name(format); | |
1700 break; | |
1701 } | |
1702 | |
1703 extensions++; | |
1704 } | |
1705 | |
1706 g_strfreev(p); | |
1707 | |
1708 if(type) | |
1709 break; | |
1710 | |
1711 formats = formats->next; | |
1712 } | |
1713 | |
5020 | 1714 g_slist_free(formats); |
1715 #else | |
1716 /* this is really ugly code, but I think it will work */ | |
1717 if(ext) { | |
1718 ext++; | |
1719 if(!g_ascii_strcasecmp(ext, "jpeg") || !g_ascii_strcasecmp(ext, "jpg")) | |
1720 type = g_strdup("jpeg"); | |
1721 else if(!g_ascii_strcasecmp(ext, "png")) | |
1722 type = g_strdup("png"); | |
1723 } | |
1724 | |
1725 g_free(basename); | |
1726 #endif | |
1727 | |
5012 | 1728 /* If I can't find a valid type, I will just tell the user about it and then assume |
1729 it's a png */ | |
1730 if(!type){ | |
1731 gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, | |
5967 | 1732 _("Unable to guess the image type based on the file extension supplied. Defaulting to PNG.")); |
5012 | 1733 type = g_strdup("png"); |
1734 } | |
1735 | |
5046 | 1736 gdk_pixbuf_save(image->pixbuf, filename, type, &error, NULL); |
5012 | 1737 |
1738 if(error){ | |
1739 gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, | |
1740 _("Error saving image: %s"), error->message); | |
1741 g_error_free(error); | |
1742 } | |
1743 | |
1744 g_free(type); | |
1745 } | |
1746 | |
5967 | 1747 static void gtk_imhtml_image_save(GtkWidget *w, GtkIMHtmlImage *image) |
5012 | 1748 { |
5967 | 1749 GtkWidget *sel = gtk_file_selection_new(_("Save Image")); |
5012 | 1750 |
6982 | 1751 if (image->filename) |
1752 gtk_file_selection_set_filename(GTK_FILE_SELECTION(sel), image->filename); | |
5967 | 1753 g_object_set_data(G_OBJECT(sel), "GtkIMHtmlImage", image); |
5012 | 1754 g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(sel)->ok_button), "clicked", |
1755 G_CALLBACK(write_img_to_file), sel); | |
1756 | |
1757 g_signal_connect_swapped(G_OBJECT(GTK_FILE_SELECTION(sel)->ok_button), "clicked", | |
1758 G_CALLBACK(gtk_widget_destroy), sel); | |
1759 g_signal_connect_swapped(G_OBJECT(GTK_FILE_SELECTION(sel)->cancel_button), "clicked", | |
1760 G_CALLBACK(gtk_widget_destroy), sel); | |
1761 | |
1762 gtk_widget_show(sel); | |
1763 } | |
1764 | |
5967 | 1765 static gboolean gtk_imhtml_image_clicked(GtkWidget *w, GdkEvent *event, GtkIMHtmlImage *image) |
5012 | 1766 { |
1767 GdkEventButton *event_button = (GdkEventButton *) event; | |
1768 | |
1769 if (event->type == GDK_BUTTON_RELEASE) { | |
1770 if(event_button->button == 3) { | |
1771 GtkWidget *img, *item, *menu; | |
1772 gchar *text = g_strdup_printf(_("_Save Image...")); | |
1773 menu = gtk_menu_new(); | |
1774 | |
1775 /* buttons and such */ | |
1776 img = gtk_image_new_from_stock(GTK_STOCK_SAVE, GTK_ICON_SIZE_MENU); | |
1777 item = gtk_image_menu_item_new_with_mnemonic(text); | |
1778 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), img); | |
5967 | 1779 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(gtk_imhtml_image_save), image); |
5012 | 1780 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); |
1781 | |
1782 gtk_widget_show_all(menu); | |
1783 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, | |
1784 event_button->button, event_button->time); | |
1785 | |
1786 g_free(text); | |
1787 return TRUE; | |
1788 } | |
1789 } | |
1790 if(event->type == GDK_BUTTON_PRESS && event_button->button == 3) | |
1791 return TRUE; /* Clicking the right mouse button on a link shouldn't | |
1792 be caught by the regular GtkTextView menu */ | |
1793 else | |
1794 return FALSE; /* Let clicks go through if we didn't catch anything */ | |
1795 | |
1796 } | |
5967 | 1797 void gtk_imhtml_image_free(GtkIMHtmlScalable *scale) |
1798 { | |
1799 GtkIMHtmlImage *image = (GtkIMHtmlImage *)scale; | |
1800 | |
1801 g_object_unref(image->pixbuf); | |
6982 | 1802 if (image->filename) |
1803 g_free(image->filename); | |
5967 | 1804 g_free(scale); |
1805 } | |
1806 | |
1807 void gtk_imhtml_image_add_to(GtkIMHtmlScalable *scale, GtkIMHtml *imhtml, GtkTextIter *iter) | |
1808 { | |
1809 GtkIMHtmlImage *image = (GtkIMHtmlImage *)scale; | |
1810 GtkWidget *box = gtk_event_box_new(); | |
1811 GtkTextChildAnchor *anchor = gtk_text_buffer_create_child_anchor(imhtml->text_buffer, iter); | |
1812 | |
1813 gtk_container_add(GTK_CONTAINER(box), GTK_WIDGET(image->image)); | |
1814 | |
1815 gtk_widget_show(GTK_WIDGET(image->image)); | |
1816 gtk_widget_show(box); | |
1817 | |
1818 gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), box, anchor); | |
1819 g_signal_connect(G_OBJECT(box), "event", G_CALLBACK(gtk_imhtml_image_clicked), image); | |
1820 } | |
1821 | |
1822 GtkIMHtmlScalable *gtk_imhtml_hr_new() | |
1823 { | |
1824 GtkIMHtmlHr *hr = g_malloc(sizeof(GtkIMHtmlHr)); | |
1825 | |
1826 GTK_IMHTML_SCALABLE(hr)->scale = gtk_imhtml_hr_scale; | |
1827 GTK_IMHTML_SCALABLE(hr)->add_to = gtk_imhtml_hr_add_to; | |
1828 GTK_IMHTML_SCALABLE(hr)->free = gtk_imhtml_hr_free; | |
1829 | |
1830 hr->sep = gtk_hseparator_new(); | |
1831 gtk_widget_set_size_request(hr->sep, 5000, 2); | |
1832 gtk_widget_show(hr->sep); | |
1833 | |
1834 return GTK_IMHTML_SCALABLE(hr); | |
1835 } | |
1836 | |
1837 void gtk_imhtml_hr_scale(GtkIMHtmlScalable *scale, int width, int height) | |
1838 { | |
1839 gtk_widget_set_size_request(((GtkIMHtmlHr *)scale)->sep, width, 2); | |
1840 } | |
1841 | |
1842 void gtk_imhtml_hr_add_to(GtkIMHtmlScalable *scale, GtkIMHtml *imhtml, GtkTextIter *iter) | |
1843 { | |
1844 GtkIMHtmlHr *hr = (GtkIMHtmlHr *)scale; | |
1845 GtkTextChildAnchor *anchor = gtk_text_buffer_create_child_anchor(imhtml->text_buffer, iter); | |
1846 | |
1847 gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), hr->sep, anchor); | |
1848 } | |
1849 | |
1850 void gtk_imhtml_hr_free(GtkIMHtmlScalable *scale) | |
1851 { | |
1852 g_free(scale); | |
1853 } | |
7295 | 1854 |
1855 gboolean gtk_imhtml_search_find(GtkIMHtml *imhtml, const gchar *text) | |
1856 { | |
1857 GtkTextIter iter, start, end; | |
1858 gboolean new_search = TRUE; | |
1859 | |
1860 g_return_val_if_fail(imhtml != NULL, FALSE); | |
1861 g_return_val_if_fail(text != NULL, FALSE); | |
1862 | |
1863 if (imhtml->search_string && !strcmp(text, imhtml->search_string)) | |
1864 new_search = FALSE; | |
1865 | |
1866 | |
1867 if (new_search) { | |
1868 gtk_imhtml_search_clear(imhtml); | |
1869 gtk_text_buffer_get_start_iter(imhtml->text_buffer, &iter); | |
1870 } else { | |
1871 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, | |
1872 gtk_text_buffer_get_mark(imhtml->text_buffer, "search")); | |
1873 } | |
1874 imhtml->search_string = g_strdup(text); | |
1875 | |
1876 if (gtk_text_iter_forward_search(&iter, imhtml->search_string, | |
1877 GTK_TEXT_SEARCH_VISIBLE_ONLY, | |
1878 &start, &end, NULL)) { | |
1879 | |
1880 gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(imhtml), &start, 0, TRUE, 0, 0); | |
1881 gtk_text_buffer_create_mark(imhtml->text_buffer, "search", &end, FALSE); | |
1882 if (new_search) { | |
1883 gtk_text_buffer_remove_tag_by_name(imhtml->text_buffer, "search", &iter, &end); | |
1884 do | |
1885 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "search", &start, &end); | |
1886 while (gtk_text_iter_forward_search(&end, imhtml->search_string, GTK_TEXT_SEARCH_VISIBLE_ONLY, | |
1887 &start, &end, NULL)); | |
1888 } | |
1889 return TRUE; | |
1890 } | |
1891 return FALSE; | |
1892 } | |
1893 | |
1894 void gtk_imhtml_search_clear(GtkIMHtml *imhtml) | |
1895 { | |
1896 GtkTextIter start, end; | |
1897 | |
1898 g_return_if_fail(imhtml != NULL); | |
1899 | |
1900 gtk_text_buffer_get_start_iter(imhtml->text_buffer, &start); | |
1901 gtk_text_buffer_get_end_iter(imhtml->text_buffer, &end); | |
1902 | |
1903 gtk_text_buffer_remove_tag_by_name(imhtml->text_buffer, "search", &start, &end); | |
1904 if (imhtml->search_string) | |
1905 g_free(imhtml->search_string); | |
1906 imhtml->search_string = NULL; | |
1907 } |