Mercurial > pidgin
annotate src/gtkimhtml.c @ 8319:a2c5537a814b
[gaim-migrate @ 9043]
This fixes the symbol collision, incorrect data types, lack of casting,
unused variables, and comments inside comments that were preventing the new
toolbar code from compiling in some cases here.
committer: Tailor Script <tailor@pidgin.im>
author | Christian Hammond <chipx86@chipx86.com> |
---|---|
date | Mon, 23 Feb 2004 22:13:43 +0000 |
parents | 6f549c1d0829 |
children | 0d1e5870d328 |
rev | line source |
---|---|
1428 | 1 /* |
2 * GtkIMHtml | |
3 * | |
8046 | 4 * Gaim is the legal property of its developers, whose names are too numerous |
5 * to list here. Please refer to the COPYRIGHT file distributed with this | |
6 * source distribution. | |
1428 | 7 * |
8 * This program is free software; you can redistribute it and/or modify | |
9 * under the terms of the GNU General Public License as published by | |
10 * the Free Software Foundation; either version 2 of the License, or | |
11 * (at your option) any later version. | |
12 * | |
13 * This program is distributed in the hope that it will be useful, | |
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 * GNU General Public License for more details. | |
17 * | |
18 * You should have received a copy of the GNU General Public License | |
19 * along with this program; if not, write to the Free Software | |
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
21 * | |
22 */ | |
23 | |
2541
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2365
diff
changeset
|
24 #ifdef HAVE_CONFIG_H |
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2365
diff
changeset
|
25 #include <config.h> |
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2365
diff
changeset
|
26 #endif |
8091 | 27 #include "util.h" |
1428 | 28 #include "gtkimhtml.h" |
7358 | 29 #include "gtksourceiter.h" |
1428 | 30 #include <gtk/gtk.h> |
4895 | 31 #include <glib/gerror.h> |
4046 | 32 #include <gdk/gdkkeysyms.h> |
1428 | 33 #include <string.h> |
34 #include <ctype.h> | |
35 #include <stdio.h> | |
4629 | 36 #include <stdlib.h> |
1428 | 37 #include <math.h> |
2541
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2365
diff
changeset
|
38 #ifdef HAVE_LANGINFO_CODESET |
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2365
diff
changeset
|
39 #include <langinfo.h> |
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2365
diff
changeset
|
40 #include <locale.h> |
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2365
diff
changeset
|
41 #endif |
1428 | 42 |
4417 | 43 #ifdef ENABLE_NLS |
44 # include <libintl.h> | |
45 # define _(x) gettext(x) | |
46 # ifdef gettext_noop | |
47 # define N_(String) gettext_noop (String) | |
48 # else | |
49 # define N_(String) (String) | |
50 # endif | |
51 #else | |
52 # define N_(String) (String) | |
53 # define _(x) (x) | |
54 #endif | |
55 | |
4735 | 56 #include <pango/pango-font.h> |
57 | |
5105 | 58 /* GTK+ < 2.2.2 hack, see ui.h for details. */ |
59 #ifndef GTK_WRAP_WORD_CHAR | |
60 #define GTK_WRAP_WORD_CHAR GTK_WRAP_WORD | |
61 #endif | |
62 | |
4735 | 63 #define TOOLTIP_TIMEOUT 500 |
64 | |
8061 | 65 static void insert_cb(GtkTextBuffer *buffer, GtkTextIter *iter, gchar *text, gint len, GtkIMHtml *imhtml); |
66 void gtk_imhtml_close_tags(GtkIMHtml *imhtml); | |
8091 | 67 static void gtk_imhtml_link_drag_rcv_cb(GtkWidget *widget, GdkDragContext *dc, guint x, guint y, GtkSelectionData *sd, guint info, guint t, GtkIMHtml *imhtml); |
8061 | 68 |
3922 | 69 /* POINT_SIZE converts from AIM font sizes to point sizes. It probably should be redone in such a |
70 * way that it base the sizes off the default font size rather than using arbitrary font sizes. */ | |
71 #define MAX_FONT_SIZE 7 | |
5367 | 72 #define POINT_SIZE(x) (options & GTK_IMHTML_USE_POINTSIZE ? x : _point_sizes [MIN ((x), MAX_FONT_SIZE) - 1]) |
8309 | 73 static gdouble _point_sizes [] = { .5, .75, 1, 1.5, 2, 3, 4}; |
2349
60c716c32c40
[gaim-migrate @ 2362]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2348
diff
changeset
|
74 |
8061 | 75 enum { |
76 TARGET_HTML, | |
77 TARGET_UTF8_STRING, | |
78 TARGET_COMPOUND_TEXT, | |
79 TARGET_STRING, | |
80 TARGET_TEXT | |
81 }; | |
82 | |
8091 | 83 enum { |
84 DRAG_URL | |
85 }; | |
86 | |
8061 | 87 GtkTargetEntry selection_targets[] = { |
88 { "text/html", 0, TARGET_HTML }, | |
89 { "UTF8_STRING", 0, TARGET_UTF8_STRING }, | |
90 { "COMPOUND_TEXT", 0, TARGET_COMPOUND_TEXT }, | |
91 { "STRING", 0, TARGET_STRING }, | |
92 { "TEXT", 0, TARGET_TEXT}}; | |
93 | |
8091 | 94 GtkTargetEntry link_drag_drop_targets[] = { |
95 {"x-url/ftp", 0, DRAG_URL}, | |
96 {"x-url/http", 0, DRAG_URL}, | |
97 {"text/uri-list", 0, DRAG_URL}, | |
98 {"_NETSCAPE_URL", 0, DRAG_URL}}; | |
99 | |
4032 | 100 static GtkSmileyTree* |
101 gtk_smiley_tree_new () | |
102 { | |
103 return g_new0 (GtkSmileyTree, 1); | |
104 } | |
105 | |
106 static void | |
107 gtk_smiley_tree_insert (GtkSmileyTree *tree, | |
4263 | 108 GtkIMHtmlSmiley *smiley) |
4032 | 109 { |
110 GtkSmileyTree *t = tree; | |
4263 | 111 const gchar *x = smiley->smile; |
4032 | 112 |
113 if (!strlen (x)) | |
114 return; | |
115 | |
116 while (*x) { | |
117 gchar *pos; | |
118 gint index; | |
119 | |
120 if (!t->values) | |
121 t->values = g_string_new (""); | |
122 | |
123 pos = strchr (t->values->str, *x); | |
124 if (!pos) { | |
125 t->values = g_string_append_c (t->values, *x); | |
126 index = t->values->len - 1; | |
127 t->children = g_realloc (t->children, t->values->len * sizeof (GtkSmileyTree *)); | |
128 t->children [index] = g_new0 (GtkSmileyTree, 1); | |
129 } else | |
7386 | 130 index = GPOINTER_TO_INT(pos) - GPOINTER_TO_INT(t->values->str); |
8061 | 131 |
4032 | 132 t = t->children [index]; |
8061 | 133 |
4032 | 134 x++; |
135 } | |
8061 | 136 |
4263 | 137 t->image = smiley; |
4032 | 138 } |
4041 | 139 |
4263 | 140 |
4264 | 141 void gtk_smiley_tree_destroy (GtkSmileyTree *tree) |
4032 | 142 { |
143 GSList *list = g_slist_append (NULL, tree); | |
144 | |
145 while (list) { | |
146 GtkSmileyTree *t = list->data; | |
147 gint i; | |
148 list = g_slist_remove(list, t); | |
7384 | 149 if (t && t->values) { |
4032 | 150 for (i = 0; i < t->values->len; i++) |
151 list = g_slist_append (list, t->children [i]); | |
152 g_string_free (t->values, TRUE); | |
153 g_free (t->children); | |
154 } | |
155 g_free (t); | |
156 } | |
157 } | |
158 | |
5967 | 159 static gboolean gtk_size_allocate_cb(GtkIMHtml *widget, GtkAllocation *alloc, gpointer user_data) |
160 { | |
161 GdkRectangle rect; | |
162 | |
163 gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(widget), &rect); | |
164 if(widget->old_rect.width != rect.width || widget->old_rect.height != rect.height){ | |
165 GList *iter = GTK_IMHTML(widget)->scalables; | |
166 | |
167 while(iter){ | |
168 GtkIMHtmlScalable *scale = GTK_IMHTML_SCALABLE(iter->data); | |
169 scale->scale(scale, rect.width, rect.height); | |
170 | |
171 iter = iter->next; | |
172 } | |
173 } | |
174 | |
175 widget->old_rect = rect; | |
176 return FALSE; | |
177 } | |
178 | |
179 static gint | |
180 gtk_imhtml_tip_paint (GtkIMHtml *imhtml) | |
181 { | |
182 PangoLayout *layout; | |
183 | |
184 g_return_val_if_fail(GTK_IS_IMHTML(imhtml), FALSE); | |
185 | |
186 layout = gtk_widget_create_pango_layout(imhtml->tip_window, imhtml->tip); | |
187 | |
8061 | 188 gtk_paint_flat_box (imhtml->tip_window->style, imhtml->tip_window->window, |
5967 | 189 GTK_STATE_NORMAL, GTK_SHADOW_OUT, NULL, imhtml->tip_window, |
190 "tooltip", 0, 0, -1, -1); | |
191 | |
192 gtk_paint_layout (imhtml->tip_window->style, imhtml->tip_window->window, GTK_STATE_NORMAL, | |
193 FALSE, NULL, imhtml->tip_window, NULL, 4, 4, layout); | |
194 | |
195 g_object_unref(layout); | |
196 return FALSE; | |
197 } | |
198 | |
199 static gint | |
200 gtk_imhtml_tip (gpointer data) | |
201 { | |
202 GtkIMHtml *imhtml = data; | |
203 PangoFontMetrics *font; | |
204 PangoLayout *layout; | |
205 | |
206 gint gap, x, y, h, w, scr_w, baseline_skip; | |
207 | |
208 g_return_val_if_fail(GTK_IS_IMHTML(imhtml), FALSE); | |
209 | |
210 if (!imhtml->tip || !GTK_WIDGET_DRAWABLE (GTK_WIDGET(imhtml))) { | |
211 imhtml->tip_timer = 0; | |
212 return FALSE; | |
213 } | |
8061 | 214 |
5967 | 215 if (imhtml->tip_window){ |
216 gtk_widget_destroy (imhtml->tip_window); | |
217 imhtml->tip_window = NULL; | |
218 } | |
219 | |
220 imhtml->tip_timer = 0; | |
221 imhtml->tip_window = gtk_window_new (GTK_WINDOW_POPUP); | |
222 gtk_widget_set_app_paintable (imhtml->tip_window, TRUE); | |
223 gtk_window_set_resizable (GTK_WINDOW (imhtml->tip_window), FALSE); | |
224 gtk_widget_set_name (imhtml->tip_window, "gtk-tooltips"); | |
225 g_signal_connect_swapped (G_OBJECT (imhtml->tip_window), "expose_event", | |
226 G_CALLBACK (gtk_imhtml_tip_paint), imhtml); | |
227 | |
228 gtk_widget_ensure_style (imhtml->tip_window); | |
229 layout = gtk_widget_create_pango_layout(imhtml->tip_window, imhtml->tip); | |
230 font = pango_font_get_metrics(pango_context_load_font(pango_layout_get_context(layout), | |
8309 | 231 imhtml->tip_window->style->font_desc), |
232 NULL); | |
233 | |
5967 | 234 |
235 pango_layout_get_pixel_size(layout, &scr_w, NULL); | |
8061 | 236 gap = PANGO_PIXELS((pango_font_metrics_get_ascent(font) + |
5967 | 237 pango_font_metrics_get_descent(font))/ 4); |
238 | |
239 if (gap < 2) | |
240 gap = 2; | |
8061 | 241 baseline_skip = PANGO_PIXELS(pango_font_metrics_get_ascent(font) + |
5967 | 242 pango_font_metrics_get_descent(font)); |
243 w = 8 + scr_w; | |
244 h = 8 + baseline_skip; | |
245 | |
246 gdk_window_get_pointer (NULL, &x, &y, NULL); | |
247 if (GTK_WIDGET_NO_WINDOW (GTK_WIDGET(imhtml))) | |
248 y += GTK_WIDGET(imhtml)->allocation.y; | |
249 | |
250 scr_w = gdk_screen_width(); | |
251 | |
252 x -= ((w >> 1) + 4); | |
253 | |
254 if ((x + w) > scr_w) | |
255 x -= (x + w) - scr_w; | |
256 else if (x < 0) | |
257 x = 0; | |
258 | |
8061 | 259 y = y + PANGO_PIXELS(pango_font_metrics_get_ascent(font) + |
5967 | 260 pango_font_metrics_get_descent(font)); |
261 | |
262 gtk_widget_set_size_request (imhtml->tip_window, w, h); | |
263 gtk_widget_show (imhtml->tip_window); | |
264 gtk_window_move (GTK_WINDOW(imhtml->tip_window), x, y); | |
265 | |
266 pango_font_metrics_unref(font); | |
267 g_object_unref(layout); | |
268 | |
269 return FALSE; | |
270 } | |
271 | |
272 gboolean gtk_motion_event_notify(GtkWidget *imhtml, GdkEventMotion *event, gpointer data) | |
8061 | 273 { |
5967 | 274 GtkTextIter iter; |
275 GdkWindow *win = event->window; | |
276 int x, y; | |
277 char *tip = NULL; | |
278 GSList *tags = NULL, *templist = NULL; | |
279 gdk_window_get_pointer(GTK_WIDGET(imhtml)->window, NULL, NULL, NULL); | |
280 gtk_text_view_window_to_buffer_coords(GTK_TEXT_VIEW(imhtml), GTK_TEXT_WINDOW_WIDGET, | |
281 event->x, event->y, &x, &y); | |
282 gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(imhtml), &iter, x, y); | |
283 tags = gtk_text_iter_get_tags(&iter); | |
284 | |
285 templist = tags; | |
286 while (templist) { | |
287 GtkTextTag *tag = templist->data; | |
288 tip = g_object_get_data(G_OBJECT(tag), "link_url"); | |
289 if (tip) | |
290 break; | |
291 templist = templist->next; | |
292 } | |
8061 | 293 |
5967 | 294 if (GTK_IMHTML(imhtml)->tip) { |
295 if ((tip == GTK_IMHTML(imhtml)->tip)) { | |
296 return FALSE; | |
297 } | |
298 /* We've left the cell. Remove the timeout and create a new one below */ | |
299 if (GTK_IMHTML(imhtml)->tip_window) { | |
300 gtk_widget_destroy(GTK_IMHTML(imhtml)->tip_window); | |
301 GTK_IMHTML(imhtml)->tip_window = NULL; | |
302 } | |
8061 | 303 if (GTK_IMHTML(imhtml)->editable) |
304 gdk_window_set_cursor(win, GTK_IMHTML(imhtml)->text_cursor); | |
305 else | |
306 gdk_window_set_cursor(win, GTK_IMHTML(imhtml)->arrow_cursor); | |
5967 | 307 if (GTK_IMHTML(imhtml)->tip_timer) |
308 g_source_remove(GTK_IMHTML(imhtml)->tip_timer); | |
309 GTK_IMHTML(imhtml)->tip_timer = 0; | |
310 } | |
8061 | 311 |
5967 | 312 if(tip){ |
8061 | 313 if (!GTK_IMHTML(imhtml)->editable) |
314 gdk_window_set_cursor(win, GTK_IMHTML(imhtml)->hand_cursor); | |
315 GTK_IMHTML(imhtml)->tip_timer = g_timeout_add (TOOLTIP_TIMEOUT, | |
5967 | 316 gtk_imhtml_tip, imhtml); |
317 } | |
8061 | 318 |
5967 | 319 GTK_IMHTML(imhtml)->tip = tip; |
320 g_slist_free(tags); | |
321 return FALSE; | |
322 } | |
323 | |
324 gboolean gtk_leave_event_notify(GtkWidget *imhtml, GdkEventCrossing *event, gpointer data) | |
325 { | |
326 /* when leaving the widget, clear any current & pending tooltips and restore the cursor */ | |
327 if (GTK_IMHTML(imhtml)->tip_window) { | |
328 gtk_widget_destroy(GTK_IMHTML(imhtml)->tip_window); | |
329 GTK_IMHTML(imhtml)->tip_window = NULL; | |
330 } | |
331 if (GTK_IMHTML(imhtml)->tip_timer) { | |
332 g_source_remove(GTK_IMHTML(imhtml)->tip_timer); | |
333 GTK_IMHTML(imhtml)->tip_timer = 0; | |
334 } | |
8061 | 335 if (GTK_IMHTML(imhtml)->editable) |
336 gdk_window_set_cursor(event->window, GTK_IMHTML(imhtml)->text_cursor); | |
337 else | |
338 gdk_window_set_cursor(event->window, GTK_IMHTML(imhtml)->arrow_cursor); | |
5967 | 339 |
340 /* propogate the event normally */ | |
341 return FALSE; | |
342 } | |
343 | |
6066 | 344 /* |
345 * XXX - This should be removed eventually. | |
346 * | |
8061 | 347 * This function exists to work around a gross bug in GtkTextView. |
348 * Basically, we short circuit ctrl+a and ctrl+end because they make | |
6066 | 349 * el program go boom. |
350 * | |
8061 | 351 * It's supposed to be fixed in gtk2.2. You can view the bug report at |
6066 | 352 * http://bugzilla.gnome.org/show_bug.cgi?id=107939 |
353 */ | |
8317 | 354 |
355 /* | |
356 * I'm adding some keyboard shortcuts too. | |
357 */ | |
358 | |
359 gboolean gtk_key_pressed_cb(GtkIMHtml *imhtml, GdkEventKey *event, gpointer data) | |
360 { | |
361 char buf[7]; | |
362 buf[0] = '\0'; | |
363 | |
6066 | 364 if (event->state & GDK_CONTROL_MASK) |
365 switch (event->keyval) { | |
8317 | 366 case 'a': |
367 return TRUE; | |
368 break; | |
369 | |
370 case GDK_Home: | |
371 return TRUE; | |
372 break; | |
373 | |
374 case GDK_End: | |
375 return TRUE; | |
376 break; | |
377 | |
378 case 'b': /* ctrl-b is GDK_Left, which moves backwards. */ | |
379 case 'B': | |
380 gtk_imhtml_toggle_bold(imhtml); | |
381 return TRUE; | |
382 break; | |
383 | |
384 case 'f': | |
385 case 'F': | |
386 /*set_toggle(gtkconv->toolbar.font, | |
387 !gtk_toggle_button_get_active( | |
388 GTK_TOGGLE_BUTTON(gtkconv->toolbar.font)));*/ | |
389 | |
390 return TRUE; | |
391 break; | |
392 | |
393 case 'i': | |
394 case 'I': | |
395 /*set_toggle(gtkconv->toolbar.italic, | |
396 !gtk_toggle_button_get_active( | |
397 GTK_TOGGLE_BUTTON(gtkconv->toolbar.italic)));*/ | |
398 gtk_imhtml_toggle_italic(imhtml); | |
399 return TRUE; | |
400 break; | |
401 | |
402 case 'u': /* ctrl-u is GDK_Clear, which clears the line. */ | |
403 case 'U': | |
404 /*set_toggle(gtkconv->toolbar.underline, | |
405 !gtk_toggle_button_get_active( | |
406 GTK_TOGGLE_BUTTON(gtkconv->toolbar.underline)));*/ | |
407 gtk_imhtml_toggle_underline(imhtml); | |
408 return TRUE; | |
409 break; | |
410 | |
411 case '-': | |
412 /*set_toggle(gtkconv->toolbar.smaller_size, | |
413 !gtk_toggle_button_get_active( | |
414 GTK_TOGGLE_BUTTON(gtkconv->toolbar.smaller_size)));*/ | |
415 gtk_imhtml_font_shrink(imhtml); | |
416 return TRUE; | |
417 break; | |
418 | |
419 case '=': | |
420 case '+': | |
421 /*set_toggle(gtkconv->toolbar.larger_size, | |
422 !gtk_toggle_button_get_active( | |
423 GTK_TOGGLE_BUTTON(gtkconv->toolbar.larger_size)));*/ | |
424 gtk_imhtml_font_grow(imhtml); | |
425 return TRUE; | |
426 break; | |
427 | |
428 case '1': strcpy(buf, ":-)"); break; | |
429 case '2': strcpy(buf, ":-("); break; | |
430 case '3': strcpy(buf, ";-)"); break; | |
431 case '4': strcpy(buf, ":-P"); break; | |
432 case '5': strcpy(buf, "=-O"); break; | |
433 case '6': strcpy(buf, ":-*"); break; | |
434 case '7': strcpy(buf, ">:o"); break; | |
435 case '8': strcpy(buf, "8-)"); break; | |
436 case '!': strcpy(buf, ":-$"); break; | |
437 case '@': strcpy(buf, ":-!"); break; | |
438 case '#': strcpy(buf, ":-["); break; | |
439 case '$': strcpy(buf, "O:-)"); break; | |
440 case '%': strcpy(buf, ":-/"); break; | |
441 case '^': strcpy(buf, ":'("); break; | |
442 case '&': strcpy(buf, ":-X"); break; | |
443 case '*': strcpy(buf, ":-D"); break; | |
6066 | 444 } |
8317 | 445 if (*buf) { |
446 gtk_imhtml_insert_smiley(imhtml, NULL, buf);//->account->protocol_id, buf); | |
447 return TRUE; | |
448 } | |
6066 | 449 return FALSE; |
450 } | |
451 | |
7404
d889a99e0eb1
[gaim-migrate @ 8000]
Christian Hammond <chipx86@chipx86.com>
parents:
7386
diff
changeset
|
452 #if GTK_CHECK_VERSION(2,2,0) |
8061 | 453 static void gtk_imhtml_clipboard_get(GtkClipboard *clipboard, GtkSelectionData *selection_data, guint info, GtkIMHtml *imhtml) { |
454 GtkTextIter start, end; | |
455 GtkTextMark *sel = gtk_text_buffer_get_selection_bound(imhtml->text_buffer); | |
456 GtkTextMark *ins = gtk_text_buffer_get_insert(imhtml->text_buffer); | |
457 char *text; | |
458 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &start, sel); | |
459 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &end, ins); | |
460 | |
461 | |
462 if (info == TARGET_HTML) { | |
8149 | 463 int len; |
8148 | 464 char *selection; |
8061 | 465 GString *str = g_string_new(NULL); |
466 text = gtk_imhtml_get_markup_range(imhtml, &start, &end); | |
467 | |
468 /* Mozilla asks that we start our text/html with the Unicode byte order mark */ | |
469 str = g_string_append_unichar(str, 0xfeff); | |
470 str = g_string_append(str, text); | |
471 str = g_string_append_unichar(str, 0x0000); | |
8148 | 472 selection = g_convert(str->str, str->len, "UCS-2", "UTF-8", NULL, &len, NULL); |
8061 | 473 gtk_selection_data_set (selection_data, gdk_atom_intern("text/html", FALSE), 16, selection, len); |
474 g_string_free(str, TRUE); | |
475 g_free(selection); | |
476 } else { | |
477 text = gtk_text_buffer_get_text(imhtml->text_buffer, &start, &end, FALSE); | |
478 gtk_selection_data_set_text(selection_data, text, strlen(text)); | |
479 } | |
480 g_free(text); | |
481 } | |
482 | |
483 static void gtk_imhtml_primary_clipboard_clear(GtkClipboard *clipboard, GtkIMHtml *imhtml) | |
7749 | 484 { |
8061 | 485 GtkTextIter insert; |
486 GtkTextIter selection_bound; | |
487 | |
488 gtk_text_buffer_get_iter_at_mark (imhtml->text_buffer, &insert, | |
489 gtk_text_buffer_get_mark (imhtml->text_buffer, "insert")); | |
490 gtk_text_buffer_get_iter_at_mark (imhtml->text_buffer, &selection_bound, | |
491 gtk_text_buffer_get_mark (imhtml->text_buffer, "selection_bound")); | |
492 | |
493 if (!gtk_text_iter_equal (&insert, &selection_bound)) | |
494 gtk_text_buffer_move_mark (imhtml->text_buffer, | |
495 gtk_text_buffer_get_mark (imhtml->text_buffer, "selection_bound"), | |
496 &insert); | |
7749 | 497 } |
7742 | 498 |
7749 | 499 static void copy_clipboard_cb(GtkIMHtml *imhtml, GtkClipboard *clipboard) |
500 { | |
8061 | 501 gtk_clipboard_set_with_owner(gtk_widget_get_clipboard(GTK_WIDGET(imhtml), GDK_SELECTION_CLIPBOARD), |
502 selection_targets, sizeof(selection_targets) / sizeof(GtkTargetEntry), | |
503 (GtkClipboardGetFunc)gtk_imhtml_clipboard_get, | |
504 (GtkClipboardClearFunc)NULL, G_OBJECT(imhtml)); | |
7346 | 505 |
8061 | 506 g_signal_stop_emission_by_name(imhtml, "copy-clipboard"); |
507 } | |
508 | |
509 static void paste_received_cb (GtkClipboard *clipboard, GtkSelectionData *selection_data, gpointer data) | |
510 { | |
511 char *text; | |
512 guint16 c; | |
513 GtkIMHtml *imhtml = data; | |
7809 | 514 |
8123 | 515 if (!gtk_text_view_get_editable(GTK_TEXT_VIEW(imhtml))) |
8105 | 516 return; |
517 | |
8061 | 518 if (selection_data->length < 0) { |
519 text = gtk_clipboard_wait_for_text(clipboard); | |
8128
9aafd344230d
[gaim-migrate @ 8833]
Christian Hammond <chipx86@chipx86.com>
parents:
8123
diff
changeset
|
520 |
9aafd344230d
[gaim-migrate @ 8833]
Christian Hammond <chipx86@chipx86.com>
parents:
8123
diff
changeset
|
521 if (text == NULL) |
9aafd344230d
[gaim-migrate @ 8833]
Christian Hammond <chipx86@chipx86.com>
parents:
8123
diff
changeset
|
522 return; |
9aafd344230d
[gaim-migrate @ 8833]
Christian Hammond <chipx86@chipx86.com>
parents:
8123
diff
changeset
|
523 |
8061 | 524 } else { |
525 text = g_malloc((selection_data->format / 8) * selection_data->length); | |
526 memcpy(text, selection_data->data, selection_data->length * (selection_data->format / 8)); | |
7766 | 527 } |
8061 | 528 |
529 memcpy (&c, text, 2); | |
530 if (c == 0xfeff) { | |
531 /* This is UCS2 */ | |
532 char *utf8 = g_convert(text+2, (selection_data->length * (selection_data->format / 8)) - 2, "UTF-8", "UCS-2", NULL, NULL, NULL); | |
533 g_free(text); | |
534 text = utf8; | |
535 } | |
536 gtk_imhtml_close_tags(imhtml); | |
537 gtk_imhtml_append_text_with_images(imhtml, text, GTK_IMHTML_NO_NEWLINE, NULL); | |
538 } | |
539 | |
540 | |
541 static void paste_clipboard_cb(GtkIMHtml *imhtml, gpointer blah) | |
542 { | |
543 | |
544 GtkClipboard *clipboard = gtk_widget_get_clipboard(GTK_WIDGET(imhtml), GDK_SELECTION_CLIPBOARD); | |
545 gtk_clipboard_request_contents(clipboard, gdk_atom_intern("text/html", FALSE), | |
546 paste_received_cb, imhtml); | |
547 g_signal_stop_emission_by_name(imhtml, "paste-clipboard"); | |
7766 | 548 } |
549 | |
7346 | 550 static gboolean button_release_cb(GtkIMHtml *imhtml, GdkEventButton event, gpointer the_foibles_of_man) |
551 { | |
8061 | 552 GtkClipboard *clipboard; |
553 if (event.button == 1) { | |
554 if ((clipboard = gtk_widget_get_clipboard (GTK_WIDGET (imhtml), | |
555 GDK_SELECTION_PRIMARY))) | |
556 gtk_text_buffer_remove_selection_clipboard (imhtml->text_buffer, clipboard); | |
557 gtk_clipboard_set_with_owner(gtk_widget_get_clipboard(GTK_WIDGET(imhtml), GDK_SELECTION_PRIMARY), | |
558 selection_targets, sizeof(selection_targets) / sizeof(GtkTargetEntry), | |
559 (GtkClipboardGetFunc)gtk_imhtml_clipboard_get, | |
560 (GtkClipboardClearFunc)gtk_imhtml_primary_clipboard_clear, G_OBJECT(imhtml)); | |
561 } | |
7346 | 562 return FALSE; |
563 } | |
7404
d889a99e0eb1
[gaim-migrate @ 8000]
Christian Hammond <chipx86@chipx86.com>
parents:
7386
diff
changeset
|
564 #endif |
5967 | 565 |
4263 | 566 |
4032 | 567 static GtkTextViewClass *parent_class = NULL; |
568 | |
3922 | 569 /* GtkIMHtml has one signal--URL_CLICKED */ |
1428 | 570 enum { |
571 URL_CLICKED, | |
572 LAST_SIGNAL | |
573 }; | |
574 static guint signals [LAST_SIGNAL] = { 0 }; | |
575 | |
4032 | 576 static void |
577 gtk_imhtml_finalize (GObject *object) | |
578 { | |
579 GtkIMHtml *imhtml = GTK_IMHTML(object); | |
4895 | 580 GList *scalables; |
8061 | 581 |
4138 | 582 g_hash_table_destroy(imhtml->smiley_data); |
4032 | 583 gtk_smiley_tree_destroy(imhtml->default_smilies); |
4138 | 584 gdk_cursor_unref(imhtml->hand_cursor); |
585 gdk_cursor_unref(imhtml->arrow_cursor); | |
8061 | 586 gdk_cursor_unref(imhtml->text_cursor); |
4735 | 587 if(imhtml->tip_window){ |
588 gtk_widget_destroy(imhtml->tip_window); | |
589 } | |
590 if(imhtml->tip_timer) | |
591 gtk_timeout_remove(imhtml->tip_timer); | |
592 | |
4895 | 593 for(scalables = imhtml->scalables; scalables; scalables = scalables->next) { |
594 GtkIMHtmlScalable *scale = GTK_IMHTML_SCALABLE(scalables->data); | |
595 scale->free(scale); | |
596 } | |
7991 | 597 |
4895 | 598 g_list_free(imhtml->scalables); |
4032 | 599 G_OBJECT_CLASS(parent_class)->finalize (object); |
600 } | |
1428 | 601 |
3922 | 602 /* Boring GTK stuff */ |
603 static void gtk_imhtml_class_init (GtkIMHtmlClass *class) | |
1428 | 604 { |
3922 | 605 GtkObjectClass *object_class; |
4032 | 606 GObjectClass *gobject_class; |
3922 | 607 object_class = (GtkObjectClass*) class; |
4032 | 608 gobject_class = (GObjectClass*) class; |
609 parent_class = gtk_type_class(GTK_TYPE_TEXT_VIEW); | |
4417 | 610 signals[URL_CLICKED] = g_signal_new("url_clicked", |
611 G_TYPE_FROM_CLASS(gobject_class), | |
612 G_SIGNAL_RUN_FIRST, | |
613 G_STRUCT_OFFSET(GtkIMHtmlClass, url_clicked), | |
614 NULL, | |
615 0, | |
616 g_cclosure_marshal_VOID__POINTER, | |
617 G_TYPE_NONE, 1, | |
618 G_TYPE_POINTER); | |
4032 | 619 gobject_class->finalize = gtk_imhtml_finalize; |
1428 | 620 } |
621 | |
3922 | 622 static void gtk_imhtml_init (GtkIMHtml *imhtml) |
1428 | 623 { |
3922 | 624 GtkTextIter iter; |
625 imhtml->text_buffer = gtk_text_buffer_new(NULL); | |
626 gtk_text_buffer_get_end_iter (imhtml->text_buffer, &iter); | |
627 imhtml->end = gtk_text_buffer_create_mark(imhtml->text_buffer, NULL, &iter, FALSE); | |
628 gtk_text_view_set_buffer(GTK_TEXT_VIEW(imhtml), imhtml->text_buffer); | |
5105 | 629 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(imhtml), GTK_WRAP_WORD_CHAR); |
3922 | 630 gtk_text_view_set_pixels_below_lines(GTK_TEXT_VIEW(imhtml), 5); |
8061 | 631 /*gtk_text_view_set_indent(GTK_TEXT_VIEW(imhtml), -15);*/ |
3922 | 632 /*gtk_text_view_set_justification(GTK_TEXT_VIEW(imhtml), GTK_JUSTIFY_FILL);*/ |
8061 | 633 |
3922 | 634 /* These tags will be used often and can be reused--we create them on init and then apply them by name |
8061 | 635 * other tags (color, size, face, etc.) will have to be created and applied dynamically */ |
3922 | 636 gtk_text_buffer_create_tag(imhtml->text_buffer, "BOLD", "weight", PANGO_WEIGHT_BOLD, NULL); |
637 gtk_text_buffer_create_tag(imhtml->text_buffer, "ITALICS", "style", PANGO_STYLE_ITALIC, NULL); | |
638 gtk_text_buffer_create_tag(imhtml->text_buffer, "UNDERLINE", "underline", PANGO_UNDERLINE_SINGLE, NULL); | |
639 gtk_text_buffer_create_tag(imhtml->text_buffer, "STRIKE", "strikethrough", TRUE, NULL); | |
640 gtk_text_buffer_create_tag(imhtml->text_buffer, "SUB", "rise", -5000, NULL); | |
641 gtk_text_buffer_create_tag(imhtml->text_buffer, "SUP", "rise", 5000, NULL); | |
642 gtk_text_buffer_create_tag(imhtml->text_buffer, "PRE", "family", "Monospace", NULL); | |
7295 | 643 gtk_text_buffer_create_tag(imhtml->text_buffer, "search", "background", "#22ff00", "weight", "bold", NULL); |
8061 | 644 gtk_text_buffer_create_tag(imhtml->text_buffer, "LINK", "foreground", "blue", "underline", PANGO_UNDERLINE_SINGLE, NULL); |
3922 | 645 /* When hovering over a link, we show the hand cursor--elsewhere we show the plain ol' pointer cursor */ |
646 imhtml->hand_cursor = gdk_cursor_new (GDK_HAND2); | |
647 imhtml->arrow_cursor = gdk_cursor_new (GDK_LEFT_PTR); | |
8061 | 648 imhtml->text_cursor = gdk_cursor_new (GDK_XTERM); |
2993 | 649 |
4253 | 650 imhtml->show_smileys = TRUE; |
6124 | 651 imhtml->show_comments = TRUE; |
4253 | 652 |
4892 | 653 imhtml->smiley_data = g_hash_table_new_full(g_str_hash, g_str_equal, |
4902 | 654 g_free, (GDestroyNotify)gtk_smiley_tree_destroy); |
4032 | 655 imhtml->default_smilies = gtk_smiley_tree_new(); |
4735 | 656 |
4944 | 657 g_signal_connect(G_OBJECT(imhtml), "size-allocate", G_CALLBACK(gtk_size_allocate_cb), NULL); |
4735 | 658 g_signal_connect(G_OBJECT(imhtml), "motion-notify-event", G_CALLBACK(gtk_motion_event_notify), NULL); |
4944 | 659 g_signal_connect(G_OBJECT(imhtml), "leave-notify-event", G_CALLBACK(gtk_leave_event_notify), NULL); |
6066 | 660 g_signal_connect(G_OBJECT(imhtml), "key_press_event", G_CALLBACK(gtk_key_pressed_cb), NULL); |
8061 | 661 g_signal_connect_after(G_OBJECT(imhtml->text_buffer), "insert-text", G_CALLBACK(insert_cb), imhtml); |
8091 | 662 |
663 gtk_drag_dest_set(GTK_WIDGET(imhtml), 0, | |
664 link_drag_drop_targets, sizeof(link_drag_drop_targets) / sizeof(GtkTargetEntry), | |
665 GDK_ACTION_COPY); | |
666 g_signal_connect(G_OBJECT(imhtml), "drag_data_received", G_CALLBACK(gtk_imhtml_link_drag_rcv_cb), imhtml); | |
667 | |
7404
d889a99e0eb1
[gaim-migrate @ 8000]
Christian Hammond <chipx86@chipx86.com>
parents:
7386
diff
changeset
|
668 #if GTK_CHECK_VERSION(2,2,0) |
7353 | 669 g_signal_connect(G_OBJECT(imhtml), "copy-clipboard", G_CALLBACK(copy_clipboard_cb), NULL); |
8061 | 670 g_signal_connect(G_OBJECT(imhtml), "paste-clipboard", G_CALLBACK(paste_clipboard_cb), NULL); |
7346 | 671 g_signal_connect(G_OBJECT(imhtml), "button-release-event", G_CALLBACK(button_release_cb), imhtml); |
7404
d889a99e0eb1
[gaim-migrate @ 8000]
Christian Hammond <chipx86@chipx86.com>
parents:
7386
diff
changeset
|
672 #endif |
4944 | 673 gtk_widget_add_events(GTK_WIDGET(imhtml), GDK_LEAVE_NOTIFY_MASK); |
4735 | 674 |
675 imhtml->tip = NULL; | |
676 imhtml->tip_timer = 0; | |
677 imhtml->tip_window = NULL; | |
4895 | 678 |
8061 | 679 imhtml->edit.bold = NULL; |
680 imhtml->edit.italic = NULL; | |
681 imhtml->edit.underline = NULL; | |
682 imhtml->edit.forecolor = NULL; | |
683 imhtml->edit.backcolor = NULL; | |
684 imhtml->edit.fontface = NULL; | |
685 imhtml->edit.sizespan = NULL; | |
686 imhtml->edit.fontsize = 3; | |
687 | |
688 imhtml->format_spans = NULL; | |
689 | |
4895 | 690 imhtml->scalables = NULL; |
8061 | 691 |
692 gtk_imhtml_set_editable(imhtml, FALSE); | |
693 | |
2993 | 694 } |
695 | |
3922 | 696 GtkWidget *gtk_imhtml_new(void *a, void *b) |
1428 | 697 { |
4635 | 698 return GTK_WIDGET(g_object_new(gtk_imhtml_get_type(), NULL)); |
1428 | 699 } |
700 | |
4635 | 701 GType gtk_imhtml_get_type() |
1428 | 702 { |
4635 | 703 static GType imhtml_type = 0; |
1428 | 704 |
705 if (!imhtml_type) { | |
4635 | 706 static const GTypeInfo imhtml_info = { |
707 sizeof(GtkIMHtmlClass), | |
708 NULL, | |
709 NULL, | |
710 (GClassInitFunc) gtk_imhtml_class_init, | |
711 NULL, | |
712 NULL, | |
1428 | 713 sizeof (GtkIMHtml), |
4635 | 714 0, |
715 (GInstanceInitFunc) gtk_imhtml_init | |
1428 | 716 }; |
4635 | 717 |
718 imhtml_type = g_type_register_static(gtk_text_view_get_type(), | |
719 "GtkIMHtml", &imhtml_info, 0); | |
1428 | 720 } |
721 | |
722 return imhtml_type; | |
723 } | |
724 | |
4417 | 725 struct url_data { |
726 GObject *object; | |
727 gchar *url; | |
728 }; | |
729 | |
730 static void url_open(GtkWidget *w, struct url_data *data) { | |
731 if(!data) return; | |
8061 | 732 g_signal_emit(data->object, signals[URL_CLICKED], 0, data->url); |
7988 | 733 |
4417 | 734 g_object_unref(data->object); |
735 g_free(data->url); | |
736 g_free(data); | |
737 } | |
5582 | 738 |
4417 | 739 static void url_copy(GtkWidget *w, gchar *url) { |
740 GtkClipboard *clipboard; | |
741 | |
5293
ead927e2543f
[gaim-migrate @ 5665]
Christian Hammond <chipx86@chipx86.com>
parents:
5282
diff
changeset
|
742 clipboard = gtk_clipboard_get(GDK_SELECTION_PRIMARY); |
4417 | 743 gtk_clipboard_set_text(clipboard, url, -1); |
5582 | 744 |
745 clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); | |
746 gtk_clipboard_set_text(clipboard, url, -1); | |
4417 | 747 } |
748 | |
749 /* The callback for an event on a link tag. */ | |
5091 | 750 gboolean tag_event(GtkTextTag *tag, GObject *imhtml, GdkEvent *event, GtkTextIter *arg2, char *url) { |
4417 | 751 GdkEventButton *event_button = (GdkEventButton *) event; |
8061 | 752 if (GTK_IMHTML(imhtml)->editable) |
753 return FALSE; | |
3922 | 754 if (event->type == GDK_BUTTON_RELEASE) { |
8061 | 755 if (event_button->button == 1) { |
4417 | 756 GtkTextIter start, end; |
757 /* we shouldn't open a URL if the user has selected something: */ | |
758 gtk_text_buffer_get_selection_bounds( | |
759 gtk_text_iter_get_buffer(arg2), &start, &end); | |
760 if(gtk_text_iter_get_offset(&start) != | |
761 gtk_text_iter_get_offset(&end)) | |
762 return FALSE; | |
763 | |
764 /* A link was clicked--we emit the "url_clicked" signal | |
765 * with the URL as the argument */ | |
5091 | 766 g_signal_emit(imhtml, signals[URL_CLICKED], 0, url); |
4417 | 767 return FALSE; |
768 } else if(event_button->button == 3) { | |
4745 | 769 GtkWidget *img, *item, *menu; |
4417 | 770 struct url_data *tempdata = g_new(struct url_data, 1); |
5091 | 771 tempdata->object = g_object_ref(imhtml); |
4417 | 772 tempdata->url = g_strdup(url); |
4745 | 773 |
5091 | 774 /* Don't want the tooltip around if user right-clicked on link */ |
775 if (GTK_IMHTML(imhtml)->tip_window) { | |
776 gtk_widget_destroy(GTK_IMHTML(imhtml)->tip_window); | |
777 GTK_IMHTML(imhtml)->tip_window = NULL; | |
778 } | |
779 if (GTK_IMHTML(imhtml)->tip_timer) { | |
780 g_source_remove(GTK_IMHTML(imhtml)->tip_timer); | |
781 GTK_IMHTML(imhtml)->tip_timer = 0; | |
782 } | |
8061 | 783 if (GTK_IMHTML(imhtml)->editable) |
784 gdk_window_set_cursor(event_button->window, GTK_IMHTML(imhtml)->text_cursor); | |
785 else | |
786 gdk_window_set_cursor(event_button->window, GTK_IMHTML(imhtml)->arrow_cursor); | |
4417 | 787 menu = gtk_menu_new(); |
4745 | 788 |
4417 | 789 /* buttons and such */ |
790 | |
7140
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
791 if (!strncmp(url, "mailto:", 7)) |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
792 { |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
793 /* Copy E-Mail Address */ |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
794 img = gtk_image_new_from_stock(GTK_STOCK_COPY, |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
795 GTK_ICON_SIZE_MENU); |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
796 item = gtk_image_menu_item_new_with_mnemonic( |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
797 _("_Copy E-Mail Address")); |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
798 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
|
799 g_signal_connect(G_OBJECT(item), "activate", |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
800 G_CALLBACK(url_copy), url + 7); |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
801 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
802 } |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
803 else |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
804 { |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
805 /* Copy Link Location */ |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
806 img = gtk_image_new_from_stock(GTK_STOCK_COPY, |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
807 GTK_ICON_SIZE_MENU); |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
808 item = gtk_image_menu_item_new_with_mnemonic( |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
809 _("_Copy Link Location")); |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
810 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
|
811 g_signal_connect(G_OBJECT(item), "activate", |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
812 G_CALLBACK(url_copy), url); |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
813 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
814 |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
815 /* Open Link in Browser */ |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
816 img = gtk_image_new_from_stock(GTK_STOCK_JUMP_TO, |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
817 GTK_ICON_SIZE_MENU); |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
818 item = gtk_image_menu_item_new_with_mnemonic( |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
819 _("_Open Link in Browser")); |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
820 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
|
821 g_signal_connect(G_OBJECT(item), "activate", |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
822 G_CALLBACK(url_open), tempdata); |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
823 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
824 } |
48cc5d5d5a6c
[gaim-migrate @ 7707]
Christian Hammond <chipx86@chipx86.com>
parents:
6982
diff
changeset
|
825 |
4756 | 826 |
4417 | 827 gtk_widget_show_all(menu); |
4756 | 828 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, |
829 event_button->button, event_button->time); | |
4745 | 830 |
4417 | 831 return TRUE; |
832 } | |
1428 | 833 } |
4417 | 834 if(event->type == GDK_BUTTON_PRESS && event_button->button == 3) |
835 return TRUE; /* Clicking the right mouse button on a link shouldn't | |
836 be caught by the regular GtkTextView menu */ | |
837 else | |
838 return FALSE; /* Let clicks go through if we didn't catch anything */ | |
1428 | 839 } |
840 | |
8091 | 841 static void |
842 gtk_imhtml_link_drag_rcv_cb(GtkWidget *widget, GdkDragContext *dc, guint x, guint y, | |
843 GtkSelectionData *sd, guint info, guint t, GtkIMHtml *imhtml) | |
844 { | |
845 if(gtk_imhtml_get_editable(imhtml) && sd->data){ | |
846 gchar **links; | |
847 gchar *link; | |
848 | |
849 gaim_str_strip_cr(sd->data); | |
850 | |
851 links = g_strsplit(sd->data, "\n", 0); | |
852 while((link = *links++) != NULL){ | |
853 if(gaim_str_has_prefix(link, "http://") || | |
854 gaim_str_has_prefix(link, "https://") || | |
855 gaim_str_has_prefix(link, "ftp://")){ | |
856 gtk_imhtml_insert_link(imhtml, link, link); | |
857 } else if (link=='\0') { | |
8177 | 858 /* Ignore blank lines */ |
8091 | 859 } else { |
8177 | 860 /* Special reasons, aka images being put in via other tag, etc. */ |
8091 | 861 } |
862 } | |
863 | |
864 gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t); | |
865 } else { | |
866 gtk_drag_finish(dc, FALSE, FALSE, t); | |
867 } | |
868 } | |
869 | |
4298 | 870 /* this isn't used yet |
4032 | 871 static void |
4263 | 872 gtk_smiley_tree_remove (GtkSmileyTree *tree, |
873 GtkIMHtmlSmiley *smiley) | |
4032 | 874 { |
875 GtkSmileyTree *t = tree; | |
4263 | 876 const gchar *x = smiley->smile; |
4032 | 877 gint len = 0; |
878 | |
879 while (*x) { | |
880 gchar *pos; | |
881 | |
882 if (!t->values) | |
883 return; | |
884 | |
885 pos = strchr (t->values->str, *x); | |
886 if (pos) | |
887 t = t->children [(int) pos - (int) t->values->str]; | |
888 else | |
889 return; | |
890 | |
891 x++; len++; | |
892 } | |
893 | |
4141
ccec4fde84f4
[gaim-migrate @ 4359]
Christian Hammond <chipx86@chipx86.com>
parents:
4140
diff
changeset
|
894 if (t->image) { |
4032 | 895 t->image = NULL; |
4141
ccec4fde84f4
[gaim-migrate @ 4359]
Christian Hammond <chipx86@chipx86.com>
parents:
4140
diff
changeset
|
896 } |
4032 | 897 } |
4298 | 898 */ |
899 | |
4032 | 900 |
901 static gint | |
902 gtk_smiley_tree_lookup (GtkSmileyTree *tree, | |
903 const gchar *text) | |
904 { | |
905 GtkSmileyTree *t = tree; | |
906 const gchar *x = text; | |
907 gint len = 0; | |
908 | |
909 while (*x) { | |
910 gchar *pos; | |
911 | |
912 if (!t->values) | |
913 break; | |
914 | |
915 pos = strchr (t->values->str, *x); | |
916 if (pos) | |
7371 | 917 t = t->children [GPOINTER_TO_INT(pos) - GPOINTER_TO_INT(t->values->str)]; |
4032 | 918 else |
919 break; | |
920 | |
921 x++; len++; | |
922 } | |
923 | |
924 if (t->image) | |
925 return len; | |
926 | |
927 return 0; | |
928 } | |
929 | |
930 void | |
4263 | 931 gtk_imhtml_associate_smiley (GtkIMHtml *imhtml, |
932 gchar *sml, | |
933 GtkIMHtmlSmiley *smiley) | |
4032 | 934 { |
935 GtkSmileyTree *tree; | |
936 g_return_if_fail (imhtml != NULL); | |
937 g_return_if_fail (GTK_IS_IMHTML (imhtml)); | |
7371 | 938 |
4032 | 939 if (sml == NULL) |
940 tree = imhtml->default_smilies; | |
941 else if ((tree = g_hash_table_lookup(imhtml->smiley_data, sml))) { | |
942 } else { | |
943 tree = gtk_smiley_tree_new(); | |
4892 | 944 g_hash_table_insert(imhtml->smiley_data, g_strdup(sml), tree); |
4032 | 945 } |
946 | |
4263 | 947 gtk_smiley_tree_insert (tree, smiley); |
4032 | 948 } |
949 | |
950 static gboolean | |
951 gtk_imhtml_is_smiley (GtkIMHtml *imhtml, | |
952 GSList *fonts, | |
953 const gchar *text, | |
954 gint *len) | |
955 { | |
956 GtkSmileyTree *tree; | |
5967 | 957 GtkIMHtmlFontDetail *font; |
4032 | 958 char *sml = NULL; |
959 | |
960 if (fonts) { | |
961 font = fonts->data; | |
962 sml = font->sml; | |
963 } | |
964 | |
965 if (sml == NULL) | |
966 tree = imhtml->default_smilies; | |
967 else { | |
968 tree = g_hash_table_lookup(imhtml->smiley_data, sml); | |
969 } | |
970 if (tree == NULL) | |
971 return FALSE; | |
7371 | 972 |
4032 | 973 *len = gtk_smiley_tree_lookup (tree, text); |
974 return (*len > 0); | |
975 } | |
976 | |
6814
782907a6ae65
[gaim-migrate @ 7354]
Christian Hammond <chipx86@chipx86.com>
parents:
6648
diff
changeset
|
977 GdkPixbufAnimation * |
4032 | 978 gtk_smiley_tree_image (GtkIMHtml *imhtml, |
979 const gchar *sml, | |
980 const gchar *text) | |
981 { | |
982 GtkSmileyTree *t; | |
983 const gchar *x = text; | |
984 if (sml == NULL) | |
985 t = imhtml->default_smilies; | |
7371 | 986 else |
4032 | 987 t = g_hash_table_lookup(imhtml->smiley_data, sml); |
7371 | 988 |
4032 | 989 |
990 if (t == NULL) | |
991 return sml ? gtk_smiley_tree_image(imhtml, NULL, text) : NULL; | |
992 | |
993 while (*x) { | |
994 gchar *pos; | |
995 | |
996 if (!t->values) { | |
997 return sml ? gtk_smiley_tree_image(imhtml, NULL, text) : NULL; | |
998 } | |
7371 | 999 |
4032 | 1000 pos = strchr (t->values->str, *x); |
1001 if (pos) { | |
7371 | 1002 t = t->children [GPOINTER_TO_INT(pos) - GPOINTER_TO_INT(t->values->str)]; |
4032 | 1003 } else { |
1004 return sml ? gtk_smiley_tree_image(imhtml, NULL, text) : NULL; | |
1005 } | |
1006 x++; | |
1007 } | |
1008 | |
4263 | 1009 if (!t->image->icon) |
6814
782907a6ae65
[gaim-migrate @ 7354]
Christian Hammond <chipx86@chipx86.com>
parents:
6648
diff
changeset
|
1010 t->image->icon = gdk_pixbuf_animation_new_from_file(t->image->file, NULL); |
4263 | 1011 |
1012 return t->image->icon; | |
4032 | 1013 } |
4793 | 1014 #define VALID_TAG(x) if (!g_ascii_strncasecmp (string, x ">", strlen (x ">"))) { \ |
3922 | 1015 *tag = g_strndup (string, strlen (x)); \ |
1016 *len = strlen (x) + 1; \ | |
1017 return TRUE; \ | |
1018 } \ | |
1019 (*type)++ | |
1428 | 1020 |
4793 | 1021 #define VALID_OPT_TAG(x) if (!g_ascii_strncasecmp (string, x " ", strlen (x " "))) { \ |
3922 | 1022 const gchar *c = string + strlen (x " "); \ |
1023 gchar e = '"'; \ | |
1024 gboolean quote = FALSE; \ | |
1025 while (*c) { \ | |
1026 if (*c == '"' || *c == '\'') { \ | |
1027 if (quote && (*c == e)) \ | |
1028 quote = !quote; \ | |
1029 else if (!quote) { \ | |
1030 quote = !quote; \ | |
1031 e = *c; \ | |
1032 } \ | |
1033 } else if (!quote && (*c == '>')) \ | |
1034 break; \ | |
1035 c++; \ | |
1036 } \ | |
1037 if (*c) { \ | |
1038 *tag = g_strndup (string, c - string); \ | |
1039 *len = c - string + 1; \ | |
1040 return TRUE; \ | |
1041 } \ | |
1042 } \ | |
1043 (*type)++ | |
1428 | 1044 |
1045 | |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1046 static gboolean |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1047 gtk_imhtml_is_amp_escape (const gchar *string, |
7280 | 1048 gchar **replace, |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1049 gint *length) |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1050 { |
7287 | 1051 static char buf[7]; |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1052 g_return_val_if_fail (string != NULL, FALSE); |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1053 g_return_val_if_fail (replace != NULL, FALSE); |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1054 g_return_val_if_fail (length != NULL, FALSE); |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1055 |
4793 | 1056 if (!g_ascii_strncasecmp (string, "&", 5)) { |
7280 | 1057 *replace = "&"; |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1058 *length = 5; |
4793 | 1059 } else if (!g_ascii_strncasecmp (string, "<", 4)) { |
7280 | 1060 *replace = "<"; |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1061 *length = 4; |
4793 | 1062 } else if (!g_ascii_strncasecmp (string, ">", 4)) { |
7280 | 1063 *replace = ">"; |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1064 *length = 4; |
4793 | 1065 } else if (!g_ascii_strncasecmp (string, " ", 6)) { |
7280 | 1066 *replace = " "; |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1067 *length = 6; |
4793 | 1068 } else if (!g_ascii_strncasecmp (string, "©", 6)) { |
7280 | 1069 *replace = "©"; |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1070 *length = 6; |
4793 | 1071 } else if (!g_ascii_strncasecmp (string, """, 6)) { |
7280 | 1072 *replace = "\""; |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1073 *length = 6; |
4793 | 1074 } else if (!g_ascii_strncasecmp (string, "®", 5)) { |
7280 | 1075 *replace = "®"; |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1076 *length = 5; |
5093 | 1077 } else if (!g_ascii_strncasecmp (string, "'", 6)) { |
7280 | 1078 *replace = "\'"; |
5093 | 1079 *length = 6; |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1080 } else if (*(string + 1) == '#') { |
2022
199ba82faacb
[gaim-migrate @ 2032]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2002
diff
changeset
|
1081 guint pound = 0; |
3004 | 1082 if ((sscanf (string, "&#%u;", £) == 1) && pound != 0) { |
7287 | 1083 int buflen; |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1084 if (*(string + 3 + (gint)log10 (pound)) != ';') |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1085 return FALSE; |
7287 | 1086 buflen = g_unichar_to_utf8((gunichar)pound, buf); |
1087 buf[buflen] = '\0'; | |
7280 | 1088 *replace = buf; |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1089 *length = 2; |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1090 while (isdigit ((gint) string [*length])) (*length)++; |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1091 if (string [*length] == ';') (*length)++; |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1092 } else { |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1093 return FALSE; |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1094 } |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1095 } else { |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1096 return FALSE; |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1097 } |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1098 |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1099 return TRUE; |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1100 } |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
1101 |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1102 static gboolean |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1103 gtk_imhtml_is_tag (const gchar *string, |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1104 gchar **tag, |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1105 gint *len, |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1106 gint *type) |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1107 { |
8061 | 1108 char *close; |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1109 *type = 1; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1110 |
8118 | 1111 |
8061 | 1112 if (!(close = strchr (string, '>'))) |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1113 return FALSE; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1114 |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1115 VALID_TAG ("B"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1116 VALID_TAG ("BOLD"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1117 VALID_TAG ("/B"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1118 VALID_TAG ("/BOLD"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1119 VALID_TAG ("I"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1120 VALID_TAG ("ITALIC"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1121 VALID_TAG ("/I"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1122 VALID_TAG ("/ITALIC"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1123 VALID_TAG ("U"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1124 VALID_TAG ("UNDERLINE"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1125 VALID_TAG ("/U"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1126 VALID_TAG ("/UNDERLINE"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1127 VALID_TAG ("S"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1128 VALID_TAG ("STRIKE"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1129 VALID_TAG ("/S"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1130 VALID_TAG ("/STRIKE"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1131 VALID_TAG ("SUB"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1132 VALID_TAG ("/SUB"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1133 VALID_TAG ("SUP"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1134 VALID_TAG ("/SUP"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1135 VALID_TAG ("PRE"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1136 VALID_TAG ("/PRE"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1137 VALID_TAG ("TITLE"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1138 VALID_TAG ("/TITLE"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1139 VALID_TAG ("BR"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1140 VALID_TAG ("HR"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1141 VALID_TAG ("/FONT"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1142 VALID_TAG ("/A"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1143 VALID_TAG ("P"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1144 VALID_TAG ("/P"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1145 VALID_TAG ("H3"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1146 VALID_TAG ("/H3"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1147 VALID_TAG ("HTML"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1148 VALID_TAG ("/HTML"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1149 VALID_TAG ("BODY"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1150 VALID_TAG ("/BODY"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1151 VALID_TAG ("FONT"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1152 VALID_TAG ("HEAD"); |
2993 | 1153 VALID_TAG ("/HEAD"); |
1154 VALID_TAG ("BINARY"); | |
1155 VALID_TAG ("/BINARY"); | |
5093 | 1156 |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1157 VALID_OPT_TAG ("HR"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1158 VALID_OPT_TAG ("FONT"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1159 VALID_OPT_TAG ("BODY"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1160 VALID_OPT_TAG ("A"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1161 VALID_OPT_TAG ("IMG"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1162 VALID_OPT_TAG ("P"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1163 VALID_OPT_TAG ("H3"); |
5093 | 1164 VALID_OPT_TAG ("HTML"); |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1165 |
5101 | 1166 VALID_TAG ("CITE"); |
1167 VALID_TAG ("/CITE"); | |
1168 VALID_TAG ("EM"); | |
1169 VALID_TAG ("/EM"); | |
1170 VALID_TAG ("STRONG"); | |
1171 VALID_TAG ("/STRONG"); | |
1172 | |
5104 | 1173 VALID_OPT_TAG ("SPAN"); |
1174 VALID_TAG ("/SPAN"); | |
5174 | 1175 VALID_TAG ("BR/"); /* hack until gtkimhtml handles things better */ |
6982 | 1176 VALID_TAG ("IMG"); |
8026 | 1177 VALID_TAG("SPAN"); |
8061 | 1178 VALID_OPT_TAG("BR"); |
7988 | 1179 |
4793 | 1180 if (!g_ascii_strncasecmp(string, "!--", strlen ("!--"))) { |
2954
f6c4f2187c08
[gaim-migrate @ 2967]
Christian Hammond <chipx86@chipx86.com>
parents:
2898
diff
changeset
|
1181 gchar *e = strstr (string + strlen("!--"), "-->"); |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1182 if (e) { |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1183 *len = e - string + strlen ("-->"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1184 *tag = g_strndup (string + strlen ("!--"), *len - strlen ("!---->")); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1185 return TRUE; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1186 } |
8118 | 1187 } |
1188 | |
8061 | 1189 *type = -1; |
1190 *len = close - string + 1; | |
1191 *tag = g_strndup(string, *len - 1); | |
1192 return TRUE; | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1193 } |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1194 |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1195 static gchar* |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1196 gtk_imhtml_get_html_opt (gchar *tag, |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1197 const gchar *opt) |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1198 { |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1199 gchar *t = tag; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1200 gchar *e, *a; |
5177 | 1201 gchar *val; |
1202 gint len; | |
7280 | 1203 gchar *c; |
5177 | 1204 GString *ret; |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1205 |
4793 | 1206 while (g_ascii_strncasecmp (t, opt, strlen (opt))) { |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1207 gboolean quote = FALSE; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1208 if (*t == '\0') break; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1209 while (*t && !((*t == ' ') && !quote)) { |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1210 if (*t == '\"') |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1211 quote = ! quote; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1212 t++; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1213 } |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1214 while (*t && (*t == ' ')) t++; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1215 } |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1216 |
4793 | 1217 if (!g_ascii_strncasecmp (t, opt, strlen (opt))) { |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1218 t += strlen (opt); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1219 } else { |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1220 return NULL; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1221 } |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1222 |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1223 if ((*t == '\"') || (*t == '\'')) { |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1224 e = a = ++t; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1225 while (*e && (*e != *(t - 1))) e++; |
2993 | 1226 if (*e == '\0') { |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1227 return NULL; |
5177 | 1228 } else |
1229 val = g_strndup(a, e - a); | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1230 } else { |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1231 e = a = t; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1232 while (*e && !isspace ((gint) *e)) e++; |
5177 | 1233 val = g_strndup(a, e - a); |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1234 } |
5177 | 1235 |
1236 ret = g_string_new(""); | |
1237 e = val; | |
1238 while(*e) { | |
1239 if(gtk_imhtml_is_amp_escape(e, &c, &len)) { | |
7280 | 1240 ret = g_string_append(ret, c); |
5177 | 1241 e += len; |
1242 } else { | |
1243 ret = g_string_append_c(ret, *e); | |
1244 e++; | |
1245 } | |
1246 } | |
1247 | |
1248 g_free(val); | |
1249 val = ret->str; | |
1250 g_string_free(ret, FALSE); | |
1251 return val; | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1252 } |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1253 |
8118 | 1254 /* Inline CSS Support - Douglas Thrift */ |
1255 static gchar* | |
1256 gtk_imhtml_get_css_opt (gchar *style, | |
1257 const gchar *opt) | |
1258 { | |
1259 gchar *t = style; | |
1260 gchar *e, *a; | |
1261 gchar *val; | |
1262 gint len; | |
1263 gchar *c; | |
1264 GString *ret; | |
1265 | |
1266 while (g_ascii_strncasecmp (t, opt, strlen (opt))) { | |
8177 | 1267 /* gboolean quote = FALSE; */ |
8118 | 1268 if (*t == '\0') break; |
1269 while (*t && !((*t == ' ') /*&& !quote*/)) { | |
1270 /* if (*t == '\"') | |
8177 | 1271 quote = ! quote; */ |
8118 | 1272 t++; |
1273 } | |
1274 while (*t && (*t == ' ')) t++; | |
1275 } | |
1276 | |
1277 if (!g_ascii_strncasecmp (t, opt, strlen (opt))) { | |
1278 t += strlen (opt); | |
1279 } else { | |
1280 return NULL; | |
1281 } | |
1282 | |
1283 /* if ((*t == '\"') || (*t == '\'')) { | |
1284 e = a = ++t; | |
1285 while (*e && (*e != *(t - 1))) e++; | |
1286 if (*e == '\0') { | |
1287 return NULL; | |
1288 } else | |
1289 val = g_strndup(a, e - a); | |
1290 } else { | |
1291 e = a = t; | |
1292 while (*e && !isspace ((gint) *e)) e++; | |
1293 val = g_strndup(a, e - a); | |
1294 }*/ | |
1295 | |
1296 e = a = t; | |
1297 while (*e && *e != ';') e++; | |
1298 val = g_strndup(a, e - a); | |
1299 | |
1300 ret = g_string_new(""); | |
1301 e = val; | |
1302 while(*e) { | |
1303 if(gtk_imhtml_is_amp_escape(e, &c, &len)) { | |
1304 ret = g_string_append(ret, c); | |
1305 e += len; | |
1306 } else { | |
1307 ret = g_string_append_c(ret, *e); | |
1308 e++; | |
1309 } | |
1310 } | |
1311 | |
1312 g_free(val); | |
1313 val = ret->str; | |
1314 g_string_free(ret, FALSE); | |
1315 return val; | |
1316 } | |
3922 | 1317 |
6982 | 1318 GString* gtk_imhtml_append_text_with_images (GtkIMHtml *imhtml, |
1319 const gchar *text, | |
1320 GtkIMHtmlOptions options, | |
1321 GSList *images) | |
1428 | 1322 { |
8061 | 1323 GtkTextMark *ins = gtk_text_buffer_get_insert(imhtml->text_buffer); |
1324 GtkTextIter insert; | |
1325 GdkRectangle rect; | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1326 gint pos = 0; |
3922 | 1327 GString *str = NULL; |
8061 | 1328 GtkTextIter iter; |
1329 GtkTextMark *mark; | |
3922 | 1330 gchar *ws; |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1331 gchar *tag; |
3922 | 1332 gchar *url = NULL; |
1333 gchar *bg = NULL; | |
6982 | 1334 gint len; |
4032 | 1335 gint tlen, smilelen, wpos=0; |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1336 gint type; |
3922 | 1337 const gchar *c; |
7280 | 1338 gchar *amp; |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1339 |
1428 | 1340 guint bold = 0, |
1341 italics = 0, | |
1342 underline = 0, | |
1343 strike = 0, | |
1344 sub = 0, | |
1345 sup = 0, | |
1691
d802b115800f
[gaim-migrate @ 1701]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1647
diff
changeset
|
1346 title = 0, |
8061 | 1347 pre = 0; |
1428 | 1348 |
3922 | 1349 GSList *fonts = NULL; |
8061 | 1350 GtkIMHtmlScalable *scalable = NULL; |
4612 | 1351 int y, height; |
1352 | |
4895 | 1353 |
1428 | 1354 g_return_val_if_fail (imhtml != NULL, NULL); |
1355 g_return_val_if_fail (GTK_IS_IMHTML (imhtml), NULL); | |
1356 g_return_val_if_fail (text != NULL, NULL); | |
8061 | 1357 printf("Appending: %s\n", text); |
3922 | 1358 c = text; |
6982 | 1359 len = strlen(text); |
3922 | 1360 ws = g_malloc(len + 1); |
1361 ws[0] = 0; | |
1428 | 1362 |
1363 if (options & GTK_IMHTML_RETURN_LOG) | |
3922 | 1364 str = g_string_new(""); |
1428 | 1365 |
8061 | 1366 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &insert, ins); |
1367 | |
3922 | 1368 gtk_text_buffer_get_end_iter(imhtml->text_buffer, &iter); |
1369 mark = gtk_text_buffer_create_mark (imhtml->text_buffer, NULL, &iter, /* right grav */ FALSE); | |
4612 | 1370 |
8061 | 1371 gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(imhtml), &rect); |
4612 | 1372 gtk_text_view_get_line_yrange(GTK_TEXT_VIEW(imhtml), &iter, &y, &height); |
1373 | |
8061 | 1374 #if GTK_CHECK_VERSION(2,2,0) |
1375 gtk_imhtml_primary_clipboard_clear(NULL, imhtml); | |
1376 #endif | |
1377 gtk_text_buffer_move_mark (imhtml->text_buffer, | |
1378 gtk_text_buffer_get_mark (imhtml->text_buffer, "insert"), | |
1379 &iter); | |
1380 | |
1381 if(((y + height) - (rect.y + rect.height)) > height | |
4612 | 1382 && gtk_text_buffer_get_char_count(imhtml->text_buffer)){ |
1383 options |= GTK_IMHTML_NO_SCROLL; | |
1384 } | |
1385 | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1386 while (pos < len) { |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1387 if (*c == '<' && gtk_imhtml_is_tag (c + 1, &tag, &tlen, &type)) { |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1388 c++; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1389 pos++; |
8061 | 1390 ws[wpos] = '\0'; |
1391 switch (type) | |
3922 | 1392 { |
1393 case 1: /* B */ | |
1394 case 2: /* BOLD */ | |
5101 | 1395 case 54: /* STRONG */ |
8061 | 1396 if (url) |
1397 gtk_imhtml_insert_link(imhtml, url, ws); | |
1398 else | |
1399 gtk_text_buffer_insert(imhtml->text_buffer, &iter, ws, wpos); | |
1400 if (bold == 0) | |
1401 gtk_imhtml_toggle_bold(imhtml); | |
3922 | 1402 bold++; |
8061 | 1403 ws[0] = '\0'; wpos = 0; |
3922 | 1404 break; |
1405 case 3: /* /B */ | |
1406 case 4: /* /BOLD */ | |
5101 | 1407 case 55: /* /STRONG */ |
8061 | 1408 if (url) |
1409 gtk_imhtml_insert_link(imhtml, url, ws); | |
1410 else | |
1411 gtk_text_buffer_insert(imhtml->text_buffer, &iter, ws, wpos); | |
1412 ws[0] = '\0'; wpos = 0; | |
1413 | |
3922 | 1414 if (bold) |
1415 bold--; | |
8061 | 1416 if (bold == 0) |
1417 gtk_imhtml_toggle_bold(imhtml); | |
3922 | 1418 break; |
1419 case 5: /* I */ | |
1420 case 6: /* ITALIC */ | |
5101 | 1421 case 52: /* EM */ |
8061 | 1422 if (url) |
1423 gtk_imhtml_insert_link(imhtml, url, ws); | |
1424 else | |
1425 gtk_text_buffer_insert(imhtml->text_buffer, &iter, ws, wpos); | |
1426 ws[0] = '\0'; wpos = 0; | |
1427 if (italics == 0) | |
1428 gtk_imhtml_toggle_italic(imhtml); | |
3922 | 1429 italics++; |
1430 break; | |
1431 case 7: /* /I */ | |
1432 case 8: /* /ITALIC */ | |
5101 | 1433 case 53: /* /EM */ |
8061 | 1434 if (url) |
1435 gtk_imhtml_insert_link(imhtml, url, ws); | |
1436 else | |
1437 gtk_text_buffer_insert(imhtml->text_buffer, &iter, ws, wpos); | |
1438 ws[0] = '\0'; wpos = 0; | |
3922 | 1439 if (italics) |
1440 italics--; | |
8061 | 1441 if (italics == 0) |
1442 gtk_imhtml_toggle_italic(imhtml); | |
3922 | 1443 break; |
1444 case 9: /* U */ | |
1445 case 10: /* UNDERLINE */ | |
8061 | 1446 if (url) |
1447 gtk_imhtml_insert_link(imhtml, url, ws); | |
1448 else | |
1449 gtk_text_buffer_insert(imhtml->text_buffer, &iter, ws, wpos); | |
1450 ws[0] = '\0'; wpos = 0; | |
1451 if (underline == 0) | |
1452 gtk_imhtml_toggle_underline(imhtml); | |
3922 | 1453 underline++; |
1454 break; | |
1455 case 11: /* /U */ | |
1456 case 12: /* /UNDERLINE */ | |
8061 | 1457 if (url) |
1458 gtk_imhtml_insert_link(imhtml, url, ws); | |
1459 else | |
1460 gtk_text_buffer_insert(imhtml->text_buffer, &iter, ws, wpos); | |
1461 ws[0] = '\0'; wpos = 0; | |
3922 | 1462 if (underline) |
1463 underline--; | |
8061 | 1464 if (underline == 0) |
1465 gtk_imhtml_toggle_underline(imhtml); | |
3922 | 1466 break; |
1467 case 13: /* S */ | |
1468 case 14: /* STRIKE */ | |
8177 | 1469 /* NEW_BIT (NEW_TEXT_BIT); */ |
3922 | 1470 strike++; |
1471 break; | |
1472 case 15: /* /S */ | |
1473 case 16: /* /STRIKE */ | |
8177 | 1474 /* NEW_BIT (NEW_TEXT_BIT); */ |
3922 | 1475 if (strike) |
1476 strike--; | |
1477 break; | |
1478 case 17: /* SUB */ | |
8177 | 1479 /* NEW_BIT (NEW_TEXT_BIT); */ |
3922 | 1480 sub++; |
1481 break; | |
1482 case 18: /* /SUB */ | |
8177 | 1483 /* NEW_BIT (NEW_TEXT_BIT); */ |
3922 | 1484 if (sub) |
1485 sub--; | |
1486 break; | |
1487 case 19: /* SUP */ | |
8177 | 1488 /* NEW_BIT (NEW_TEXT_BIT); */ |
3922 | 1489 sup++; |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1490 break; |
3922 | 1491 case 20: /* /SUP */ |
8177 | 1492 /* NEW_BIT (NEW_TEXT_BIT); */ |
3922 | 1493 if (sup) |
1494 sup--; | |
1495 break; | |
1496 case 21: /* PRE */ | |
8177 | 1497 /* NEW_BIT (NEW_TEXT_BIT); */ |
3922 | 1498 pre++; |
1499 break; | |
1500 case 22: /* /PRE */ | |
8177 | 1501 /* NEW_BIT (NEW_TEXT_BIT); */ |
3922 | 1502 if (pre) |
1503 pre--; | |
1504 break; | |
1505 case 23: /* TITLE */ | |
8177 | 1506 /* NEW_BIT (NEW_TEXT_BIT); */ |
3922 | 1507 title++; |
1508 break; | |
1509 case 24: /* /TITLE */ | |
1510 if (title) { | |
1511 if (options & GTK_IMHTML_NO_TITLE) { | |
1512 wpos = 0; | |
1513 ws [wpos] = '\0'; | |
1514 } | |
1515 title--; | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1516 } |
3922 | 1517 break; |
1518 case 25: /* BR */ | |
5174 | 1519 case 58: /* BR/ */ |
8061 | 1520 case 61: /* BR (opt) */ |
3922 | 1521 ws[wpos] = '\n'; |
1522 wpos++; | |
8177 | 1523 /* NEW_BIT (NEW_TEXT_BIT); */ |
6982 | 1524 break; |
3922 | 1525 case 26: /* HR */ |
1526 case 42: /* HR (opt) */ | |
1527 ws[wpos++] = '\n'; | |
8061 | 1528 if (url) |
1529 gtk_imhtml_insert_link(imhtml, url, ws); | |
1530 else | |
1531 gtk_text_buffer_insert(imhtml->text_buffer, &iter, ws, wpos); | |
5967 | 1532 scalable = gtk_imhtml_hr_new(); |
8061 | 1533 gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(imhtml), &rect); |
1534 scalable->add_to(scalable, imhtml, &iter); | |
1535 scalable->scale(scalable, rect.width, rect.height); | |
1536 imhtml->scalables = g_list_append(imhtml->scalables, scalable); | |
1537 ws[0] = '\0'; wpos = 0; | |
7942 | 1538 ws[wpos++] = '\n'; |
8061 | 1539 |
3922 | 1540 break; |
1541 case 27: /* /FONT */ | |
1542 if (fonts) { | |
5967 | 1543 GtkIMHtmlFontDetail *font = fonts->data; |
8061 | 1544 if (url) |
1545 gtk_imhtml_insert_link(imhtml, url, ws); | |
1546 else | |
1547 gtk_text_buffer_insert(imhtml->text_buffer, &iter, ws, wpos); | |
1548 ws[0] = '\0'; wpos = 0; | |
8177 | 1549 /* NEW_BIT (NEW_TEXT_BIT); */ |
8309 | 1550 |
8061 | 1551 if (font->face) { |
1552 gtk_imhtml_toggle_fontface(imhtml, NULL); | |
3922 | 1553 g_free (font->face); |
8061 | 1554 } |
1555 if (font->fore) { | |
1556 gtk_imhtml_toggle_forecolor(imhtml, NULL); | |
3922 | 1557 g_free (font->fore); |
8061 | 1558 } |
1559 if (font->back) { | |
1560 gtk_imhtml_toggle_backcolor(imhtml, NULL); | |
3922 | 1561 g_free (font->back); |
8061 | 1562 } |
4032 | 1563 if (font->sml) |
1564 g_free (font->sml); | |
3922 | 1565 g_free (font); |
8309 | 1566 |
1567 if (font->size != 3) | |
1568 gtk_imhtml_font_set_size(imhtml, 3); | |
1569 | |
1570 fonts = fonts->next; | |
1571 if (fonts) { | |
1572 GtkIMHtmlFontDetail *font = fonts->data; | |
1573 | |
1574 if (font->face) | |
1575 gtk_imhtml_toggle_fontface(imhtml, font->face); | |
1576 if (font->fore) | |
1577 gtk_imhtml_toggle_forecolor(imhtml, font->fore); | |
1578 if (font->back) | |
1579 gtk_imhtml_toggle_backcolor(imhtml, font->back); | |
1580 if (font->size != 3) | |
1581 gtk_imhtml_font_set_size(imhtml, font->size); | |
1582 } | |
3922 | 1583 } |
8309 | 1584 break; |
3922 | 1585 case 28: /* /A */ |
1586 if (url) { | |
8061 | 1587 gtk_imhtml_insert_link(imhtml, url, ws); |
3922 | 1588 g_free(url); |
8061 | 1589 ws[0] = '\0'; wpos = 0; |
3922 | 1590 url = NULL; |
8061 | 1591 ins = gtk_text_buffer_get_insert(imhtml->text_buffer); |
1592 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, ins); | |
2993 | 1593 } |
8061 | 1594 break; |
8118 | 1595 |
3922 | 1596 case 29: /* P */ |
1597 case 30: /* /P */ | |
1598 case 31: /* H3 */ | |
1599 case 32: /* /H3 */ | |
1600 case 33: /* HTML */ | |
1601 case 34: /* /HTML */ | |
1602 case 35: /* BODY */ | |
1603 case 36: /* /BODY */ | |
1604 case 37: /* FONT */ | |
1605 case 38: /* HEAD */ | |
1606 case 39: /* /HEAD */ | |
6982 | 1607 case 40: /* BINARY */ |
1608 case 41: /* /BINARY */ | |
3922 | 1609 break; |
1610 case 43: /* FONT (opt) */ | |
1611 { | |
4032 | 1612 gchar *color, *back, *face, *size, *sml; |
5967 | 1613 GtkIMHtmlFontDetail *font, *oldfont = NULL; |
3922 | 1614 color = gtk_imhtml_get_html_opt (tag, "COLOR="); |
1615 back = gtk_imhtml_get_html_opt (tag, "BACK="); | |
1616 face = gtk_imhtml_get_html_opt (tag, "FACE="); | |
1617 size = gtk_imhtml_get_html_opt (tag, "SIZE="); | |
4032 | 1618 sml = gtk_imhtml_get_html_opt (tag, "SML="); |
1619 if (!(color || back || face || size || sml)) | |
3922 | 1620 break; |
8061 | 1621 |
1622 if (url) | |
1623 gtk_imhtml_insert_link(imhtml, url, ws); | |
1624 else | |
1625 gtk_text_buffer_insert(imhtml->text_buffer, &iter, ws, wpos); | |
1626 ws[0] = '\0'; wpos = 0; | |
1627 | |
5967 | 1628 font = g_new0 (GtkIMHtmlFontDetail, 1); |
3922 | 1629 if (fonts) |
1630 oldfont = fonts->data; | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1631 |
8309 | 1632 if (color && !(options & GTK_IMHTML_NO_COLOURS)) { |
3922 | 1633 font->fore = color; |
8061 | 1634 gtk_imhtml_toggle_forecolor(imhtml, font->fore); |
8309 | 1635 } |
1636 //else if (oldfont && oldfont->fore) | |
1637 // font->fore = g_strdup(oldfont->fore); | |
1638 | |
1639 if (back && !(options & GTK_IMHTML_NO_COLOURS)) { | |
3922 | 1640 font->back = back; |
8061 | 1641 gtk_imhtml_toggle_backcolor(imhtml, font->back); |
8309 | 1642 } |
1643 //else if (oldfont && oldfont->back) | |
1644 // font->back = g_strdup(oldfont->back); | |
1645 | |
1646 if (face && !(options & GTK_IMHTML_NO_FONTS)) { | |
3922 | 1647 font->face = face; |
8061 | 1648 gtk_imhtml_toggle_fontface(imhtml, font->face); |
8309 | 1649 } |
1650 //else if (oldfont && oldfont->face) | |
1651 // font->face = g_strdup(oldfont->face); | |
4032 | 1652 |
1653 if (sml) | |
1654 font->sml = sml; | |
1655 else if (oldfont && oldfont->sml) | |
1656 font->sml = g_strdup(oldfont->sml); | |
1657 | |
3922 | 1658 if (size && !(options & GTK_IMHTML_NO_SIZES)) { |
1659 if (*size == '+') { | |
1660 sscanf (size + 1, "%hd", &font->size); | |
1661 font->size += 3; | |
1662 } else if (*size == '-') { | |
1663 sscanf (size + 1, "%hd", &font->size); | |
1664 font->size = MAX (0, 3 - font->size); | |
1665 } else if (isdigit (*size)) { | |
1666 sscanf (size, "%hd", &font->size); | |
8061 | 1667 } |
6042 | 1668 if (font->size > 100) |
1669 font->size = 100; | |
3922 | 1670 } else if (oldfont) |
1671 font->size = oldfont->size; | |
8309 | 1672 else |
1673 font->size = 3; | |
1674 gtk_imhtml_font_set_size(imhtml, font->size); | |
3922 | 1675 g_free(size); |
1676 fonts = g_slist_prepend (fonts, font); | |
1677 } | |
1678 break; | |
1679 case 44: /* BODY (opt) */ | |
1680 if (!(options & GTK_IMHTML_NO_COLOURS)) { | |
1681 char *bgcolor = gtk_imhtml_get_html_opt (tag, "BGCOLOR="); | |
1682 if (bgcolor) { | |
8061 | 1683 if (url) |
1684 gtk_imhtml_insert_link(imhtml, url, ws); | |
1685 else | |
1686 gtk_text_buffer_insert(imhtml->text_buffer, &iter, ws, wpos); | |
1687 ws[0] = '\0'; wpos = 0; | |
8177 | 1688 /* NEW_BIT(NEW_TEXT_BIT); */ |
3922 | 1689 if (bg) |
1690 g_free(bg); | |
1691 bg = bgcolor; | |
8061 | 1692 gtk_imhtml_toggle_backcolor(imhtml, bg); |
2885
f72efa29c109
[gaim-migrate @ 2898]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2871
diff
changeset
|
1693 } |
1428 | 1694 } |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1695 break; |
3922 | 1696 case 45: /* A (opt) */ |
1697 { | |
1698 gchar *href = gtk_imhtml_get_html_opt (tag, "HREF="); | |
1699 if (href) { | |
8061 | 1700 if (url) { |
1701 gtk_imhtml_insert_link(imhtml, url, ws); | |
1702 g_free(url); | |
1703 } else | |
1704 gtk_text_buffer_insert(imhtml->text_buffer, &iter, ws, wpos); | |
1705 ws[0] = '\0'; wpos = 0; | |
3922 | 1706 url = href; |
1707 } | |
2993 | 1708 } |
3922 | 1709 break; |
4895 | 1710 case 46: /* IMG (opt) */ |
6982 | 1711 case 59: /* IMG */ |
4895 | 1712 { |
6982 | 1713 GdkPixbuf *img = NULL; |
1714 const gchar *filename = NULL; | |
4895 | 1715 |
6982 | 1716 if (images && images->data) { |
1717 img = images->data; | |
1718 images = images->next; | |
1719 filename = g_object_get_data(G_OBJECT(img), "filename"); | |
1720 g_object_ref(G_OBJECT(img)); | |
1721 } else { | |
1722 img = gtk_widget_render_icon(GTK_WIDGET(imhtml), | |
1723 GTK_STOCK_MISSING_IMAGE, GTK_ICON_SIZE_BUTTON, | |
1724 "gtkimhtml-missing-image"); | |
1725 } | |
4895 | 1726 |
6982 | 1727 scalable = gtk_imhtml_image_new(img, filename); |
8177 | 1728 /* NEW_BIT(NEW_SCALABLE_BIT); */ |
6982 | 1729 g_object_unref(G_OBJECT(img)); |
4895 | 1730 } |
3922 | 1731 case 47: /* P (opt) */ |
1732 case 48: /* H3 (opt) */ | |
5093 | 1733 case 49: /* HTML (opt) */ |
5101 | 1734 case 50: /* CITE */ |
1735 case 51: /* /CITE */ | |
8026 | 1736 case 56: /* SPAN (opt) */ |
8118 | 1737 /* Inline CSS Support - Douglas Thrift |
1738 * | |
1739 * color | |
1740 * font-family | |
1741 * font-size | |
1742 */ | |
1743 { | |
1744 gchar *style, *color, *family, *size; | |
1745 GtkIMHtmlFontDetail *font, *oldfont = NULL; | |
1746 style = gtk_imhtml_get_html_opt (tag, "style="); | |
1747 | |
1748 if (!style) break; | |
1749 | |
1750 color = gtk_imhtml_get_css_opt (style, "color: "); | |
1751 family = gtk_imhtml_get_css_opt (style, | |
1752 "font-family: "); | |
1753 size = gtk_imhtml_get_css_opt (style, "font-size: "); | |
1754 | |
8120 | 1755 if (!(color || family || size)) { |
1756 g_free(style); | |
1757 break; | |
1758 } | |
8118 | 1759 |
1760 if (url) | |
1761 gtk_imhtml_insert_link(imhtml, url, ws); | |
1762 else | |
1763 gtk_text_buffer_insert(imhtml->text_buffer, &iter, ws, wpos); | |
1764 ws[0] = '\0'; wpos = 0; | |
8177 | 1765 /* NEW_BIT (NEW_TEXT_BIT); */ |
8118 | 1766 |
1767 font = g_new0 (GtkIMHtmlFontDetail, 1); | |
1768 if (fonts) | |
1769 oldfont = fonts->data; | |
1770 | |
1771 if (color && !(options & GTK_IMHTML_NO_COLOURS)) | |
1772 font->fore = color; | |
1773 else if (oldfont && oldfont->fore) | |
1774 font->fore = g_strdup(oldfont->fore); | |
1775 | |
1776 if (oldfont && oldfont->back) | |
1777 font->back = g_strdup(oldfont->back); | |
1778 | |
1779 if (family && !(options & GTK_IMHTML_NO_FONTS)) | |
1780 font->face = family; | |
1781 else if (oldfont && oldfont->face) | |
1782 font->face = g_strdup(oldfont->face); | |
1783 if (font->face && (atoi(font->face) > 100)) { | |
1784 g_free(font->face); | |
1785 font->face = g_strdup("100"); | |
1786 } | |
1787 | |
1788 if (oldfont && oldfont->sml) | |
1789 font->sml = g_strdup(oldfont->sml); | |
1790 | |
1791 if (size && !(options & GTK_IMHTML_NO_SIZES)) { | |
1792 if (g_ascii_strcasecmp(size, "smaller") == 0) | |
1793 { | |
1794 font->size = 2; | |
1795 } | |
1796 else if (g_ascii_strcasecmp(size, "larger") == 0) | |
1797 { | |
1798 font->size = 4; | |
1799 } | |
1800 else | |
1801 { | |
1802 font->size = 3; | |
1803 } | |
1804 } else if (oldfont) | |
1805 font->size = oldfont->size; | |
1806 | |
1807 g_free(style); | |
1808 g_free(size); | |
1809 fonts = g_slist_prepend (fonts, font); | |
1810 } | |
1811 break; | |
5104 | 1812 case 57: /* /SPAN */ |
8118 | 1813 /* Inline CSS Support - Douglas Thrift */ |
1814 if (fonts) { | |
1815 GtkIMHtmlFontDetail *font = fonts->data; | |
1816 if (url) | |
1817 gtk_imhtml_insert_link(imhtml, url, ws); | |
1818 else | |
1819 gtk_text_buffer_insert(imhtml->text_buffer, &iter, ws, wpos); | |
1820 ws[0] = '\0'; wpos = 0; | |
8177 | 1821 /* NEW_BIT (NEW_TEXT_BIT); */ |
8118 | 1822 fonts = g_slist_remove (fonts, font); |
1823 if (font->face) | |
1824 g_free (font->face); | |
1825 if (font->fore) | |
1826 g_free (font->fore); | |
1827 if (font->back) | |
1828 g_free (font->back); | |
1829 if (font->sml) | |
1830 g_free (font->sml); | |
1831 g_free (font); | |
1832 } | |
1833 break; | |
8026 | 1834 case 60: /* SPAN */ |
2993 | 1835 break; |
8061 | 1836 case 62: /* comment */ |
8177 | 1837 /* NEW_BIT (NEW_TEXT_BIT); */ |
8317 | 1838 ws[wpos] = '\0'; |
1839 if (url) | |
1840 gtk_imhtml_insert_link(imhtml, url, ws); | |
1841 else | |
1842 gtk_text_buffer_insert(imhtml->text_buffer, &iter, ws, wpos); | |
6124 | 1843 if (imhtml->show_comments) |
1844 wpos = g_snprintf (ws, len, "%s", tag); | |
8177 | 1845 /* NEW_BIT (NEW_COMMENT_BIT); */ |
3922 | 1846 break; |
1847 default: | |
6882 | 1848 break; |
2993 | 1849 } |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1850 c += tlen; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1851 pos += tlen; |
4138 | 1852 if(tag) |
1853 g_free(tag); /* This was allocated back in VALID_TAG() */ | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1854 } else if (*c == '&' && gtk_imhtml_is_amp_escape (c, &, &tlen)) { |
7280 | 1855 while(*amp) { |
1856 ws [wpos++] = *amp++; | |
1857 } | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1858 c += tlen; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1859 pos += tlen; |
1428 | 1860 } else if (*c == '\n') { |
1861 if (!(options & GTK_IMHTML_NO_NEWLINE)) { | |
3922 | 1862 ws[wpos] = '\n'; |
1863 wpos++; | |
8061 | 1864 if (url) |
1865 gtk_imhtml_insert_link(imhtml, url, ws); | |
1866 else | |
1867 gtk_text_buffer_insert(imhtml->text_buffer, &iter, ws, wpos); | |
1868 ws[0] = '\0'; | |
1869 wpos = 0; | |
8177 | 1870 /* NEW_BIT (NEW_TEXT_BIT); */ |
1428 | 1871 } |
1872 c++; | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1873 pos++; |
4253 | 1874 } else if (imhtml->show_smileys && (gtk_imhtml_is_smiley (imhtml, fonts, c, &smilelen) || gtk_imhtml_is_smiley(imhtml, NULL, c, &smilelen))) { |
5967 | 1875 GtkIMHtmlFontDetail *fd; |
8061 | 1876 |
4032 | 1877 gchar *sml = NULL; |
1878 if (fonts) { | |
1879 fd = fonts->data; | |
1880 sml = fd->sml; | |
1881 } | |
8061 | 1882 if (url) |
1883 gtk_imhtml_insert_link(imhtml, url, ws); | |
1884 else { | |
1885 printf("Inserting %s\n", ws); | |
1886 gtk_text_buffer_insert(imhtml->text_buffer, &iter, ws, wpos); | |
1887 } | |
7988 | 1888 wpos = g_snprintf (ws, smilelen + 1, "%s", c); |
8061 | 1889 gtk_imhtml_insert_smiley(imhtml, sml, ws); |
7809 | 1890 |
8061 | 1891 ins = gtk_text_buffer_get_insert(imhtml->text_buffer); |
1892 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, ins); | |
1893 | |
4032 | 1894 c += smilelen; |
7809 | 1895 pos += smilelen; |
4032 | 1896 wpos = 0; |
1897 ws[0] = 0; | |
8061 | 1898 } else if (*c) { |
1428 | 1899 ws [wpos++] = *c++; |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1900 pos++; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1901 } else { |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1902 break; |
1428 | 1903 } |
1904 } | |
8061 | 1905 if (url) |
1906 gtk_imhtml_insert_link(imhtml, url, ws); | |
1907 else | |
1908 gtk_text_buffer_insert(imhtml->text_buffer, &iter, ws, wpos); | |
1909 ws[0] = '\0'; wpos = 0; | |
1910 | |
8177 | 1911 /* NEW_BIT(NEW_TEXT_BIT); */ |
1428 | 1912 if (url) { |
1913 g_free (url); | |
3922 | 1914 if (str) |
1915 str = g_string_append (str, "</A>"); | |
1428 | 1916 } |
8061 | 1917 |
4032 | 1918 while (fonts) { |
5967 | 1919 GtkIMHtmlFontDetail *font = fonts->data; |
4032 | 1920 fonts = g_slist_remove (fonts, font); |
1921 if (font->face) | |
1922 g_free (font->face); | |
1923 if (font->fore) | |
1924 g_free (font->fore); | |
1925 if (font->back) | |
1926 g_free (font->back); | |
1927 if (font->sml) | |
1928 g_free (font->sml); | |
1929 g_free (font); | |
1930 if (str) | |
1931 str = g_string_append (str, "</FONT>"); | |
1932 } | |
1933 | |
3922 | 1934 if (str) { |
1428 | 1935 while (bold) { |
3922 | 1936 str = g_string_append (str, "</B>"); |
1428 | 1937 bold--; |
1938 } | |
1939 while (italics) { | |
3922 | 1940 str = g_string_append (str, "</I>"); |
1428 | 1941 italics--; |
1942 } | |
1943 while (underline) { | |
3922 | 1944 str = g_string_append (str, "</U>"); |
1428 | 1945 underline--; |
1946 } | |
1947 while (strike) { | |
3922 | 1948 str = g_string_append (str, "</S>"); |
1428 | 1949 strike--; |
1950 } | |
1951 while (sub) { | |
3922 | 1952 str = g_string_append (str, "</SUB>"); |
1428 | 1953 sub--; |
1954 } | |
1955 while (sup) { | |
3922 | 1956 str = g_string_append (str, "</SUP>"); |
1428 | 1957 sup--; |
1958 } | |
1959 while (title) { | |
3922 | 1960 str = g_string_append (str, "</TITLE>"); |
1428 | 1961 title--; |
1962 } | |
1691
d802b115800f
[gaim-migrate @ 1701]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1647
diff
changeset
|
1963 while (pre) { |
3922 | 1964 str = g_string_append (str, "</PRE>"); |
1691
d802b115800f
[gaim-migrate @ 1701]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1647
diff
changeset
|
1965 pre--; |
d802b115800f
[gaim-migrate @ 1701]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1647
diff
changeset
|
1966 } |
1428 | 1967 } |
4032 | 1968 g_free (ws); |
4630 | 1969 if(bg) |
1970 g_free(bg); | |
8061 | 1971 gtk_imhtml_close_tags(imhtml); |
4032 | 1972 if (!(options & GTK_IMHTML_NO_SCROLL)) |
1973 gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (imhtml), mark, | |
1974 0, TRUE, 0.0, 1.0); | |
3922 | 1975 gtk_text_buffer_delete_mark (imhtml->text_buffer, mark); |
8061 | 1976 gtk_text_buffer_move_mark (imhtml->text_buffer, |
1977 gtk_text_buffer_get_mark (imhtml->text_buffer, "insert"), | |
1978 &iter); | |
3922 | 1979 return str; |
1980 } | |
1981 | |
4892 | 1982 void gtk_imhtml_remove_smileys(GtkIMHtml *imhtml) |
1983 { | |
4288 | 1984 g_hash_table_destroy(imhtml->smiley_data); |
1985 gtk_smiley_tree_destroy(imhtml->default_smilies); | |
4892 | 1986 imhtml->smiley_data = g_hash_table_new_full(g_str_hash, g_str_equal, |
4902 | 1987 g_free, (GDestroyNotify)gtk_smiley_tree_destroy); |
4288 | 1988 imhtml->default_smilies = gtk_smiley_tree_new(); |
1989 } | |
3922 | 1990 void gtk_imhtml_show_smileys (GtkIMHtml *imhtml, |
4253 | 1991 gboolean show) |
1992 { | |
1993 imhtml->show_smileys = show; | |
1994 } | |
3922 | 1995 |
1996 void gtk_imhtml_show_comments (GtkIMHtml *imhtml, | |
4253 | 1997 gboolean show) |
1998 { | |
6124 | 1999 imhtml->show_comments = show; |
4253 | 2000 } |
1780
d7cbedd1d651
[gaim-migrate @ 1790]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1738
diff
changeset
|
2001 |
d7cbedd1d651
[gaim-migrate @ 1790]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1738
diff
changeset
|
2002 void |
d7cbedd1d651
[gaim-migrate @ 1790]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1738
diff
changeset
|
2003 gtk_imhtml_clear (GtkIMHtml *imhtml) |
d7cbedd1d651
[gaim-migrate @ 1790]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1738
diff
changeset
|
2004 { |
7991 | 2005 GList *del; |
3922 | 2006 GtkTextIter start, end; |
7991 | 2007 |
3922 | 2008 gtk_text_buffer_get_start_iter(imhtml->text_buffer, &start); |
2009 gtk_text_buffer_get_end_iter(imhtml->text_buffer, &end); | |
2010 gtk_text_buffer_delete(imhtml->text_buffer, &start, &end); | |
7991 | 2011 |
8061 | 2012 for(del = imhtml->format_spans; del; del = del->next) { |
2013 GtkIMHtmlFormatSpan *span = del->data; | |
2014 if (span->start_tag) | |
2015 g_free(span->start_tag); | |
2016 if (span->end_tag) | |
2017 g_free(span->end_tag); | |
2018 g_free(span); | |
2019 } | |
2020 g_list_free(imhtml->format_spans); | |
2021 imhtml->format_spans = NULL; | |
2022 | |
7991 | 2023 for(del = imhtml->scalables; del; del = del->next) { |
2024 GtkIMHtmlScalable *scale = del->data; | |
2025 scale->free(scale); | |
2026 } | |
2027 g_list_free(imhtml->scalables); | |
2028 imhtml->scalables = NULL; | |
8061 | 2029 |
2030 imhtml->edit.bold = NULL; | |
2031 imhtml->edit.italic = NULL; | |
2032 imhtml->edit.underline = NULL; | |
2033 imhtml->edit.fontface = NULL; | |
2034 imhtml->edit.forecolor = NULL; | |
2035 imhtml->edit.backcolor = NULL; | |
2036 imhtml->edit.sizespan = NULL; | |
2037 imhtml->edit.fontsize = 3; | |
1780
d7cbedd1d651
[gaim-migrate @ 1790]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1738
diff
changeset
|
2038 } |
2363
08c66712364c
[gaim-migrate @ 2376]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2349
diff
changeset
|
2039 |
4046 | 2040 void gtk_imhtml_page_up (GtkIMHtml *imhtml) |
2041 { | |
5282 | 2042 GdkRectangle rect; |
2043 GtkTextIter iter; | |
4046 | 2044 |
5282 | 2045 gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(imhtml), &rect); |
2046 gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(imhtml), &iter, rect.x, | |
2047 rect.y - rect.height); | |
2048 gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(imhtml), &iter, 0, TRUE, 0, 0); | |
8061 | 2049 |
4046 | 2050 } |
5282 | 2051 void gtk_imhtml_page_down (GtkIMHtml *imhtml) |
2052 { | |
2053 GdkRectangle rect; | |
2054 GtkTextIter iter; | |
2055 | |
2056 gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(imhtml), &rect); | |
2057 gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(imhtml), &iter, rect.x, | |
2058 rect.y + rect.height); | |
2059 gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(imhtml), &iter, 0, TRUE, 0, 0); | |
2060 } | |
4735 | 2061 |
5967 | 2062 /* GtkIMHtmlScalable, gtk_imhtml_image, gtk_imhtml_hr */ |
6982 | 2063 GtkIMHtmlScalable *gtk_imhtml_image_new(GdkPixbuf *img, const gchar *filename) |
4735 | 2064 { |
5967 | 2065 GtkIMHtmlImage *im_image = g_malloc(sizeof(GtkIMHtmlImage)); |
5012 | 2066 GtkImage *image = GTK_IMAGE(gtk_image_new_from_pixbuf(img)); |
4895 | 2067 |
5967 | 2068 GTK_IMHTML_SCALABLE(im_image)->scale = gtk_imhtml_image_scale; |
2069 GTK_IMHTML_SCALABLE(im_image)->add_to = gtk_imhtml_image_add_to; | |
2070 GTK_IMHTML_SCALABLE(im_image)->free = gtk_imhtml_image_free; | |
5046 | 2071 |
2072 im_image->pixbuf = img; | |
5012 | 2073 im_image->image = image; |
4895 | 2074 im_image->width = gdk_pixbuf_get_width(img); |
2075 im_image->height = gdk_pixbuf_get_height(img); | |
2076 im_image->mark = NULL; | |
6982 | 2077 im_image->filename = filename ? g_strdup(filename) : NULL; |
4895 | 2078 |
5046 | 2079 g_object_ref(img); |
4895 | 2080 return GTK_IMHTML_SCALABLE(im_image); |
2081 } | |
2082 | |
5967 | 2083 void gtk_imhtml_image_scale(GtkIMHtmlScalable *scale, int width, int height) |
4895 | 2084 { |
5967 | 2085 GtkIMHtmlImage *image = (GtkIMHtmlImage *)scale; |
4895 | 2086 |
2087 if(image->width > width || image->height > height){ | |
2088 GdkPixbuf *new_image = NULL; | |
2089 float factor; | |
2090 int new_width = image->width, new_height = image->height; | |
2091 | |
2092 if(image->width > width){ | |
2093 factor = (float)(width)/image->width; | |
2094 new_width = width; | |
2095 new_height = image->height * factor; | |
2096 } | |
2097 if(new_height > height){ | |
2098 factor = (float)(height)/new_height; | |
2099 new_height = height; | |
2100 new_width = new_width * factor; | |
2101 } | |
2102 | |
5046 | 2103 new_image = gdk_pixbuf_scale_simple(image->pixbuf, new_width, new_height, GDK_INTERP_BILINEAR); |
5012 | 2104 gtk_image_set_from_pixbuf(image->image, new_image); |
4895 | 2105 g_object_unref(G_OBJECT(new_image)); |
2106 } | |
2107 } | |
2108 | |
5012 | 2109 static void write_img_to_file(GtkWidget *w, GtkFileSelection *sel) |
2110 { | |
2111 const gchar *filename = gtk_file_selection_get_filename(sel); | |
5967 | 2112 gchar *dirname; |
2113 GtkIMHtmlImage *image = g_object_get_data(G_OBJECT(sel), "GtkIMHtmlImage"); | |
5012 | 2114 gchar *type = NULL; |
5019 | 2115 GError *error = NULL; |
5015 | 2116 #if GTK_CHECK_VERSION(2,2,0) |
5012 | 2117 GSList *formats = gdk_pixbuf_get_formats(); |
6162 | 2118 #else |
2119 char *basename = g_path_get_basename(filename); | |
2120 char *ext = strrchr(basename, '.'); | |
5959 | 2121 #endif |
5012 | 2122 |
5967 | 2123 if (g_file_test(filename, G_FILE_TEST_IS_DIR)) { |
2124 /* append a / if needed */ | |
2125 if (filename[strlen(filename) - 1] != '/') { | |
2126 dirname = g_strconcat(filename, "/", NULL); | |
2127 } else { | |
2128 dirname = g_strdup(filename); | |
2129 } | |
2130 gtk_file_selection_set_filename(sel, dirname); | |
2131 g_free(dirname); | |
5959 | 2132 return; |
5967 | 2133 } |
5959 | 2134 |
2135 #if GTK_CHECK_VERSION(2,2,0) | |
5012 | 2136 while(formats){ |
2137 GdkPixbufFormat *format = formats->data; | |
2138 gchar **extensions = gdk_pixbuf_format_get_extensions(format); | |
2139 gpointer p = extensions; | |
2140 | |
2141 while(gdk_pixbuf_format_is_writable(format) && extensions && extensions[0]){ | |
2142 gchar *fmt_ext = extensions[0]; | |
2143 const gchar* file_ext = filename + strlen(filename) - strlen(fmt_ext); | |
2144 | |
2145 if(!strcmp(fmt_ext, file_ext)){ | |
2146 type = gdk_pixbuf_format_get_name(format); | |
2147 break; | |
2148 } | |
2149 | |
2150 extensions++; | |
2151 } | |
2152 | |
2153 g_strfreev(p); | |
2154 | |
2155 if(type) | |
2156 break; | |
2157 | |
2158 formats = formats->next; | |
2159 } | |
2160 | |
5020 | 2161 g_slist_free(formats); |
2162 #else | |
2163 /* this is really ugly code, but I think it will work */ | |
2164 if(ext) { | |
2165 ext++; | |
2166 if(!g_ascii_strcasecmp(ext, "jpeg") || !g_ascii_strcasecmp(ext, "jpg")) | |
2167 type = g_strdup("jpeg"); | |
2168 else if(!g_ascii_strcasecmp(ext, "png")) | |
2169 type = g_strdup("png"); | |
2170 } | |
2171 | |
2172 g_free(basename); | |
2173 #endif | |
2174 | |
5012 | 2175 /* If I can't find a valid type, I will just tell the user about it and then assume |
2176 it's a png */ | |
2177 if(!type){ | |
2178 gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, | |
5967 | 2179 _("Unable to guess the image type based on the file extension supplied. Defaulting to PNG.")); |
5012 | 2180 type = g_strdup("png"); |
2181 } | |
2182 | |
5046 | 2183 gdk_pixbuf_save(image->pixbuf, filename, type, &error, NULL); |
5012 | 2184 |
2185 if(error){ | |
2186 gtk_message_dialog_new(NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, | |
2187 _("Error saving image: %s"), error->message); | |
2188 g_error_free(error); | |
2189 } | |
2190 | |
2191 g_free(type); | |
2192 } | |
2193 | |
5967 | 2194 static void gtk_imhtml_image_save(GtkWidget *w, GtkIMHtmlImage *image) |
5012 | 2195 { |
5967 | 2196 GtkWidget *sel = gtk_file_selection_new(_("Save Image")); |
5012 | 2197 |
6982 | 2198 if (image->filename) |
2199 gtk_file_selection_set_filename(GTK_FILE_SELECTION(sel), image->filename); | |
5967 | 2200 g_object_set_data(G_OBJECT(sel), "GtkIMHtmlImage", image); |
5012 | 2201 g_signal_connect(G_OBJECT(GTK_FILE_SELECTION(sel)->ok_button), "clicked", |
2202 G_CALLBACK(write_img_to_file), sel); | |
2203 | |
2204 g_signal_connect_swapped(G_OBJECT(GTK_FILE_SELECTION(sel)->ok_button), "clicked", | |
2205 G_CALLBACK(gtk_widget_destroy), sel); | |
2206 g_signal_connect_swapped(G_OBJECT(GTK_FILE_SELECTION(sel)->cancel_button), "clicked", | |
8061 | 2207 G_CALLBACK(gtk_widget_destroy), sel); |
5012 | 2208 |
2209 gtk_widget_show(sel); | |
2210 } | |
2211 | |
5967 | 2212 static gboolean gtk_imhtml_image_clicked(GtkWidget *w, GdkEvent *event, GtkIMHtmlImage *image) |
5012 | 2213 { |
2214 GdkEventButton *event_button = (GdkEventButton *) event; | |
2215 | |
2216 if (event->type == GDK_BUTTON_RELEASE) { | |
2217 if(event_button->button == 3) { | |
2218 GtkWidget *img, *item, *menu; | |
2219 gchar *text = g_strdup_printf(_("_Save Image...")); | |
2220 menu = gtk_menu_new(); | |
2221 | |
2222 /* buttons and such */ | |
2223 img = gtk_image_new_from_stock(GTK_STOCK_SAVE, GTK_ICON_SIZE_MENU); | |
2224 item = gtk_image_menu_item_new_with_mnemonic(text); | |
2225 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), img); | |
5967 | 2226 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(gtk_imhtml_image_save), image); |
5012 | 2227 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); |
2228 | |
2229 gtk_widget_show_all(menu); | |
2230 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, | |
2231 event_button->button, event_button->time); | |
2232 | |
2233 g_free(text); | |
2234 return TRUE; | |
2235 } | |
2236 } | |
2237 if(event->type == GDK_BUTTON_PRESS && event_button->button == 3) | |
2238 return TRUE; /* Clicking the right mouse button on a link shouldn't | |
2239 be caught by the regular GtkTextView menu */ | |
2240 else | |
2241 return FALSE; /* Let clicks go through if we didn't catch anything */ | |
2242 | |
2243 } | |
5967 | 2244 void gtk_imhtml_image_free(GtkIMHtmlScalable *scale) |
2245 { | |
2246 GtkIMHtmlImage *image = (GtkIMHtmlImage *)scale; | |
2247 | |
2248 g_object_unref(image->pixbuf); | |
6982 | 2249 if (image->filename) |
2250 g_free(image->filename); | |
5967 | 2251 g_free(scale); |
2252 } | |
2253 | |
2254 void gtk_imhtml_image_add_to(GtkIMHtmlScalable *scale, GtkIMHtml *imhtml, GtkTextIter *iter) | |
2255 { | |
2256 GtkIMHtmlImage *image = (GtkIMHtmlImage *)scale; | |
2257 GtkWidget *box = gtk_event_box_new(); | |
2258 GtkTextChildAnchor *anchor = gtk_text_buffer_create_child_anchor(imhtml->text_buffer, iter); | |
2259 | |
2260 gtk_container_add(GTK_CONTAINER(box), GTK_WIDGET(image->image)); | |
2261 | |
2262 gtk_widget_show(GTK_WIDGET(image->image)); | |
2263 gtk_widget_show(box); | |
2264 | |
2265 gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), box, anchor); | |
2266 g_signal_connect(G_OBJECT(box), "event", G_CALLBACK(gtk_imhtml_image_clicked), image); | |
2267 } | |
2268 | |
2269 GtkIMHtmlScalable *gtk_imhtml_hr_new() | |
2270 { | |
2271 GtkIMHtmlHr *hr = g_malloc(sizeof(GtkIMHtmlHr)); | |
2272 | |
2273 GTK_IMHTML_SCALABLE(hr)->scale = gtk_imhtml_hr_scale; | |
2274 GTK_IMHTML_SCALABLE(hr)->add_to = gtk_imhtml_hr_add_to; | |
2275 GTK_IMHTML_SCALABLE(hr)->free = gtk_imhtml_hr_free; | |
2276 | |
2277 hr->sep = gtk_hseparator_new(); | |
2278 gtk_widget_set_size_request(hr->sep, 5000, 2); | |
2279 gtk_widget_show(hr->sep); | |
2280 | |
2281 return GTK_IMHTML_SCALABLE(hr); | |
2282 } | |
2283 | |
2284 void gtk_imhtml_hr_scale(GtkIMHtmlScalable *scale, int width, int height) | |
2285 { | |
2286 gtk_widget_set_size_request(((GtkIMHtmlHr *)scale)->sep, width, 2); | |
2287 } | |
2288 | |
2289 void gtk_imhtml_hr_add_to(GtkIMHtmlScalable *scale, GtkIMHtml *imhtml, GtkTextIter *iter) | |
2290 { | |
2291 GtkIMHtmlHr *hr = (GtkIMHtmlHr *)scale; | |
2292 GtkTextChildAnchor *anchor = gtk_text_buffer_create_child_anchor(imhtml->text_buffer, iter); | |
8061 | 2293 g_object_set_data(G_OBJECT(anchor), "text_tag", "<hr>"); |
5967 | 2294 gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), hr->sep, anchor); |
2295 } | |
2296 | |
2297 void gtk_imhtml_hr_free(GtkIMHtmlScalable *scale) | |
2298 { | |
2299 g_free(scale); | |
2300 } | |
7295 | 2301 |
2302 gboolean gtk_imhtml_search_find(GtkIMHtml *imhtml, const gchar *text) | |
2303 { | |
2304 GtkTextIter iter, start, end; | |
2305 gboolean new_search = TRUE; | |
2306 | |
2307 g_return_val_if_fail(imhtml != NULL, FALSE); | |
2308 g_return_val_if_fail(text != NULL, FALSE); | |
8061 | 2309 |
7295 | 2310 if (imhtml->search_string && !strcmp(text, imhtml->search_string)) |
2311 new_search = FALSE; | |
8061 | 2312 |
7295 | 2313 if (new_search) { |
2314 gtk_imhtml_search_clear(imhtml); | |
2315 gtk_text_buffer_get_start_iter(imhtml->text_buffer, &iter); | |
2316 } else { | |
2317 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, | |
8061 | 2318 gtk_text_buffer_get_mark(imhtml->text_buffer, "search")); |
7295 | 2319 } |
2320 imhtml->search_string = g_strdup(text); | |
2321 | |
7358 | 2322 if (gtk_source_iter_forward_search(&iter, imhtml->search_string, |
2323 GTK_SOURCE_SEARCH_VISIBLE_ONLY | GTK_SOURCE_SEARCH_CASE_INSENSITIVE, | |
7295 | 2324 &start, &end, NULL)) { |
2325 | |
2326 gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(imhtml), &start, 0, TRUE, 0, 0); | |
2327 gtk_text_buffer_create_mark(imhtml->text_buffer, "search", &end, FALSE); | |
2328 if (new_search) { | |
2329 gtk_text_buffer_remove_tag_by_name(imhtml->text_buffer, "search", &iter, &end); | |
8061 | 2330 do |
7295 | 2331 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "search", &start, &end); |
8061 | 2332 while (gtk_source_iter_forward_search(&end, imhtml->search_string, |
2333 GTK_SOURCE_SEARCH_VISIBLE_ONLY | | |
7358 | 2334 GTK_SOURCE_SEARCH_CASE_INSENSITIVE, |
7295 | 2335 &start, &end, NULL)); |
2336 } | |
2337 return TRUE; | |
2338 } | |
8061 | 2339 |
2340 gtk_imhtml_search_clear(imhtml); | |
2341 | |
7295 | 2342 return FALSE; |
2343 } | |
2344 | |
2345 void gtk_imhtml_search_clear(GtkIMHtml *imhtml) | |
2346 { | |
2347 GtkTextIter start, end; | |
8061 | 2348 |
7295 | 2349 g_return_if_fail(imhtml != NULL); |
8061 | 2350 |
7295 | 2351 gtk_text_buffer_get_start_iter(imhtml->text_buffer, &start); |
2352 gtk_text_buffer_get_end_iter(imhtml->text_buffer, &end); | |
2353 | |
2354 gtk_text_buffer_remove_tag_by_name(imhtml->text_buffer, "search", &start, &end); | |
2355 if (imhtml->search_string) | |
2356 g_free(imhtml->search_string); | |
2357 imhtml->search_string = NULL; | |
2358 } | |
8061 | 2359 |
2360 /* Editable stuff */ | |
2361 static void insert_cb(GtkTextBuffer *buffer, GtkTextIter *iter, gchar *text, gint len, GtkIMHtml *imhtml) | |
2362 { | |
2363 GtkIMHtmlFormatSpan *span = NULL; | |
2364 GtkTextIter end; | |
2365 | |
2366 gtk_text_iter_forward_chars(iter, len); | |
2367 gtk_text_buffer_get_end_iter(imhtml->text_buffer, &end); | |
2368 gtk_text_iter_forward_char(&end); | |
2369 | |
2370 if (!gtk_text_iter_equal(&end, iter)) | |
2371 return; | |
2372 | |
2373 | |
2374 if ((span = imhtml->edit.bold)) { | |
2375 GtkTextIter bold; | |
2376 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &bold, span->start); | |
2377 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "BOLD", &bold, iter); | |
2378 } | |
2379 | |
2380 if ((span = imhtml->edit.italic)) { | |
2381 GtkTextIter italic; | |
2382 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &italic, span->start); | |
2383 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "ITALICS", &italic, | |
2384 iter); | |
2385 } | |
2386 | |
2387 if ((span = imhtml->edit.underline)) { | |
2388 GtkTextIter underline; | |
2389 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &underline, span->start); | |
2390 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "UNDERLINE", &underline, | |
2391 iter); | |
2392 } | |
2393 | |
2394 if ((span = imhtml->edit.forecolor)) { | |
2395 GtkTextIter fore; | |
2396 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &fore, span->start); | |
2397 gtk_text_buffer_apply_tag(imhtml->text_buffer, span->tag, &fore, iter); | |
2398 } | |
2399 | |
2400 if ((span = imhtml->edit.backcolor)) { | |
2401 GtkTextIter back; | |
2402 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &back, span->start); | |
2403 gtk_text_buffer_apply_tag(imhtml->text_buffer, span->tag, &back, iter); | |
2404 } | |
2405 | |
2406 if ((span = imhtml->edit.fontface)) { | |
2407 GtkTextIter face; | |
2408 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &face, span->start); | |
2409 gtk_text_buffer_apply_tag(imhtml->text_buffer, span->tag, &face, iter); | |
2410 } | |
2411 | |
2412 if ((span = imhtml->edit.sizespan)) { | |
2413 GtkTextIter size; | |
2414 /* We create the tags here so that one can grow font or shrink font several times | |
2415 * in a row without creating unnecessary tags */ | |
2416 if (span->tag == NULL) { | |
2417 span->tag = gtk_text_buffer_create_tag | |
8309 | 2418 (imhtml->text_buffer, NULL, "scale", (double)_point_sizes [imhtml->edit.fontsize-1], NULL); |
8061 | 2419 span->start_tag = g_strdup_printf("<font size=\"%d\">", imhtml->edit.fontsize); |
2420 span->end_tag = g_strdup("</font>"); | |
2421 } | |
2422 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &size, span->start); | |
2423 gtk_text_buffer_apply_tag(imhtml->text_buffer, span->tag, &size, iter); | |
2424 } | |
2425 } | |
2426 | |
2427 void gtk_imhtml_set_editable(GtkIMHtml *imhtml, gboolean editable) | |
2428 { | |
2429 gtk_text_view_set_editable(GTK_TEXT_VIEW(imhtml), editable); | |
8177 | 2430 /* |
2431 * We need a visible caret for accessibility, so mouseless | |
2432 * people can highlight stuff. | |
2433 */ | |
2434 /* gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(imhtml), editable); */ | |
8061 | 2435 imhtml->editable = editable; |
2436 } | |
2437 | |
2438 gboolean gtk_imhtml_get_editable(GtkIMHtml *imhtml) | |
2439 { | |
2440 return imhtml->editable; | |
2441 } | |
2442 | |
2443 gboolean gtk_imhtml_toggle_bold(GtkIMHtml *imhtml) | |
2444 { | |
2445 GtkIMHtmlFormatSpan *span; | |
2446 GtkTextMark *ins = gtk_text_buffer_get_insert(imhtml->text_buffer); | |
2447 GtkTextIter iter; | |
2448 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, ins); | |
2449 if (!imhtml->edit.bold) { | |
2450 span = g_malloc(sizeof(GtkIMHtmlFormatSpan)); | |
2451 span->start = gtk_text_buffer_create_mark(imhtml->text_buffer, NULL, &iter, TRUE); | |
2452 span->start_tag = g_strdup("<b>"); | |
2453 span->end = NULL; | |
2454 span->end_tag = g_strdup("</b>"); | |
2455 span->buffer = imhtml->text_buffer; | |
2456 span->tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(imhtml->text_buffer), "BOLD"); | |
2457 imhtml->edit.bold = span; | |
2458 imhtml->format_spans = g_list_append(imhtml->format_spans, span); | |
2459 } else { | |
2460 span = imhtml->edit.bold; | |
2461 span->end = gtk_text_buffer_create_mark(imhtml->text_buffer, NULL, &iter, TRUE); | |
2462 imhtml->edit.bold = NULL; | |
2463 } | |
2464 return imhtml->edit.bold != NULL; | |
2465 } | |
2466 | |
2467 gboolean gtk_imhtml_toggle_italic(GtkIMHtml *imhtml) | |
2468 { | |
2469 GtkIMHtmlFormatSpan *span; | |
2470 GtkTextMark *ins = gtk_text_buffer_get_insert(imhtml->text_buffer); | |
2471 GtkTextIter iter; | |
2472 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, ins); | |
2473 if (!imhtml->edit.italic) { | |
2474 span = g_malloc(sizeof(GtkIMHtmlFormatSpan)); | |
2475 span->start = gtk_text_buffer_create_mark(imhtml->text_buffer, NULL, &iter, TRUE); | |
2476 span->start_tag = g_strdup("<i>"); | |
2477 span->end = NULL; | |
2478 span->end_tag = g_strdup("</i>"); | |
2479 span->buffer = imhtml->text_buffer; | |
2480 span->tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(imhtml->text_buffer), "ITALIC"); | |
2481 imhtml->edit.italic = span; | |
2482 imhtml->format_spans = g_list_append(imhtml->format_spans, span); | |
2483 } else { | |
2484 span = imhtml->edit.italic; | |
2485 span->end = gtk_text_buffer_create_mark(imhtml->text_buffer, NULL, &iter, TRUE); | |
2486 imhtml->edit.italic = NULL; | |
2487 } | |
2488 return imhtml->edit.italic != NULL; | |
2489 } | |
2490 | |
2491 gboolean gtk_imhtml_toggle_underline(GtkIMHtml *imhtml) | |
2492 { | |
2493 GtkIMHtmlFormatSpan *span; | |
2494 GtkTextMark *ins = gtk_text_buffer_get_insert(imhtml->text_buffer); | |
2495 GtkTextIter iter; | |
2496 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, ins); | |
2497 if (!imhtml->edit.underline) { | |
2498 span = g_malloc(sizeof(GtkIMHtmlFormatSpan)); | |
2499 span->start = gtk_text_buffer_create_mark(imhtml->text_buffer, NULL, &iter, TRUE); | |
2500 span->start_tag = g_strdup("<u>"); | |
2501 span->end = NULL; | |
2502 span->end_tag = g_strdup("</u>"); | |
2503 span->buffer = imhtml->text_buffer; | |
2504 span->tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(imhtml->text_buffer), "UNDERLINE"); | |
2505 imhtml->edit.underline = span; | |
2506 imhtml->format_spans = g_list_append(imhtml->format_spans, span); | |
2507 } else { | |
2508 span = imhtml->edit.underline; | |
2509 span->end = gtk_text_buffer_create_mark(imhtml->text_buffer, NULL, &iter, TRUE); | |
2510 imhtml->edit.underline = NULL; | |
2511 } | |
2512 return imhtml->edit.underline != NULL; | |
2513 } | |
2514 | |
2515 void gtk_imhtml_font_set_size(GtkIMHtml *imhtml, gint size) | |
2516 { | |
2517 GtkIMHtmlFormatSpan *span; | |
2518 GtkTextMark *ins = gtk_text_buffer_get_insert(imhtml->text_buffer); | |
2519 GtkTextIter iter; | |
2520 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, ins); | |
2521 | |
2522 imhtml->edit.fontsize = size; | |
2523 | |
2524 if (imhtml->edit.sizespan) { | |
2525 GtkTextIter iter2; | |
2526 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter2, imhtml->edit.sizespan->start); | |
2527 if (gtk_text_iter_equal(&iter2, &iter)) | |
2528 return; | |
2529 span = imhtml->edit.sizespan; | |
2530 span->end = gtk_text_buffer_create_mark(imhtml->text_buffer, NULL, &iter, TRUE); | |
2531 } | |
2532 if (size != -1) { | |
8250 | 2533 span = g_malloc0(sizeof(GtkIMHtmlFormatSpan)); |
8061 | 2534 span->start = gtk_text_buffer_create_mark(imhtml->text_buffer, NULL, &iter, TRUE); |
2535 span->end = NULL; | |
2536 span->buffer = imhtml->text_buffer; | |
2537 span->tag = NULL; | |
2538 imhtml->edit.sizespan = span; | |
2539 imhtml->format_spans = g_list_append(imhtml->format_spans, span); | |
2540 } | |
2541 } | |
2542 | |
2543 void gtk_imhtml_font_shrink(GtkIMHtml *imhtml) | |
2544 { | |
2545 GtkIMHtmlFormatSpan *span; | |
2546 GtkTextMark *ins = gtk_text_buffer_get_insert(imhtml->text_buffer); | |
2547 GtkTextIter iter; | |
2548 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, ins); | |
2549 if (imhtml->edit.fontsize == 1) | |
2550 return; | |
2551 | |
2552 imhtml->edit.fontsize--; | |
2553 | |
2554 if (imhtml->edit.sizespan) { | |
2555 GtkTextIter iter2; | |
2556 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter2, imhtml->edit.sizespan->start); | |
2557 if (gtk_text_iter_equal(&iter2, &iter)) | |
2558 return; | |
2559 span = imhtml->edit.sizespan; | |
2560 span->end = gtk_text_buffer_create_mark(imhtml->text_buffer, NULL, &iter, TRUE); | |
2561 } | |
2562 | |
8250 | 2563 span = g_malloc0(sizeof(GtkIMHtmlFormatSpan)); |
8061 | 2564 span->start = gtk_text_buffer_create_mark(imhtml->text_buffer, NULL, &iter, TRUE); |
2565 span->end = NULL; | |
2566 span->buffer = imhtml->text_buffer; | |
2567 span->tag = NULL; | |
2568 imhtml->edit.sizespan = span; | |
2569 imhtml->format_spans = g_list_append(imhtml->format_spans, span); | |
2570 } | |
2571 | |
2572 void gtk_imhtml_font_grow(GtkIMHtml *imhtml) | |
2573 { | |
2574 GtkIMHtmlFormatSpan *span; | |
2575 GtkTextMark *ins = gtk_text_buffer_get_insert(imhtml->text_buffer); | |
2576 GtkTextIter iter; | |
2577 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, ins); | |
2578 if (imhtml->edit.fontsize == MAX_FONT_SIZE) | |
2579 return; | |
2580 | |
2581 imhtml->edit.fontsize++; | |
2582 | |
2583 if (imhtml->edit.sizespan) { | |
2584 GtkTextIter iter2; | |
2585 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter2, imhtml->edit.sizespan->start); | |
2586 if (gtk_text_iter_equal(&iter2, &iter)) | |
2587 return; | |
2588 span = imhtml->edit.sizespan; | |
2589 span->end = gtk_text_buffer_create_mark(imhtml->text_buffer, NULL, &iter, TRUE); | |
2590 } | |
2591 | |
8250 | 2592 span = g_malloc0(sizeof(GtkIMHtmlFormatSpan)); |
8061 | 2593 span->start = gtk_text_buffer_create_mark(imhtml->text_buffer, NULL, &iter, TRUE); |
2594 span->end = NULL; | |
2595 span->tag = NULL; | |
2596 span->buffer = imhtml->text_buffer; | |
2597 imhtml->edit.sizespan = span; | |
2598 imhtml->format_spans = g_list_append(imhtml->format_spans, span); | |
2599 } | |
2600 | |
2601 gboolean gtk_imhtml_toggle_forecolor(GtkIMHtml *imhtml, const char *color) | |
2602 { | |
2603 GtkIMHtmlFormatSpan *span; | |
2604 GtkTextMark *ins = gtk_text_buffer_get_insert(imhtml->text_buffer); | |
2605 GtkTextIter iter; | |
2606 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, ins); | |
8309 | 2607 if (color) { //!imhtml->edit.forecolor) { |
8061 | 2608 span = g_malloc(sizeof(GtkIMHtmlFormatSpan)); |
2609 span->start = gtk_text_buffer_create_mark(imhtml->text_buffer, NULL, &iter, TRUE); | |
2610 span->start_tag = g_strdup_printf("<font color=\"%s\">", color); | |
2611 span->end = NULL; | |
2612 span->end_tag = g_strdup("</font>"); | |
2613 span->buffer = imhtml->text_buffer; | |
2614 span->tag = gtk_text_buffer_create_tag(imhtml->text_buffer, NULL, "foreground", color, NULL); | |
2615 imhtml->edit.forecolor = span; | |
2616 imhtml->format_spans = g_list_append(imhtml->format_spans, span); | |
2617 } else { | |
2618 span = imhtml->edit.forecolor; | |
2619 span->end = gtk_text_buffer_create_mark(imhtml->text_buffer, NULL, &iter, TRUE); | |
2620 imhtml->edit.forecolor = NULL; | |
2621 } | |
2622 | |
2623 | |
2624 return imhtml->edit.forecolor != NULL; | |
2625 } | |
2626 | |
2627 gboolean gtk_imhtml_toggle_backcolor(GtkIMHtml *imhtml, const char *color) | |
2628 { | |
2629 GtkIMHtmlFormatSpan *span; | |
2630 GtkTextMark *ins = gtk_text_buffer_get_insert(imhtml->text_buffer); | |
2631 GtkTextIter iter; | |
2632 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, ins); | |
8309 | 2633 if (color) { //!imhtml->edit.backcolor) { |
8061 | 2634 span = g_malloc(sizeof(GtkIMHtmlFormatSpan)); |
2635 span->start = gtk_text_buffer_create_mark(imhtml->text_buffer, NULL, &iter, TRUE); | |
2636 span->start_tag = g_strdup_printf("<font back=\"%s\">", color); | |
2637 span->end = NULL; | |
2638 span->end_tag = g_strdup("</font>"); | |
2639 span->buffer = imhtml->text_buffer; | |
2640 span->tag = gtk_text_buffer_create_tag(imhtml->text_buffer, NULL, "background", color, NULL); | |
2641 imhtml->edit.backcolor = span; | |
2642 imhtml->format_spans = g_list_append(imhtml->format_spans, span); | |
2643 } else { | |
2644 span = imhtml->edit.backcolor; | |
2645 span->end = gtk_text_buffer_create_mark(imhtml->text_buffer, NULL, &iter, TRUE); | |
2646 imhtml->edit.backcolor = NULL; | |
2647 } | |
2648 return imhtml->edit.backcolor != NULL; | |
2649 } | |
2650 | |
2651 gboolean gtk_imhtml_toggle_fontface(GtkIMHtml *imhtml, const char *face) | |
2652 { | |
2653 GtkIMHtmlFormatSpan *span; | |
2654 GtkTextMark *ins = gtk_text_buffer_get_insert(imhtml->text_buffer); | |
2655 GtkTextIter iter; | |
2656 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, ins); | |
8309 | 2657 if (face) { //!imhtml->edit.fontface) { |
8061 | 2658 span = g_malloc(sizeof(GtkIMHtmlFormatSpan)); |
2659 span->start = gtk_text_buffer_create_mark(imhtml->text_buffer, NULL, &iter, TRUE); | |
2660 span->start_tag = g_strdup_printf("<font face=\"%s\">", face); | |
2661 span->end = NULL; | |
2662 span->end_tag = g_strdup("</font>"); | |
2663 span->buffer = imhtml->text_buffer; | |
2664 span->tag = gtk_text_buffer_create_tag(imhtml->text_buffer, NULL, "family", face, NULL); | |
2665 imhtml->edit.fontface = span; | |
2666 imhtml->format_spans = g_list_append(imhtml->format_spans, span); | |
2667 } else { | |
2668 span = imhtml->edit.fontface; | |
2669 span->end = gtk_text_buffer_create_mark(imhtml->text_buffer, NULL, &iter, TRUE); | |
2670 imhtml->edit.fontface = NULL; | |
2671 } | |
2672 return imhtml->edit.fontface != NULL; | |
2673 } | |
2674 | |
2675 void gtk_imhtml_insert_link(GtkIMHtml *imhtml, const char *url, const char *text) | |
2676 { | |
2677 GtkIMHtmlFormatSpan *span = g_malloc(sizeof(GtkIMHtmlFormatSpan)); | |
2678 GtkTextMark *mark = gtk_text_buffer_get_insert(imhtml->text_buffer); | |
2679 GtkTextIter iter; | |
2680 GtkTextTag *tag, *linktag; | |
2681 | |
2682 tag = gtk_text_buffer_create_tag(imhtml->text_buffer, NULL, NULL); | |
2683 g_object_set_data(G_OBJECT(tag), "link_url", g_strdup(url)); | |
2684 | |
2685 linktag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(imhtml->text_buffer), "LINK"); | |
2686 | |
2687 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, mark); | |
2688 span->start = gtk_text_buffer_create_mark(imhtml->text_buffer, NULL, &iter, TRUE); | |
2689 span->buffer = imhtml->text_buffer; | |
2690 span->start_tag = g_strdup_printf("<a href=\"%s\">", url); | |
2691 span->end_tag = g_strdup("</a>"); | |
2692 g_signal_connect(G_OBJECT(tag), "event", G_CALLBACK(tag_event), g_strdup(url)); | |
2693 | |
2694 gtk_text_buffer_insert_with_tags(imhtml->text_buffer, &iter, text, strlen(text), linktag, tag, NULL); | |
2695 span->end = gtk_text_buffer_create_mark(imhtml->text_buffer, NULL, &iter, TRUE); | |
2696 imhtml->format_spans = g_list_append(imhtml->format_spans, span); | |
2697 } | |
2698 | |
2699 void gtk_imhtml_insert_smiley(GtkIMHtml *imhtml, const char *sml, char *smiley) | |
2700 { | |
2701 GtkTextMark *ins = gtk_text_buffer_get_insert(imhtml->text_buffer); | |
2702 GtkTextIter iter; | |
2703 GdkPixbuf *pixbuf = NULL; | |
2704 GdkPixbufAnimation *annipixbuf = NULL; | |
2705 GtkWidget *icon = NULL; | |
2706 GtkTextChildAnchor *anchor; | |
2707 | |
2708 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, ins); | |
2709 anchor = gtk_text_buffer_create_child_anchor(imhtml->text_buffer, &iter); | |
2710 g_object_set_data(G_OBJECT(anchor), "text_tag", g_strdup(smiley)); | |
2711 | |
2712 annipixbuf = gtk_smiley_tree_image(imhtml, sml, smiley); | |
2713 if(annipixbuf) { | |
2714 if(gdk_pixbuf_animation_is_static_image(annipixbuf)) { | |
2715 pixbuf = gdk_pixbuf_animation_get_static_image(annipixbuf); | |
2716 if(pixbuf) | |
2717 icon = gtk_image_new_from_pixbuf(pixbuf); | |
2718 } else { | |
2719 icon = gtk_image_new_from_animation(annipixbuf); | |
2720 } | |
2721 } | |
2722 | |
2723 if (icon) { | |
2724 gtk_widget_show(icon); | |
2725 gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), icon, anchor); | |
2726 } | |
2727 } | |
2728 | |
2729 int span_compare_begin(const GtkIMHtmlFormatSpan *a, const GtkIMHtmlFormatSpan *b, GtkTextBuffer *buffer) | |
2730 { | |
2731 GtkTextIter ia, ib; | |
2732 gtk_text_buffer_get_iter_at_mark(buffer, &ia, a->start); | |
2733 gtk_text_buffer_get_iter_at_mark(buffer, &ib, b->start); | |
2734 return gtk_text_iter_compare(&ia, &ib); | |
2735 } | |
2736 | |
2737 int span_compare_end(GtkIMHtmlFormatSpan *a, GtkIMHtmlFormatSpan *b) | |
2738 { | |
2739 GtkTextIter ia, ib; | |
2740 gtk_text_buffer_get_iter_at_mark(a->buffer, &ia, a->start); | |
2741 gtk_text_buffer_get_iter_at_mark(b->buffer, &ib, b->start); | |
2742 /* The -1 here makes it so that if I have two spans that close at the same point, the | |
2743 * span added second will be closed first, as in <b><i>Hello</i></b>. Without this, | |
2744 * it would be <b><i>Hello</b></i> */ | |
2745 return gtk_text_iter_compare(&ia, &ib) - 1; | |
2746 } | |
2747 | |
2748 /* Basic notion here: traverse through the text buffer one-by-one, non-character elements, such | |
2749 * as smileys and IM images are represented by the Unicode "unknown" character. Handle them. Else | |
2750 * check the list of formatted strings, sorted by the position of the starting tags and apply them as | |
2751 * needed. After applying the start tags, add the end tags to the "closers" list, which is sorted by | |
2752 * location of ending tags. These get applied in a similar fashion. Finally, replace <, >, &, and " | |
2753 * with their HTML equivilent. */ | |
2754 char *gtk_imhtml_get_markup_range(GtkIMHtml *imhtml, GtkTextIter *start, GtkTextIter *end) | |
2755 { | |
2756 gunichar c; | |
2757 GtkIMHtmlFormatSpan *sspan = NULL, *espan = NULL; | |
2758 GtkTextIter iter, siter, eiter; | |
2759 GList *starters = imhtml->format_spans; | |
2760 GList *closers = NULL; | |
2761 GString *str = g_string_new(""); | |
2762 g_list_sort_with_data(starters, (GCompareDataFunc)span_compare_begin, imhtml->text_buffer); | |
2763 | |
2764 gtk_text_iter_order(start, end); | |
2765 iter = *start; | |
2766 | |
2767 | |
2768 /* Initialize these to the end iter */ | |
2769 gtk_text_buffer_get_end_iter(imhtml->text_buffer, &siter); | |
2770 eiter = siter; | |
2771 | |
2772 if (starters) { | |
2773 while (starters) { | |
2774 GtkTextIter tagend; | |
2775 sspan = (GtkIMHtmlFormatSpan*)starters->data; | |
2776 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &siter, sspan->start); | |
2777 if (gtk_text_iter_compare(&siter, start) > 0) | |
2778 break; | |
2779 if (sspan->end) | |
2780 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &tagend, sspan->end); | |
2781 if (sspan->end == NULL || gtk_text_iter_compare(&tagend, start) > 0) { | |
2782 str = g_string_append(str, sspan->start_tag); | |
2783 closers = g_list_insert_sorted(closers, sspan, (GCompareFunc)span_compare_end); | |
2784 espan = (GtkIMHtmlFormatSpan*)closers->data; | |
2785 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &eiter, espan->end); | |
2786 } | |
2787 sspan = (GtkIMHtmlFormatSpan*)starters->data; | |
2788 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &siter, sspan->start); | |
2789 starters = starters->next; | |
2790 } | |
2791 if (!starters) { | |
2792 gtk_text_buffer_get_end_iter(imhtml->text_buffer, &siter); | |
2793 sspan = NULL; | |
2794 } | |
2795 } | |
2796 | |
2797 while ((c = gtk_text_iter_get_char(&iter)) != 0 && !gtk_text_iter_equal(&iter, end)) { | |
2798 if (c == 0xFFFC) { | |
2799 GtkTextChildAnchor* anchor = gtk_text_iter_get_child_anchor(&iter); | |
2800 char *text = g_object_get_data(G_OBJECT(anchor), "text_tag"); | |
2801 str = g_string_append(str, text); | |
2802 } else { | |
2803 while (gtk_text_iter_equal(&eiter, &iter)) { | |
2804 /* This is where we shall insert the ending tag of | |
2805 * this format span */ | |
2806 str = g_string_append(str, espan->end_tag); | |
2807 closers = g_list_remove(closers, espan); | |
2808 if (!closers) { | |
2809 espan = NULL; | |
2810 gtk_text_buffer_get_end_iter(imhtml->text_buffer, &eiter); | |
2811 } else { | |
2812 espan = (GtkIMHtmlFormatSpan*)closers->data; | |
2813 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &eiter, espan->end); | |
2814 } | |
2815 } | |
2816 while (gtk_text_iter_equal(&siter, &iter)) { | |
2817 /* This is where we shall insert the starting tag of | |
2818 * this format span */ | |
2819 str = g_string_append(str, sspan->start_tag); | |
2820 if (sspan->end) { | |
2821 closers = g_list_insert_sorted(closers, sspan, (GCompareFunc)span_compare_end); | |
2822 espan = (GtkIMHtmlFormatSpan*)closers->data; | |
2823 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &eiter, espan->end); | |
2824 | |
2825 } | |
2826 starters = starters->next; | |
2827 if (starters) { | |
2828 sspan = (GtkIMHtmlFormatSpan*)starters->data; | |
2829 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &siter, sspan->start); | |
2830 } else { | |
2831 sspan = NULL; | |
2832 gtk_text_buffer_get_end_iter(imhtml->text_buffer, &siter); | |
2833 } | |
2834 | |
2835 } | |
2836 | |
2837 if (c == '<') | |
2838 str = g_string_append(str, "<"); | |
2839 else if (c == '>') | |
2840 str = g_string_append(str, ">"); | |
2841 else if (c == '&') | |
2842 str = g_string_append(str, "&"); | |
2843 else if (c == '"') | |
2844 str = g_string_append(str, """); | |
2845 else if (c == '\n') | |
2846 str = g_string_append(str, "<br>"); | |
2847 else | |
2848 str = g_string_append_unichar(str, c); | |
2849 } | |
2850 gtk_text_iter_forward_char(&iter); | |
2851 } | |
2852 while (closers) { | |
2853 GtkIMHtmlFormatSpan *span = (GtkIMHtmlFormatSpan*)closers->data; | |
2854 str = g_string_append(str, span->end_tag); | |
2855 closers = g_list_remove(closers, span); | |
2856 | |
2857 } | |
2858 printf("Gotten: %s\n", str->str); | |
2859 return g_string_free(str, FALSE); | |
2860 } | |
2861 | |
2862 void gtk_imhtml_close_tags(GtkIMHtml *imhtml) | |
2863 { | |
2864 | |
2865 if (imhtml->edit.bold) | |
2866 gtk_imhtml_toggle_bold(imhtml); | |
2867 | |
2868 if (imhtml->edit.italic) | |
2869 gtk_imhtml_toggle_italic(imhtml); | |
2870 | |
2871 if (imhtml->edit.underline) | |
2872 gtk_imhtml_toggle_underline(imhtml); | |
2873 | |
2874 if (imhtml->edit.forecolor) | |
2875 gtk_imhtml_toggle_forecolor(imhtml, NULL); | |
2876 | |
2877 if (imhtml->edit.backcolor) | |
2878 gtk_imhtml_toggle_backcolor(imhtml, NULL); | |
2879 | |
2880 if (imhtml->edit.fontface) | |
2881 gtk_imhtml_toggle_fontface(imhtml, NULL); | |
2882 | |
2883 if (imhtml->edit.sizespan) | |
2884 gtk_imhtml_font_set_size(imhtml, -1); | |
2885 | |
2886 } | |
2887 | |
2888 char *gtk_imhtml_get_markup(GtkIMHtml *imhtml) | |
2889 { | |
2890 GtkTextIter start, end; | |
2891 | |
2892 gtk_text_buffer_get_start_iter(imhtml->text_buffer, &start); | |
2893 gtk_text_buffer_get_end_iter(imhtml->text_buffer, &end); | |
2894 return gtk_imhtml_get_markup_range(imhtml, &start, &end); | |
2895 } | |
2896 | |
2897 char *gtk_imhtml_get_text(GtkIMHtml *imhtml) | |
2898 { | |
2899 GtkTextIter start_iter, end_iter; | |
2900 gtk_text_buffer_get_start_iter(imhtml->text_buffer, &start_iter); | |
2901 gtk_text_buffer_get_end_iter(imhtml->text_buffer, &end_iter); | |
2902 return gtk_text_buffer_get_text(imhtml->text_buffer, &start_iter, &end_iter, FALSE); | |
2903 | |
2904 } | |
2905 |