Mercurial > pidgin.yaz
annotate src/gtkimhtml.c @ 4960:42bd8ab53234
[gaim-migrate @ 5294]
I "made" some status icons for ICQ away states. They suck. Someone
with some skills of an artist please to try improve them. Or even just
whichever one you hate the most. Really, new icons are welcome. Email
them to mark izat kingant dizot net and we'll put them under
consideration.
I actually think the DND and free for chat icons look pretty nice. The
NA on the NA icon is not readable enough. The invisible is plain and
not very meaningful. The occupied is not easily discernable and stupid.
I also removed the option to have buddy list tabs at the top or bottom
of the buddy list.
And I took out my April Fools joke.
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Wed, 02 Apr 2003 06:32:54 +0000 |
parents | 24c9a23df63b |
children | c307d769cefa |
rev | line source |
---|---|
1428 | 1 /* |
2 * GtkIMHtml | |
3 * | |
4 * Copyright (C) 2000, Eric Warmenhoven <warmenhoven@yahoo.com> | |
5 * | |
6 * This program is free software; you can redistribute it and/or modify | |
7 * under the terms of the GNU General Public License as published by | |
8 * the Free Software Foundation; either version 2 of the License, or | |
9 * (at your option) any later version. | |
10 * | |
11 * This program is distributed in the hope that it will be useful, | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 * GNU General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU General Public License | |
17 * along with this program; if not, write to the Free Software | |
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
19 * | |
20 */ | |
21 | |
2541
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2365
diff
changeset
|
22 #ifdef HAVE_CONFIG_H |
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2365
diff
changeset
|
23 #include <config.h> |
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2365
diff
changeset
|
24 #endif |
1428 | 25 #include "gtkimhtml.h" |
26 #include <gtk/gtk.h> | |
4895 | 27 #include <glib/gerror.h> |
4046 | 28 #include <gdk/gdkkeysyms.h> |
1428 | 29 #include <string.h> |
30 #include <ctype.h> | |
31 #include <stdio.h> | |
4629 | 32 #include <stdlib.h> |
1428 | 33 #include <math.h> |
2541
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2365
diff
changeset
|
34 #ifdef HAVE_LANGINFO_CODESET |
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2365
diff
changeset
|
35 #include <langinfo.h> |
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2365
diff
changeset
|
36 #include <locale.h> |
8229710b343b
[gaim-migrate @ 2554]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2365
diff
changeset
|
37 #endif |
1428 | 38 |
4417 | 39 #ifdef ENABLE_NLS |
40 # include <libintl.h> | |
41 # define _(x) gettext(x) | |
42 # ifdef gettext_noop | |
43 # define N_(String) gettext_noop (String) | |
44 # else | |
45 # define N_(String) (String) | |
46 # endif | |
47 #else | |
48 # define N_(String) (String) | |
49 # define _(x) (x) | |
50 #endif | |
51 | |
4735 | 52 #include <pango/pango-font.h> |
53 | |
54 #define TOOLTIP_TIMEOUT 500 | |
55 | |
4764 | 56 static gboolean gtk_motion_event_notify(GtkWidget *imhtml, GdkEventMotion *event, gpointer user_data); |
4944 | 57 static gboolean gtk_leave_event_notify(GtkWidget *imhtml, GdkEventCrossing *event, gpointer user_data); |
4764 | 58 |
4947 | 59 static gboolean gtk_size_allocate_cb(GtkIMHtml *widget, GtkAllocation *alloc, gpointer user_data); |
4895 | 60 static gint gtk_imhtml_tip (gpointer data); |
4764 | 61 |
4735 | 62 |
3922 | 63 /* POINT_SIZE converts from AIM font sizes to point sizes. It probably should be redone in such a |
64 * way that it base the sizes off the default font size rather than using arbitrary font sizes. */ | |
65 #define MAX_FONT_SIZE 7 | |
66 #define POINT_SIZE(x) (_point_sizes [MIN ((x), MAX_FONT_SIZE) - 1]) | |
3928 | 67 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
|
68 |
3922 | 69 /* The four elements present in a <FONT> tag contained in a struct */ |
70 typedef struct _FontDetail FontDetail; | |
1428 | 71 struct _FontDetail { |
72 gushort size; | |
73 gchar *face; | |
3922 | 74 gchar *fore; |
75 gchar *back; | |
4032 | 76 gchar *sml; |
1428 | 77 }; |
78 | |
4032 | 79 struct _GtkSmileyTree { |
80 GString *values; | |
81 GtkSmileyTree **children; | |
4263 | 82 GtkIMHtmlSmiley *image; |
4032 | 83 }; |
84 | |
85 static GtkSmileyTree* | |
86 gtk_smiley_tree_new () | |
87 { | |
88 return g_new0 (GtkSmileyTree, 1); | |
89 } | |
90 | |
91 static void | |
92 gtk_smiley_tree_insert (GtkSmileyTree *tree, | |
4263 | 93 GtkIMHtmlSmiley *smiley) |
4032 | 94 { |
95 GtkSmileyTree *t = tree; | |
4263 | 96 const gchar *x = smiley->smile; |
4032 | 97 |
98 if (!strlen (x)) | |
99 return; | |
100 | |
101 while (*x) { | |
102 gchar *pos; | |
103 gint index; | |
104 | |
105 if (!t->values) | |
106 t->values = g_string_new (""); | |
107 | |
108 pos = strchr (t->values->str, *x); | |
109 if (!pos) { | |
110 t->values = g_string_append_c (t->values, *x); | |
111 index = t->values->len - 1; | |
112 t->children = g_realloc (t->children, t->values->len * sizeof (GtkSmileyTree *)); | |
113 t->children [index] = g_new0 (GtkSmileyTree, 1); | |
114 } else | |
115 index = (int) pos - (int) t->values->str; | |
116 | |
117 t = t->children [index]; | |
118 | |
119 x++; | |
120 } | |
121 | |
4263 | 122 t->image = smiley; |
4032 | 123 } |
4041 | 124 |
4263 | 125 |
4264 | 126 void gtk_smiley_tree_destroy (GtkSmileyTree *tree) |
4032 | 127 { |
128 GSList *list = g_slist_append (NULL, tree); | |
129 | |
130 while (list) { | |
131 GtkSmileyTree *t = list->data; | |
132 gint i; | |
133 list = g_slist_remove(list, t); | |
134 if (t->values) { | |
135 for (i = 0; i < t->values->len; i++) | |
136 list = g_slist_append (list, t->children [i]); | |
137 g_string_free (t->values, TRUE); | |
138 g_free (t->children); | |
139 } | |
140 g_free (t); | |
141 } | |
142 } | |
143 | |
4263 | 144 |
4032 | 145 static GtkTextViewClass *parent_class = NULL; |
146 | |
147 | |
3922 | 148 /* GtkIMHtml has one signal--URL_CLICKED */ |
1428 | 149 enum { |
150 URL_CLICKED, | |
151 LAST_SIGNAL | |
152 }; | |
153 static guint signals [LAST_SIGNAL] = { 0 }; | |
154 | |
4032 | 155 static void |
156 gtk_imhtml_finalize (GObject *object) | |
157 { | |
158 GtkIMHtml *imhtml = GTK_IMHTML(object); | |
4895 | 159 GList *scalables; |
160 | |
4138 | 161 g_hash_table_destroy(imhtml->smiley_data); |
4032 | 162 gtk_smiley_tree_destroy(imhtml->default_smilies); |
4138 | 163 gdk_cursor_unref(imhtml->hand_cursor); |
164 gdk_cursor_unref(imhtml->arrow_cursor); | |
4735 | 165 if(imhtml->tip_window){ |
166 gtk_widget_destroy(imhtml->tip_window); | |
167 } | |
168 if(imhtml->tip_timer) | |
169 gtk_timeout_remove(imhtml->tip_timer); | |
170 | |
4895 | 171 for(scalables = imhtml->scalables; scalables; scalables = scalables->next) { |
172 GtkIMHtmlScalable *scale = GTK_IMHTML_SCALABLE(scalables->data); | |
173 scale->free(scale); | |
174 } | |
175 | |
176 g_list_free(imhtml->scalables); | |
4032 | 177 G_OBJECT_CLASS(parent_class)->finalize (object); |
178 } | |
1428 | 179 |
3922 | 180 /* Boring GTK stuff */ |
181 static void gtk_imhtml_class_init (GtkIMHtmlClass *class) | |
1428 | 182 { |
3922 | 183 GtkObjectClass *object_class; |
4032 | 184 GObjectClass *gobject_class; |
3922 | 185 object_class = (GtkObjectClass*) class; |
4032 | 186 gobject_class = (GObjectClass*) class; |
187 parent_class = gtk_type_class(GTK_TYPE_TEXT_VIEW); | |
4417 | 188 signals[URL_CLICKED] = g_signal_new("url_clicked", |
189 G_TYPE_FROM_CLASS(gobject_class), | |
190 G_SIGNAL_RUN_FIRST, | |
191 G_STRUCT_OFFSET(GtkIMHtmlClass, url_clicked), | |
192 NULL, | |
193 0, | |
194 g_cclosure_marshal_VOID__POINTER, | |
195 G_TYPE_NONE, 1, | |
196 G_TYPE_POINTER); | |
4032 | 197 gobject_class->finalize = gtk_imhtml_finalize; |
1428 | 198 } |
199 | |
3922 | 200 static void gtk_imhtml_init (GtkIMHtml *imhtml) |
1428 | 201 { |
3922 | 202 GtkTextIter iter; |
203 imhtml->text_buffer = gtk_text_buffer_new(NULL); | |
204 gtk_text_buffer_get_end_iter (imhtml->text_buffer, &iter); | |
205 imhtml->end = gtk_text_buffer_create_mark(imhtml->text_buffer, NULL, &iter, FALSE); | |
206 gtk_text_view_set_buffer(GTK_TEXT_VIEW(imhtml), imhtml->text_buffer); | |
207 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(imhtml), GTK_WRAP_WORD); | |
208 gtk_text_view_set_editable(GTK_TEXT_VIEW(imhtml), FALSE); | |
209 gtk_text_view_set_pixels_below_lines(GTK_TEXT_VIEW(imhtml), 5); | |
210 gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(imhtml), FALSE); | |
211 /*gtk_text_view_set_justification(GTK_TEXT_VIEW(imhtml), GTK_JUSTIFY_FILL);*/ | |
3465 | 212 |
3922 | 213 /* These tags will be used often and can be reused--we create them on init and then apply them by name |
214 * other tags (color, size, face, etc.) will have to be created and applied dynamically */ | |
215 gtk_text_buffer_create_tag(imhtml->text_buffer, "BOLD", "weight", PANGO_WEIGHT_BOLD, NULL); | |
216 gtk_text_buffer_create_tag(imhtml->text_buffer, "ITALICS", "style", PANGO_STYLE_ITALIC, NULL); | |
217 gtk_text_buffer_create_tag(imhtml->text_buffer, "UNDERLINE", "underline", PANGO_UNDERLINE_SINGLE, NULL); | |
218 gtk_text_buffer_create_tag(imhtml->text_buffer, "STRIKE", "strikethrough", TRUE, NULL); | |
219 gtk_text_buffer_create_tag(imhtml->text_buffer, "SUB", "rise", -5000, NULL); | |
220 gtk_text_buffer_create_tag(imhtml->text_buffer, "SUP", "rise", 5000, NULL); | |
221 gtk_text_buffer_create_tag(imhtml->text_buffer, "PRE", "family", "Monospace", NULL); | |
3465 | 222 |
3922 | 223 /* When hovering over a link, we show the hand cursor--elsewhere we show the plain ol' pointer cursor */ |
224 imhtml->hand_cursor = gdk_cursor_new (GDK_HAND2); | |
225 imhtml->arrow_cursor = gdk_cursor_new (GDK_LEFT_PTR); | |
2993 | 226 |
4253 | 227 imhtml->show_smileys = TRUE; |
228 imhtml->show_comments = TRUE; | |
229 | |
4892 | 230 imhtml->smiley_data = g_hash_table_new_full(g_str_hash, g_str_equal, |
4902 | 231 g_free, (GDestroyNotify)gtk_smiley_tree_destroy); |
4032 | 232 imhtml->default_smilies = gtk_smiley_tree_new(); |
4735 | 233 |
4944 | 234 g_signal_connect(G_OBJECT(imhtml), "size-allocate", G_CALLBACK(gtk_size_allocate_cb), NULL); |
4735 | 235 g_signal_connect(G_OBJECT(imhtml), "motion-notify-event", G_CALLBACK(gtk_motion_event_notify), NULL); |
4944 | 236 g_signal_connect(G_OBJECT(imhtml), "leave-notify-event", G_CALLBACK(gtk_leave_event_notify), NULL); |
237 gtk_widget_add_events(GTK_WIDGET(imhtml), GDK_LEAVE_NOTIFY_MASK); | |
4735 | 238 |
239 imhtml->tip = NULL; | |
240 imhtml->tip_timer = 0; | |
241 imhtml->tip_window = NULL; | |
4895 | 242 |
243 imhtml->scalables = NULL; | |
2993 | 244 } |
245 | |
3922 | 246 GtkWidget *gtk_imhtml_new(void *a, void *b) |
1428 | 247 { |
4635 | 248 return GTK_WIDGET(g_object_new(gtk_imhtml_get_type(), NULL)); |
1428 | 249 } |
250 | |
4635 | 251 GType gtk_imhtml_get_type() |
1428 | 252 { |
4635 | 253 static GType imhtml_type = 0; |
1428 | 254 |
255 if (!imhtml_type) { | |
4635 | 256 static const GTypeInfo imhtml_info = { |
257 sizeof(GtkIMHtmlClass), | |
258 NULL, | |
259 NULL, | |
260 (GClassInitFunc) gtk_imhtml_class_init, | |
261 NULL, | |
262 NULL, | |
1428 | 263 sizeof (GtkIMHtml), |
4635 | 264 0, |
265 (GInstanceInitFunc) gtk_imhtml_init | |
1428 | 266 }; |
4635 | 267 |
268 imhtml_type = g_type_register_static(gtk_text_view_get_type(), | |
269 "GtkIMHtml", &imhtml_info, 0); | |
1428 | 270 } |
271 | |
272 return imhtml_type; | |
273 } | |
274 | |
4417 | 275 struct url_data { |
276 GObject *object; | |
277 gchar *url; | |
278 }; | |
279 | |
280 static void url_open(GtkWidget *w, struct url_data *data) { | |
281 if(!data) return; | |
282 | |
283 g_signal_emit(data->object, signals[URL_CLICKED], 0, data->url); | |
284 | |
285 g_object_unref(data->object); | |
286 g_free(data->url); | |
287 g_free(data); | |
288 } | |
289 static void url_copy(GtkWidget *w, gchar *url) { | |
290 GtkClipboard *clipboard; | |
291 | |
4419 | 292 clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); |
4417 | 293 gtk_clipboard_set_text(clipboard, url, -1); |
294 } | |
295 | |
296 /* The callback for an event on a link tag. */ | |
297 gboolean tag_event(GtkTextTag *tag, GObject *arg1, GdkEvent *event, GtkTextIter *arg2, char *url) { | |
298 GdkEventButton *event_button = (GdkEventButton *) event; | |
299 | |
3922 | 300 if (event->type == GDK_BUTTON_RELEASE) { |
4417 | 301 if (event_button->button == 1) { |
302 GtkTextIter start, end; | |
303 /* we shouldn't open a URL if the user has selected something: */ | |
304 gtk_text_buffer_get_selection_bounds( | |
305 gtk_text_iter_get_buffer(arg2), &start, &end); | |
306 if(gtk_text_iter_get_offset(&start) != | |
307 gtk_text_iter_get_offset(&end)) | |
308 return FALSE; | |
309 | |
310 /* A link was clicked--we emit the "url_clicked" signal | |
311 * with the URL as the argument */ | |
312 g_signal_emit(arg1, signals[URL_CLICKED], 0, url); | |
313 return FALSE; | |
314 } else if(event_button->button == 3) { | |
4745 | 315 GtkWidget *img, *item, *menu; |
4417 | 316 struct url_data *tempdata = g_new(struct url_data, 1); |
317 tempdata->object = g_object_ref(arg1); | |
318 tempdata->url = g_strdup(url); | |
4745 | 319 |
4417 | 320 menu = gtk_menu_new(); |
4745 | 321 |
4417 | 322 /* buttons and such */ |
323 img = gtk_image_new_from_stock(GTK_STOCK_COPY, GTK_ICON_SIZE_MENU); | |
4420 | 324 item = gtk_image_menu_item_new_with_mnemonic(_("_Copy Link Location")); |
4417 | 325 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), img); |
326 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(url_copy), | |
327 url); | |
328 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); | |
329 | |
330 img = gtk_image_new_from_stock(GTK_STOCK_JUMP_TO, GTK_ICON_SIZE_MENU); | |
4420 | 331 item = gtk_image_menu_item_new_with_mnemonic(_("_Open Link in Browser")); |
4417 | 332 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), img); |
333 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(url_open), | |
334 tempdata); | |
335 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); | |
4756 | 336 |
4417 | 337 gtk_widget_show_all(menu); |
4756 | 338 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, |
339 event_button->button, event_button->time); | |
4745 | 340 |
4417 | 341 return TRUE; |
342 } | |
1428 | 343 } |
4417 | 344 if(event->type == GDK_BUTTON_PRESS && event_button->button == 3) |
345 return TRUE; /* Clicking the right mouse button on a link shouldn't | |
346 be caught by the regular GtkTextView menu */ | |
347 else | |
348 return FALSE; /* Let clicks go through if we didn't catch anything */ | |
1428 | 349 } |
350 | |
4735 | 351 gboolean gtk_motion_event_notify(GtkWidget *imhtml, GdkEventMotion *event, gpointer data) |
352 { | |
353 GtkTextIter iter; | |
354 GdkWindow *win = event->window; | |
355 int x, y; | |
4740 | 356 char *tip = NULL; |
4735 | 357 GSList *tags = NULL, *templist = NULL; |
358 gdk_window_get_pointer(GTK_WIDGET(imhtml)->window, NULL, NULL, NULL); | |
359 gtk_text_view_window_to_buffer_coords(GTK_TEXT_VIEW(imhtml), GTK_TEXT_WINDOW_WIDGET, | |
360 event->x, event->y, &x, &y); | |
361 gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(imhtml), &iter, x, y); | |
362 tags = gtk_text_iter_get_tags(&iter); | |
363 | |
4740 | 364 templist = tags; |
365 while (templist) { | |
4735 | 366 GtkTextTag *tag = templist->data; |
4740 | 367 tip = g_object_get_data(G_OBJECT(tag), "link_url"); |
368 if (tip) | |
369 break; | |
370 templist = templist->next; | |
4735 | 371 } |
4740 | 372 |
373 if (GTK_IMHTML(imhtml)->tip) { | |
374 if ((tip == GTK_IMHTML(imhtml)->tip)) { | |
375 return FALSE; | |
376 } | |
377 /* We've left the cell. Remove the timeout and create a new one below */ | |
378 if (GTK_IMHTML(imhtml)->tip_window) { | |
379 gtk_widget_destroy(GTK_IMHTML(imhtml)->tip_window); | |
380 GTK_IMHTML(imhtml)->tip_window = NULL; | |
381 } | |
382 gdk_window_set_cursor(win, GTK_IMHTML(imhtml)->arrow_cursor); | |
383 if (GTK_IMHTML(imhtml)->tip_timer) | |
384 g_source_remove(GTK_IMHTML(imhtml)->tip_timer); | |
385 GTK_IMHTML(imhtml)->tip_timer = 0; | |
386 } | |
387 | |
388 if(tip){ | |
4735 | 389 gdk_window_set_cursor(win, GTK_IMHTML(imhtml)->hand_cursor); |
4740 | 390 GTK_IMHTML(imhtml)->tip_timer = g_timeout_add (TOOLTIP_TIMEOUT, |
391 gtk_imhtml_tip, imhtml); | |
4735 | 392 } |
4740 | 393 |
394 GTK_IMHTML(imhtml)->tip = tip; | |
4735 | 395 g_slist_free(tags); |
396 return FALSE; | |
397 } | |
398 | |
4944 | 399 gboolean gtk_leave_event_notify(GtkWidget *imhtml, GdkEventCrossing *event, gpointer data) |
400 { | |
401 /* when leaving the widget, clear any current & pending tooltips and restore the cursor */ | |
402 if (GTK_IMHTML(imhtml)->tip_window) { | |
403 gtk_widget_destroy(GTK_IMHTML(imhtml)->tip_window); | |
404 GTK_IMHTML(imhtml)->tip_window = NULL; | |
405 } | |
406 if (GTK_IMHTML(imhtml)->tip_timer) { | |
407 g_source_remove(GTK_IMHTML(imhtml)->tip_timer); | |
408 GTK_IMHTML(imhtml)->tip_timer = 0; | |
409 } | |
410 gdk_window_set_cursor(event->window, GTK_IMHTML(imhtml)->arrow_cursor); | |
411 | |
412 /* propogate the event normally */ | |
413 return FALSE; | |
414 } | |
415 | |
4298 | 416 /* this isn't used yet |
4032 | 417 static void |
4263 | 418 gtk_smiley_tree_remove (GtkSmileyTree *tree, |
419 GtkIMHtmlSmiley *smiley) | |
4032 | 420 { |
421 GtkSmileyTree *t = tree; | |
4263 | 422 const gchar *x = smiley->smile; |
4032 | 423 gint len = 0; |
424 | |
425 while (*x) { | |
426 gchar *pos; | |
427 | |
428 if (!t->values) | |
429 return; | |
430 | |
431 pos = strchr (t->values->str, *x); | |
432 if (pos) | |
433 t = t->children [(int) pos - (int) t->values->str]; | |
434 else | |
435 return; | |
436 | |
437 x++; len++; | |
438 } | |
439 | |
4141
ccec4fde84f4
[gaim-migrate @ 4359]
Christian Hammond <chipx86@chipx86.com>
parents:
4140
diff
changeset
|
440 if (t->image) { |
4032 | 441 t->image = NULL; |
4141
ccec4fde84f4
[gaim-migrate @ 4359]
Christian Hammond <chipx86@chipx86.com>
parents:
4140
diff
changeset
|
442 } |
4032 | 443 } |
4298 | 444 */ |
445 | |
4032 | 446 |
447 static gint | |
448 gtk_smiley_tree_lookup (GtkSmileyTree *tree, | |
449 const gchar *text) | |
450 { | |
451 GtkSmileyTree *t = tree; | |
452 const gchar *x = text; | |
453 gint len = 0; | |
454 | |
455 while (*x) { | |
456 gchar *pos; | |
457 | |
458 if (!t->values) | |
459 break; | |
460 | |
461 pos = strchr (t->values->str, *x); | |
462 if (pos) | |
463 t = t->children [(int) pos - (int) t->values->str]; | |
464 else | |
465 break; | |
466 | |
467 x++; len++; | |
468 } | |
469 | |
470 if (t->image) | |
471 return len; | |
472 | |
473 return 0; | |
474 } | |
475 | |
476 void | |
4263 | 477 gtk_imhtml_associate_smiley (GtkIMHtml *imhtml, |
478 gchar *sml, | |
479 GtkIMHtmlSmiley *smiley) | |
4032 | 480 { |
481 GtkSmileyTree *tree; | |
482 g_return_if_fail (imhtml != NULL); | |
483 g_return_if_fail (GTK_IS_IMHTML (imhtml)); | |
4263 | 484 |
4032 | 485 if (sml == NULL) |
486 tree = imhtml->default_smilies; | |
487 else if ((tree = g_hash_table_lookup(imhtml->smiley_data, sml))) { | |
488 } else { | |
489 tree = gtk_smiley_tree_new(); | |
4892 | 490 g_hash_table_insert(imhtml->smiley_data, g_strdup(sml), tree); |
4032 | 491 } |
492 | |
4263 | 493 gtk_smiley_tree_insert (tree, smiley); |
4032 | 494 } |
495 | |
496 static gboolean | |
497 gtk_imhtml_is_smiley (GtkIMHtml *imhtml, | |
498 GSList *fonts, | |
499 const gchar *text, | |
500 gint *len) | |
501 { | |
502 GtkSmileyTree *tree; | |
503 FontDetail *font; | |
504 char *sml = NULL; | |
505 | |
506 if (fonts) { | |
507 font = fonts->data; | |
508 sml = font->sml; | |
509 } | |
510 | |
511 if (sml == NULL) | |
512 tree = imhtml->default_smilies; | |
513 else { | |
514 tree = g_hash_table_lookup(imhtml->smiley_data, sml); | |
515 } | |
516 if (tree == NULL) | |
517 return FALSE; | |
518 | |
519 *len = gtk_smiley_tree_lookup (tree, text); | |
520 return (*len > 0); | |
521 } | |
522 | |
4263 | 523 GdkPixbuf* |
4032 | 524 gtk_smiley_tree_image (GtkIMHtml *imhtml, |
525 const gchar *sml, | |
526 const gchar *text) | |
527 { | |
528 GtkSmileyTree *t; | |
529 const gchar *x = text; | |
530 if (sml == NULL) | |
531 t = imhtml->default_smilies; | |
532 else | |
533 t = g_hash_table_lookup(imhtml->smiley_data, sml); | |
534 | |
535 | |
536 if (t == NULL) | |
537 return sml ? gtk_smiley_tree_image(imhtml, NULL, text) : NULL; | |
538 | |
539 while (*x) { | |
540 gchar *pos; | |
541 | |
542 if (!t->values) { | |
543 return sml ? gtk_smiley_tree_image(imhtml, NULL, text) : NULL; | |
544 } | |
545 | |
546 pos = strchr (t->values->str, *x); | |
547 if (pos) { | |
548 t = t->children [(int) pos - (int) t->values->str]; | |
549 } else { | |
550 return sml ? gtk_smiley_tree_image(imhtml, NULL, text) : NULL; | |
551 } | |
552 x++; | |
553 } | |
554 | |
4263 | 555 if (!t->image->icon) |
556 t->image->icon = gdk_pixbuf_new_from_file(t->image->file, NULL); | |
557 | |
558 return t->image->icon; | |
4032 | 559 } |
4793 | 560 #define VALID_TAG(x) if (!g_ascii_strncasecmp (string, x ">", strlen (x ">"))) { \ |
3922 | 561 *tag = g_strndup (string, strlen (x)); \ |
562 *len = strlen (x) + 1; \ | |
563 return TRUE; \ | |
564 } \ | |
565 (*type)++ | |
1428 | 566 |
4793 | 567 #define VALID_OPT_TAG(x) if (!g_ascii_strncasecmp (string, x " ", strlen (x " "))) { \ |
3922 | 568 const gchar *c = string + strlen (x " "); \ |
569 gchar e = '"'; \ | |
570 gboolean quote = FALSE; \ | |
571 while (*c) { \ | |
572 if (*c == '"' || *c == '\'') { \ | |
573 if (quote && (*c == e)) \ | |
574 quote = !quote; \ | |
575 else if (!quote) { \ | |
576 quote = !quote; \ | |
577 e = *c; \ | |
578 } \ | |
579 } else if (!quote && (*c == '>')) \ | |
580 break; \ | |
581 c++; \ | |
582 } \ | |
583 if (*c) { \ | |
584 *tag = g_strndup (string, c - string); \ | |
585 *len = c - string + 1; \ | |
586 return TRUE; \ | |
587 } \ | |
588 } \ | |
589 (*type)++ | |
1428 | 590 |
591 | |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
592 static gboolean |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
593 gtk_imhtml_is_amp_escape (const gchar *string, |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
594 gchar *replace, |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
595 gint *length) |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
596 { |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
597 g_return_val_if_fail (string != NULL, FALSE); |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
598 g_return_val_if_fail (replace != NULL, FALSE); |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
599 g_return_val_if_fail (length != NULL, FALSE); |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
600 |
4793 | 601 if (!g_ascii_strncasecmp (string, "&", 5)) { |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
602 *replace = '&'; |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
603 *length = 5; |
4793 | 604 } else if (!g_ascii_strncasecmp (string, "<", 4)) { |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
605 *replace = '<'; |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
606 *length = 4; |
4793 | 607 } else if (!g_ascii_strncasecmp (string, ">", 4)) { |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
608 *replace = '>'; |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
609 *length = 4; |
4793 | 610 } else if (!g_ascii_strncasecmp (string, " ", 6)) { |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
611 *replace = ' '; |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
612 *length = 6; |
4793 | 613 } else if (!g_ascii_strncasecmp (string, "©", 6)) { |
3717
988485669631
[gaim-migrate @ 3850]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
3705
diff
changeset
|
614 *replace = '©'; /* was: '©' */ |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
615 *length = 6; |
4793 | 616 } else if (!g_ascii_strncasecmp (string, """, 6)) { |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
617 *replace = '\"'; |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
618 *length = 6; |
4793 | 619 } else if (!g_ascii_strncasecmp (string, "®", 5)) { |
3717
988485669631
[gaim-migrate @ 3850]
Herman Bloggs <hermanator12002@yahoo.com>
parents:
3705
diff
changeset
|
620 *replace = '®'; /* was: '®' */ |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
621 *length = 5; |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
622 } else if (*(string + 1) == '#') { |
2022
199ba82faacb
[gaim-migrate @ 2032]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2002
diff
changeset
|
623 guint pound = 0; |
3004 | 624 if ((sscanf (string, "&#%u;", £) == 1) && pound != 0) { |
1472
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
625 if (*(string + 3 + (gint)log10 (pound)) != ';') |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
626 return FALSE; |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
627 *replace = (gchar)pound; |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
628 *length = 2; |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
629 while (isdigit ((gint) string [*length])) (*length)++; |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
630 if (string [*length] == ';') (*length)++; |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
631 } else { |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
632 return FALSE; |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
633 } |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
634 } else { |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
635 return FALSE; |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
636 } |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
637 |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
638 return TRUE; |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
639 } |
be620a051d6d
[gaim-migrate @ 1482]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1463
diff
changeset
|
640 |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
641 static gboolean |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
642 gtk_imhtml_is_tag (const gchar *string, |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
643 gchar **tag, |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
644 gint *len, |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
645 gint *type) |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
646 { |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
647 *type = 1; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
648 |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
649 if (!strchr (string, '>')) |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
650 return FALSE; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
651 |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
652 VALID_TAG ("B"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
653 VALID_TAG ("BOLD"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
654 VALID_TAG ("/B"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
655 VALID_TAG ("/BOLD"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
656 VALID_TAG ("I"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
657 VALID_TAG ("ITALIC"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
658 VALID_TAG ("/I"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
659 VALID_TAG ("/ITALIC"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
660 VALID_TAG ("U"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
661 VALID_TAG ("UNDERLINE"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
662 VALID_TAG ("/U"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
663 VALID_TAG ("/UNDERLINE"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
664 VALID_TAG ("S"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
665 VALID_TAG ("STRIKE"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
666 VALID_TAG ("/S"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
667 VALID_TAG ("/STRIKE"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
668 VALID_TAG ("SUB"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
669 VALID_TAG ("/SUB"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
670 VALID_TAG ("SUP"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
671 VALID_TAG ("/SUP"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
672 VALID_TAG ("PRE"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
673 VALID_TAG ("/PRE"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
674 VALID_TAG ("TITLE"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
675 VALID_TAG ("/TITLE"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
676 VALID_TAG ("BR"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
677 VALID_TAG ("HR"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
678 VALID_TAG ("/FONT"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
679 VALID_TAG ("/A"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
680 VALID_TAG ("P"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
681 VALID_TAG ("/P"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
682 VALID_TAG ("H3"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
683 VALID_TAG ("/H3"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
684 VALID_TAG ("HTML"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
685 VALID_TAG ("/HTML"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
686 VALID_TAG ("BODY"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
687 VALID_TAG ("/BODY"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
688 VALID_TAG ("FONT"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
689 VALID_TAG ("HEAD"); |
2993 | 690 VALID_TAG ("/HEAD"); |
691 VALID_TAG ("BINARY"); | |
692 VALID_TAG ("/BINARY"); | |
693 | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
694 VALID_OPT_TAG ("HR"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
695 VALID_OPT_TAG ("FONT"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
696 VALID_OPT_TAG ("BODY"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
697 VALID_OPT_TAG ("A"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
698 VALID_OPT_TAG ("IMG"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
699 VALID_OPT_TAG ("P"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
700 VALID_OPT_TAG ("H3"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
701 |
4793 | 702 if (!g_ascii_strncasecmp(string, "!--", strlen ("!--"))) { |
2954
f6c4f2187c08
[gaim-migrate @ 2967]
Christian Hammond <chipx86@chipx86.com>
parents:
2898
diff
changeset
|
703 gchar *e = strstr (string + strlen("!--"), "-->"); |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
704 if (e) { |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
705 *len = e - string + strlen ("-->"); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
706 *tag = g_strndup (string + strlen ("!--"), *len - strlen ("!---->")); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
707 return TRUE; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
708 } |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
709 } |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
710 |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
711 return FALSE; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
712 } |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
713 |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
714 static gchar* |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
715 gtk_imhtml_get_html_opt (gchar *tag, |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
716 const gchar *opt) |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
717 { |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
718 gchar *t = tag; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
719 gchar *e, *a; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
720 |
4793 | 721 while (g_ascii_strncasecmp (t, opt, strlen (opt))) { |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
722 gboolean quote = FALSE; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
723 if (*t == '\0') break; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
724 while (*t && !((*t == ' ') && !quote)) { |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
725 if (*t == '\"') |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
726 quote = ! quote; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
727 t++; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
728 } |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
729 while (*t && (*t == ' ')) t++; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
730 } |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
731 |
4793 | 732 if (!g_ascii_strncasecmp (t, opt, strlen (opt))) { |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
733 t += strlen (opt); |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
734 } else { |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
735 return NULL; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
736 } |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
737 |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
738 if ((*t == '\"') || (*t == '\'')) { |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
739 e = a = ++t; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
740 while (*e && (*e != *(t - 1))) e++; |
2993 | 741 if (*e == '\0') { |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
742 return NULL; |
2993 | 743 } else |
744 return g_strndup (a, e - a); | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
745 } else { |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
746 e = a = t; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
747 while (*e && !isspace ((gint) *e)) e++; |
2993 | 748 return g_strndup (a, e - a); |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
749 } |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
750 } |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
751 |
3922 | 752 |
753 | |
754 #define NEW_TEXT_BIT 0 | |
4343 | 755 #define NEW_COMMENT_BIT 2 |
4895 | 756 #define NEW_SCALABLE_BIT 1 |
3922 | 757 #define NEW_BIT(x) ws [wpos] = '\0'; \ |
758 mark2 = gtk_text_buffer_create_mark(imhtml->text_buffer, NULL, &iter, TRUE); \ | |
759 gtk_text_buffer_insert(imhtml->text_buffer, &iter, ws, -1); \ | |
4895 | 760 gtk_text_buffer_get_end_iter(imhtml->text_buffer, &iter); \ |
3922 | 761 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &siter, mark2); \ |
762 gtk_text_buffer_delete_mark(imhtml->text_buffer, mark2); \ | |
763 if (bold) \ | |
764 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "BOLD", &siter, &iter); \ | |
4895 | 765 if (italics) \ |
3922 | 766 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "ITALICS", &siter, &iter); \ |
767 if (underline) \ | |
768 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "UNDERLINE", &siter, &iter); \ | |
769 if (strike) \ | |
770 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "STRIKE", &siter, &iter); \ | |
771 if (sub) \ | |
772 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "SUB", &siter, &iter); \ | |
773 if (sup) \ | |
774 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "SUP", &siter, &iter); \ | |
775 if (pre) \ | |
776 gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "PRE", &siter, &iter); \ | |
777 if (bg) { \ | |
778 texttag = gtk_text_buffer_create_tag(imhtml->text_buffer, NULL, "background", bg, NULL); \ | |
779 gtk_text_buffer_apply_tag(imhtml->text_buffer, texttag, &siter, &iter); \ | |
780 } \ | |
781 if (fonts) { \ | |
782 FontDetail *fd = fonts->data; \ | |
783 if (fd->fore) { \ | |
784 texttag = gtk_text_buffer_create_tag(imhtml->text_buffer, NULL, "foreground", fd->fore, NULL); \ | |
785 gtk_text_buffer_apply_tag(imhtml->text_buffer, texttag, &siter, &iter); \ | |
786 } \ | |
787 if (fd->back) { \ | |
788 texttag = gtk_text_buffer_create_tag(imhtml->text_buffer, NULL, "background", fd->back, NULL); \ | |
789 gtk_text_buffer_apply_tag(imhtml->text_buffer, texttag, &siter, &iter); \ | |
790 } \ | |
791 if (fd->face) { \ | |
792 texttag = gtk_text_buffer_create_tag(imhtml->text_buffer, NULL, "font", fd->face, NULL); \ | |
793 gtk_text_buffer_apply_tag(imhtml->text_buffer, texttag, &siter, &iter); \ | |
794 } \ | |
795 if (fd->size) { \ | |
796 texttag = gtk_text_buffer_create_tag(imhtml->text_buffer, NULL, "size-points", (double)POINT_SIZE(fd->size), NULL); \ | |
797 gtk_text_buffer_apply_tag(imhtml->text_buffer, texttag, &siter, &iter); \ | |
798 } \ | |
799 } \ | |
800 if (url) { \ | |
801 texttag = gtk_text_buffer_create_tag(imhtml->text_buffer, NULL, "foreground", "blue", "underline", PANGO_UNDERLINE_SINGLE, NULL); \ | |
802 g_signal_connect(G_OBJECT(texttag), "event", G_CALLBACK(tag_event), strdup(url)); \ | |
803 gtk_text_buffer_apply_tag(imhtml->text_buffer, texttag, &siter, &iter); \ | |
4735 | 804 texttag = gtk_text_buffer_create_tag(imhtml->text_buffer, NULL, NULL); \ |
805 g_object_set_data(G_OBJECT(texttag), "link_url", g_strdup(url)); \ | |
806 gtk_text_buffer_apply_tag(imhtml->text_buffer, texttag, &siter, &iter); \ | |
3922 | 807 } \ |
808 wpos = 0; \ | |
809 ws[0] = 0; \ | |
810 gtk_text_buffer_get_end_iter(imhtml->text_buffer, &iter); \ | |
4895 | 811 if (x == NEW_SCALABLE_BIT) { \ |
812 GdkRectangle rect; \ | |
813 gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(imhtml), &rect); \ | |
814 scalable->add_to(scalable, imhtml, &iter); \ | |
815 scalable->scale(scalable, rect.width, rect.height); \ | |
816 imhtml->scalables = g_list_append(imhtml->scalables, scalable); \ | |
817 gtk_text_buffer_get_end_iter(imhtml->text_buffer, &iter); \ | |
4343 | 818 } \ |
3922 | 819 |
4895 | 820 |
821 | |
3922 | 822 GString* gtk_imhtml_append_text (GtkIMHtml *imhtml, |
823 const gchar *text, | |
824 gint len, | |
825 GtkIMHtmlOptions options) | |
1428 | 826 { |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
827 gint pos = 0; |
3922 | 828 GString *str = NULL; |
829 GtkTextIter iter, siter; | |
830 GtkTextMark *mark, *mark2; | |
831 GtkTextTag *texttag; | |
832 gchar *ws; | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
833 gchar *tag; |
3922 | 834 gchar *url = NULL; |
835 gchar *bg = NULL; | |
4032 | 836 gint tlen, smilelen, wpos=0; |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
837 gint type; |
3922 | 838 const gchar *c; |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
839 gchar amp; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
840 |
1428 | 841 guint bold = 0, |
842 italics = 0, | |
843 underline = 0, | |
844 strike = 0, | |
845 sub = 0, | |
846 sup = 0, | |
1691
d802b115800f
[gaim-migrate @ 1701]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1647
diff
changeset
|
847 title = 0, |
3922 | 848 pre = 0; |
1428 | 849 |
3922 | 850 GSList *fonts = NULL; |
1428 | 851 |
4612 | 852 GdkRectangle rect; |
853 int y, height; | |
854 | |
4895 | 855 GtkIMHtmlScalable *scalable = NULL; |
856 | |
1428 | 857 g_return_val_if_fail (imhtml != NULL, NULL); |
858 g_return_val_if_fail (GTK_IS_IMHTML (imhtml), NULL); | |
859 g_return_val_if_fail (text != NULL, NULL); | |
3922 | 860 g_return_val_if_fail (len != 0, NULL); |
861 | |
862 c = text; | |
863 if (len == -1) | |
864 len = strlen(text); | |
865 ws = g_malloc(len + 1); | |
866 ws[0] = 0; | |
1428 | 867 |
868 if (options & GTK_IMHTML_RETURN_LOG) | |
3922 | 869 str = g_string_new(""); |
1428 | 870 |
3922 | 871 gtk_text_buffer_get_end_iter(imhtml->text_buffer, &iter); |
872 mark = gtk_text_buffer_create_mark (imhtml->text_buffer, NULL, &iter, /* right grav */ FALSE); | |
4612 | 873 |
874 gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(imhtml), &rect); | |
875 gtk_text_view_get_line_yrange(GTK_TEXT_VIEW(imhtml), &iter, &y, &height); | |
876 | |
877 if(((y + height) - (rect.y + rect.height)) > height | |
878 && gtk_text_buffer_get_char_count(imhtml->text_buffer)){ | |
879 options |= GTK_IMHTML_NO_SCROLL; | |
880 } | |
881 | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
882 while (pos < len) { |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
883 if (*c == '<' && gtk_imhtml_is_tag (c + 1, &tag, &tlen, &type)) { |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
884 c++; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
885 pos++; |
3922 | 886 switch (type) |
887 { | |
888 case 1: /* B */ | |
889 case 2: /* BOLD */ | |
890 NEW_BIT (NEW_TEXT_BIT); | |
891 bold++; | |
892 break; | |
893 case 3: /* /B */ | |
894 case 4: /* /BOLD */ | |
895 NEW_BIT (NEW_TEXT_BIT); | |
896 if (bold) | |
897 bold--; | |
898 break; | |
899 case 5: /* I */ | |
900 case 6: /* ITALIC */ | |
901 NEW_BIT (NEW_TEXT_BIT); | |
902 italics++; | |
903 break; | |
904 case 7: /* /I */ | |
905 case 8: /* /ITALIC */ | |
906 NEW_BIT (NEW_TEXT_BIT); | |
907 if (italics) | |
908 italics--; | |
909 break; | |
910 case 9: /* U */ | |
911 case 10: /* UNDERLINE */ | |
912 NEW_BIT (NEW_TEXT_BIT); | |
913 underline++; | |
914 break; | |
915 case 11: /* /U */ | |
916 case 12: /* /UNDERLINE */ | |
917 NEW_BIT (NEW_TEXT_BIT); | |
918 if (underline) | |
919 underline--; | |
920 break; | |
921 case 13: /* S */ | |
922 case 14: /* STRIKE */ | |
923 NEW_BIT (NEW_TEXT_BIT); | |
924 strike++; | |
925 break; | |
926 case 15: /* /S */ | |
927 case 16: /* /STRIKE */ | |
928 NEW_BIT (NEW_TEXT_BIT); | |
929 if (strike) | |
930 strike--; | |
931 break; | |
932 case 17: /* SUB */ | |
933 NEW_BIT (NEW_TEXT_BIT); | |
934 sub++; | |
935 break; | |
936 case 18: /* /SUB */ | |
937 NEW_BIT (NEW_TEXT_BIT); | |
938 if (sub) | |
939 sub--; | |
940 break; | |
941 case 19: /* SUP */ | |
942 NEW_BIT (NEW_TEXT_BIT); | |
943 sup++; | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
944 break; |
3922 | 945 case 20: /* /SUP */ |
946 NEW_BIT (NEW_TEXT_BIT); | |
947 if (sup) | |
948 sup--; | |
949 break; | |
950 case 21: /* PRE */ | |
951 NEW_BIT (NEW_TEXT_BIT); | |
952 pre++; | |
953 break; | |
954 case 22: /* /PRE */ | |
955 NEW_BIT (NEW_TEXT_BIT); | |
956 if (pre) | |
957 pre--; | |
958 break; | |
959 case 23: /* TITLE */ | |
960 NEW_BIT (NEW_TEXT_BIT); | |
961 title++; | |
962 break; | |
963 case 24: /* /TITLE */ | |
964 if (title) { | |
965 if (options & GTK_IMHTML_NO_TITLE) { | |
966 wpos = 0; | |
967 ws [wpos] = '\0'; | |
968 } | |
969 title--; | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
970 } |
3922 | 971 break; |
972 case 25: /* BR */ | |
973 ws[wpos] = '\n'; | |
974 wpos++; | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
975 NEW_BIT (NEW_TEXT_BIT); |
3922 | 976 break; |
977 case 26: /* HR */ | |
978 case 42: /* HR (opt) */ | |
979 ws[wpos++] = '\n'; | |
4895 | 980 scalable = gaim_hr_new(); |
981 NEW_BIT(NEW_SCALABLE_BIT); | |
4343 | 982 ws[wpos++] = '\n'; |
3922 | 983 break; |
984 case 27: /* /FONT */ | |
985 if (fonts) { | |
986 FontDetail *font = fonts->data; | |
987 NEW_BIT (NEW_TEXT_BIT); | |
988 fonts = g_slist_remove (fonts, font); | |
989 if (font->face) | |
990 g_free (font->face); | |
991 if (font->fore) | |
992 g_free (font->fore); | |
993 if (font->back) | |
994 g_free (font->back); | |
4032 | 995 if (font->sml) |
996 g_free (font->sml); | |
3922 | 997 g_free (font); |
998 } | |
999 break; | |
1000 case 28: /* /A */ | |
1001 if (url) { | |
1002 NEW_BIT(NEW_TEXT_BIT); | |
1003 g_free(url); | |
1004 url = NULL; | |
2993 | 1005 break; |
1006 } | |
3922 | 1007 case 29: /* P */ |
1008 case 30: /* /P */ | |
1009 case 31: /* H3 */ | |
1010 case 32: /* /H3 */ | |
1011 case 33: /* HTML */ | |
1012 case 34: /* /HTML */ | |
1013 case 35: /* BODY */ | |
1014 case 36: /* /BODY */ | |
1015 case 37: /* FONT */ | |
1016 case 38: /* HEAD */ | |
1017 case 39: /* /HEAD */ | |
1018 break; | |
1019 case 40: /* BINARY */ | |
4895 | 1020 NEW_BIT (NEW_TEXT_BIT); |
1021 break; | |
3922 | 1022 case 41: /* /BINARY */ |
1023 break; | |
1024 case 43: /* FONT (opt) */ | |
1025 { | |
4032 | 1026 gchar *color, *back, *face, *size, *sml; |
3922 | 1027 FontDetail *font, *oldfont = NULL; |
1028 color = gtk_imhtml_get_html_opt (tag, "COLOR="); | |
1029 back = gtk_imhtml_get_html_opt (tag, "BACK="); | |
1030 face = gtk_imhtml_get_html_opt (tag, "FACE="); | |
1031 size = gtk_imhtml_get_html_opt (tag, "SIZE="); | |
4032 | 1032 sml = gtk_imhtml_get_html_opt (tag, "SML="); |
1033 if (!(color || back || face || size || sml)) | |
3922 | 1034 break; |
1035 | |
1036 NEW_BIT (NEW_TEXT_BIT); | |
1037 | |
1038 font = g_new0 (FontDetail, 1); | |
1039 if (fonts) | |
1040 oldfont = fonts->data; | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1041 |
3922 | 1042 if (color && !(options & GTK_IMHTML_NO_COLOURS)) |
1043 font->fore = color; | |
1044 else if (oldfont && oldfont->fore) | |
1045 font->fore = g_strdup(oldfont->fore); | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1046 |
3922 | 1047 if (back && !(options & GTK_IMHTML_NO_COLOURS)) |
1048 font->back = back; | |
1049 else if (oldfont && oldfont->back) | |
1050 font->back = g_strdup(oldfont->back); | |
1051 | |
1052 if (face && !(options & GTK_IMHTML_NO_FONTS)) | |
1053 font->face = face; | |
1054 else if (oldfont && oldfont->face) | |
1055 font->face = g_strdup(oldfont->face); | |
4629 | 1056 if (font->face && (atoi(font->face) > 100)) { |
1057 g_free(font->face); | |
1058 font->face = g_strdup("100"); | |
1059 } | |
4032 | 1060 |
1061 if (sml) | |
1062 font->sml = sml; | |
1063 else if (oldfont && oldfont->sml) | |
1064 font->sml = g_strdup(oldfont->sml); | |
1065 | |
3922 | 1066 if (size && !(options & GTK_IMHTML_NO_SIZES)) { |
1067 if (*size == '+') { | |
1068 sscanf (size + 1, "%hd", &font->size); | |
1069 font->size += 3; | |
1070 } else if (*size == '-') { | |
1071 sscanf (size + 1, "%hd", &font->size); | |
1072 font->size = MAX (0, 3 - font->size); | |
1073 } else if (isdigit (*size)) { | |
1074 sscanf (size, "%hd", &font->size); | |
1075 } | |
1076 } else if (oldfont) | |
1077 font->size = oldfont->size; | |
1078 g_free(size); | |
1079 fonts = g_slist_prepend (fonts, font); | |
1080 } | |
1081 break; | |
1082 case 44: /* BODY (opt) */ | |
1083 if (!(options & GTK_IMHTML_NO_COLOURS)) { | |
1084 char *bgcolor = gtk_imhtml_get_html_opt (tag, "BGCOLOR="); | |
1085 if (bgcolor) { | |
1086 NEW_BIT(NEW_TEXT_BIT); | |
1087 if (bg) | |
1088 g_free(bg); | |
1089 bg = bgcolor; | |
2885
f72efa29c109
[gaim-migrate @ 2898]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2871
diff
changeset
|
1090 } |
1428 | 1091 } |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1092 break; |
3922 | 1093 case 45: /* A (opt) */ |
1094 { | |
1095 gchar *href = gtk_imhtml_get_html_opt (tag, "HREF="); | |
1096 if (href) { | |
1097 NEW_BIT (NEW_TEXT_BIT); | |
1098 if (url) | |
1099 g_free (url); | |
1100 url = href; | |
1101 } | |
2993 | 1102 } |
3922 | 1103 break; |
4895 | 1104 case 46: /* IMG (opt) */ |
1105 { | |
1106 gchar *src = gtk_imhtml_get_html_opt (tag, "SRC="); | |
1107 gchar *id = gtk_imhtml_get_html_opt (tag, "ID="); | |
1108 gchar *datasize = gtk_imhtml_get_html_opt (tag, "DATASIZE="); | |
1109 gint im_len = datasize?atoi(datasize):0; | |
1110 | |
1111 if (src && id && im_len && im_len <= len - pos) { | |
1112 /* This is an embedded IM image, or is it? */ | |
1113 char *tmp = NULL; | |
1114 const char *alltext; | |
1115 guchar *imagedata = NULL; | |
1116 | |
1117 GdkPixbufLoader *load; | |
1118 GdkPixbuf *imagepb = NULL; | |
1119 GError *error = NULL; | |
1120 | |
1121 tmp = g_strdup_printf("<DATA ID=\"%s\" SIZE=\"%s\">", id, datasize); | |
1122 alltext = strstr(c, tmp); | |
1123 imagedata = g_memdup(alltext + strlen(tmp), im_len); | |
1124 | |
1125 g_free(tmp); | |
1126 | |
1127 load = gdk_pixbuf_loader_new(); | |
1128 if (!gdk_pixbuf_loader_write(load, imagedata, im_len, &error)){ | |
1129 fprintf(stderr, "IM Image corrupted or unreadable.: %s\n", error->message); | |
1130 } else { | |
1131 imagepb = gdk_pixbuf_loader_get_pixbuf(load); | |
1132 if (imagepb) { | |
1133 scalable = gaim_im_image_new(imagepb); | |
1134 NEW_BIT(NEW_SCALABLE_BIT); | |
1135 } | |
1136 } | |
1137 | |
1138 gdk_pixbuf_loader_close(load, NULL); | |
1139 | |
1140 | |
1141 g_free(imagedata); | |
1142 g_free(id); | |
1143 g_free(datasize); | |
1144 g_free(src); | |
1145 | |
1146 break; | |
1147 } | |
1148 g_free(id); | |
1149 g_free(datasize); | |
1150 g_free(src); | |
1151 } | |
3922 | 1152 case 47: /* P (opt) */ |
1153 case 48: /* H3 (opt) */ | |
2993 | 1154 break; |
3922 | 1155 case 49: /* comment */ |
1156 NEW_BIT (NEW_TEXT_BIT); | |
4253 | 1157 if (imhtml->show_comments) |
1158 wpos = g_snprintf (ws, len, "%s", tag); | |
3922 | 1159 NEW_BIT (NEW_COMMENT_BIT); |
1160 break; | |
1161 default: | |
1162 break; | |
2993 | 1163 } |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1164 c += tlen; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1165 pos += tlen; |
4138 | 1166 if(tag) |
1167 g_free(tag); /* This was allocated back in VALID_TAG() */ | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1168 } else if (*c == '&' && gtk_imhtml_is_amp_escape (c, &, &tlen)) { |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1169 ws [wpos++] = amp; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1170 c += tlen; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1171 pos += tlen; |
1428 | 1172 } else if (*c == '\n') { |
1173 if (!(options & GTK_IMHTML_NO_NEWLINE)) { | |
3922 | 1174 ws[wpos] = '\n'; |
1175 wpos++; | |
1428 | 1176 NEW_BIT (NEW_TEXT_BIT); |
1177 } | |
1178 c++; | |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1179 pos++; |
4253 | 1180 } else if (imhtml->show_smileys && (gtk_imhtml_is_smiley (imhtml, fonts, c, &smilelen) || gtk_imhtml_is_smiley(imhtml, NULL, c, &smilelen))) { |
4032 | 1181 FontDetail *fd; |
1182 gchar *sml = NULL; | |
1183 if (fonts) { | |
1184 fd = fonts->data; | |
1185 sml = fd->sml; | |
1186 } | |
1187 NEW_BIT (NEW_TEXT_BIT); | |
1188 wpos = g_snprintf (ws, smilelen + 1, "%s", c); | |
4263 | 1189 gtk_text_buffer_insert_pixbuf(imhtml->text_buffer, &iter, gtk_smiley_tree_image (imhtml, sml, ws)); |
4032 | 1190 c += smilelen; |
1191 pos += smilelen; | |
1192 wpos = 0; | |
1193 ws[0] = 0; | |
1194 } else if (*c) { | |
1428 | 1195 ws [wpos++] = *c++; |
2856
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1196 pos++; |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1197 } else { |
b1e300a85678
[gaim-migrate @ 2869]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2826
diff
changeset
|
1198 break; |
1428 | 1199 } |
1200 } | |
3922 | 1201 |
1202 NEW_BIT(NEW_TEXT_BIT); | |
1428 | 1203 if (url) { |
1204 g_free (url); | |
3922 | 1205 if (str) |
1206 str = g_string_append (str, "</A>"); | |
1428 | 1207 } |
3922 | 1208 |
4032 | 1209 while (fonts) { |
1210 FontDetail *font = fonts->data; | |
1211 fonts = g_slist_remove (fonts, font); | |
1212 if (font->face) | |
1213 g_free (font->face); | |
1214 if (font->fore) | |
1215 g_free (font->fore); | |
1216 if (font->back) | |
1217 g_free (font->back); | |
1218 if (font->sml) | |
1219 g_free (font->sml); | |
1220 g_free (font); | |
1221 if (str) | |
1222 str = g_string_append (str, "</FONT>"); | |
1223 } | |
1224 | |
3922 | 1225 if (str) { |
1428 | 1226 while (bold) { |
3922 | 1227 str = g_string_append (str, "</B>"); |
1428 | 1228 bold--; |
1229 } | |
1230 while (italics) { | |
3922 | 1231 str = g_string_append (str, "</I>"); |
1428 | 1232 italics--; |
1233 } | |
1234 while (underline) { | |
3922 | 1235 str = g_string_append (str, "</U>"); |
1428 | 1236 underline--; |
1237 } | |
1238 while (strike) { | |
3922 | 1239 str = g_string_append (str, "</S>"); |
1428 | 1240 strike--; |
1241 } | |
1242 while (sub) { | |
3922 | 1243 str = g_string_append (str, "</SUB>"); |
1428 | 1244 sub--; |
1245 } | |
1246 while (sup) { | |
3922 | 1247 str = g_string_append (str, "</SUP>"); |
1428 | 1248 sup--; |
1249 } | |
1250 while (title) { | |
3922 | 1251 str = g_string_append (str, "</TITLE>"); |
1428 | 1252 title--; |
1253 } | |
1691
d802b115800f
[gaim-migrate @ 1701]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1647
diff
changeset
|
1254 while (pre) { |
3922 | 1255 str = g_string_append (str, "</PRE>"); |
1691
d802b115800f
[gaim-migrate @ 1701]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1647
diff
changeset
|
1256 pre--; |
d802b115800f
[gaim-migrate @ 1701]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1647
diff
changeset
|
1257 } |
1428 | 1258 } |
4032 | 1259 g_free (ws); |
4630 | 1260 if(bg) |
1261 g_free(bg); | |
4032 | 1262 if (!(options & GTK_IMHTML_NO_SCROLL)) |
1263 gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (imhtml), mark, | |
1264 0, TRUE, 0.0, 1.0); | |
3922 | 1265 gtk_text_buffer_delete_mark (imhtml->text_buffer, mark); |
1266 return str; | |
1267 } | |
1268 | |
4892 | 1269 void gtk_imhtml_remove_smileys(GtkIMHtml *imhtml) |
1270 { | |
4288 | 1271 g_hash_table_destroy(imhtml->smiley_data); |
1272 gtk_smiley_tree_destroy(imhtml->default_smilies); | |
4892 | 1273 imhtml->smiley_data = g_hash_table_new_full(g_str_hash, g_str_equal, |
4902 | 1274 g_free, (GDestroyNotify)gtk_smiley_tree_destroy); |
4288 | 1275 imhtml->default_smilies = gtk_smiley_tree_new(); |
1276 } | |
3922 | 1277 void gtk_imhtml_show_smileys (GtkIMHtml *imhtml, |
4253 | 1278 gboolean show) |
1279 { | |
1280 imhtml->show_smileys = show; | |
1281 } | |
3922 | 1282 |
1283 void gtk_imhtml_show_comments (GtkIMHtml *imhtml, | |
4253 | 1284 gboolean show) |
1285 { | |
1286 imhtml->show_comments = show; | |
1287 } | |
1780
d7cbedd1d651
[gaim-migrate @ 1790]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1738
diff
changeset
|
1288 |
d7cbedd1d651
[gaim-migrate @ 1790]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1738
diff
changeset
|
1289 void |
d7cbedd1d651
[gaim-migrate @ 1790]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1738
diff
changeset
|
1290 gtk_imhtml_clear (GtkIMHtml *imhtml) |
d7cbedd1d651
[gaim-migrate @ 1790]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1738
diff
changeset
|
1291 { |
3922 | 1292 GtkTextIter start, end; |
2993 | 1293 |
3922 | 1294 gtk_text_buffer_get_start_iter(imhtml->text_buffer, &start); |
1295 gtk_text_buffer_get_end_iter(imhtml->text_buffer, &end); | |
1296 gtk_text_buffer_delete(imhtml->text_buffer, &start, &end); | |
1780
d7cbedd1d651
[gaim-migrate @ 1790]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1738
diff
changeset
|
1297 } |
2363
08c66712364c
[gaim-migrate @ 2376]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2349
diff
changeset
|
1298 |
4046 | 1299 void gtk_imhtml_page_up (GtkIMHtml *imhtml) |
1300 { | |
1301 | |
1302 } | |
3922 | 1303 void gtk_imhtml_page_down (GtkIMHtml *imhtml){} |
4735 | 1304 |
1305 static gint | |
1306 gtk_imhtml_tip_paint (GtkIMHtml *imhtml) | |
1307 { | |
1308 PangoLayout *layout; | |
1309 | |
1310 g_return_val_if_fail(GTK_IS_IMHTML(imhtml), FALSE); | |
1311 | |
1312 layout = gtk_widget_create_pango_layout(imhtml->tip_window, imhtml->tip); | |
1313 | |
1314 gtk_paint_flat_box (imhtml->tip_window->style, imhtml->tip_window->window, | |
1315 GTK_STATE_NORMAL, GTK_SHADOW_OUT, NULL, imhtml->tip_window, | |
1316 "tooltip", 0, 0, -1, -1); | |
1317 | |
1318 gtk_paint_layout (imhtml->tip_window->style, imhtml->tip_window->window, GTK_STATE_NORMAL, | |
1319 FALSE, NULL, imhtml->tip_window, NULL, 4, 4, layout); | |
1320 | |
4764 | 1321 g_object_unref(layout); |
4735 | 1322 return FALSE; |
1323 } | |
1324 | |
1325 static gint | |
1326 gtk_imhtml_tip (gpointer data) | |
1327 { | |
1328 GtkIMHtml *imhtml = data; | |
1329 PangoFontMetrics *font; | |
1330 PangoLayout *layout; | |
1331 | |
1332 gint gap, x, y, h, w, scr_w, baseline_skip; | |
1333 | |
1334 g_return_val_if_fail(GTK_IS_IMHTML(imhtml), FALSE); | |
1335 | |
1336 if (!imhtml->tip || !GTK_WIDGET_DRAWABLE (GTK_WIDGET(imhtml))) { | |
1337 imhtml->tip_timer = 0; | |
1338 return FALSE; | |
1339 } | |
1340 | |
1341 if (imhtml->tip_window){ | |
1342 gtk_widget_destroy (imhtml->tip_window); | |
1343 imhtml->tip_window = NULL; | |
1344 } | |
1345 | |
1346 imhtml->tip_timer = 0; | |
1347 imhtml->tip_window = gtk_window_new (GTK_WINDOW_POPUP); | |
1348 gtk_widget_set_app_paintable (imhtml->tip_window, TRUE); | |
1349 gtk_window_set_resizable (GTK_WINDOW (imhtml->tip_window), FALSE); | |
1350 gtk_widget_set_name (imhtml->tip_window, "gtk-tooltips"); | |
1351 g_signal_connect_swapped (G_OBJECT (imhtml->tip_window), "expose_event", | |
1352 G_CALLBACK (gtk_imhtml_tip_paint), imhtml); | |
1353 | |
1354 gtk_widget_ensure_style (imhtml->tip_window); | |
1355 layout = gtk_widget_create_pango_layout(imhtml->tip_window, imhtml->tip); | |
1356 font = pango_font_get_metrics(pango_context_load_font(pango_layout_get_context(layout), | |
1357 imhtml->tip_window->style->font_desc), | |
1358 NULL); | |
1359 | |
1360 | |
1361 pango_layout_get_pixel_size(layout, &scr_w, NULL); | |
1362 gap = PANGO_PIXELS((pango_font_metrics_get_ascent(font) + | |
1363 pango_font_metrics_get_descent(font))/ 4); | |
1364 | |
1365 if (gap < 2) | |
1366 gap = 2; | |
1367 baseline_skip = PANGO_PIXELS(pango_font_metrics_get_ascent(font) + | |
1368 pango_font_metrics_get_descent(font)); | |
1369 w = 8 + scr_w; | |
1370 h = 8 + baseline_skip; | |
1371 | |
1372 gdk_window_get_pointer (NULL, &x, &y, NULL); | |
1373 if (GTK_WIDGET_NO_WINDOW (GTK_WIDGET(imhtml))) | |
1374 y += GTK_WIDGET(imhtml)->allocation.y; | |
1375 | |
1376 scr_w = gdk_screen_width(); | |
1377 | |
1378 x -= ((w >> 1) + 4); | |
1379 | |
1380 if ((x + w) > scr_w) | |
1381 x -= (x + w) - scr_w; | |
1382 else if (x < 0) | |
1383 x = 0; | |
1384 | |
1385 y = y + PANGO_PIXELS(pango_font_metrics_get_ascent(font) + | |
1386 pango_font_metrics_get_descent(font)); | |
1387 | |
1388 gtk_widget_set_size_request (imhtml->tip_window, w, h); | |
1389 gtk_widget_show (imhtml->tip_window); | |
1390 gtk_window_move (GTK_WINDOW(imhtml->tip_window), x, y); | |
1391 | |
1392 pango_font_metrics_unref(font); | |
4895 | 1393 g_object_unref(layout); |
4735 | 1394 |
1395 return FALSE; | |
1396 } | |
4895 | 1397 |
4947 | 1398 static gboolean gtk_size_allocate_cb(GtkIMHtml *widget, GtkAllocation *alloc, gpointer user_data) |
4895 | 1399 { |
4903 | 1400 GdkRectangle rect; |
4895 | 1401 |
4903 | 1402 gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(widget), &rect); |
4947 | 1403 if(widget->old_rect.width != rect.width || widget->old_rect.height != rect.height){ |
4902 | 1404 GList *iter = GTK_IMHTML(widget)->scalables; |
4895 | 1405 |
1406 while(iter){ | |
1407 GtkIMHtmlScalable *scale = GTK_IMHTML_SCALABLE(iter->data); | |
4903 | 1408 scale->scale(scale, rect.width, rect.height); |
4895 | 1409 |
1410 iter = iter->next; | |
1411 } | |
1412 } | |
1413 | |
4947 | 1414 widget->old_rect = rect; |
4895 | 1415 return FALSE; |
1416 } | |
1417 | |
1418 /* GtkIMHtmlScalable, gaim_im_image, gaim_hr */ | |
1419 GtkIMHtmlScalable *gaim_im_image_new(GdkPixbuf *img) | |
1420 { | |
1421 gaim_im_image *im_image = g_malloc(sizeof(gaim_im_image)); | |
1422 | |
1423 GTK_IMHTML_SCALABLE(im_image)->scale = gaim_im_image_scale; | |
1424 GTK_IMHTML_SCALABLE(im_image)->add_to = gaim_im_image_add_to; | |
1425 GTK_IMHTML_SCALABLE(im_image)->free = gaim_im_image_free; | |
1426 im_image->image = img; | |
1427 im_image->width = gdk_pixbuf_get_width(img); | |
1428 im_image->height = gdk_pixbuf_get_height(img); | |
1429 im_image->imhtml = NULL; | |
1430 im_image->mark = NULL; | |
1431 | |
1432 return GTK_IMHTML_SCALABLE(im_image); | |
1433 } | |
1434 | |
1435 void gaim_im_image_scale(GtkIMHtmlScalable *scale, int width, int height) | |
1436 { | |
1437 gaim_im_image *image = (gaim_im_image *)scale; | |
1438 | |
1439 if(image->width > width || image->height > height){ | |
1440 GdkPixbuf *new_image = NULL; | |
1441 GtkTextIter start, end; | |
1442 float factor; | |
1443 int new_width = image->width, new_height = image->height; | |
1444 | |
1445 gtk_text_buffer_get_iter_at_mark(image->imhtml->text_buffer, &start, image->mark); | |
1446 end = start; | |
1447 gtk_text_iter_forward_char(&end); | |
1448 gtk_text_buffer_delete(image->imhtml->text_buffer, &start, &end); | |
1449 | |
1450 if(image->width > width){ | |
1451 factor = (float)(width)/image->width; | |
1452 new_width = width; | |
1453 new_height = image->height * factor; | |
1454 } | |
1455 if(new_height > height){ | |
1456 factor = (float)(height)/new_height; | |
1457 new_height = height; | |
1458 new_width = new_width * factor; | |
1459 } | |
1460 | |
1461 gtk_text_buffer_get_iter_at_mark(image->imhtml->text_buffer, &start, image->mark); | |
1462 new_image = gdk_pixbuf_scale_simple(image->image, new_width, new_height, GDK_INTERP_BILINEAR); | |
1463 gtk_text_buffer_insert_pixbuf(image->imhtml->text_buffer, &start, new_image); | |
1464 | |
1465 g_object_unref(G_OBJECT(new_image)); | |
1466 } | |
1467 } | |
1468 | |
1469 void gaim_im_image_free(GtkIMHtmlScalable *scale) | |
1470 { | |
1471 gaim_im_image *image = (gaim_im_image *)scale; | |
1472 | |
1473 g_object_unref(image->image); | |
1474 g_free(scale); | |
1475 } | |
1476 | |
1477 void gaim_im_image_add_to(GtkIMHtmlScalable *scale, GtkIMHtml *imhtml, GtkTextIter *iter) | |
1478 { | |
1479 gaim_im_image *image = (gaim_im_image *)scale; | |
1480 | |
1481 image->mark = gtk_text_buffer_create_mark(imhtml->text_buffer, NULL, iter, TRUE); | |
1482 gtk_text_buffer_insert_pixbuf(imhtml->text_buffer, iter, image->image); | |
1483 image->imhtml = imhtml; | |
1484 } | |
1485 | |
1486 GtkIMHtmlScalable *gaim_hr_new() | |
1487 { | |
1488 gaim_hr *hr = g_malloc(sizeof(gaim_hr)); | |
1489 | |
1490 GTK_IMHTML_SCALABLE(hr)->scale = gaim_hr_scale; | |
1491 GTK_IMHTML_SCALABLE(hr)->add_to = gaim_hr_add_to; | |
1492 GTK_IMHTML_SCALABLE(hr)->free = gaim_hr_free; | |
1493 | |
1494 hr->sep = gtk_hseparator_new(); | |
1495 gtk_widget_set_size_request(hr->sep, 5000, 2); | |
1496 gtk_widget_show(hr->sep); | |
1497 | |
1498 return GTK_IMHTML_SCALABLE(hr); | |
1499 } | |
1500 | |
1501 void gaim_hr_scale(GtkIMHtmlScalable *scale, int width, int height) | |
1502 { | |
1503 gtk_widget_set_size_request(((gaim_hr *)scale)->sep, width, 2); | |
1504 } | |
1505 | |
1506 void gaim_hr_add_to(GtkIMHtmlScalable *scale, GtkIMHtml *imhtml, GtkTextIter *iter) | |
1507 { | |
1508 gaim_hr *hr = (gaim_hr *)scale; | |
1509 GtkTextChildAnchor *anchor = gtk_text_buffer_create_child_anchor(imhtml->text_buffer, iter); | |
1510 | |
1511 gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), hr->sep, anchor); | |
1512 } | |
1513 | |
1514 void gaim_hr_free(GtkIMHtmlScalable *scale) | |
1515 { | |
1516 /* gtk_widget_destroy(((gaim_hr *)scale)->sep); */ | |
1517 g_free(scale); | |
1518 } |