Mercurial > pidgin
changeset 15358:7c41ecf41614
[gaim-migrate @ 18151]
Revert GtkIMHtml hacks that tried to fix gtkimhtml bugs, replace it with
heuristic workaround. If you receive a message with more than 100 HTML tags
strip all formatting before displaying it. Hopefully nobody has any legitimate
uses for 100 HTML tags in a message. I guess we'll see in beta6... which I think
we're good for now.
I think that post-2.0.0 we'll wind up replacing GtkIMHtml with a legitimate
HTML widget and do the Adium/Kopete "chat theme" thing. An HTML widget should
be able to handle formatting more efficiently than GtkTextView.
committer: Tailor Script <tailor@pidgin.im>
author | Sean Egan <seanegan@gmail.com> |
---|---|
date | Thu, 18 Jan 2007 02:35:14 +0000 |
parents | b49e2327088a |
children | 541032720845 |
files | gtk/gtkconv.c gtk/gtkimhtml.c gtk/gtkimhtml.h |
diffstat | 3 files changed, 22 insertions(+), 126 deletions(-) [+] |
line wrap: on
line diff
--- a/gtk/gtkconv.c Wed Jan 17 22:44:30 2007 +0000 +++ b/gtk/gtkconv.c Thu Jan 18 02:35:14 2007 +0000 @@ -4810,7 +4810,9 @@ GaimConversationType type; char *displaying; gboolean plugin_return; - + char *bracket; + int tag_count = 0; + g_return_if_fail(conv != NULL); gtkconv = GAIM_GTK_CONVERSATION(conv); g_return_if_fail(gtkconv != NULL); @@ -4853,6 +4855,19 @@ message = displaying; length = strlen(message) + 1; + /* Awful hack to work around GtkIMHtml's inefficient rendering of messages with lots of formatting changes. + * If a message has over 100 '<' characters, strip formatting before appending it. Hopefully nobody actually + * needs that much formatting, anyway. + */ + for (bracket = strchr(message, '<'); bracket && *(bracket + 1); bracket = strchr(bracket + 1, '<')) + tag_count++; + + if (tag_count > 100) { + char *tmp = message; + message = displaying = gaim_markup_strip_html(message); + g_free(tmp); + } + win = gtkconv->win; prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(gc->prpl);
--- a/gtk/gtkimhtml.c Wed Jan 17 22:44:30 2007 +0000 +++ b/gtk/gtkimhtml.c Thu Jan 18 02:35:14 2007 +0000 @@ -1215,19 +1215,11 @@ g_free(imhtml->clipboard_text_string); g_free(imhtml->clipboard_html_string); } - - for (l = imhtml->anchors; l; l = l->next) { - GtkIMHtmlAnchor *anchor = l->data; - gtk_imhtml_anchor_free(anchor); - } - - g_slist_free(imhtml->anchors); + g_list_free(imhtml->scalables); g_slist_free(imhtml->im_images); g_free(imhtml->protocol_name); g_free(imhtml->search_string); - g_object_unref(imhtml->empty_buffer); - g_object_unref(imhtml->text_buffer); G_OBJECT_CLASS(parent_class)->finalize (object); } @@ -1325,7 +1317,6 @@ { GtkTextIter iter; imhtml->text_buffer = gtk_text_buffer_new(NULL); - imhtml->empty_buffer = gtk_text_buffer_new(NULL); gtk_text_buffer_get_end_iter (imhtml->text_buffer, &iter); gtk_text_view_set_buffer(GTK_TEXT_VIEW(imhtml), imhtml->text_buffer); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(imhtml), GTK_WRAP_WORD_CHAR); @@ -2364,23 +2355,12 @@ } } -static gboolean -set_adj_idle_cb(gpointer data) -{ - GtkIMHtml *imhtml = data; - - gtk_adjustment_set_value(GTK_TEXT_VIEW(imhtml)->vadjustment, imhtml->adj); - return FALSE; -} - void gtk_imhtml_insert_html_at_iter(GtkIMHtml *imhtml, const gchar *text, GtkIMHtmlOptions options, GtkTextIter *iter) { GdkRectangle rect; - GtkAdjustment *adj = GTK_TEXT_VIEW(imhtml)->vadjustment; - GSList *anchors; gint pos = 0; gchar *ws; gchar *tag; @@ -2391,8 +2371,6 @@ const gchar *c; gchar *amp; gint len_protocol; - gboolean refocus = GTK_WIDGET_HAS_FOCUS(imhtml); - guint bold = 0, italics = 0, @@ -2404,6 +2382,7 @@ pre = 0; gboolean br = FALSE; + GSList *fonts = NULL; GObject *object; GtkIMHtmlScalable *scalable = NULL; @@ -2416,22 +2395,6 @@ ws = g_malloc(len + 1); ws[0] = 0; - imhtml->adj = gtk_adjustment_get_value(adj); - - for (anchors = imhtml->anchors; anchors; anchors = anchors->next) { - GtkIMHtmlAnchor *anchor = anchors->data; - if (gtk_text_child_anchor_get_deleted(anchor->anchor)) { - imhtml->anchors = g_slist_remove(imhtml->anchors, anchor); - gtk_imhtml_anchor_free(anchor); - continue; - } - gtk_container_remove(GTK_CONTAINER(imhtml), anchor->widget); - - } - gtk_widget_hide(GTK_WIDGET(imhtml)); - gtk_widget_unrealize(GTK_WIDGET(imhtml)); - gtk_text_view_set_buffer(GTK_TEXT_VIEW(imhtml), imhtml->empty_buffer); - while (pos < len) { if (*c == '<' && gtk_imhtml_is_tag (c + 1, &tag, &tlen, &type)) { c++; @@ -3088,19 +3051,10 @@ if (!imhtml->wbfo) gtk_imhtml_close_tags(imhtml, iter); - gtk_text_view_set_buffer(GTK_TEXT_VIEW(imhtml), imhtml->text_buffer); - for (anchors = imhtml->anchors; anchors; anchors = anchors->next) { - GtkIMHtmlAnchor *anchor = anchors->data; - gtk_imhtml_add_anchor(imhtml, anchor); - } object = g_object_ref(G_OBJECT(imhtml)); - gtk_widget_realize(GTK_WIDGET(imhtml)); - gtk_widget_show_all(GTK_WIDGET(imhtml)); - g_idle_add_full(G_PRIORITY_HIGH_IDLE, set_adj_idle_cb, imhtml, NULL); - if (refocus) - gtk_widget_grab_focus(GTK_WIDGET(imhtml)); g_signal_emit(object, signals[UPDATE_FORMAT], 0); g_object_unref(object); + } void gtk_imhtml_remove_smileys(GtkIMHtml *imhtml) @@ -3491,7 +3445,6 @@ void gtk_imhtml_image_add_to(GtkIMHtmlScalable *scale, GtkIMHtml *imhtml, GtkTextIter *iter) { - GtkIMHtmlAnchor *ianchor; GtkIMHtmlImage *image = (GtkIMHtmlImage *)scale; GtkWidget *box = gtk_event_box_new(); char *tag; @@ -3509,9 +3462,7 @@ g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_htmltext", tag, g_free); g_object_set_data(G_OBJECT(anchor), "gtkimhtml_plaintext", "[Image]"); - ianchor = gtk_imhtml_anchor_new(anchor, box); - imhtml->anchors = g_slist_append(imhtml->anchors, ianchor); - + gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), box, anchor); g_signal_connect(G_OBJECT(box), "event", G_CALLBACK(gtk_imhtml_image_clicked), image); } @@ -3537,13 +3488,11 @@ void gtk_imhtml_hr_add_to(GtkIMHtmlScalable *scale, GtkIMHtml *imhtml, GtkTextIter *iter) { - GtkIMHtmlAnchor *ianchor; GtkIMHtmlHr *hr = (GtkIMHtmlHr *)scale; GtkTextChildAnchor *anchor = gtk_text_buffer_create_child_anchor(imhtml->text_buffer, iter); g_object_set_data(G_OBJECT(anchor), "gtkimhtml_htmltext", "<hr>"); g_object_set_data(G_OBJECT(anchor), "gtkimhtml_plaintext", "\n---\n"); - ianchor = gtk_imhtml_anchor_new(anchor, hr->sep); - imhtml->anchors = g_slist_append(imhtml->anchors, ianchor); + gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), hr->sep, anchor); } void gtk_imhtml_hr_free(GtkIMHtmlScalable *scale) @@ -3551,36 +3500,6 @@ g_free(scale); } -GtkIMHtmlAnchor *gtk_imhtml_anchor_new(GtkTextChildAnchor *anchor, GtkWidget *widget) -{ - GtkIMHtmlAnchor *a = g_new0(GtkIMHtmlAnchor, 1); - a->anchor = anchor; - a->widget = widget; - - g_object_ref(anchor); - g_object_ref(widget); - - return a; -} - -void gtk_imhtml_anchor_free(GtkIMHtmlAnchor *anchor) -{ - g_object_unref(anchor->anchor); - g_object_unref(anchor->widget); - g_free(anchor); -} - -void gtk_imhtml_add_anchor(GtkIMHtml *imhtml, GtkIMHtmlAnchor *anchor) -{ - if (gtk_text_child_anchor_get_deleted(anchor->anchor)) { - imhtml->anchors = g_slist_remove(imhtml->anchors, anchor); - gtk_imhtml_anchor_free(anchor); - return; - } - - gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), anchor->widget, anchor->anchor); -} - gboolean gtk_imhtml_search_find(GtkIMHtml *imhtml, const gchar *text) { GtkTextIter iter, start, end; @@ -4530,7 +4449,6 @@ } if (icon) { - GtkIMHtmlAnchor *ianchor; anchor = gtk_text_buffer_create_child_anchor(imhtml->text_buffer, iter); g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_plaintext", g_strdup(unescaped), g_free); g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_htmltext", g_strdup(smiley), g_free); @@ -4542,10 +4460,7 @@ g_signal_connect(G_OBJECT(icon), "expose-event", G_CALLBACK(image_expose), NULL); gtk_widget_show(icon); - ianchor = gtk_imhtml_anchor_new(anchor, icon); - imhtml->anchors = g_slist_append(imhtml->anchors, ianchor); - if (imhtml->text_buffer == GTK_TEXT_VIEW(imhtml)->buffer) - gtk_imhtml_add_anchor(imhtml, ianchor); + gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), icon, anchor); } else if (imhtml_smiley != NULL && (imhtml->format_functions & GTK_IMHTML_SMILEY)) { anchor = gtk_text_buffer_create_child_anchor(imhtml->text_buffer, iter); imhtml_smiley->anchors = g_slist_append(imhtml_smiley->anchors, anchor);
--- a/gtk/gtkimhtml.h Wed Jan 17 22:44:30 2007 +0000 +++ b/gtk/gtkimhtml.h Thu Jan 18 02:35:14 2007 +0000 @@ -53,7 +53,6 @@ typedef struct _GtkIMHtmlImage GtkIMHtmlImage; typedef struct _GtkIMHtmlHr GtkIMHtmlHr; typedef struct _GtkIMHtmlFuncs GtkIMHtmlFuncs; -typedef struct _GtkIMHtmlAnchor GtkIMHtmlAnchor; typedef enum { GTK_IMHTML_BOLD = 1 << 0, @@ -80,7 +79,6 @@ struct _GtkIMHtml { GtkTextView text_view; GtkTextBuffer *text_buffer; - GtkTextBuffer *empty_buffer; GdkCursor *hand_cursor; GdkCursor *arrow_cursor; GdkCursor *text_cursor; @@ -89,7 +87,6 @@ char *protocol_name; guint scroll_src; GTimer *scroll_time; - gdouble adj; gboolean show_comments; @@ -126,7 +123,6 @@ char *clipboard_html_string; GSList *im_images; - GSList *anchors; GtkIMHtmlFuncs *funcs; }; @@ -192,11 +188,6 @@ GtkWidget *sep; }; -struct _GtkIMHtmlAnchor { - GtkTextChildAnchor *anchor; - GtkWidget *widget; -}; - typedef enum { GTK_IMHTML_NO_COLOURS = 1 << 0, GTK_IMHTML_NO_FONTS = 1 << 1, @@ -481,31 +472,6 @@ void gtk_imhtml_hr_add_to(GtkIMHtmlScalable *scale, GtkIMHtml *imhtml, GtkTextIter *iter); /** - * Creates a new anchor for GTK+ widgets, taking care of reference counting - * - * @param anchor The GtkTextChildAnchor - * @param widget The GtkWidget - * - * @return The GtkIMHtmlAnchor - */ -GtkIMHtmlAnchor *gtk_imhtml_anchor_new(GtkTextChildAnchor *anchor, GtkWidget *widget); - -/** - * Frees an anchor, taking care of refcounting - * - * @param anchor The anchor - */ -void gtk_imhtml_anchor_free(GtkIMHtmlAnchor *anchor); - -/** - * Associates an anchor with an imhtml - * - * @param imhtml The IMHTML to associate with. - * @param anchor The anchor to associate - */ -void gtk_imhtml_add_anchor(GtkIMHtml *imhtml, GtkIMHtmlAnchor *anchor); - -/** * Finds and highlights a given string in a GTK+ IM/HTML. * * @param imhtml The GTK+ IM/HTML.