changeset 32420:4039f92cc589

JS-ify the markerline plugin.
author Elliott Sales de Andrade <qulogic@pidgin.im>
date Wed, 28 Dec 2011 05:07:15 +0000
parents 7b9566b77501
children 3e82cdc85a45
files pidgin/plugins/Makefile.am pidgin/plugins/markerline.c
diffstat 2 files changed, 30 insertions(+), 94 deletions(-) [+]
line wrap: on
line diff
--- a/pidgin/plugins/Makefile.am	Tue Dec 27 22:00:00 2011 +0000
+++ b/pidgin/plugins/Makefile.am	Wed Dec 28 05:07:15 2011 +0000
@@ -38,6 +38,7 @@
 gtkbuddynote_la_LDFLAGS     = -module -avoid-version
 history_la_LDFLAGS          = -module -avoid-version
 iconaway_la_LDFLAGS         = -module -avoid-version
+markerline_la_LDFLAGS       = -module -avoid-version
 notify_la_LDFLAGS           = -module -avoid-version
 pidginrc_la_LDFLAGS         = -module -avoid-version
 relnot_la_LDFLAGS           = -module -avoid-version
@@ -56,6 +57,7 @@
 	gtkbuddynote.la     \
 	history.la          \
 	iconaway.la         \
+	markerline.la       \
 	notify.la           \
 	pidginrc.la         \
 	relnot.la           \
@@ -80,6 +82,7 @@
 gtkbuddynote_la_SOURCES     = gtkbuddynote.c
 history_la_SOURCES          = history.c
 iconaway_la_SOURCES         = iconaway.c
+markerline_la_SOURCES       = markerline.c
 notify_la_SOURCES           = notify.c
 pidginrc_la_SOURCES         = pidginrc.c
 relnot_la_SOURCES           = relnot.c
@@ -96,6 +99,7 @@
 gtkbuddynote_la_LIBADD      = $(GTK_LIBS)
 history_la_LIBADD           = $(GTK_LIBS)
 iconaway_la_LIBADD          = $(GTK_LIBS)
+markerline_la_LIBADD        = $(GTK_LIBS) $(WEBKIT_LIBS)
 notify_la_LIBADD            = $(GTK_LIBS)
 pidginrc_la_LIBADD          = $(GTK_LIBS)
 relnot_la_LIBADD            = $(GLIB_LIBS)
--- a/pidgin/plugins/markerline.c	Tue Dec 27 22:00:00 2011 +0000
+++ b/pidgin/plugins/markerline.c	Wed Dec 28 05:07:15 2011 +0000
@@ -33,81 +33,38 @@
 
 /* Purple headers */
 #include <gtkconv.h>
-#include <gtkimhtml.h>
 #include <gtkplugin.h>
+#include <gtkwebview.h>
 #include <version.h>
 
 #define PREF_PREFIX     "/plugins/gtk/" PLUGIN_ID
 #define PREF_IMS        PREF_PREFIX "/ims"
 #define PREF_CHATS      PREF_PREFIX "/chats"
 
-static int
-imhtml_expose_cb(GtkWidget *widget, GdkEventExpose *event, PidginConversation *gtkconv)
-{
-	int y, last_y, offset;
-	GdkRectangle visible_rect;
-	GtkTextIter iter;
-	GdkRectangle buf;
-	int pad;
-	PurpleConversation *conv = gtkconv->active_conv;
-	PurpleConversationType type = purple_conversation_get_type(conv);
-
-	if ((type == PURPLE_CONV_TYPE_CHAT && !purple_prefs_get_bool(PREF_CHATS)) ||
-			(type == PURPLE_CONV_TYPE_IM && !purple_prefs_get_bool(PREF_IMS)))
-		return FALSE;
-
-	gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(widget), &visible_rect);
-
-	offset = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "markerline"));
-	if (offset)
-	{
-		gtk_text_buffer_get_iter_at_offset(gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget)),
-							&iter, offset);
-
-		gtk_text_view_get_iter_location(GTK_TEXT_VIEW(widget), &iter, &buf);
-		last_y = buf.y + buf.height;
-		pad = (gtk_text_view_get_pixels_below_lines(GTK_TEXT_VIEW(widget)) +
-				gtk_text_view_get_pixels_above_lines(GTK_TEXT_VIEW(widget))) / 2;
-		last_y += pad;
-	}
-	else
-		last_y = 0;
-
-	gtk_text_view_buffer_to_window_coords(GTK_TEXT_VIEW(widget), GTK_TEXT_WINDOW_TEXT,
-										0, last_y, 0, &y);
-
-	if (y >= event->area.y)
-	{
-		GdkColor red = {0, 0xffff, 0, 0};
-		cairo_t *cr = gdk_cairo_create(GDK_DRAWABLE(event->window));
-
-		gdk_cairo_set_source_color(cr, &red);
-		cairo_move_to(cr, 0.0, y + 0.5);
-		cairo_rel_line_to(cr, visible_rect.width, 0.0);
-		cairo_set_line_width(cr, 1.0);
-		cairo_stroke(cr);
-		cairo_destroy(cr);
-	}
-	return FALSE;
-}
-
 static void
 update_marker_for_gtkconv(PidginConversation *gtkconv)
 {
-	GtkTextIter iter;
-	GtkTextBuffer *buffer;
+	PurpleConversation *conv;
+	PurpleConversationType type;
+
 	g_return_if_fail(gtkconv != NULL);
 
-	buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->imhtml));
+	conv = gtkconv->active_conv;
+	type = purple_conversation_get_type(conv);
 
-	if (!gtk_text_buffer_get_char_count(buffer))
+	if ((type == PURPLE_CONV_TYPE_CHAT && !purple_prefs_get_bool(PREF_CHATS)) ||
+	    (type == PURPLE_CONV_TYPE_IM && !purple_prefs_get_bool(PREF_IMS)))
 		return;
 
-	gtk_text_buffer_get_end_iter(buffer, &iter);
-
-	g_object_set_data(G_OBJECT(gtkconv->imhtml), "markerline",
-						GINT_TO_POINTER(gtk_text_iter_get_offset(&iter)));
-	gtk_widget_queue_draw(gtkconv->imhtml);
+	gtk_webview_safe_execute_script(GTK_WEBVIEW(gtkconv->webview),
+		"var mhr = document.getElementById(\"markerhr\");"
+		"if (!mhr) {"
+			"mhr = document.createElement(\"hr\");"
+			"mhr.setAttribute(\"id\", \"markerhr\");"
+			"mhr.setAttribute(\"color\", \"#ff0000\");"
+			"mhr.setAttribute(\"size\", \"1\");"
+		"}"
+		"document.getElementById(\"Chat\").appendChild(mhr);");
 }
 
 static gboolean
@@ -125,28 +82,6 @@
 	return FALSE;
 }
 
-#if 0
-static gboolean
-window_resized(GtkWidget *w, GdkEventConfigure *event, PidginWindow *win)
-{
-	GList *list;
-
-	list = pidgin_conv_window_get_gtkconvs(win);
-
-	for (; list; list = list->next)
-		update_marker_for_gtkconv(list->data);
-
-	return FALSE;
-}
-
-static gboolean
-imhtml_resize_cb(GtkWidget *w, GtkAllocation *allocation, PidginConversation *gtkconv)
-{
-	gtk_widget_queue_draw(w);
-	return FALSE;
-}
-#endif
-
 static void
 page_switched(GtkWidget *widget, GtkWidget *page, gint num, PidginWindow *win)
 {
@@ -156,7 +91,9 @@
 static void
 detach_from_gtkconv(PidginConversation *gtkconv, gpointer null)
 {
-	g_signal_handlers_disconnect_by_func(G_OBJECT(gtkconv->imhtml), imhtml_expose_cb, gtkconv);
+	gtk_webview_safe_execute_script(GTK_WEBVIEW(gtkconv->webview),
+		"var mhr = document.getElementById(\"markerhr\");"
+		"if (mhr) mhr.parentNode.removeChild(mhr);");
 }
 
 static void
@@ -165,16 +102,13 @@
 	g_list_foreach(pidgin_conv_window_get_gtkconvs(win), (GFunc)detach_from_gtkconv, NULL);
 	g_signal_handlers_disconnect_by_func(G_OBJECT(win->notebook), page_switched, win);
 	g_signal_handlers_disconnect_by_func(G_OBJECT(win->window), focus_removed, win);
-
-	gtk_widget_queue_draw(win->window);
 }
 
 static void
 attach_to_gtkconv(PidginConversation *gtkconv, gpointer null)
 {
 	detach_from_gtkconv(gtkconv, NULL);
-	g_signal_connect(G_OBJECT(gtkconv->imhtml), "expose_event",
-					 G_CALLBACK(imhtml_expose_cb), gtkconv);
+	update_marker_for_gtkconv(gtkconv);
 }
 
 static void
@@ -187,8 +121,6 @@
 
 	g_signal_connect(G_OBJECT(win->notebook), "switch_page",
 					G_CALLBACK(page_switched), win);
-
-	gtk_widget_queue_draw(win->window);
 }
 
 static void
@@ -220,15 +152,15 @@
 jump_to_markerline(PurpleConversation *conv, gpointer null)
 {
 	PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv);
-	int offset;
-	GtkTextIter iter;
 
 	if (!gtkconv)
 		return;
 
-	offset = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(gtkconv->imhtml), "markerline"));
-	gtk_text_buffer_get_iter_at_offset(GTK_IMHTML(gtkconv->imhtml)->text_buffer, &iter, offset);
-	gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(gtkconv->imhtml), &iter, 0, TRUE, 0, 0);
+	gtk_webview_safe_execute_script(GTK_WEBVIEW(gtkconv->webview),
+		"var mhr = document.getElementById(\"markerhr\");"
+		"if (mhr) {"
+			"window.scroll(0, mhr.offsetTop);"
+		"}");
 }
 
 static void