| 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); |
| 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 |
| 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; |
| 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++; |
| 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) { |
| 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; |