comparison gtk/gtkimhtml.c @ 15341:ca7cc867fa58

[gaim-migrate @ 18134] Syncing up my tree. I've gotten smileys, <hr>'s and IM images to *mostly* work. Scrolling's the only obviously busted thing right now. I also made blist headlines set the URGENT hint. committer: Tailor Script <tailor@pidgin.im>
author Sean Egan <seanegan@gmail.com>
date Tue, 16 Jan 2007 02:48:36 +0000
parents 3abb476aab94
children 965f7e53e7c5
comparison
equal deleted inserted replaced
15340:29e9a2373d32 15341:ca7cc867fa58
1213 1213
1214 if (imhtml->clipboard_text_string) { 1214 if (imhtml->clipboard_text_string) {
1215 g_free(imhtml->clipboard_text_string); 1215 g_free(imhtml->clipboard_text_string);
1216 g_free(imhtml->clipboard_html_string); 1216 g_free(imhtml->clipboard_html_string);
1217 } 1217 }
1218 1218
1219 for (l = imhtml->anchors; l; l = l->next) {
1220 GtkIMHtmlAnchor *anchor = l->data;
1221 gtk_imhtml_anchor_free(anchor);
1222 }
1223
1224 g_slist_free(imhtml->anchors);
1219 g_list_free(imhtml->scalables); 1225 g_list_free(imhtml->scalables);
1220 g_slist_free(imhtml->im_images); 1226 g_slist_free(imhtml->im_images);
1221 g_free(imhtml->protocol_name); 1227 g_free(imhtml->protocol_name);
1222 g_free(imhtml->search_string); 1228 g_free(imhtml->search_string);
1223 g_object_unref(imhtml->empty_buffer); 1229 g_object_unref(imhtml->empty_buffer);
2360 2366
2361 static gboolean 2367 static gboolean
2362 set_adj_idle_cb(gpointer data) 2368 set_adj_idle_cb(gpointer data)
2363 { 2369 {
2364 GtkIMHtml *imhtml = data; 2370 GtkIMHtml *imhtml = data;
2371
2365 gtk_adjustment_set_value(GTK_TEXT_VIEW(imhtml)->vadjustment, imhtml->adj); 2372 gtk_adjustment_set_value(GTK_TEXT_VIEW(imhtml)->vadjustment, imhtml->adj);
2366 return FALSE; 2373 return FALSE;
2367 } 2374 }
2368 2375
2369 void gtk_imhtml_insert_html_at_iter(GtkIMHtml *imhtml, 2376 void gtk_imhtml_insert_html_at_iter(GtkIMHtml *imhtml,
2371 GtkIMHtmlOptions options, 2378 GtkIMHtmlOptions options,
2372 GtkTextIter *iter) 2379 GtkTextIter *iter)
2373 { 2380 {
2374 GdkRectangle rect; 2381 GdkRectangle rect;
2375 GtkAdjustment *adj = GTK_TEXT_VIEW(imhtml)->vadjustment; 2382 GtkAdjustment *adj = GTK_TEXT_VIEW(imhtml)->vadjustment;
2383 GSList *anchors;
2376 gint pos = 0; 2384 gint pos = 0;
2377 gchar *ws; 2385 gchar *ws;
2378 gchar *tag; 2386 gchar *tag;
2379 gchar *bg = NULL; 2387 gchar *bg = NULL;
2380 gint len; 2388 gint len;
2381 gint tlen, smilelen, wpos=0; 2389 gint tlen, smilelen, wpos=0;
2382 gint type; 2390 gint type;
2383 const gchar *c; 2391 const gchar *c;
2384 gchar *amp; 2392 gchar *amp;
2385 gint len_protocol; 2393 gint len_protocol;
2394 gboolean refocus = GTK_WIDGET_HAS_FOCUS(imhtml);
2386 2395
2387 2396
2388 guint bold = 0, 2397 guint bold = 0,
2389 italics = 0, 2398 italics = 0,
2390 underline = 0, 2399 underline = 0,
2393 sup = 0, 2402 sup = 0,
2394 title = 0, 2403 title = 0,
2395 pre = 0; 2404 pre = 0;
2396 2405
2397 gboolean br = FALSE; 2406 gboolean br = FALSE;
2398
2399 GSList *fonts = NULL; 2407 GSList *fonts = NULL;
2400 GObject *object; 2408 GObject *object;
2401 GtkIMHtmlScalable *scalable = NULL; 2409 GtkIMHtmlScalable *scalable = NULL;
2402 2410
2403 g_return_if_fail (imhtml != NULL); 2411 g_return_if_fail (imhtml != NULL);
2407 len = strlen(text); 2415 len = strlen(text);
2408 ws = g_malloc(len + 1); 2416 ws = g_malloc(len + 1);
2409 ws[0] = 0; 2417 ws[0] = 0;
2410 2418
2411 imhtml->adj = gtk_adjustment_get_value(adj); 2419 imhtml->adj = gtk_adjustment_get_value(adj);
2420
2421 for (anchors = imhtml->anchors; anchors; anchors = anchors->next) {
2422 GtkIMHtmlAnchor *anchor = anchors->data;
2423 if (gtk_text_child_anchor_get_deleted(anchor->anchor)) {
2424 imhtml->anchors = g_slist_remove(imhtml->anchors, anchor);
2425 gtk_imhtml_anchor_free(anchor);
2426 continue;
2427 }
2428 gtk_container_remove(GTK_CONTAINER(imhtml), anchor->widget);
2429
2430 }
2412 gtk_widget_hide(GTK_WIDGET(imhtml)); 2431 gtk_widget_hide(GTK_WIDGET(imhtml));
2413 gtk_widget_unrealize(GTK_WIDGET(imhtml)); 2432 gtk_widget_unrealize(GTK_WIDGET(imhtml));
2414 gtk_text_view_set_buffer(GTK_TEXT_VIEW(imhtml), imhtml->empty_buffer); 2433 gtk_text_view_set_buffer(GTK_TEXT_VIEW(imhtml), imhtml->empty_buffer);
2415 2434
2416 while (pos < len) { 2435 while (pos < len) {
3068 3087
3069 if (!imhtml->wbfo) 3088 if (!imhtml->wbfo)
3070 gtk_imhtml_close_tags(imhtml, iter); 3089 gtk_imhtml_close_tags(imhtml, iter);
3071 3090
3072 gtk_text_view_set_buffer(GTK_TEXT_VIEW(imhtml), imhtml->text_buffer); 3091 gtk_text_view_set_buffer(GTK_TEXT_VIEW(imhtml), imhtml->text_buffer);
3092 for (anchors = imhtml->anchors; anchors; anchors = anchors->next) {
3093 GtkIMHtmlAnchor *anchor = anchors->data;
3094 gtk_imhtml_add_anchor(imhtml, anchor);
3095 }
3096 object = g_object_ref(G_OBJECT(imhtml));
3073 gtk_widget_realize(GTK_WIDGET(imhtml)); 3097 gtk_widget_realize(GTK_WIDGET(imhtml));
3074 gtk_widget_show_all(GTK_WIDGET(imhtml)); 3098 gtk_widget_show_all(GTK_WIDGET(imhtml));
3075 object = g_object_ref(G_OBJECT(imhtml)); 3099 g_idle_add_full(G_PRIORITY_HIGH_IDLE, set_adj_idle_cb, imhtml, NULL);
3076 g_idle_add(set_adj_idle_cb, imhtml); 3100 if (refocus){
3101 printf("refocusing\n");
3102 gtk_widget_grab_focus(GTK_WIDGET(imhtml));
3103 }
3077 g_signal_emit(object, signals[UPDATE_FORMAT], 0); 3104 g_signal_emit(object, signals[UPDATE_FORMAT], 0);
3078 g_object_unref(object); 3105 g_object_unref(object);
3079 } 3106 }
3080 3107
3081 void gtk_imhtml_remove_smileys(GtkIMHtml *imhtml) 3108 void gtk_imhtml_remove_smileys(GtkIMHtml *imhtml)
3464 g_free(scale); 3491 g_free(scale);
3465 } 3492 }
3466 3493
3467 void gtk_imhtml_image_add_to(GtkIMHtmlScalable *scale, GtkIMHtml *imhtml, GtkTextIter *iter) 3494 void gtk_imhtml_image_add_to(GtkIMHtmlScalable *scale, GtkIMHtml *imhtml, GtkTextIter *iter)
3468 { 3495 {
3496 GtkIMHtmlAnchor *ianchor;
3469 GtkIMHtmlImage *image = (GtkIMHtmlImage *)scale; 3497 GtkIMHtmlImage *image = (GtkIMHtmlImage *)scale;
3470 GtkWidget *box = gtk_event_box_new(); 3498 GtkWidget *box = gtk_event_box_new();
3471 char *tag; 3499 char *tag;
3472 GtkTextChildAnchor *anchor = gtk_text_buffer_create_child_anchor(imhtml->text_buffer, iter); 3500 GtkTextChildAnchor *anchor = gtk_text_buffer_create_child_anchor(imhtml->text_buffer, iter);
3473 3501
3481 3509
3482 tag = g_strdup_printf("<IMG ID=\"%d\">", image->id); 3510 tag = g_strdup_printf("<IMG ID=\"%d\">", image->id);
3483 g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_htmltext", tag, g_free); 3511 g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_htmltext", tag, g_free);
3484 g_object_set_data(G_OBJECT(anchor), "gtkimhtml_plaintext", "[Image]"); 3512 g_object_set_data(G_OBJECT(anchor), "gtkimhtml_plaintext", "[Image]");
3485 3513
3486 gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), box, anchor); 3514 ianchor = gtk_imhtml_anchor_new(anchor, box);
3515 imhtml->anchors = g_slist_append(imhtml->anchors, ianchor);
3516
3487 g_signal_connect(G_OBJECT(box), "event", G_CALLBACK(gtk_imhtml_image_clicked), image); 3517 g_signal_connect(G_OBJECT(box), "event", G_CALLBACK(gtk_imhtml_image_clicked), image);
3488 } 3518 }
3489 3519
3490 GtkIMHtmlScalable *gtk_imhtml_hr_new() 3520 GtkIMHtmlScalable *gtk_imhtml_hr_new()
3491 { 3521 {
3507 gtk_widget_set_size_request(((GtkIMHtmlHr *)scale)->sep, width - 2, 2); 3537 gtk_widget_set_size_request(((GtkIMHtmlHr *)scale)->sep, width - 2, 2);
3508 } 3538 }
3509 3539
3510 void gtk_imhtml_hr_add_to(GtkIMHtmlScalable *scale, GtkIMHtml *imhtml, GtkTextIter *iter) 3540 void gtk_imhtml_hr_add_to(GtkIMHtmlScalable *scale, GtkIMHtml *imhtml, GtkTextIter *iter)
3511 { 3541 {
3542 GtkIMHtmlAnchor *ianchor;
3512 GtkIMHtmlHr *hr = (GtkIMHtmlHr *)scale; 3543 GtkIMHtmlHr *hr = (GtkIMHtmlHr *)scale;
3513 GtkTextChildAnchor *anchor = gtk_text_buffer_create_child_anchor(imhtml->text_buffer, iter); 3544 GtkTextChildAnchor *anchor = gtk_text_buffer_create_child_anchor(imhtml->text_buffer, iter);
3514 g_object_set_data(G_OBJECT(anchor), "gtkimhtml_htmltext", "<hr>"); 3545 g_object_set_data(G_OBJECT(anchor), "gtkimhtml_htmltext", "<hr>");
3515 g_object_set_data(G_OBJECT(anchor), "gtkimhtml_plaintext", "\n---\n"); 3546 g_object_set_data(G_OBJECT(anchor), "gtkimhtml_plaintext", "\n---\n");
3516 gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), hr->sep, anchor); 3547 ianchor = gtk_imhtml_anchor_new(anchor, hr->sep);
3548 imhtml->anchors = g_slist_append(imhtml->anchors, ianchor);
3517 } 3549 }
3518 3550
3519 void gtk_imhtml_hr_free(GtkIMHtmlScalable *scale) 3551 void gtk_imhtml_hr_free(GtkIMHtmlScalable *scale)
3520 { 3552 {
3521 g_free(scale); 3553 g_free(scale);
3554 }
3555
3556 GtkIMHtmlAnchor *gtk_imhtml_anchor_new(GtkTextChildAnchor *anchor, GtkWidget *widget)
3557 {
3558 GtkIMHtmlAnchor *a = g_new0(GtkIMHtmlAnchor, 1);
3559 a->anchor = anchor;
3560 a->widget = widget;
3561
3562 g_object_ref(anchor);
3563 g_object_ref(widget);
3564
3565 return a;
3566 }
3567
3568 void gtk_imhtml_anchor_free(GtkIMHtmlAnchor *anchor)
3569 {
3570 g_object_unref(anchor->anchor);
3571 g_object_unref(anchor->widget);
3572 g_free(anchor);
3573 }
3574
3575 void gtk_imhtml_add_anchor(GtkIMHtml *imhtml, GtkIMHtmlAnchor *anchor)
3576 {
3577 if (gtk_text_child_anchor_get_deleted(anchor->anchor)) {
3578 imhtml->anchors = g_slist_remove(imhtml->anchors, anchor);
3579 gtk_imhtml_anchor_free(anchor);
3580 return;
3581 }
3582
3583 gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), anchor->widget, anchor->anchor);
3522 } 3584 }
3523 3585
3524 gboolean gtk_imhtml_search_find(GtkIMHtml *imhtml, const gchar *text) 3586 gboolean gtk_imhtml_search_find(GtkIMHtml *imhtml, const gchar *text)
3525 { 3587 {
3526 GtkTextIter iter, start, end; 3588 GtkTextIter iter, start, end;
4468 } 4530 }
4469 } 4531 }
4470 } 4532 }
4471 4533
4472 if (icon) { 4534 if (icon) {
4535 GtkIMHtmlAnchor *ianchor;
4473 anchor = gtk_text_buffer_create_child_anchor(imhtml->text_buffer, iter); 4536 anchor = gtk_text_buffer_create_child_anchor(imhtml->text_buffer, iter);
4474 g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_plaintext", g_strdup(unescaped), g_free); 4537 g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_plaintext", g_strdup(unescaped), g_free);
4475 g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_htmltext", g_strdup(smiley), g_free); 4538 g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_htmltext", g_strdup(smiley), g_free);
4476 4539
4477 /* This catches the expose events generated by animated 4540 /* This catches the expose events generated by animated
4479 * itself, without propagating to the textview and causing 4542 * itself, without propagating to the textview and causing
4480 * a complete refresh */ 4543 * a complete refresh */
4481 g_signal_connect(G_OBJECT(icon), "expose-event", G_CALLBACK(image_expose), NULL); 4544 g_signal_connect(G_OBJECT(icon), "expose-event", G_CALLBACK(image_expose), NULL);
4482 4545
4483 gtk_widget_show(icon); 4546 gtk_widget_show(icon);
4484 gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), icon, anchor); 4547 ianchor = gtk_imhtml_anchor_new(anchor, icon);
4548 imhtml->anchors = g_slist_append(imhtml->anchors, ianchor);
4485 } else if (imhtml_smiley != NULL && (imhtml->format_functions & GTK_IMHTML_SMILEY)) { 4549 } else if (imhtml_smiley != NULL && (imhtml->format_functions & GTK_IMHTML_SMILEY)) {
4486 anchor = gtk_text_buffer_create_child_anchor(imhtml->text_buffer, iter); 4550 anchor = gtk_text_buffer_create_child_anchor(imhtml->text_buffer, iter);
4487 imhtml_smiley->anchors = g_slist_append(imhtml_smiley->anchors, anchor); 4551 imhtml_smiley->anchors = g_slist_append(imhtml_smiley->anchors, anchor);
4488 } else { 4552 } else {
4489 gtk_text_buffer_insert(imhtml->text_buffer, iter, smiley, -1); 4553 gtk_text_buffer_insert(imhtml->text_buffer, iter, smiley, -1);