| 497 |
497 |
| 498 static gint |
498 static gint |
| 499 gtk_imhtml_tip_paint (GtkIMHtml *imhtml) |
499 gtk_imhtml_tip_paint (GtkIMHtml *imhtml) |
| 500 { |
500 { |
| 501 PangoLayout *layout; |
501 PangoLayout *layout; |
| |
502 cairo_t *cr = gdk_cairo_create(gtk_widget_get_window(imhtml->tip_window)); |
| 502 |
503 |
| 503 g_return_val_if_fail(GTK_IS_IMHTML(imhtml), FALSE); |
504 g_return_val_if_fail(GTK_IS_IMHTML(imhtml), FALSE); |
| 504 |
505 |
| 505 layout = gtk_widget_create_pango_layout(imhtml->tip_window, imhtml->tip); |
506 layout = gtk_widget_create_pango_layout(imhtml->tip_window, imhtml->tip); |
| 506 |
507 |
| 507 gtk_paint_flat_box (imhtml->tip_window->style, imhtml->tip_window->window, |
508 gtk_paint_flat_box (gtk_widget_get_style(imhtml->tip_window), cr, |
| 508 GTK_STATE_NORMAL, GTK_SHADOW_OUT, NULL, imhtml->tip_window, |
509 GTK_STATE_NORMAL, GTK_SHADOW_OUT, imhtml->tip_window, "tooltip", |
| 509 "tooltip", 0, 0, -1, -1); |
510 0, 0, -1, -1); |
| 510 |
511 |
| 511 gtk_paint_layout (imhtml->tip_window->style, imhtml->tip_window->window, GTK_STATE_NORMAL, |
512 gtk_paint_layout (gtk_widget_get_style(imhtml->tip_window), cr, |
| 512 FALSE, NULL, imhtml->tip_window, NULL, 4, 4, layout); |
513 GTK_STATE_NORMAL, TRUE, imhtml->tip_window, NULL, 4, 4, layout); |
| 513 |
514 |
| |
515 cairo_destroy(cr); |
| 514 g_object_unref(layout); |
516 g_object_unref(layout); |
| 515 return FALSE; |
517 return FALSE; |
| 516 } |
518 } |
| 517 |
519 |
| 518 static gint |
520 static gint |
| 520 { |
522 { |
| 521 GtkIMHtml *imhtml = data; |
523 GtkIMHtml *imhtml = data; |
| 522 PangoFontMetrics *font_metrics; |
524 PangoFontMetrics *font_metrics; |
| 523 PangoLayout *layout; |
525 PangoLayout *layout; |
| 524 PangoFont *font; |
526 PangoFont *font; |
| 525 |
527 GtkStyle *style = gtk_widget_get_style(imhtml->tip_window); |
| |
528 GtkAllocation allocation; |
| 526 gint gap, x, y, h, w, scr_w, baseline_skip; |
529 gint gap, x, y, h, w, scr_w, baseline_skip; |
| 527 |
530 |
| 528 g_return_val_if_fail(GTK_IS_IMHTML(imhtml), FALSE); |
531 g_return_val_if_fail(GTK_IS_IMHTML(imhtml), FALSE); |
| 529 |
532 |
| 530 if (!imhtml->tip || !GTK_WIDGET_DRAWABLE (GTK_WIDGET(imhtml))) { |
533 gtk_widget_get_allocation(GTK_WIDGET(imhtml), &allocation); |
| |
534 |
| |
535 if (!imhtml->tip || !gtk_widget_is_drawable(GTK_WIDGET(imhtml))) { |
| 531 imhtml->tip_timer = 0; |
536 imhtml->tip_timer = 0; |
| 532 return FALSE; |
537 return FALSE; |
| 533 } |
538 } |
| 534 |
539 |
| 535 if (imhtml->tip_window){ |
540 if (imhtml->tip_window){ |
| 549 G_CALLBACK (gtk_imhtml_tip_paint), imhtml); |
554 G_CALLBACK (gtk_imhtml_tip_paint), imhtml); |
| 550 |
555 |
| 551 gtk_widget_ensure_style (imhtml->tip_window); |
556 gtk_widget_ensure_style (imhtml->tip_window); |
| 552 layout = gtk_widget_create_pango_layout(imhtml->tip_window, imhtml->tip); |
557 layout = gtk_widget_create_pango_layout(imhtml->tip_window, imhtml->tip); |
| 553 font = pango_context_load_font(pango_layout_get_context(layout), |
558 font = pango_context_load_font(pango_layout_get_context(layout), |
| 554 imhtml->tip_window->style->font_desc); |
559 style->font_desc); |
| 555 |
560 |
| 556 if (font == NULL) { |
561 if (font == NULL) { |
| 557 char *tmp = pango_font_description_to_string( |
562 char *tmp = pango_font_description_to_string(style->font_desc); |
| 558 imhtml->tip_window->style->font_desc); |
|
| 559 |
563 |
| 560 purple_debug(PURPLE_DEBUG_ERROR, "gtk_imhtml_tip", |
564 purple_debug(PURPLE_DEBUG_ERROR, "gtk_imhtml_tip", |
| 561 "pango_context_load_font() couldn't load font: '%s'\n", |
565 "pango_context_load_font() couldn't load font: '%s'\n", |
| 562 tmp); |
566 tmp); |
| 563 g_free(tmp); |
567 g_free(tmp); |
| 619 gboolean hand = TRUE; |
623 gboolean hand = TRUE; |
| 620 GdkCursor *cursor = NULL; |
624 GdkCursor *cursor = NULL; |
| 621 |
625 |
| 622 oldprelit_tag = GTK_IMHTML(imhtml)->prelit_tag; |
626 oldprelit_tag = GTK_IMHTML(imhtml)->prelit_tag; |
| 623 |
627 |
| 624 gdk_window_get_pointer(GTK_WIDGET(imhtml)->window, NULL, NULL, NULL); |
628 gdk_window_get_pointer(gtk_widget_get_window(GTK_WIDGET(imhtml)), NULL, NULL, NULL); |
| 625 gtk_text_view_window_to_buffer_coords(GTK_TEXT_VIEW(imhtml), GTK_TEXT_WINDOW_WIDGET, |
629 gtk_text_view_window_to_buffer_coords(GTK_TEXT_VIEW(imhtml), GTK_TEXT_WINDOW_WIDGET, |
| 626 event->x, event->y, &x, &y); |
630 event->x, event->y, &x, &y); |
| 627 gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(imhtml), &iter, x, y); |
631 gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(imhtml), &iter, x, y); |
| 628 tags = gtk_text_iter_get_tags(&iter); |
632 tags = gtk_text_iter_get_tags(&iter); |
| 629 |
633 |
| 1184 } |
1193 } |
| 1185 printf("\n"); |
1194 printf("\n"); |
| 1186 } |
1195 } |
| 1187 #endif |
1196 #endif |
| 1188 |
1197 |
| 1189 text = g_malloc(selection_data->length + 1); |
1198 text = g_malloc(length + 1); |
| 1190 memcpy(text, selection_data->data, selection_data->length); |
1199 memcpy(text, gtk_selection_data_get_data(selection_data), length); |
| 1191 /* Make sure the paste data is null-terminated. Given that |
1200 /* Make sure the paste data is null-terminated. Given that |
| 1192 * we're passed length (but assume later that it is |
1201 * we're passed length (but assume later that it is |
| 1193 * null-terminated), this seems sensible to me. |
1202 * null-terminated), this seems sensible to me. |
| 1194 */ |
1203 */ |
| 1195 text[selection_data->length] = '\0'; |
1204 text[length] = '\0'; |
| 1196 } |
1205 } |
| 1197 |
1206 |
| 1198 #ifdef _WIN32 |
1207 #ifdef _WIN32 |
| 1199 if (gtk_selection_data_get_data_type(selection_data) == gdk_atom_intern("HTML Format", FALSE)) { |
1208 if (gtk_selection_data_get_data_type(selection_data) == gdk_atom_intern("HTML Format", FALSE)) { |
| 1200 char *tmp = clipboard_win32_to_html(text); |
1209 char *tmp = clipboard_win32_to_html(text); |
| 1201 g_free(text); |
1210 g_free(text); |
| 1202 text = tmp; |
1211 text = tmp; |
| 1203 } |
1212 } |
| 1204 #endif |
1213 #endif |
| 1205 |
1214 |
| 1206 if (selection_data->length >= 2 && |
1215 if (length >= 2 && |
| 1207 (*(guint16 *)text == 0xfeff || *(guint16 *)text == 0xfffe)) { |
1216 (*(guint16 *)text == 0xfeff || *(guint16 *)text == 0xfffe)) { |
| 1208 /* This is UTF-16 */ |
1217 /* This is UTF-16 */ |
| 1209 char *utf8 = utf16_to_utf8_with_bom_check(text, selection_data->length); |
1218 char *utf8 = utf16_to_utf8_with_bom_check(text, length); |
| 1210 g_free(text); |
1219 g_free(text); |
| 1211 text = utf8; |
1220 text = utf8; |
| 1212 if (!text) { |
1221 if (!text) { |
| 1213 purple_debug_warning("gtkimhtml", "g_convert from UTF-16 failed in paste_received_cb\n"); |
1222 purple_debug_warning("gtkimhtml", "g_convert from UTF-16 failed in paste_received_cb\n"); |
| 1214 return; |
1223 return; |
| 1627 _("Enable typing notification"), |
1637 _("Enable typing notification"), |
| 1628 _("Enable typing notification"), |
1638 _("Enable typing notification"), |
| 1629 TRUE, G_PARAM_READABLE)); |
1639 TRUE, G_PARAM_READABLE)); |
| 1630 |
1640 |
| 1631 binding_set = gtk_binding_set_by_class (parent_class); |
1641 binding_set = gtk_binding_set_by_class (parent_class); |
| 1632 gtk_binding_entry_add_signal (binding_set, GDK_b, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_BOLD); |
1642 gtk_binding_entry_add_signal (binding_set, GDK_KEY_b, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_BOLD); |
| 1633 gtk_binding_entry_add_signal (binding_set, GDK_i, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_ITALIC); |
1643 gtk_binding_entry_add_signal (binding_set, GDK_KEY_i, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_ITALIC); |
| 1634 gtk_binding_entry_add_signal (binding_set, GDK_u, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_UNDERLINE); |
1644 gtk_binding_entry_add_signal (binding_set, GDK_KEY_u, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_UNDERLINE); |
| 1635 gtk_binding_entry_add_signal (binding_set, GDK_plus, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_GROW); |
1645 gtk_binding_entry_add_signal (binding_set, GDK_KEY_plus, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_GROW); |
| 1636 gtk_binding_entry_add_signal (binding_set, GDK_equal, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_GROW); |
1646 gtk_binding_entry_add_signal (binding_set, GDK_KEY_equal, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_GROW); |
| 1637 gtk_binding_entry_add_signal (binding_set, GDK_minus, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_SHRINK); |
1647 gtk_binding_entry_add_signal (binding_set, GDK_KEY_minus, GDK_CONTROL_MASK, "format_function_toggle", 1, G_TYPE_INT, GTK_IMHTML_SHRINK); |
| 1638 binding_set = gtk_binding_set_by_class(klass); |
1648 binding_set = gtk_binding_set_by_class(klass); |
| 1639 gtk_binding_entry_add_signal (binding_set, GDK_r, GDK_CONTROL_MASK, "format_function_clear", 0); |
1649 gtk_binding_entry_add_signal (binding_set, GDK_KEY_r, GDK_CONTROL_MASK, "format_function_clear", 0); |
| 1640 gtk_binding_entry_add_signal (binding_set, GDK_KP_Enter, 0, "message_send", 0); |
1650 gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Enter, 0, "message_send", 0); |
| 1641 gtk_binding_entry_add_signal (binding_set, GDK_Return, 0, "message_send", 0); |
1651 gtk_binding_entry_add_signal (binding_set, GDK_KEY_Return, 0, "message_send", 0); |
| 1642 gtk_binding_entry_add_signal (binding_set, GDK_z, GDK_CONTROL_MASK, "undo", 0); |
1652 gtk_binding_entry_add_signal (binding_set, GDK_KEY_z, GDK_CONTROL_MASK, "undo", 0); |
| 1643 gtk_binding_entry_add_signal (binding_set, GDK_z, GDK_CONTROL_MASK | GDK_SHIFT_MASK, "redo", 0); |
1653 gtk_binding_entry_add_signal (binding_set, GDK_KEY_z, GDK_CONTROL_MASK | GDK_SHIFT_MASK, "redo", 0); |
| 1644 gtk_binding_entry_add_signal (binding_set, GDK_F14, 0, "undo", 0); |
1654 gtk_binding_entry_add_signal (binding_set, GDK_KEY_F14, 0, "undo", 0); |
| 1645 gtk_binding_entry_add_signal(binding_set, GDK_v, GDK_CONTROL_MASK | GDK_SHIFT_MASK, "paste", 1, G_TYPE_STRING, "text"); |
1655 gtk_binding_entry_add_signal(binding_set, GDK_KEY_v, GDK_CONTROL_MASK | GDK_SHIFT_MASK, "paste", 1, G_TYPE_STRING, "text"); |
| 1646 } |
1656 } |
| 1647 |
1657 |
| 1648 static void gtk_imhtml_init (GtkIMHtml *imhtml) |
1658 static void gtk_imhtml_init (GtkIMHtml *imhtml) |
| 1649 { |
1659 { |
| 1650 imhtml->text_buffer = gtk_text_buffer_new(NULL); |
1660 imhtml->text_buffer = gtk_text_buffer_new(NULL); |
| 1867 |
1877 |
| 1868 if (gtk_drag_dest_find_target (widget, context, NULL) == GDK_NONE) { |
1878 if (gtk_drag_dest_find_target (widget, context, NULL) == GDK_NONE) { |
| 1869 /* can't accept any of the offered targets */ |
1879 /* can't accept any of the offered targets */ |
| 1870 } else { |
1880 } else { |
| 1871 GtkWidget *source_widget; |
1881 GtkWidget *source_widget; |
| 1872 suggested_action = context->suggested_action; |
1882 suggested_action = gdk_drag_context_get_suggested_action(context); |
| 1873 source_widget = gtk_drag_get_source_widget (context); |
1883 source_widget = gtk_drag_get_source_widget (context); |
| 1874 if (source_widget == widget) { |
1884 if (source_widget == widget) { |
| 1875 /* Default to MOVE, unless the user has |
1885 /* Default to MOVE, unless the user has |
| 1876 * pressed ctrl or alt to affect available actions |
1886 * pressed ctrl or alt to affect available actions |
| 1877 */ |
1887 */ |
| 1878 if ((context->actions & GDK_ACTION_MOVE) != 0) |
1888 if ((gdk_drag_context_get_actions(context) & GDK_ACTION_MOVE) != 0) |
| 1879 suggested_action = GDK_ACTION_MOVE; |
1889 suggested_action = GDK_ACTION_MOVE; |
| 1880 } |
1890 } |
| 1881 } |
1891 } |
| 1882 |
1892 |
| 1883 gdk_drag_status (context, suggested_action, time); |
1893 gdk_drag_status (context, suggested_action, time); |
| 1905 gtk_imhtml_link_drag_rcv_cb(GtkWidget *widget, GdkDragContext *dc, guint x, guint y, |
1915 gtk_imhtml_link_drag_rcv_cb(GtkWidget *widget, GdkDragContext *dc, guint x, guint y, |
| 1906 GtkSelectionData *sd, guint info, guint t, GtkIMHtml *imhtml) |
1916 GtkSelectionData *sd, guint info, guint t, GtkIMHtml *imhtml) |
| 1907 { |
1917 { |
| 1908 gchar **links; |
1918 gchar **links; |
| 1909 gchar *link; |
1919 gchar *link; |
| 1910 char *text = (char *)sd->data; |
1920 char *text = (char *) gtk_selection_data_get_data(sd); |
| 1911 GtkTextMark *mark = gtk_text_buffer_get_insert(imhtml->text_buffer); |
1921 GtkTextMark *mark = gtk_text_buffer_get_insert(imhtml->text_buffer); |
| 1912 GtkTextIter iter; |
1922 GtkTextIter iter; |
| 1913 gint i = 0; |
1923 gint i = 0; |
| |
1924 gint length = gtk_selection_data_get_length(sd); |
| 1914 |
1925 |
| 1915 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, mark); |
1926 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, mark); |
| 1916 |
1927 |
| 1917 if(gtk_imhtml_get_editable(imhtml) && sd->data){ |
1928 if(gtk_imhtml_get_editable(imhtml) && text){ |
| 1918 switch (info) { |
1929 switch (info) { |
| 1919 case GTK_IMHTML_DRAG_URL: |
1930 case GTK_IMHTML_DRAG_URL: |
| 1920 /* TODO: Is it really ok to change sd->data...? */ |
1931 /* TODO: Is it really ok to change sd->data...? */ |
| 1921 purple_str_strip_char((char *)sd->data, '\r'); |
1932 purple_str_strip_char(text, '\r'); |
| 1922 |
1933 |
| 1923 links = g_strsplit((char *)sd->data, "\n", 0); |
1934 links = g_strsplit(text, "\n", 0); |
| 1924 while((link = links[i]) != NULL){ |
1935 while((link = links[i]) != NULL){ |
| 1925 if (gtk_imhtml_is_protocol(link)) { |
1936 if (gtk_imhtml_is_protocol(link)) { |
| 1926 gchar *label; |
1937 gchar *label; |
| 1927 |
1938 |
| 1928 if(links[i + 1]) |
1939 if(links[i + 1]) |
| 4325 if (tag && /* Remove the formatting only if */ |
4348 if (tag && /* Remove the formatting only if */ |
| 4326 gtk_text_iter_starts_word(start) && /* beginning of a word */ |
4349 gtk_text_iter_starts_word(start) && /* beginning of a word */ |
| 4327 gtk_text_iter_begins_tag(start, tag) && /* the tag starts with the selection */ |
4350 gtk_text_iter_begins_tag(start, tag) && /* the tag starts with the selection */ |
| 4328 (!gtk_text_iter_has_tag(end, tag) || /* the tag ends within the selection */ |
4351 (!gtk_text_iter_has_tag(end, tag) || /* the tag ends within the selection */ |
| 4329 gtk_text_iter_ends_tag(end, tag))) { |
4352 gtk_text_iter_ends_tag(end, tag))) { |
| |
4353 gchar *name; |
| |
4354 |
| |
4355 g_object_get(G_OBJECT(tag), "name", &name, NULL); |
| 4330 gtk_text_buffer_remove_tag(imhtml->text_buffer, tag, start, end); |
4356 gtk_text_buffer_remove_tag(imhtml->text_buffer, tag, start, end); |
| 4331 if (tag->name && |
4357 |
| 4332 strncmp(tag->name, "LINK ", 5) == 0 && imhtml->edit.link) { |
4358 if (name && strncmp(name, "LINK ", 5) == 0 && imhtml->edit.link) { |
| 4333 gtk_imhtml_toggle_link(imhtml, NULL); |
4359 gtk_imhtml_toggle_link(imhtml, NULL); |
| 4334 } |
4360 } |
| |
4361 |
| |
4362 g_free(name); |
| 4335 } |
4363 } |
| 4336 } |
4364 } |
| 4337 g_slist_free(tags); |
4365 g_slist_free(tags); |
| 4338 } |
4366 } |
| 4339 |
4367 |
| 4551 else |
4579 else |
| 4552 tags = gtk_text_iter_get_tags(&iter); |
4580 tags = gtk_text_iter_get_tags(&iter); |
| 4553 |
4581 |
| 4554 for (l = tags; l != NULL; l = l->next) { |
4582 for (l = tags; l != NULL; l = l->next) { |
| 4555 GtkTextTag *tag = GTK_TEXT_TAG(l->data); |
4583 GtkTextTag *tag = GTK_TEXT_TAG(l->data); |
| 4556 |
4584 gchar *name; |
| 4557 if (tag->name) { |
4585 |
| 4558 if (strcmp(tag->name, "BOLD") == 0) |
4586 g_object_get(G_OBJECT(tag), "name", &name, NULL); |
| |
4587 |
| |
4588 if (name) { |
| |
4589 if (strcmp(name, "BOLD") == 0) |
| 4559 imhtml->edit.bold = TRUE; |
4590 imhtml->edit.bold = TRUE; |
| 4560 else if (strcmp(tag->name, "ITALICS") == 0) |
4591 else if (strcmp(name, "ITALICS") == 0) |
| 4561 imhtml->edit.italic = TRUE; |
4592 imhtml->edit.italic = TRUE; |
| 4562 else if (strcmp(tag->name, "UNDERLINE") == 0) |
4593 else if (strcmp(name, "UNDERLINE") == 0) |
| 4563 imhtml->edit.underline = TRUE; |
4594 imhtml->edit.underline = TRUE; |
| 4564 else if (strcmp(tag->name, "STRIKE") == 0) |
4595 else if (strcmp(name, "STRIKE") == 0) |
| 4565 imhtml->edit.strike = TRUE; |
4596 imhtml->edit.strike = TRUE; |
| 4566 else if (strncmp(tag->name, "FORECOLOR ", 10) == 0) |
4597 else if (strncmp(name, "FORECOLOR ", 10) == 0) |
| 4567 imhtml->edit.forecolor = g_strdup(&(tag->name)[10]); |
4598 imhtml->edit.forecolor = g_strdup(&(name)[10]); |
| 4568 else if (strncmp(tag->name, "BACKCOLOR ", 10) == 0) |
4599 else if (strncmp(name, "BACKCOLOR ", 10) == 0) |
| 4569 imhtml->edit.backcolor = g_strdup(&(tag->name)[10]); |
4600 imhtml->edit.backcolor = g_strdup(&(name)[10]); |
| 4570 else if (strncmp(tag->name, "FONT FACE ", 10) == 0) |
4601 else if (strncmp(name, "FONT FACE ", 10) == 0) |
| 4571 imhtml->edit.fontface = g_strdup(&(tag->name)[10]); |
4602 imhtml->edit.fontface = g_strdup(&(name)[10]); |
| 4572 else if (strncmp(tag->name, "FONT SIZE ", 10) == 0) |
4603 else if (strncmp(name, "FONT SIZE ", 10) == 0) |
| 4573 imhtml->edit.fontsize = strtol(&(tag->name)[10], NULL, 10); |
4604 imhtml->edit.fontsize = strtol(&(name)[10], NULL, 10); |
| 4574 else if ((strncmp(tag->name, "LINK ", 5) == 0) && !gtk_text_iter_is_end(&iter)) |
4605 else if ((strncmp(name, "LINK ", 5) == 0) && !gtk_text_iter_is_end(&iter)) |
| 4575 imhtml->edit.link = tag; |
4606 imhtml->edit.link = tag; |
| 4576 } |
4607 } |
| |
4608 |
| |
4609 g_free(name); |
| 4577 } |
4610 } |
| 4578 |
4611 |
| 4579 g_slist_free(tags); |
4612 g_slist_free(tags); |
| 4580 } |
4613 } |
| 4581 |
4614 |
| 4862 gtk_text_buffer_begin_user_action(imhtml->text_buffer); |
4895 gtk_text_buffer_begin_user_action(imhtml->text_buffer); |
| 4863 gtk_imhtml_insert_smiley_at_iter(imhtml, sml, smiley, &iter); |
4896 gtk_imhtml_insert_smiley_at_iter(imhtml, sml, smiley, &iter); |
| 4864 gtk_text_buffer_end_user_action(imhtml->text_buffer); |
4897 gtk_text_buffer_end_user_action(imhtml->text_buffer); |
| 4865 } |
4898 } |
| 4866 |
4899 |
| |
4900 /* TODO: I think this can be removed for GTK+ 3.0... */ |
| |
4901 #if 0 |
| 4867 static gboolean |
4902 static gboolean |
| 4868 image_expose(GtkWidget *widget, GdkEventExpose *event, gpointer user_data) |
4903 image_expose(GtkWidget *widget, GdkEventExpose *event, gpointer user_data) |
| 4869 { |
4904 { |
| 4870 GTK_WIDGET_CLASS(GTK_WIDGET_GET_CLASS(widget))->expose_event(widget, event); |
4905 GTK_WIDGET_CLASS(GTK_WIDGET_GET_CLASS(widget))->expose_event(widget, event); |
| 4871 |
4906 |
| 4872 return TRUE; |
4907 return TRUE; |
| 4873 } |
4908 } |
| |
4909 #endif |
| 4874 |
4910 |
| 4875 /* In case the smiley gets removed from the imhtml before it gets removed from the queue */ |
4911 /* In case the smiley gets removed from the imhtml before it gets removed from the queue */ |
| 4876 static void animated_smiley_destroy_cb(GtkObject *widget, GtkIMHtml *imhtml) |
4912 static void animated_smiley_destroy_cb(GtkWidget *widget, GtkIMHtml *imhtml) |
| 4877 { |
4913 { |
| 4878 GList *l = imhtml->animations->head; |
4914 GList *l = imhtml->animations->head; |
| 4879 while (l) { |
4915 while (l) { |
| 4880 GList *next = l->next; |
4916 GList *next = l->next; |
| 4881 if (l->data == widget) { |
4917 if (l->data == widget) { |
| 4966 |
5002 |
| 4967 /* This catches the expose events generated by animated |
5003 /* This catches the expose events generated by animated |
| 4968 * images, and ensures that they are handled by the image |
5004 * images, and ensures that they are handled by the image |
| 4969 * itself, without propagating to the textview and causing |
5005 * itself, without propagating to the textview and causing |
| 4970 * a complete refresh */ |
5006 * a complete refresh */ |
| |
5007 /* TODO: I think this should be removed for GTK+ 3.0? |
| 4971 g_signal_connect(G_OBJECT(icon), "expose-event", G_CALLBACK(image_expose), NULL); |
5008 g_signal_connect(G_OBJECT(icon), "expose-event", G_CALLBACK(image_expose), NULL); |
| 4972 |
5009 */ |
| |
5010 |
| 4973 gtk_widget_show(icon); |
5011 gtk_widget_show(icon); |
| 4974 if (ebox) |
5012 if (ebox) |
| 4975 gtk_container_add(GTK_CONTAINER(ebox), icon); |
5013 gtk_container_add(GTK_CONTAINER(ebox), icon); |
| 4976 gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), ebox ? ebox : icon, anchor); |
5014 gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), ebox ? ebox : icon, anchor); |
| 4977 |
5015 |
| 5068 imhtml->scalables = g_list_append(imhtml->scalables, sd); |
5106 imhtml->scalables = g_list_append(imhtml->scalables, sd); |
| 5069 } |
5107 } |
| 5070 |
5108 |
| 5071 static const gchar *tag_to_html_start(GtkTextTag *tag) |
5109 static const gchar *tag_to_html_start(GtkTextTag *tag) |
| 5072 { |
5110 { |
| 5073 const gchar *name; |
|
| 5074 static gchar buf[1024]; |
5111 static gchar buf[1024]; |
| 5075 |
5112 gchar *name; |
| 5076 name = tag->name; |
5113 |
| |
5114 g_object_get(G_OBJECT(tag), "name", &name, NULL); |
| 5077 g_return_val_if_fail(name != NULL, ""); |
5115 g_return_val_if_fail(name != NULL, ""); |
| 5078 |
5116 |
| 5079 if (strcmp(name, "BOLD") == 0) { |
5117 if (strcmp(name, "BOLD") == 0) { |
| |
5118 g_free(name); |
| 5080 return "<b>"; |
5119 return "<b>"; |
| 5081 } else if (strcmp(name, "ITALICS") == 0) { |
5120 } else if (strcmp(name, "ITALICS") == 0) { |
| |
5121 g_free(name); |
| 5082 return "<i>"; |
5122 return "<i>"; |
| 5083 } else if (strcmp(name, "UNDERLINE") == 0) { |
5123 } else if (strcmp(name, "UNDERLINE") == 0) { |
| 5084 return "<u>"; |
5124 g_free(name); |
| |
5125 return "<u>"; |
| 5085 } else if (strcmp(name, "STRIKE") == 0) { |
5126 } else if (strcmp(name, "STRIKE") == 0) { |
| 5086 return "<s>"; |
5127 g_free(name); |
| |
5128 return "<s>"; |
| 5087 } else if (strncmp(name, "LINK ", 5) == 0) { |
5129 } else if (strncmp(name, "LINK ", 5) == 0) { |
| 5088 char *tmp = g_object_get_data(G_OBJECT(tag), "link_url"); |
5130 char *tmp = g_object_get_data(G_OBJECT(tag), "link_url"); |
| 5089 if (tmp) { |
5131 |
| |
5132 g_free(name); |
| |
5133 |
| |
5134 if (tmp) { |
| 5090 g_snprintf(buf, sizeof(buf), "<a href=\"%s\">", tmp); |
5135 g_snprintf(buf, sizeof(buf), "<a href=\"%s\">", tmp); |
| 5091 buf[sizeof(buf)-1] = '\0'; |
5136 buf[sizeof(buf)-1] = '\0'; |
| 5092 return buf; |
5137 return buf; |
| 5093 } else { |
5138 } else { |
| 5094 return ""; |
5139 return ""; |
| 5095 } |
5140 } |
| 5096 } else if (strncmp(name, "FORECOLOR ", 10) == 0) { |
5141 } else if (strncmp(name, "FORECOLOR ", 10) == 0) { |
| 5097 g_snprintf(buf, sizeof(buf), "<font color=\"%s\">", &name[10]); |
5142 g_snprintf(buf, sizeof(buf), "<font color=\"%s\">", &name[10]); |
| 5098 return buf; |
5143 |
| |
5144 g_free(name); |
| |
5145 |
| |
5146 return buf; |
| 5099 } else if (strncmp(name, "BACKCOLOR ", 10) == 0) { |
5147 } else if (strncmp(name, "BACKCOLOR ", 10) == 0) { |
| 5100 g_snprintf(buf, sizeof(buf), "<font back=\"%s\">", &name[10]); |
5148 g_snprintf(buf, sizeof(buf), "<font back=\"%s\">", &name[10]); |
| 5101 return buf; |
5149 g_free(name); |
| |
5150 |
| |
5151 return buf; |
| 5102 } else if (strncmp(name, "BACKGROUND ", 10) == 0) { |
5152 } else if (strncmp(name, "BACKGROUND ", 10) == 0) { |
| 5103 g_snprintf(buf, sizeof(buf), "<body bgcolor=\"%s\">", &name[11]); |
5153 g_snprintf(buf, sizeof(buf), "<body bgcolor=\"%s\">", &name[11]); |
| 5104 return buf; |
5154 g_free(name); |
| |
5155 |
| |
5156 return buf; |
| 5105 } else if (strncmp(name, "FONT FACE ", 10) == 0) { |
5157 } else if (strncmp(name, "FONT FACE ", 10) == 0) { |
| 5106 g_snprintf(buf, sizeof(buf), "<font face=\"%s\">", &name[10]); |
5158 g_snprintf(buf, sizeof(buf), "<font face=\"%s\">", &name[10]); |
| 5107 return buf; |
5159 g_free(name); |
| |
5160 |
| |
5161 return buf; |
| 5108 } else if (strncmp(name, "FONT SIZE ", 10) == 0) { |
5162 } else if (strncmp(name, "FONT SIZE ", 10) == 0) { |
| 5109 g_snprintf(buf, sizeof(buf), "<font size=\"%s\">", &name[10]); |
5163 g_snprintf(buf, sizeof(buf), "<font size=\"%s\">", &name[10]); |
| 5110 return buf; |
5164 g_free(name); |
| |
5165 |
| |
5166 return buf; |
| 5111 } else { |
5167 } else { |
| 5112 char *str = buf; |
5168 char *str = buf; |
| 5113 gboolean isset; |
5169 gboolean isset; |
| 5114 int ivalue = 0; |
5170 int ivalue = 0; |
| 5115 GdkColor *color = NULL; |
5171 GdkColor *color = NULL; |
| 5167 empty = FALSE; |
5223 empty = FALSE; |
| 5168 } |
5224 } |
| 5169 } |
5225 } |
| 5170 |
5226 |
| 5171 g_snprintf(str, sizeof(buf) - (str - buf), "'>"); |
5227 g_snprintf(str, sizeof(buf) - (str - buf), "'>"); |
| 5172 |
5228 g_free(name); |
| |
5229 |
| 5173 return (empty ? "" : buf); |
5230 return (empty ? "" : buf); |
| 5174 } |
5231 } |
| 5175 } |
5232 } |
| 5176 |
5233 |
| 5177 static const gchar *tag_to_html_end(GtkTextTag *tag) |
5234 static const gchar *tag_to_html_end(GtkTextTag *tag) |
| 5178 { |
5235 { |
| 5179 const gchar *name; |
5236 gchar *name; |
| 5180 |
5237 |
| 5181 name = tag->name; |
5238 g_object_get(G_OBJECT(tag), "name", &name, NULL); |
| 5182 g_return_val_if_fail(name != NULL, ""); |
5239 g_return_val_if_fail(name != NULL, ""); |
| 5183 |
5240 |
| 5184 if (strcmp(name, "BOLD") == 0) { |
5241 if (strcmp(name, "BOLD") == 0) { |
| |
5242 g_free(name); |
| 5185 return "</b>"; |
5243 return "</b>"; |
| 5186 } else if (strcmp(name, "ITALICS") == 0) { |
5244 } else if (strcmp(name, "ITALICS") == 0) { |
| 5187 return "</i>"; |
5245 g_free(name); |
| |
5246 return "</i>"; |
| 5188 } else if (strcmp(name, "UNDERLINE") == 0) { |
5247 } else if (strcmp(name, "UNDERLINE") == 0) { |
| 5189 return "</u>"; |
5248 g_free(name); |
| |
5249 return "</u>"; |
| 5190 } else if (strcmp(name, "STRIKE") == 0) { |
5250 } else if (strcmp(name, "STRIKE") == 0) { |
| 5191 return "</s>"; |
5251 g_free(name); |
| |
5252 return "</s>"; |
| 5192 } else if (strncmp(name, "LINK ", 5) == 0) { |
5253 } else if (strncmp(name, "LINK ", 5) == 0) { |
| 5193 return "</a>"; |
5254 g_free(name); |
| |
5255 return "</a>"; |
| 5194 } else if (strncmp(name, "FORECOLOR ", 10) == 0) { |
5256 } else if (strncmp(name, "FORECOLOR ", 10) == 0) { |
| 5195 return "</font>"; |
5257 g_free(name); |
| |
5258 return "</font>"; |
| 5196 } else if (strncmp(name, "BACKCOLOR ", 10) == 0) { |
5259 } else if (strncmp(name, "BACKCOLOR ", 10) == 0) { |
| 5197 return "</font>"; |
5260 g_free(name); |
| |
5261 return "</font>"; |
| 5198 } else if (strncmp(name, "BACKGROUND ", 10) == 0) { |
5262 } else if (strncmp(name, "BACKGROUND ", 10) == 0) { |
| 5199 return "</body>"; |
5263 g_free(name); |
| |
5264 return "</body>"; |
| 5200 } else if (strncmp(name, "FONT FACE ", 10) == 0) { |
5265 } else if (strncmp(name, "FONT FACE ", 10) == 0) { |
| 5201 return "</font>"; |
5266 g_free(name); |
| |
5267 return "</font>"; |
| 5202 } else if (strncmp(name, "FONT SIZE ", 10) == 0) { |
5268 } else if (strncmp(name, "FONT SIZE ", 10) == 0) { |
| 5203 return "</font>"; |
5269 g_free(name); |
| |
5270 return "</font>"; |
| 5204 } else { |
5271 } else { |
| 5205 const char *props[] = {"weight-set", "foreground-set", "background-set", |
5272 const char *props[] = {"weight-set", "foreground-set", "background-set", |
| 5206 "size-set", "underline-set", NULL}; |
5273 "size-set", "underline-set", NULL}; |
| 5207 int i; |
5274 int i; |
| 5208 for (i = 0; props[i]; i++) { |
5275 for (i = 0; props[i]; i++) { |
| 5209 gboolean set = FALSE; |
5276 gboolean set = FALSE; |
| 5210 g_object_get(G_OBJECT(tag), props[i], &set, NULL); |
5277 g_object_get(G_OBJECT(tag), props[i], &set, NULL); |
| 5211 if (set) |
5278 if (set) |
| 5212 return "</span>"; |
5279 return "</span>"; |
| 5213 } |
5280 } |
| |
5281 |
| |
5282 g_free(name); |
| 5214 |
5283 |
| 5215 return ""; |
5284 return ""; |
| 5216 } |
5285 } |
| 5217 } |
5286 } |
| 5218 |
5287 |