changeset 24130:0d0f99cd425e

Show visited links in a different color. This also plugs a memory leak that happens when hovering over a hyperlink.
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Fri, 19 Sep 2008 05:29:38 +0000
parents 824e346c5713
children 8f30b1f32f46 f3788288961b
files ChangeLog pidgin/gtkimhtml.c pidgin/plugins/pidginrc.c
diffstat 3 files changed, 42 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Thu Sep 18 16:19:11 2008 +0000
+++ b/ChangeLog	Fri Sep 19 05:29:38 2008 +0000
@@ -11,6 +11,8 @@
 	* Fix a case where a conversation window could close unexpectedly.
 	* A mute sounds option has been added to the preferences window to
 	  help with discoverability.  CTRL+S is no longer bound to mute.
+	* Added ability to change the color of visited links (using the theme
+	  control plugin, or setting the color in ~/.gtkrc-2.0)
 
 	Finch:
 	* A new 'Nested Grouping' option in the 'Grouping' plugin. Group
--- a/pidgin/gtkimhtml.c	Thu Sep 18 16:19:11 2008 +0000
+++ b/pidgin/gtkimhtml.c	Fri Sep 19 05:29:38 2008 +0000
@@ -446,6 +446,20 @@
 	parent_style_set(widget, prev_style);
 }
 
+static void
+gtk_imhtml_set_link_color(GtkIMHtml *imhtml, GtkTextTag *tag)
+{
+	GdkColor *color = NULL;
+	gboolean visited = !!g_object_get_data(G_OBJECT(tag), "visited");
+	gtk_widget_style_get(GTK_WIDGET(imhtml), visited ? "hyperlink-visited-color" : "hyperlink-color", &color, NULL);
+	if (color) {
+		g_object_set(G_OBJECT(tag), "foreground-gdk", color, NULL);
+		gdk_color_free(color);
+	} else {
+		g_object_set(G_OBJECT(tag), "foreground", visited ? "#800000" : "blue", NULL);
+	}
+}
+
 static gint
 gtk_imhtml_tip_paint (GtkIMHtml *imhtml)
 {
@@ -566,7 +580,6 @@
 	int x, y;
 	char *tip = NULL;
 	GSList *tags = NULL, *templist = NULL;
-	GdkColor *norm, *pre;
 	GtkTextTag *tag = NULL, *oldprelit_tag;
 	GtkTextChildAnchor* anchor;
 	gboolean hand = TRUE;
@@ -588,13 +601,15 @@
 		templist = templist->next;
 	}
 
-	if (tip) {
-		gtk_widget_style_get(GTK_WIDGET(imhtml), "hyperlink-prelight-color", &pre, NULL);
+	if (tip && (!tag || !g_object_get_data(G_OBJECT(tag), "visited"))) {
 		GTK_IMHTML(imhtml)->prelit_tag = tag;
 		if (tag != oldprelit_tag) {
-			if (pre)
+			GdkColor *pre = NULL;
+			gtk_widget_style_get(GTK_WIDGET(imhtml), "hyperlink-prelight-color", &pre, NULL);
+			if (pre) {
 				g_object_set(G_OBJECT(tag), "foreground-gdk", pre, NULL);
-			else
+				gdk_color_free(pre);
+			} else
 				g_object_set(G_OBJECT(tag), "foreground", "#70a0ff", NULL);
 		}
 	} else {
@@ -602,11 +617,7 @@
 	}
 
 	if ((oldprelit_tag != NULL) && (GTK_IMHTML(imhtml)->prelit_tag != oldprelit_tag)) {
-		gtk_widget_style_get(GTK_WIDGET(imhtml), "hyperlink-color", &norm, NULL);
-		if (norm)
-			g_object_set(G_OBJECT(oldprelit_tag), "foreground-gdk", norm, NULL);
-		else
-			g_object_set(G_OBJECT(oldprelit_tag), "foreground", "blue", NULL);
+		gtk_imhtml_set_link_color(GTK_IMHTML(imhtml), oldprelit_tag);
 	}
 
 	if (GTK_IMHTML(imhtml)->tip) {
@@ -670,12 +681,7 @@
 {
 	/* when leaving the widget, clear any current & pending tooltips and restore the cursor */
 	if (GTK_IMHTML(imhtml)->prelit_tag) {
-		GdkColor *norm;
-		gtk_widget_style_get(GTK_WIDGET(imhtml), "hyperlink-color", &norm, NULL);
-		if (norm)
-			g_object_set(G_OBJECT(GTK_IMHTML(imhtml)->prelit_tag), "foreground-gdk", norm, NULL);
-		else
-			g_object_set(G_OBJECT(GTK_IMHTML(imhtml)->prelit_tag), "foreground", "blue", NULL);
+		gtk_imhtml_set_link_color(GTK_IMHTML(imhtml), GTK_IMHTML(imhtml)->prelit_tag);
 		GTK_IMHTML(imhtml)->prelit_tag = NULL;
 	}
 
@@ -1482,6 +1488,10 @@
 	                                        _("Hyperlink color"),
 	                                        _("Color to draw hyperlinks."),
 	                                        GDK_TYPE_COLOR, G_PARAM_READABLE));
+	gtk_widget_class_install_style_property(widget_class, g_param_spec_boxed("hyperlink-visited-color",
+	                                        _("Hyperlink visited color"),
+	                                        _("Color to draw hyperlinks after it has been visited (or activated)."),
+	                                        GDK_TYPE_COLOR, G_PARAM_READABLE));
 	gtk_widget_class_install_style_property(widget_class, g_param_spec_boxed("hyperlink-prelight-color",
 	                                        _("Hyperlink prelight color"),
 	                                        _("Color to draw hyperlinks when mouse is over them."),
@@ -1679,20 +1689,24 @@
 struct url_data {
 	GObject *object;
 	gchar *url;
+	GtkTextTag *tag;
 };
 
 static void url_data_destroy(gpointer mydata)
 {
 	struct url_data *data = mydata;
 	g_object_unref(data->object);
+	g_object_unref(data->tag);
 	g_free(data->url);
 	g_free(data);
 }
 
-static void url_open(GtkWidget *w, struct url_data *data) {
+static void url_open(GtkWidget *w, struct url_data *data)
+{
 	if(!data) return;
 	g_signal_emit(data->object, signals[URL_CLICKED], 0, data->url);
-
+	g_object_set_data(G_OBJECT(data->tag), "visited", GINT_TO_POINTER(TRUE));
+	gtk_imhtml_set_link_color(GTK_IMHTML(data->object), data->tag);
 }
 
 static void url_copy(GtkWidget *w, gchar *url) {
@@ -1706,7 +1720,8 @@
 }
 
 /* The callback for an event on a link tag. */
-static gboolean tag_event(GtkTextTag *tag, GObject *imhtml, GdkEvent *event, GtkTextIter *arg2, gpointer unused) {
+static gboolean tag_event(GtkTextTag *tag, GObject *imhtml, GdkEvent *event, GtkTextIter *arg2, gpointer unused)
+{
 	GdkEventButton *event_button = (GdkEventButton *) event;
 	if (GTK_IMHTML(imhtml)->editable)
 		return FALSE;
@@ -1723,12 +1738,15 @@
 			g_object_ref(G_OBJECT(tag));
 			g_signal_emit(imhtml, signals[URL_CLICKED], 0, g_object_get_data(G_OBJECT(tag), "link_url"));
 			g_object_unref(G_OBJECT(tag));
+			g_object_set_data(G_OBJECT(tag), "visited", GINT_TO_POINTER(TRUE));
+			gtk_imhtml_set_link_color(GTK_IMHTML(imhtml), tag);
 			return FALSE;
 		} else if(event_button->button == 3) {
 			GtkWidget *img, *item, *menu;
 			struct url_data *tempdata = g_new(struct url_data, 1);
 			tempdata->object = g_object_ref(imhtml);
 			tempdata->url = g_strdup(g_object_get_data(G_OBJECT(tag), "link_url"));
+			tempdata->tag = g_object_ref(tag);
 
 			/* Don't want the tooltip around if user right-clicked on link */
 			if (GTK_IMHTML(imhtml)->tip_window) {
--- a/pidgin/plugins/pidginrc.c	Thu Sep 18 16:19:11 2008 +0000
+++ b/pidgin/plugins/pidginrc.c	Fri Sep 19 05:29:38 2008 +0000
@@ -31,6 +31,7 @@
 	"/plugins/gtk/purplerc/color/GtkWidget::cursor-color",
 	"/plugins/gtk/purplerc/color/GtkWidget::secondary-cursor-color",
 	"/plugins/gtk/purplerc/color/GtkIMHtml::hyperlink-color",
+	"/plugins/gtk/purplerc/color/GtkIMHtml::hyperlink-visited-color",
 	"/plugins/gtk/purplerc/color/GtkIMHtml::send-name-color",
 	"/plugins/gtk/purplerc/color/GtkIMHtml::receive-name-color",
 	"/plugins/gtk/purplerc/color/GtkIMHtml::highlight-name-color",
@@ -40,6 +41,7 @@
 	"/plugins/gtk/purplerc/set/color/GtkWidget::cursor-color",
 	"/plugins/gtk/purplerc/set/color/GtkWidget::secondary-cursor-color",
 	"/plugins/gtk/purplerc/set/color/GtkIMHtml::hyperlink-color",
+	"/plugins/gtk/purplerc/set/color/GtkIMHtml::hyperlink-visited-color",
 	"/plugins/gtk/purplerc/set/color/GtkIMHtml::send-name-color",
 	"/plugins/gtk/purplerc/set/color/GtkIMHtml::receive-name-color",
 	"/plugins/gtk/purplerc/set/color/GtkIMHtml::highlight-name-color",
@@ -49,6 +51,7 @@
 	N_("Cursor Color"),
 	N_("Secondary Cursor Color"),
 	N_("Hyperlink Color"),
+	N_("Visited Hyperlink Color"),
 	N_("Sent Message Name Color"),
 	N_("Received Message Name Color"),
 	N_("Highlighted Message Name Color"),