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