diff gtk/gtkimhtml.c @ 15341:ca7cc867fa58

[gaim-migrate @ 18134] Syncing up my tree. I've gotten smileys, <hr>'s and IM images to *mostly* work. Scrolling's the only obviously busted thing right now. I also made blist headlines set the URGENT hint. committer: Tailor Script <tailor@pidgin.im>
author Sean Egan <seanegan@gmail.com>
date Tue, 16 Jan 2007 02:48:36 +0000
parents 3abb476aab94
children 965f7e53e7c5
line wrap: on
line diff
--- a/gtk/gtkimhtml.c	Mon Jan 15 23:33:50 2007 +0000
+++ b/gtk/gtkimhtml.c	Tue Jan 16 02:48:36 2007 +0000
@@ -1215,7 +1215,13 @@
 		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);
@@ -2362,6 +2368,7 @@
 set_adj_idle_cb(gpointer data)
 {
 	GtkIMHtml *imhtml = data;
+
 	gtk_adjustment_set_value(GTK_TEXT_VIEW(imhtml)->vadjustment, imhtml->adj);
 	return FALSE;
 }
@@ -2373,6 +2380,7 @@
 {
 	GdkRectangle rect;
 	GtkAdjustment *adj = GTK_TEXT_VIEW(imhtml)->vadjustment;
+	GSList *anchors;
 	gint pos = 0;
 	gchar *ws;
 	gchar *tag;
@@ -2383,6 +2391,7 @@
 	const gchar *c;
 	gchar *amp;
 	gint len_protocol;
+	gboolean refocus = GTK_WIDGET_HAS_FOCUS(imhtml);
 
 
 	guint	bold = 0,
@@ -2395,7 +2404,6 @@
 		pre = 0;
 
 	gboolean br = FALSE;
-
 	GSList *fonts = NULL;
 	GObject *object;
 	GtkIMHtmlScalable *scalable = NULL;
@@ -2409,6 +2417,17 @@
 	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);
@@ -3070,10 +3089,18 @@
 		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));
-	object = g_object_ref(G_OBJECT(imhtml));
-	g_idle_add(set_adj_idle_cb, imhtml);
+	g_idle_add_full(G_PRIORITY_HIGH_IDLE, set_adj_idle_cb, imhtml, NULL);
+	if (refocus){
+		printf("refocusing\n");
+		gtk_widget_grab_focus(GTK_WIDGET(imhtml));
+	}
 	g_signal_emit(object, signals[UPDATE_FORMAT], 0);
 	g_object_unref(object);
 }
@@ -3466,6 +3493,7 @@
 
 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;
@@ -3483,7 +3511,9 @@
 	g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_htmltext", tag, g_free);
 	g_object_set_data(G_OBJECT(anchor), "gtkimhtml_plaintext", "[Image]");
 
-	gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), box, anchor);
+	ianchor = gtk_imhtml_anchor_new(anchor, box);
+	imhtml->anchors = g_slist_append(imhtml->anchors, ianchor);
+
 	g_signal_connect(G_OBJECT(box), "event", G_CALLBACK(gtk_imhtml_image_clicked), image);
 }
 
@@ -3509,11 +3539,13 @@
 
 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");
-	gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), hr->sep, anchor);
+	ianchor = gtk_imhtml_anchor_new(anchor, hr->sep);
+	imhtml->anchors = g_slist_append(imhtml->anchors, ianchor);
 }
 
 void gtk_imhtml_hr_free(GtkIMHtmlScalable *scale)
@@ -3521,6 +3553,36 @@
 	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;
@@ -4470,6 +4532,7 @@
 	}
 
 	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);
@@ -4481,7 +4544,8 @@
 		g_signal_connect(G_OBJECT(icon), "expose-event", G_CALLBACK(image_expose), NULL);
 
 		gtk_widget_show(icon);
-		gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), icon, anchor);
+		ianchor = gtk_imhtml_anchor_new(anchor, icon);
+		imhtml->anchors = g_slist_append(imhtml->anchors, ianchor);
 	} 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);