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