pidgin/gtkimhtml.c

branch
cpw.qulogic.gtk3-required
changeset 33120
f6f1a27ade72
parent 32656
d26e0b6b9d2c
parent 32433
f539a2c083b2
child 33132
24afd2b22579
equal deleted inserted replaced
32771:681ca041d42b 33120:f6f1a27ade72
456 imhtml->old_rect = rect; 456 imhtml->old_rect = rect;
457 parent_size_allocate(widget, alloc); 457 parent_size_allocate(widget, alloc);
458 458
459 /* Don't scroll here if we're in the middle of a smooth scroll */ 459 /* Don't scroll here if we're in the middle of a smooth scroll */
460 if (scroll && imhtml->scroll_time == NULL && 460 if (scroll && imhtml->scroll_time == NULL &&
461 GTK_WIDGET_REALIZED(imhtml)) 461 gtk_widget_get_realized(GTK_WIDGET(imhtml)))
462 gtk_imhtml_scroll_to_end(imhtml, FALSE); 462 gtk_imhtml_scroll_to_end(imhtml, FALSE);
463 } 463 }
464 464
465 #define DEFAULT_SEND_COLOR "#204a87" 465 #define DEFAULT_SEND_COLOR "#204a87"
466 #define DEFAULT_RECV_COLOR "#cc0000" 466 #define DEFAULT_RECV_COLOR "#cc0000"
545 545
546 static gint 546 static gint
547 gtk_imhtml_tip_paint (GtkIMHtml *imhtml) 547 gtk_imhtml_tip_paint (GtkIMHtml *imhtml)
548 { 548 {
549 PangoLayout *layout; 549 PangoLayout *layout;
550 cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(imhtml->tip_window));
550 551
551 g_return_val_if_fail(GTK_IS_IMHTML(imhtml), FALSE); 552 g_return_val_if_fail(GTK_IS_IMHTML(imhtml), FALSE);
552 553
553 layout = gtk_widget_create_pango_layout(imhtml->tip_window, imhtml->tip); 554 layout = gtk_widget_create_pango_layout(imhtml->tip_window, imhtml->tip);
554 555
555 gtk_paint_flat_box (imhtml->tip_window->style, imhtml->tip_window->window, 556 gtk_paint_flat_box (gtk_widget_get_style(imhtml->tip_window), cr,
556 GTK_STATE_NORMAL, GTK_SHADOW_OUT, NULL, imhtml->tip_window, 557 GTK_STATE_NORMAL, GTK_SHADOW_OUT, imhtml->tip_window, "tooltip",
557 "tooltip", 0, 0, -1, -1); 558 0, 0, -1, -1);
558 559
559 gtk_paint_layout (imhtml->tip_window->style, imhtml->tip_window->window, GTK_STATE_NORMAL, 560 gtk_paint_layout (gtk_widget_get_style(imhtml->tip_window), cr,
560 FALSE, NULL, imhtml->tip_window, NULL, 4, 4, layout); 561 GTK_STATE_NORMAL, TRUE, imhtml->tip_window, NULL, 4, 4, layout);
561 562
563 cairo_destroy(cr);
562 g_object_unref(layout); 564 g_object_unref(layout);
563 return FALSE; 565 return FALSE;
564 } 566 }
565 567
566 static gint 568 static gint
568 { 570 {
569 GtkIMHtml *imhtml = data; 571 GtkIMHtml *imhtml = data;
570 PangoFontMetrics *font_metrics; 572 PangoFontMetrics *font_metrics;
571 PangoLayout *layout; 573 PangoLayout *layout;
572 PangoFont *font; 574 PangoFont *font;
573 575 GtkStyle *style = gtk_widget_get_style(imhtml->tip_window);
576 GtkAllocation allocation;
574 gint gap, x, y, h, w, scr_w, baseline_skip; 577 gint gap, x, y, h, w, scr_w, baseline_skip;
575 578
576 g_return_val_if_fail(GTK_IS_IMHTML(imhtml), FALSE); 579 g_return_val_if_fail(GTK_IS_IMHTML(imhtml), FALSE);
577 580
578 if (!imhtml->tip || !GTK_WIDGET_DRAWABLE (GTK_WIDGET(imhtml))) { 581 gtk_widget_get_allocation(GTK_WIDGET(imhtml), &allocation);
582
583 if (!imhtml->tip || !gtk_widget_is_drawable(GTK_WIDGET(imhtml))) {
579 imhtml->tip_timer = 0; 584 imhtml->tip_timer = 0;
580 return FALSE; 585 return FALSE;
581 } 586 }
582 587
583 if (imhtml->tip_window){ 588 if (imhtml->tip_window){
597 G_CALLBACK (gtk_imhtml_tip_paint), imhtml); 602 G_CALLBACK (gtk_imhtml_tip_paint), imhtml);
598 603
599 gtk_widget_ensure_style (imhtml->tip_window); 604 gtk_widget_ensure_style (imhtml->tip_window);
600 layout = gtk_widget_create_pango_layout(imhtml->tip_window, imhtml->tip); 605 layout = gtk_widget_create_pango_layout(imhtml->tip_window, imhtml->tip);
601 font = pango_context_load_font(pango_layout_get_context(layout), 606 font = pango_context_load_font(pango_layout_get_context(layout),
602 imhtml->tip_window->style->font_desc); 607 style->font_desc);
603 608
604 if (font == NULL) { 609 if (font == NULL) {
605 char *tmp = pango_font_description_to_string( 610 char *tmp = pango_font_description_to_string(style->font_desc);
606 imhtml->tip_window->style->font_desc);
607 611
608 purple_debug(PURPLE_DEBUG_ERROR, "gtk_imhtml_tip", 612 purple_debug(PURPLE_DEBUG_ERROR, "gtk_imhtml_tip",
609 "pango_context_load_font() couldn't load font: '%s'\n", 613 "pango_context_load_font() couldn't load font: '%s'\n",
610 tmp); 614 tmp);
611 g_free(tmp); 615 g_free(tmp);
626 pango_font_metrics_get_descent(font_metrics)); 630 pango_font_metrics_get_descent(font_metrics));
627 w = 8 + scr_w; 631 w = 8 + scr_w;
628 h = 8 + baseline_skip; 632 h = 8 + baseline_skip;
629 633
630 gdk_window_get_pointer (NULL, &x, &y, NULL); 634 gdk_window_get_pointer (NULL, &x, &y, NULL);
631 if (GTK_WIDGET_NO_WINDOW (GTK_WIDGET(imhtml))) 635 if ((!gtk_widget_get_has_window(GTK_WIDGET(imhtml))))
632 y += GTK_WIDGET(imhtml)->allocation.y; 636 y += allocation.y;
633 637
634 scr_w = gdk_screen_width(); 638 scr_w = gdk_screen_width();
635 639
636 x -= ((w >> 1) + 4); 640 x -= ((w >> 1) + 4);
637 641
667 gboolean hand = TRUE; 671 gboolean hand = TRUE;
668 GdkCursor *cursor = NULL; 672 GdkCursor *cursor = NULL;
669 673
670 oldprelit_tag = GTK_IMHTML(imhtml)->prelit_tag; 674 oldprelit_tag = GTK_IMHTML(imhtml)->prelit_tag;
671 675
672 gdk_window_get_pointer(GTK_WIDGET(imhtml)->window, NULL, NULL, NULL); 676 gdk_window_get_pointer(gtk_widget_get_window(GTK_WIDGET(imhtml)), NULL, NULL, NULL);
673 gtk_text_view_window_to_buffer_coords(GTK_TEXT_VIEW(imhtml), GTK_TEXT_WINDOW_WIDGET, 677 gtk_text_view_window_to_buffer_coords(GTK_TEXT_VIEW(imhtml), GTK_TEXT_WINDOW_WIDGET,
674 event->x, event->y, &x, &y); 678 event->x, event->y, &x, &y);
675 gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(imhtml), &iter, x, y); 679 gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(imhtml), &iter, x, y);
676 tags = gtk_text_iter_get_tags(&iter); 680 tags = gtk_text_iter_get_tags(&iter);
677 681
795 799
796 /* propagate the event normally */ 800 /* propagate the event normally */
797 return FALSE; 801 return FALSE;
798 } 802 }
799 803
804 /* TODO: I think this can be removed for GTK+ 3.0... */
805 #if 0
800 static gint 806 static gint
801 gtk_imhtml_expose_event (GtkWidget *widget, 807 gtk_imhtml_expose_event (GtkWidget *widget,
802 GdkEventExpose *event) 808 GdkEventExpose *event)
803 { 809 {
804 GtkTextIter start, end, cur; 810 GtkTextIter start, end, cur;
822 828
823 if (GTK_IMHTML(widget)->edit.background) { 829 if (GTK_IMHTML(widget)->edit.background) {
824 gdk_color_parse(GTK_IMHTML(widget)->edit.background, &gcolor); 830 gdk_color_parse(GTK_IMHTML(widget)->edit.background, &gcolor);
825 gdk_cairo_set_source_color(cr, &gcolor); 831 gdk_cairo_set_source_color(cr, &gcolor);
826 } else { 832 } else {
827 gdk_cairo_set_source_color(cr, &(widget->style->base[GTK_WIDGET_STATE(widget)])); 833 gdk_cairo_set_source_color(cr,
834 &(gtk_widget_get_style(widget)->base[gtk_widget_get_state(widget)]));
828 } 835 }
829 836
830 cairo_rectangle(cr, 837 cairo_rectangle(cr,
831 visible_rect.x, visible_rect.y, 838 visible_rect.x, visible_rect.y,
832 visible_rect.width, visible_rect.height); 839 visible_rect.width, visible_rect.height);
928 return (* GTK_WIDGET_CLASS (parent_class)->expose_event) 935 return (* GTK_WIDGET_CLASS (parent_class)->expose_event)
929 (widget, event); 936 (widget, event);
930 937
931 return FALSE; 938 return FALSE;
932 } 939 }
940 #endif
933 941
934 942
935 static void paste_unformatted_cb(GtkMenuItem *menu, GtkIMHtml *imhtml) 943 static void paste_unformatted_cb(GtkMenuItem *menu, GtkIMHtml *imhtml)
936 { 944 {
937 GtkClipboard *clipboard = gtk_widget_get_clipboard(GTK_WIDGET(imhtml), GDK_SELECTION_CLIPBOARD); 945 GtkClipboard *clipboard = gtk_widget_get_clipboard(GTK_WIDGET(imhtml), GDK_SELECTION_CLIPBOARD);
1099 text = text_clipboard; 1107 text = text_clipboard;
1100 gtk_selection_data_set_text(selection_data, text, strlen(text)); 1108 gtk_selection_data_set_text(selection_data, text, strlen(text));
1101 } 1109 }
1102 if (primary) /* This was allocated here */ 1110 if (primary) /* This was allocated here */
1103 g_free(text); 1111 g_free(text);
1104 } 1112 }
1105 1113
1106 static void gtk_imhtml_primary_clipboard_clear(GtkClipboard *clipboard, GtkIMHtml *imhtml) 1114 static void gtk_imhtml_primary_clipboard_clear(GtkClipboard *clipboard, GtkIMHtml *imhtml)
1107 { 1115 {
1108 GtkTextIter insert; 1116 GtkTextIter insert;
1109 GtkTextIter selection_bound; 1117 GtkTextIter selection_bound;
1204 1212
1205 static void paste_received_cb (GtkClipboard *clipboard, GtkSelectionData *selection_data, gpointer data) 1213 static void paste_received_cb (GtkClipboard *clipboard, GtkSelectionData *selection_data, gpointer data)
1206 { 1214 {
1207 char *text; 1215 char *text;
1208 GtkIMHtml *imhtml = data; 1216 GtkIMHtml *imhtml = data;
1217 gint length = gtk_selection_data_get_length(selection_data);
1209 1218
1210 if (!gtk_text_view_get_editable(GTK_TEXT_VIEW(imhtml))) 1219 if (!gtk_text_view_get_editable(GTK_TEXT_VIEW(imhtml)))
1211 return; 1220 return;
1212 1221
1213 if (imhtml->wbfo || selection_data->length <= 0) { 1222 if (imhtml->wbfo || length <= 0) {
1214 gtk_clipboard_request_text(clipboard, paste_plaintext_received_cb, imhtml); 1223 gtk_clipboard_request_text(clipboard, paste_plaintext_received_cb, imhtml);
1215 return; 1224 return;
1216 } else { 1225 } else {
1217 #if 0 1226 #if 0
1218 /* Here's some debug code, for figuring out what sent to us over the clipboard. */ 1227 /* Here's some debug code, for figuring out what sent to us over the clipboard. */
1232 } 1241 }
1233 printf("\n"); 1242 printf("\n");
1234 } 1243 }
1235 #endif 1244 #endif
1236 1245
1237 text = g_malloc(selection_data->length + 1); 1246 text = g_malloc(length + 1);
1238 memcpy(text, selection_data->data, selection_data->length); 1247 memcpy(text, gtk_selection_data_get_data(selection_data), length);
1239 /* Make sure the paste data is null-terminated. Given that 1248 /* Make sure the paste data is null-terminated. Given that
1240 * we're passed length (but assume later that it is 1249 * we're passed length (but assume later that it is
1241 * null-terminated), this seems sensible to me. 1250 * null-terminated), this seems sensible to me.
1242 */ 1251 */
1243 text[selection_data->length] = '\0'; 1252 text[length] = '\0';
1244 } 1253 }
1245 1254
1246 #ifdef _WIN32 1255 #ifdef _WIN32
1247 if (gtk_selection_data_get_data_type(selection_data) == gdk_atom_intern("HTML Format", FALSE)) { 1256 if (gtk_selection_data_get_data_type(selection_data) == gdk_atom_intern("HTML Format", FALSE)) {
1248 char *tmp = clipboard_win32_to_html(text); 1257 char *tmp = clipboard_win32_to_html(text);
1249 g_free(text); 1258 g_free(text);
1250 text = tmp; 1259 text = tmp;
1251 } 1260 }
1252 #endif 1261 #endif
1253 1262
1254 if (selection_data->length >= 2 && 1263 if (length >= 2 &&
1255 (*(guint16 *)text == 0xfeff || *(guint16 *)text == 0xfffe)) { 1264 (*(guint16 *)text == 0xfeff || *(guint16 *)text == 0xfffe)) {
1256 /* This is UTF-16 */ 1265 /* This is UTF-16 */
1257 char *utf8 = utf16_to_utf8_with_bom_check(text, selection_data->length); 1266 char *utf8 = utf16_to_utf8_with_bom_check(text, length);
1258 g_free(text); 1267 g_free(text);
1259 text = utf8; 1268 text = utf8;
1260 if (!text) { 1269 if (!text) {
1261 purple_debug_warning("gtkimhtml", "g_convert from UTF-16 failed in paste_received_cb\n"); 1270 purple_debug_warning("gtkimhtml", "g_convert from UTF-16 failed in paste_received_cb\n");
1262 return; 1271 return;
1367 1376
1368 gtk_clipboard_request_contents(clipboard, gdk_atom_intern("text/html", FALSE), 1377 gtk_clipboard_request_contents(clipboard, gdk_atom_intern("text/html", FALSE),
1369 paste_received_cb, imhtml); 1378 paste_received_cb, imhtml);
1370 1379
1371 return TRUE; 1380 return TRUE;
1372 } 1381 }
1373 1382
1374 return FALSE; 1383 return FALSE;
1375 } 1384 }
1376 1385
1377 static void 1386 static void
1613 klass->undo = gtk_imhtml_undo; 1622 klass->undo = gtk_imhtml_undo;
1614 klass->redo = gtk_imhtml_redo; 1623 klass->redo = gtk_imhtml_redo;
1615 1624
1616 gobject_class->finalize = gtk_imhtml_finalize; 1625 gobject_class->finalize = gtk_imhtml_finalize;
1617 widget_class->drag_motion = gtk_text_view_drag_motion; 1626 widget_class->drag_motion = gtk_text_view_drag_motion;
1618 widget_class->expose_event = gtk_imhtml_expose_event; 1627 /* TODO: I _think_ this should be removed for GTK+ 3.0 */
1628 /*widget_class->expose_event = gtk_imhtml_expose_event;*/
1619 parent_size_allocate = widget_class->size_allocate; 1629 parent_size_allocate = widget_class->size_allocate;
1620 widget_class->size_allocate = gtk_imhtml_size_allocate; 1630 widget_class->size_allocate = gtk_imhtml_size_allocate;
1621 parent_style_set = widget_class->style_set; 1631 parent_style_set = widget_class->style_set;
1622 widget_class->style_set = gtk_imhtml_style_set; 1632 widget_class->style_set = gtk_imhtml_style_set;
1623 1633
1675 _("Enable typing notification"), 1685 _("Enable typing notification"),
1676 _("Enable typing notification"), 1686 _("Enable typing notification"),
1677 TRUE, G_PARAM_READABLE)); 1687 TRUE, G_PARAM_READABLE));
1678 1688
1679 binding_set = gtk_binding_set_by_class (parent_class); 1689 binding_set = gtk_binding_set_by_class (parent_class);
1680 gtk_binding_entry_add_signal (binding_set, GDK_b, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_BOLD); 1690 gtk_binding_entry_add_signal (binding_set, GDK_KEY_b, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_BOLD);
1681 gtk_binding_entry_add_signal (binding_set, GDK_i, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_ITALIC); 1691 gtk_binding_entry_add_signal (binding_set, GDK_KEY_i, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_ITALIC);
1682 gtk_binding_entry_add_signal (binding_set, GDK_u, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_UNDERLINE); 1692 gtk_binding_entry_add_signal (binding_set, GDK_KEY_u, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_UNDERLINE);
1683 gtk_binding_entry_add_signal (binding_set, GDK_plus, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_GROW); 1693 gtk_binding_entry_add_signal (binding_set, GDK_KEY_plus, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_GROW);
1684 gtk_binding_entry_add_signal (binding_set, GDK_equal, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_GROW); 1694 gtk_binding_entry_add_signal (binding_set, GDK_KEY_equal, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_GROW);
1685 gtk_binding_entry_add_signal (binding_set, GDK_minus, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_SHRINK); 1695 gtk_binding_entry_add_signal (binding_set, GDK_KEY_minus, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_SHRINK);
1686 binding_set = gtk_binding_set_by_class(klass); 1696 binding_set = gtk_binding_set_by_class(klass);
1687 gtk_binding_entry_add_signal (binding_set, GDK_r, GDK_CONTROL_MASK, "format_function_clear", 0); 1697 gtk_binding_entry_add_signal (binding_set, GDK_KEY_r, GDK_CONTROL_MASK, "format_function_clear", 0);
1688 gtk_binding_entry_add_signal (binding_set, GDK_KP_Enter, 0, "message_send", 0); 1698 gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Enter, 0, "message_send", 0);
1689 gtk_binding_entry_add_signal (binding_set, GDK_Return, 0, "message_send", 0); 1699 gtk_binding_entry_add_signal (binding_set, GDK_KEY_Return, 0, "message_send", 0);
1690 gtk_binding_entry_add_signal (binding_set, GDK_z, GDK_CONTROL_MASK, "undo", 0); 1700 gtk_binding_entry_add_signal (binding_set, GDK_KEY_z, GDK_CONTROL_MASK, "undo", 0);
1691 gtk_binding_entry_add_signal (binding_set, GDK_z, GDK_CONTROL_MASK | GDK_SHIFT_MASK, "redo", 0); 1701 gtk_binding_entry_add_signal (binding_set, GDK_KEY_z, GDK_CONTROL_MASK | GDK_SHIFT_MASK, "redo", 0);
1692 gtk_binding_entry_add_signal (binding_set, GDK_F14, 0, "undo", 0); 1702 gtk_binding_entry_add_signal (binding_set, GDK_KEY_F14, 0, "undo", 0);
1693 gtk_binding_entry_add_signal(binding_set, GDK_v, GDK_CONTROL_MASK | GDK_SHIFT_MASK, "paste", 1, G_TYPE_STRING, "text"); 1703 gtk_binding_entry_add_signal(binding_set, GDK_KEY_v, GDK_CONTROL_MASK | GDK_SHIFT_MASK, "paste", 1, G_TYPE_STRING, "text");
1694 } 1704 }
1695 1705
1696 static void gtk_imhtml_init (GtkIMHtml *imhtml) 1706 static void gtk_imhtml_init (GtkIMHtml *imhtml)
1697 { 1707 {
1698 imhtml->text_buffer = gtk_text_buffer_new(NULL); 1708 imhtml->text_buffer = gtk_text_buffer_new(NULL);
1915 1925
1916 if (gtk_drag_dest_find_target (widget, context, NULL) == GDK_NONE) { 1926 if (gtk_drag_dest_find_target (widget, context, NULL) == GDK_NONE) {
1917 /* can't accept any of the offered targets */ 1927 /* can't accept any of the offered targets */
1918 } else { 1928 } else {
1919 GtkWidget *source_widget; 1929 GtkWidget *source_widget;
1920 suggested_action = context->suggested_action; 1930 suggested_action = gdk_drag_context_get_suggested_action(context);
1921 source_widget = gtk_drag_get_source_widget (context); 1931 source_widget = gtk_drag_get_source_widget (context);
1922 if (source_widget == widget) { 1932 if (source_widget == widget) {
1923 /* Default to MOVE, unless the user has 1933 /* Default to MOVE, unless the user has
1924 * pressed ctrl or alt to affect available actions 1934 * pressed ctrl or alt to affect available actions
1925 */ 1935 */
1926 if ((context->actions & GDK_ACTION_MOVE) != 0) 1936 if ((gdk_drag_context_get_actions(context) & GDK_ACTION_MOVE) != 0)
1927 suggested_action = GDK_ACTION_MOVE; 1937 suggested_action = GDK_ACTION_MOVE;
1928 } 1938 }
1929 } 1939 }
1930 1940
1931 gdk_drag_status (context, suggested_action, time); 1941 gdk_drag_status (context, suggested_action, time);
1932 1942
1933 /* TRUE return means don't propagate the drag motion to parent 1943 /* TRUE return means don't propagate the drag motion to parent
1934 * widgets that may also be drop sites. 1944 * widgets that may also be drop sites.
1935 */ 1945 */
1936 return TRUE; 1946 return TRUE;
1937 } 1947 }
1938 1948
1939 static void 1949 static void
1940 gtk_imhtml_link_drop_cb(GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time, gpointer user_data) 1950 gtk_imhtml_link_drop_cb(GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time, gpointer user_data)
1941 { 1951 {
1953 gtk_imhtml_link_drag_rcv_cb(GtkWidget *widget, GdkDragContext *dc, guint x, guint y, 1963 gtk_imhtml_link_drag_rcv_cb(GtkWidget *widget, GdkDragContext *dc, guint x, guint y,
1954 GtkSelectionData *sd, guint info, guint t, GtkIMHtml *imhtml) 1964 GtkSelectionData *sd, guint info, guint t, GtkIMHtml *imhtml)
1955 { 1965 {
1956 gchar **links; 1966 gchar **links;
1957 gchar *link; 1967 gchar *link;
1958 char *text = (char *)sd->data; 1968 char *text = (char *) gtk_selection_data_get_data(sd);
1959 GtkTextMark *mark = gtk_text_buffer_get_insert(imhtml->text_buffer); 1969 GtkTextMark *mark = gtk_text_buffer_get_insert(imhtml->text_buffer);
1960 GtkTextIter iter; 1970 GtkTextIter iter;
1961 gint i = 0; 1971 gint i = 0;
1972 gint length = gtk_selection_data_get_length(sd);
1962 1973
1963 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, mark); 1974 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, mark);
1964 1975
1965 if(gtk_imhtml_get_editable(imhtml) && sd->data){ 1976 if (gtk_imhtml_get_editable(imhtml) && text) {
1966 switch (info) { 1977 switch (info) {
1967 case GTK_IMHTML_DRAG_URL: 1978 case GTK_IMHTML_DRAG_URL:
1968 /* TODO: Is it really ok to change sd->data...? */ 1979 /* TODO: Is it really ok to change sd->data...? */
1969 purple_str_strip_char((char *)sd->data, '\r'); 1980 purple_str_strip_char(text, '\r');
1970 1981
1971 links = g_strsplit((char *)sd->data, "\n", 0); 1982 links = g_strsplit(text, "\n", 0);
1972 while((link = links[i]) != NULL){ 1983 while ((link = links[i]) != NULL) {
1973 if (gtk_imhtml_is_protocol(link)) { 1984 if (gtk_imhtml_is_protocol(link)) {
1974 gchar *label; 1985 gchar *label;
1975 1986
1976 if(links[i + 1]) 1987 if(links[i + 1])
1977 i++; 1988 i++;
1989 return; 2000 return;
1990 } 2001 }
1991 2002
1992 i++; 2003 i++;
1993 } 2004 }
1994 g_strfreev(links); 2005 g_strfreev(links);
1995 break; 2006 break;
1996 case GTK_IMHTML_DRAG_HTML: 2007 case GTK_IMHTML_DRAG_HTML:
1997 { 2008 {
1998 char *utf8 = NULL; 2009 char *utf8 = NULL;
1999 /* Ewww. This is all because mozilla thinks that text/html is 'for internal use only.' 2010 /* Ewww. This is all because mozilla thinks that text/html is 'for internal use only.'
2005 * the string as utf8 and if that fails we assume it is ucs2 2016 * the string as utf8 and if that fails we assume it is ucs2
2006 * 2017 *
2007 * See also the comment on text/html here: 2018 * See also the comment on text/html here:
2008 * http://mail.gnome.org/archives/gtk-devel-list/2001-September/msg00114.html 2019 * http://mail.gnome.org/archives/gtk-devel-list/2001-September/msg00114.html
2009 */ 2020 */
2010 if (sd->length >= 2 && !g_utf8_validate(text, sd->length - 1, NULL)) { 2021 if (length >= 2 && !g_utf8_validate(text, length - 1, NULL)) {
2011 utf8 = utf16_to_utf8_with_bom_check(text, sd->length); 2022 utf8 = utf16_to_utf8_with_bom_check(text, length);
2012 2023
2013 if (!utf8) { 2024 if (!utf8) {
2014 purple_debug_warning("gtkimhtml", "g_convert from UTF-16 failed in drag_rcv_cb\n"); 2025 purple_debug_warning("gtkimhtml", "g_convert from UTF-16 failed in drag_rcv_cb\n");
2015 return; 2026 return;
2016 } 2027 }
2035 break; 2046 break;
2036 default: 2047 default:
2037 gtk_drag_finish(dc, FALSE, FALSE, t); 2048 gtk_drag_finish(dc, FALSE, FALSE, t);
2038 return; 2049 return;
2039 } 2050 }
2040 gtk_drag_finish(dc, TRUE, (dc->action == GDK_ACTION_MOVE), t); 2051 gtk_drag_finish(dc, TRUE,
2052 gdk_drag_context_get_actions(dc) == GDK_ACTION_MOVE, t);
2041 } else { 2053 } else {
2042 gtk_drag_finish(dc, FALSE, FALSE, t); 2054 gtk_drag_finish(dc, FALSE, FALSE, t);
2043 } 2055 }
2044 } 2056 }
2045 2057
2566 * @return TRUE if the window needs to be scrolled further, FALSE if we're at the bottom. 2578 * @return TRUE if the window needs to be scrolled further, FALSE if we're at the bottom.
2567 */ 2579 */
2568 static gboolean smooth_scroll_cb(gpointer data) 2580 static gboolean smooth_scroll_cb(gpointer data)
2569 { 2581 {
2570 GtkIMHtml *imhtml = data; 2582 GtkIMHtml *imhtml = data;
2571 GtkAdjustment *adj = GTK_TEXT_VIEW(imhtml)->vadjustment; 2583 GtkAdjustment *adj = gtk_text_view_get_vadjustment(GTK_TEXT_VIEW(imhtml));
2572 gdouble max_val = adj->upper - adj->page_size; 2584 gdouble max_val = gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj);
2573 gdouble scroll_val = gtk_adjustment_get_value(adj) + ((max_val - gtk_adjustment_get_value(adj)) / 3); 2585 gdouble scroll_val = gtk_adjustment_get_value(adj) + ((max_val - gtk_adjustment_get_value(adj)) / 3);
2574 2586
2575 g_return_val_if_fail(imhtml->scroll_time != NULL, FALSE); 2587 g_return_val_if_fail(imhtml->scroll_time != NULL, FALSE);
2576 2588
2577 if (g_timer_elapsed(imhtml->scroll_time, NULL) > MAX_SCROLL_TIME || scroll_val >= max_val) { 2589 if (g_timer_elapsed(imhtml->scroll_time, NULL) > MAX_SCROLL_TIME || scroll_val >= max_val) {
2590 } 2602 }
2591 2603
2592 static gboolean scroll_idle_cb(gpointer data) 2604 static gboolean scroll_idle_cb(gpointer data)
2593 { 2605 {
2594 GtkIMHtml *imhtml = data; 2606 GtkIMHtml *imhtml = data;
2595 GtkAdjustment *adj = GTK_TEXT_VIEW(imhtml)->vadjustment; 2607 GtkAdjustment *adj = gtk_text_view_get_vadjustment(GTK_TEXT_VIEW(imhtml));
2596 if(adj) { 2608 if (adj) {
2597 gtk_adjustment_set_value(adj, adj->upper - adj->page_size); 2609 gtk_adjustment_set_value(adj, gtk_adjustment_get_upper(adj) -
2610 gtk_adjustment_get_page_size(adj));
2598 } 2611 }
2599 imhtml->scroll_src = 0; 2612 imhtml->scroll_src = 0;
2600 return FALSE; 2613 return FALSE;
2601 } 2614 }
2602 2615
4274 4287
4275 tags = gtk_text_iter_get_tags(i); 4288 tags = gtk_text_iter_get_tags(i);
4276 4289
4277 for (l = tags; l; l = l->next) { 4290 for (l = tags; l; l = l->next) {
4278 GtkTextTag *tag = l->data; 4291 GtkTextTag *tag = l->data;
4279 4292 gchar *name = NULL;
4280 if (tag->name && !strncmp(tag->name, prefix, len)) 4293
4294 g_object_get(G_OBJECT(tag), "name", &name, NULL);
4295
4296 if (name && !strncmp(name, prefix, len))
4281 gtk_text_buffer_remove_tag(imhtml->text_buffer, tag, i, e); 4297 gtk_text_buffer_remove_tag(imhtml->text_buffer, tag, i, e);
4298
4299 g_free(name);
4282 } 4300 }
4283 4301
4284 g_slist_free(tags); 4302 g_slist_free(tags);
4285 4303
4286 if (homo) 4304 if (homo)
4292 if (gtk_text_iter_begins_tag(&iter, NULL)) { 4310 if (gtk_text_iter_begins_tag(&iter, NULL)) {
4293 tags = gtk_text_iter_get_toggled_tags(&iter, TRUE); 4311 tags = gtk_text_iter_get_toggled_tags(&iter, TRUE);
4294 4312
4295 for (l = tags; l; l = l->next) { 4313 for (l = tags; l; l = l->next) {
4296 GtkTextTag *tag = l->data; 4314 GtkTextTag *tag = l->data;
4297 4315 gchar *name = NULL;
4298 if (tag->name && !strncmp(tag->name, prefix, len)) 4316
4317 g_object_get(G_OBJECT(tag), "name", &name, NULL);
4318
4319 if (name && !strncmp(name, prefix, len))
4299 gtk_text_buffer_remove_tag(imhtml->text_buffer, tag, &iter, e); 4320 gtk_text_buffer_remove_tag(imhtml->text_buffer, tag, &iter, e);
4321
4322 g_free(name);
4300 } 4323 }
4301 4324
4302 g_slist_free(tags); 4325 g_slist_free(tags);
4303 } 4326 }
4304 } 4327 }
4415 if (tag && /* Remove the formatting only if */ 4438 if (tag && /* Remove the formatting only if */
4416 gtk_text_iter_starts_word(start) && /* beginning of a word */ 4439 gtk_text_iter_starts_word(start) && /* beginning of a word */
4417 gtk_text_iter_begins_tag(start, tag) && /* the tag starts with the selection */ 4440 gtk_text_iter_begins_tag(start, tag) && /* the tag starts with the selection */
4418 (!gtk_text_iter_has_tag(end, tag) || /* the tag ends within the selection */ 4441 (!gtk_text_iter_has_tag(end, tag) || /* the tag ends within the selection */
4419 gtk_text_iter_ends_tag(end, tag))) { 4442 gtk_text_iter_ends_tag(end, tag))) {
4443 gchar *name = NULL;
4444
4445 g_object_get(G_OBJECT(tag), "name", &name, NULL);
4420 gtk_text_buffer_remove_tag(imhtml->text_buffer, tag, start, end); 4446 gtk_text_buffer_remove_tag(imhtml->text_buffer, tag, start, end);
4421 if (tag->name && 4447
4422 strncmp(tag->name, "LINK ", 5) == 0 && imhtml->edit.link) { 4448 if (name && strncmp(name, "LINK ", 5) == 0 && imhtml->edit.link) {
4423 gtk_imhtml_toggle_link(imhtml, NULL); 4449 gtk_imhtml_toggle_link(imhtml, NULL);
4424 } 4450 }
4451
4452 g_free(name);
4425 } 4453 }
4426 } 4454 }
4427 g_slist_free(tags); 4455 g_slist_free(tags);
4428 } 4456 }
4429 4457
4641 else 4669 else
4642 tags = gtk_text_iter_get_tags(&iter); 4670 tags = gtk_text_iter_get_tags(&iter);
4643 4671
4644 for (l = tags; l != NULL; l = l->next) { 4672 for (l = tags; l != NULL; l = l->next) {
4645 GtkTextTag *tag = GTK_TEXT_TAG(l->data); 4673 GtkTextTag *tag = GTK_TEXT_TAG(l->data);
4646 4674 gchar *name = NULL;
4647 if (tag->name) { 4675
4648 if (strcmp(tag->name, "BOLD") == 0) 4676 g_object_get(G_OBJECT(tag), "name", &name, NULL);
4677
4678 if (name) {
4679 if (strcmp(name, "BOLD") == 0)
4649 imhtml->edit.bold = TRUE; 4680 imhtml->edit.bold = TRUE;
4650 else if (strcmp(tag->name, "ITALICS") == 0) 4681 else if (strcmp(name, "ITALICS") == 0)
4651 imhtml->edit.italic = TRUE; 4682 imhtml->edit.italic = TRUE;
4652 else if (strcmp(tag->name, "UNDERLINE") == 0) 4683 else if (strcmp(name, "UNDERLINE") == 0)
4653 imhtml->edit.underline = TRUE; 4684 imhtml->edit.underline = TRUE;
4654 else if (strcmp(tag->name, "STRIKE") == 0) 4685 else if (strcmp(name, "STRIKE") == 0)
4655 imhtml->edit.strike = TRUE; 4686 imhtml->edit.strike = TRUE;
4656 else if (strncmp(tag->name, "FORECOLOR ", 10) == 0) 4687 else if (strncmp(name, "FORECOLOR ", 10) == 0)
4657 imhtml->edit.forecolor = g_strdup(&(tag->name)[10]); 4688 imhtml->edit.forecolor = g_strdup(&(name)[10]);
4658 else if (strncmp(tag->name, "BACKCOLOR ", 10) == 0) 4689 else if (strncmp(name, "BACKCOLOR ", 10) == 0)
4659 imhtml->edit.backcolor = g_strdup(&(tag->name)[10]); 4690 imhtml->edit.backcolor = g_strdup(&(name)[10]);
4660 else if (strncmp(tag->name, "FONT FACE ", 10) == 0) 4691 else if (strncmp(name, "FONT FACE ", 10) == 0)
4661 imhtml->edit.fontface = g_strdup(&(tag->name)[10]); 4692 imhtml->edit.fontface = g_strdup(&(name)[10]);
4662 else if (strncmp(tag->name, "FONT SIZE ", 10) == 0) 4693 else if (strncmp(name, "FONT SIZE ", 10) == 0)
4663 imhtml->edit.fontsize = strtol(&(tag->name)[10], NULL, 10); 4694 imhtml->edit.fontsize = strtol(&(name)[10], NULL, 10);
4664 else if ((strncmp(tag->name, "LINK ", 5) == 0) && !gtk_text_iter_is_end(&iter)) 4695 else if ((strncmp(name, "LINK ", 5) == 0) && !gtk_text_iter_is_end(&iter))
4665 imhtml->edit.link = tag; 4696 imhtml->edit.link = tag;
4666 } 4697 }
4698
4699 g_free(name);
4667 } 4700 }
4668 4701
4669 g_slist_free(tags); 4702 g_slist_free(tags);
4670 } 4703 }
4671 4704
4952 gtk_text_buffer_begin_user_action(imhtml->text_buffer); 4985 gtk_text_buffer_begin_user_action(imhtml->text_buffer);
4953 gtk_imhtml_insert_smiley_at_iter(imhtml, sml, smiley, &iter); 4986 gtk_imhtml_insert_smiley_at_iter(imhtml, sml, smiley, &iter);
4954 gtk_text_buffer_end_user_action(imhtml->text_buffer); 4987 gtk_text_buffer_end_user_action(imhtml->text_buffer);
4955 } 4988 }
4956 4989
4990 /* TODO: I think this can be removed for GTK+ 3.0... */
4991 #if 0
4957 static gboolean 4992 static gboolean
4958 image_expose(GtkWidget *widget, GdkEventExpose *event, gpointer user_data) 4993 image_expose(GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
4959 { 4994 {
4960 GTK_WIDGET_CLASS(GTK_WIDGET_GET_CLASS(widget))->expose_event(widget, event); 4995 GTK_WIDGET_CLASS(GTK_WIDGET_GET_CLASS(widget))->expose_event(widget, event);
4961 4996
4962 return TRUE; 4997 return TRUE;
4963 } 4998 }
4999 #endif
4964 5000
4965 /* In case the smiley gets removed from the imhtml before it gets removed from the queue */ 5001 /* In case the smiley gets removed from the imhtml before it gets removed from the queue */
4966 static void animated_smiley_destroy_cb(GtkObject *widget, GtkIMHtml *imhtml) 5002 static void animated_smiley_destroy_cb(GtkWidget *widget, GtkIMHtml *imhtml)
4967 { 5003 {
4968 GList *l = imhtml->animations->head; 5004 GList *l = imhtml->animations->head;
4969 while (l) { 5005 while (l) {
4970 GList *next = l->next; 5006 GList *next = l->next;
4971 if (l->data == widget) { 5007 if (l->data == widget) {
5056 gtk_image_set_from_pixbuf(image, copy); 5092 gtk_image_set_from_pixbuf(image, copy);
5057 g_object_unref(G_OBJECT(copy)); 5093 g_object_unref(G_OBJECT(copy));
5058 } 5094 }
5059 } 5095 }
5060 } else { 5096 } else {
5061 imhtml->num_animations++; 5097 imhtml->num_animations++;
5062 } 5098 }
5063 g_signal_connect(G_OBJECT(icon), "destroy", G_CALLBACK(animated_smiley_destroy_cb), imhtml); 5099 g_signal_connect(G_OBJECT(icon), "destroy", G_CALLBACK(animated_smiley_destroy_cb), imhtml);
5064 g_queue_push_tail(imhtml->animations, icon); 5100 g_queue_push_tail(imhtml->animations, icon);
5065 } 5101 }
5066 } 5102 }
5080 5116
5081 /* This catches the expose events generated by animated 5117 /* This catches the expose events generated by animated
5082 * images, and ensures that they are handled by the image 5118 * images, and ensures that they are handled by the image
5083 * itself, without propagating to the textview and causing 5119 * itself, without propagating to the textview and causing
5084 * a complete refresh */ 5120 * a complete refresh */
5121 /* TODO: I think this should be removed for GTK+ 3.0?
5085 g_signal_connect(G_OBJECT(icon), "expose-event", G_CALLBACK(image_expose), NULL); 5122 g_signal_connect(G_OBJECT(icon), "expose-event", G_CALLBACK(image_expose), NULL);
5123 */
5086 5124
5087 gtk_widget_show(icon); 5125 gtk_widget_show(icon);
5088 if (ebox) 5126 if (ebox)
5089 gtk_container_add(GTK_CONTAINER(ebox), icon); 5127 gtk_container_add(GTK_CONTAINER(ebox), icon);
5090 gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), ebox ? ebox : icon, anchor); 5128 gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), ebox ? ebox : icon, anchor);
5174 imhtml->scalables = g_list_append(imhtml->scalables, sd); 5212 imhtml->scalables = g_list_append(imhtml->scalables, sd);
5175 } 5213 }
5176 5214
5177 static const gchar *tag_to_html_start(GtkTextTag *tag) 5215 static const gchar *tag_to_html_start(GtkTextTag *tag)
5178 { 5216 {
5179 const gchar *name;
5180 static gchar buf[1024]; 5217 static gchar buf[1024];
5181 5218 gchar *name = NULL;
5182 name = tag->name; 5219
5183 g_return_val_if_fail(name != NULL, ""); 5220 g_return_val_if_fail(name != NULL, "");
5221 g_object_get(G_OBJECT(tag), "name", &name, NULL);
5184 5222
5185 if (strcmp(name, "BOLD") == 0) { 5223 if (strcmp(name, "BOLD") == 0) {
5224 g_free(name);
5186 return "<b>"; 5225 return "<b>";
5187 } else if (strcmp(name, "ITALICS") == 0) { 5226 } else if (strcmp(name, "ITALICS") == 0) {
5227 g_free(name);
5188 return "<i>"; 5228 return "<i>";
5189 } else if (strcmp(name, "UNDERLINE") == 0) { 5229 } else if (strcmp(name, "UNDERLINE") == 0) {
5230 g_free(name);
5190 return "<u>"; 5231 return "<u>";
5191 } else if (strcmp(name, "STRIKE") == 0) { 5232 } else if (strcmp(name, "STRIKE") == 0) {
5233 g_free(name);
5192 return "<s>"; 5234 return "<s>";
5193 } else if (strncmp(name, "LINK ", 5) == 0) { 5235 } else if (strncmp(name, "LINK ", 5) == 0) {
5194 char *tmp = g_object_get_data(G_OBJECT(tag), "link_url"); 5236 char *tmp = g_object_get_data(G_OBJECT(tag), "link_url");
5237
5238 g_free(name);
5239
5195 if (tmp) { 5240 if (tmp) {
5196 g_snprintf(buf, sizeof(buf), "<a href=\"%s\">", tmp); 5241 g_snprintf(buf, sizeof(buf), "<a href=\"%s\">", tmp);
5197 buf[sizeof(buf)-1] = '\0'; 5242 buf[sizeof(buf)-1] = '\0';
5198 return buf; 5243 return buf;
5199 } else { 5244 } else {
5200 return ""; 5245 return "";
5201 } 5246 }
5202 } else if (strncmp(name, "FORECOLOR ", 10) == 0) { 5247 } else if (strncmp(name, "FORECOLOR ", 10) == 0) {
5203 g_snprintf(buf, sizeof(buf), "<font color=\"%s\">", &name[10]); 5248 g_snprintf(buf, sizeof(buf), "<font color=\"%s\">", &name[10]);
5249
5250 g_free(name);
5251
5204 return buf; 5252 return buf;
5205 } else if (strncmp(name, "BACKCOLOR ", 10) == 0) { 5253 } else if (strncmp(name, "BACKCOLOR ", 10) == 0) {
5206 g_snprintf(buf, sizeof(buf), "<font back=\"%s\">", &name[10]); 5254 g_snprintf(buf, sizeof(buf), "<font back=\"%s\">", &name[10]);
5255 g_free(name);
5256
5207 return buf; 5257 return buf;
5208 } else if (strncmp(name, "BACKGROUND ", 10) == 0) { 5258 } else if (strncmp(name, "BACKGROUND ", 10) == 0) {
5209 g_snprintf(buf, sizeof(buf), "<body bgcolor=\"%s\">", &name[11]); 5259 g_snprintf(buf, sizeof(buf), "<body bgcolor=\"%s\">", &name[11]);
5260 g_free(name);
5261
5210 return buf; 5262 return buf;
5211 } else if (strncmp(name, "FONT FACE ", 10) == 0) { 5263 } else if (strncmp(name, "FONT FACE ", 10) == 0) {
5212 g_snprintf(buf, sizeof(buf), "<font face=\"%s\">", &name[10]); 5264 g_snprintf(buf, sizeof(buf), "<font face=\"%s\">", &name[10]);
5265 g_free(name);
5266
5213 return buf; 5267 return buf;
5214 } else if (strncmp(name, "FONT SIZE ", 10) == 0) { 5268 } else if (strncmp(name, "FONT SIZE ", 10) == 0) {
5215 g_snprintf(buf, sizeof(buf), "<font size=\"%s\">", &name[10]); 5269 g_snprintf(buf, sizeof(buf), "<font size=\"%s\">", &name[10]);
5270 g_free(name);
5271
5216 return buf; 5272 return buf;
5217 } else { 5273 } else {
5218 char *str = buf; 5274 char *str = buf;
5219 gboolean isset; 5275 gboolean isset;
5220 int ivalue = 0; 5276 int ivalue = 0;
5273 empty = FALSE; 5329 empty = FALSE;
5274 } 5330 }
5275 } 5331 }
5276 5332
5277 g_snprintf(str, sizeof(buf) - (str - buf), "'>"); 5333 g_snprintf(str, sizeof(buf) - (str - buf), "'>");
5334 g_free(name);
5278 5335
5279 return (empty ? "" : buf); 5336 return (empty ? "" : buf);
5280 } 5337 }
5281 } 5338 }
5282 5339
5283 static const gchar *tag_to_html_end(GtkTextTag *tag) 5340 static const gchar *tag_to_html_end(GtkTextTag *tag)
5284 { 5341 {
5285 const gchar *name; 5342 gchar *name;
5286 5343
5287 name = tag->name;
5288 g_return_val_if_fail(name != NULL, ""); 5344 g_return_val_if_fail(name != NULL, "");
5345 g_object_get(G_OBJECT(tag), "name", &name, NULL);
5289 5346
5290 if (strcmp(name, "BOLD") == 0) { 5347 if (strcmp(name, "BOLD") == 0) {
5348 g_free(name);
5291 return "</b>"; 5349 return "</b>";
5292 } else if (strcmp(name, "ITALICS") == 0) { 5350 } else if (strcmp(name, "ITALICS") == 0) {
5351 g_free(name);
5293 return "</i>"; 5352 return "</i>";
5294 } else if (strcmp(name, "UNDERLINE") == 0) { 5353 } else if (strcmp(name, "UNDERLINE") == 0) {
5354 g_free(name);
5295 return "</u>"; 5355 return "</u>";
5296 } else if (strcmp(name, "STRIKE") == 0) { 5356 } else if (strcmp(name, "STRIKE") == 0) {
5357 g_free(name);
5297 return "</s>"; 5358 return "</s>";
5298 } else if (strncmp(name, "LINK ", 5) == 0) { 5359 } else if (strncmp(name, "LINK ", 5) == 0) {
5360 g_free(name);
5299 return "</a>"; 5361 return "</a>";
5300 } else if (strncmp(name, "FORECOLOR ", 10) == 0) { 5362 } else if (strncmp(name, "FORECOLOR ", 10) == 0) {
5363 g_free(name);
5301 return "</font>"; 5364 return "</font>";
5302 } else if (strncmp(name, "BACKCOLOR ", 10) == 0) { 5365 } else if (strncmp(name, "BACKCOLOR ", 10) == 0) {
5366 g_free(name);
5303 return "</font>"; 5367 return "</font>";
5304 } else if (strncmp(name, "BACKGROUND ", 10) == 0) { 5368 } else if (strncmp(name, "BACKGROUND ", 10) == 0) {
5369 g_free(name);
5305 return "</body>"; 5370 return "</body>";
5306 } else if (strncmp(name, "FONT FACE ", 10) == 0) { 5371 } else if (strncmp(name, "FONT FACE ", 10) == 0) {
5372 g_free(name);
5307 return "</font>"; 5373 return "</font>";
5308 } else if (strncmp(name, "FONT SIZE ", 10) == 0) { 5374 } else if (strncmp(name, "FONT SIZE ", 10) == 0) {
5375 g_free(name);
5309 return "</font>"; 5376 return "</font>";
5310 } else { 5377 } else {
5311 const char *props[] = {"weight-set", "foreground-set", "background-set", 5378 const char *props[] = {"weight-set", "foreground-set", "background-set",
5312 "size-set", "underline-set", NULL}; 5379 "size-set", "underline-set", NULL};
5313 int i; 5380 int i;
5315 gboolean set = FALSE; 5382 gboolean set = FALSE;
5316 g_object_get(G_OBJECT(tag), props[i], &set, NULL); 5383 g_object_get(G_OBJECT(tag), props[i], &set, NULL);
5317 if (set) 5384 if (set)
5318 return "</span>"; 5385 return "</span>";
5319 } 5386 }
5387
5388 g_free(name);
5320 5389
5321 return ""; 5390 return "";
5322 } 5391 }
5323 } 5392 }
5324 5393

mercurial