pidgin: 6d8f1be8: Apply conversation theme when opening th...

qulogic at pidgin.im qulogic at pidgin.im
Wed Sep 21 03:07:24 EDT 2011


----------------------------------------------------------------------
Revision: 6d8f1be808eb3c2766f72abdbbcc07b914164f01
Parent:   a8e18e79700a4c9bc433a1d5423ba9a77b2e3816
Author:   qulogic at pidgin.im
Date:     09/21/11 02:45:26
Branch:   im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/6d8f1be808eb3c2766f72abdbbcc07b914164f01

Changelog: 

Apply conversation theme when opening the GTK conversation. All the
parsing stuff was moved out of the theme code and into the conversation
code.

Someone (not me!) needs to check the code I commented out and see if
we really need that stuff (and then port it to WebKit/styling).

We also need to determine where to place Template.html and the rest
of our (not-yet-written) default theme.

Changes against parent a8e18e79700a4c9bc433a1d5423ba9a77b2e3816

  patched  pidgin/gtkconv-theme.c
  patched  pidgin/gtkconv-theme.h
  patched  pidgin/gtkconv.c
  patched  pidgin/gtkconv.h

-------------- next part --------------
============================================================
--- pidgin/gtkconv.c	6b8fa8ea575c7f864f9a3373d8bac70e0c9b3a6e
+++ pidgin/gtkconv.c	a6cde1c44fdb25c59b0c89dab30be32d16a3f7e9
@@ -76,6 +76,7 @@
 #include "gtkwebview.h"
 #include "pidginstock.h"
 #include "pidgintooltip.h"
+#include "smileyparser.h"
 
 #include "gtknickcolors.h"
 
@@ -4945,6 +4946,152 @@ pidgin_conv_setup_quickfind(PidginConver
 
 /* }}} */
 
+static char *
+replace_header_tokens(PurpleConversation *conv, const char *text)
+{
+	GString *str;
+	const char *cur = text;
+	const char *prev = cur;
+
+	if (text == NULL || *text == '\0')
+		return NULL;
+
+	str = g_string_new(NULL);
+	while ((cur = strchr(cur, '%'))) {
+		const char *replace = NULL;
+		const char *fin = NULL;
+
+		if (g_str_has_prefix(cur, "%chatName%")) {
+			replace = conv->name;
+
+		} else if (g_str_has_prefix(cur, "%sourceName%")) {
+			replace = purple_account_get_alias(conv->account);
+			if (replace == NULL)
+				replace = purple_account_get_username(conv->account);
+
+		} else if (g_str_has_prefix(cur, "%destinationName%")) {
+			PurpleBuddy *buddy = purple_find_buddy(conv->account, conv->name);
+			if (buddy) {
+				replace = purple_buddy_get_alias(buddy);
+			} else {
+				replace = conv->name;
+			}
+
+		} else if (g_str_has_prefix(cur, "%incomingIconPath%")) {
+			PurpleBuddyIcon *icon = purple_conv_im_get_icon(PURPLE_CONV_IM(conv));
+			if (icon)
+				replace = purple_buddy_icon_get_full_path(icon);
+
+		} else if (g_str_has_prefix(cur, "%outgoingIconPath%")) {
+			replace = purple_account_get_buddy_icon_path(conv->account);
+
+		} else if (g_str_has_prefix(cur, "%timeOpened")) {
+			const char *tmp = cur + strlen("%timeOpened");
+			char *format = NULL;
+			if (*tmp == '{') {
+				const char *end;
+				tmp++;
+				end = strstr(tmp, "}%");
+				if (!end) /* Invalid string */
+					continue;
+				format = g_strndup(tmp, end - tmp);
+				fin = end + 1;
+			}
+			replace = purple_utf8_strftime(format ? format : "%X", NULL);
+			g_free(format);
+
+		} else {
+			continue;
+		}
+
+		/* Here we have a replacement to make */
+		g_string_append_len(str, prev, cur - prev);
+		if (replace)
+			g_string_append(str, replace);
+
+		/* And update the pointers */
+		if (fin) {
+			prev = cur = fin + 1;
+		} else {
+			prev = cur = strchr(cur + 1, '%') + 1;
+		}
+	}
+
+	/* And wrap it up */
+	g_string_append(str, prev);
+	return g_string_free(str, FALSE);
+}
+
+static char *
+replace_template_tokens(PidginConvTheme *theme, const char *header, const char *footer)
+{
+	GString *str;
+	const char *text;
+	char **ms;
+	char *path;
+
+	text = pidgin_conversation_theme_get_template(theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_MAIN);
+	ms = g_strsplit(text, "%@", 6);
+	if (ms[0] == NULL || ms[1] == NULL || ms[2] == NULL || ms[3] == NULL || ms[4] == NULL || ms[5] == NULL) {
+		g_strfreev(ms);
+		return NULL;
+	}
+
+	str = g_string_new(NULL);
+
+	g_string_append(str, ms[0]);
+	g_string_append(str, "file://");
+	path = pidgin_conversation_theme_get_template_path(theme);
+	g_string_append(str, path);
+	g_free(path);
+
+	g_string_append(str, ms[1]);
+
+	text = pidgin_conversation_theme_get_template(theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_BASESTYLE_CSS);
+	g_string_append(str, text);
+
+	g_string_append(str, ms[2]);
+
+	g_string_append(str, "file://");
+	path = pidgin_conversation_theme_get_css_path(theme);
+	g_string_append(str, path);
+	g_free(path);
+
+	g_string_append(str, ms[3]);
+	if (header)
+		g_string_append(str, header);
+	g_string_append(str, ms[4]);
+	if (footer)
+		g_string_append(str, footer);
+	g_string_append(str, ms[5]);
+
+	g_strfreev(ms);
+
+	return g_string_free(str, FALSE);
+}
+
+static void
+set_theme_webkit_settings(WebKitWebView *webview, PidginConvTheme *theme)
+{
+	WebKitWebSettings *settings;
+	const GValue *val;
+
+	g_object_get(G_OBJECT(webview), "settings", &settings, NULL);
+
+	val = pidgin_conversation_theme_lookup(theme, "DefaultFontFamily", TRUE);
+	if (val && G_VALUE_HOLDS_STRING(val))
+		g_object_set(G_OBJECT(settings), "default-font-family", g_value_get_string(val), NULL);
+
+	val = pidgin_conversation_theme_lookup(theme, "DefaultFontSize", TRUE);
+	if (val && G_VALUE_HOLDS_INT(val))
+		g_object_set(G_OBJECT(settings), "default-font-size", GINT_TO_POINTER(g_value_get_int(val)), NULL);
+
+	val = pidgin_conversation_theme_lookup(theme, "DefaultBackgroundIsTransparent", TRUE);
+	if (val && G_VALUE_HOLDS_BOOLEAN(val))
+		/* this does not work :( */
+		webkit_web_view_set_transparent(webview, g_value_get_boolean(val));
+}
+
 static GtkWidget *
 setup_common_pane(PidginConversation *gtkconv)
 {
@@ -4955,6 +5102,8 @@ setup_common_pane(PidginConversation *gt
 	PurpleBuddy *buddy;
 	gboolean chat = (conv->type == PURPLE_CONV_TYPE_CHAT);
 	int buddyicon_size = 0;
+	char *header, *footer;
+	char *template;
 
 	/* Setup the top part of the pane */
 	vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
@@ -5048,6 +5197,34 @@ setup_common_pane(PidginConversation *gt
 	frame = pidgin_create_webview(FALSE, &gtkconv->webview, NULL, &webview_sw);
 	gtk_widget_set_size_request(gtkconv->webview, -1, 0);
 
+	header = replace_header_tokens(conv,
+		pidgin_conversation_theme_get_template(gtkconv->theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_HEADER));
+	footer = replace_header_tokens(conv,
+		pidgin_conversation_theme_get_template(gtkconv->theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_FOOTER));
+	template = replace_template_tokens(gtkconv->theme, header, footer);
+	g_free(header);
+	g_free(footer);
+
+	if (template != NULL) {
+		char *basedir;
+		char *baseuri;
+
+		purple_debug_info("webkit", "template: %s\n", template);
+
+		set_theme_webkit_settings(WEBKIT_WEB_VIEW(gtkconv->webview), gtkconv->theme);
+
+		basedir = pidgin_conversation_theme_get_template_path(gtkconv->theme);
+		baseuri = g_strdup_printf("file://%s", basedir);
+		webkit_web_view_load_string(WEBKIT_WEB_VIEW(gtkconv->webview), template, "text/html", "UTF-8", baseuri);
+
+		if (chat)
+			gtk_webview_safe_execute_script(GTK_WEBVIEW(gtkconv->webview), "document.getElementById('Chat').className = 'groupchat'");
+
+		g_free(basedir);
+		g_free(baseuri);
+		g_free(template);
+	}
+
 	if (chat) {
 		GtkWidget *hpaned;
 
@@ -5357,6 +5534,7 @@ private_gtkconv_new(PurpleConversation *
 private_gtkconv_new(PurpleConversation *conv, gboolean hidden)
 {
 	PidginConversation *gtkconv;
+	PurpleTheme *theme;
 	PurpleConversationType conv_type = purple_conversation_get_type(conv);
 	GtkWidget *pane = NULL;
 	GtkWidget *tab_cont;
@@ -5381,6 +5559,11 @@ private_gtkconv_new(PurpleConversation *
 	gtkconv->tooltips = gtk_tooltips_new();
 	gtkconv->unseen_state = PIDGIN_UNSEEN_NONE;
 	gtkconv->unseen_count = 0;
+	theme = purple_theme_manager_find_theme(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/theme"), "conversation");
+	if (!theme)
+		theme = purple_theme_manager_find_theme("Default", "conversation");
+	gtkconv->theme = PIDGIN_CONV_THEME(theme);
+	gtkconv->last_flags = 0;
 
 	if (conv_type == PURPLE_CONV_TYPE_IM) {
 		gtkconv->u.im = g_malloc0(sizeof(PidginImPane));
@@ -5611,6 +5794,7 @@ pidgin_conv_write_im(PurpleConversation 
 	purple_conversation_write(conv, who, message, flags, mtime);
 }
 
+#if 0
 static const char *
 get_text_tag_color(GtkTextTag *tag)
 {
@@ -5691,6 +5875,7 @@ static gboolean buddytag_event(GtkTextTa
 
 	return FALSE;
 }
+#endif
 
 static GtkTextTag *get_buddy_tag(PurpleConversation *conv, const char *who, PurpleMessageFlags flag,
 		gboolean create)
@@ -5734,6 +5919,7 @@ static GtkTextTag *get_buddy_tag(PurpleC
 	return NULL;
 }
 
+#if 0
 static void pidgin_conv_calculate_newday(PidginConversation *gtkconv, time_t mtime)
 {
 	struct tm *tm = localtime(&mtime);
@@ -5779,7 +5965,102 @@ str_embed_direction_chars(char **str)
 	*str = ret;
 #endif
 }
+#endif
 
+static char *
+replace_message_tokens(
+	const char *text,
+	PurpleConversation *conv,
+	const char *name,
+	const char *alias,
+	const char *message,
+	PurpleMessageFlags flags,
+	time_t mtime)
+{
+	GString *str = g_string_new(NULL);
+	const char *cur = text;
+	const char *prev = cur;
+
+	while ((cur = strchr(cur, '%'))) {
+		const char *replace = NULL;
+		const char *fin = NULL;
+
+		if (g_str_has_prefix(cur, "%message%")) {
+			replace = message;
+
+		} else if (g_str_has_prefix(cur, "%messageClasses%")) {
+			replace = flags & PURPLE_MESSAGE_SEND ? "outgoing" :
+				  flags & PURPLE_MESSAGE_RECV ? "incoming" : "event";
+
+		} else if (g_str_has_prefix(cur, "%time")) {
+			const char *tmp = cur + strlen("%time");
+			char *format = NULL;
+			if (*tmp == '{') {
+				char *end;
+				tmp++;
+				end = strstr(tmp, "}%");
+				if (!end) /* Invalid string */
+					continue;
+				format = g_strndup(tmp, end - tmp);
+				fin = end + 1;
+			}
+			replace = purple_utf8_strftime(format ? format : "%X", NULL);
+			g_free(format);
+
+		} else if (g_str_has_prefix(cur, "%userIconPath%")) {
+			if (flags & PURPLE_MESSAGE_SEND) {
+				if (purple_account_get_bool(conv->account, "use-global-buddyicon", TRUE)) {
+					replace = purple_prefs_get_path(PIDGIN_PREFS_ROOT "/accounts/buddyicon");
+				} else {
+					PurpleStoredImage *img = purple_buddy_icons_find_account_icon(conv->account);
+					replace = purple_imgstore_get_filename(img);
+				}
+				if (replace == NULL || !g_file_test(replace, G_FILE_TEST_EXISTS)) {
+					replace = g_build_filename("Outgoing", "buddy_icon.png", NULL);
+				}
+			} else if (flags & PURPLE_MESSAGE_RECV) {
+				PurpleBuddyIcon *icon = purple_conv_im_get_icon(PURPLE_CONV_IM(conv));
+				if (icon)
+					replace = purple_buddy_icon_get_full_path(icon);
+				if (replace == NULL || !g_file_test(replace, G_FILE_TEST_EXISTS)) {
+					replace = g_build_filename("Incoming", "buddy_icon.png", NULL);
+				}
+			}
+
+		} else if (g_str_has_prefix(cur, "%senderScreenName%")) {
+			replace = name;
+
+		} else if (g_str_has_prefix(cur, "%sender%")) {
+			replace = alias;
+
+		} else if (g_str_has_prefix(cur, "%service%")) {
+			replace = purple_account_get_protocol_name(conv->account);
+
+		} else {
+			cur++;
+			continue;
+		}
+
+		/* Here we have a replacement to make */
+		g_string_append_len(str, prev, cur - prev);
+		if (replace)
+			g_string_append(str, replace);
+
+		/* And update the pointers */
+		if (fin) {
+			prev = cur = fin + 1;
+		} else {
+			prev = cur = strchr(cur + 1, '%') + 1;
+		}
+
+	}
+
+	/* And wrap it up */
+	g_string_append(str, prev);
+
+	return g_string_free(str, FALSE);
+}
+
 static void
 pidgin_conv_write_conv(PurpleConversation *conv, const char *name, const char *alias,
 						const char *message, PurpleMessageFlags flags,
@@ -5788,6 +6069,7 @@ pidgin_conv_write_conv(PurpleConversatio
 	PidginConversation *gtkconv;
 	PurpleConnection *gc;
 	PurpleAccount *account;
+#if 0
 	int gtk_font_options = 0;
 	int gtk_font_options_all = 0;
 	char buf2[BUF_LONG];
@@ -5796,12 +6078,23 @@ pidgin_conv_write_conv(PurpleConversatio
 	char *str;
 	char *with_font_tag;
 	char *sml_attrib = NULL;
+#endif
 	size_t length;
 	PurpleConversationType type;
 	char *displaying;
 	gboolean plugin_return;
+#if 0
 	gboolean is_rtl_message = FALSE;
+#endif
 
+	const char *message_html;
+	char *msg;
+	char *escape;
+	char *script;
+	char *smileyed;
+	PurpleMessageFlags old_flags;
+	const char *func = "appendMessage";
+
 	g_return_if_fail(conv != NULL);
 	gtkconv = PIDGIN_CONVERSATION(conv);
 	g_return_if_fail(gtkconv != NULL);
@@ -5857,6 +6150,36 @@ pidgin_conv_write_conv(PurpleConversatio
 	}
 	length = strlen(displaying) + 1;
 
+	old_flags = gtkconv->last_flags;
+	if ((flags & PURPLE_MESSAGE_SEND) && (old_flags & PURPLE_MESSAGE_SEND)) {
+		message_html = pidgin_conversation_theme_get_template(gtkconv->theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_OUTGOING_NEXT_CONTENT);
+		func = "appendNextMessage";
+	} else if (flags & PURPLE_MESSAGE_SEND) {
+		message_html = pidgin_conversation_theme_get_template(gtkconv->theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_OUTGOING_CONTENT);
+	} else if ((flags & PURPLE_MESSAGE_RECV) && (old_flags & PURPLE_MESSAGE_RECV)) {
+		message_html = pidgin_conversation_theme_get_template(gtkconv->theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_INCOMING_NEXT_CONTENT);
+		func = "appendNextMessage";
+	} else if (flags & PURPLE_MESSAGE_RECV) {
+		message_html = pidgin_conversation_theme_get_template(gtkconv->theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_INCOMING_CONTENT);
+	} else {
+		message_html = pidgin_conversation_theme_get_template(gtkconv->theme, PIDGIN_CONVERSATION_THEME_TEMPLATE_STATUS);
+	}
+	gtkconv->last_flags = flags;
+
+	smileyed = smiley_parse_markup(message, purple_account_get_protocol_id(account));
+	msg = replace_message_tokens(message_html, conv, name, alias, smileyed, flags, mtime);
+	escape = gtk_webview_quote_js_string(msg);
+	script = g_strdup_printf("%s(%s)", func, escape);
+
+	purple_debug_info("webkit", "JS: %s\n", script);
+	gtk_webview_safe_execute_script(GTK_WEBVIEW(gtkconv->webview), script);
+
+	g_free(script);
+	g_free(smileyed);
+	g_free(msg);
+	g_free(escape);
+
+#if 0
 	/* if the buffer is not empty add a <br> */
 	if (!gtk_webview_is_empty(GTK_WEBVIEW(gtkconv->webview)))
 		gtk_webview_append_html(GTK_WEBVIEW(gtkconv->webview), "<br />");
@@ -6048,6 +6371,8 @@ pidgin_conv_write_conv(PurpleConversatio
 	g_free(mdate);
 	g_free(sml_attrib);
 
+#endif
+
 	/* Tab highlighting stuff */
 	if (!(flags & PURPLE_MESSAGE_SEND) && !pidgin_conv_has_focus(conv))
 	{
@@ -6066,11 +6391,13 @@ pidgin_conv_write_conv(PurpleConversatio
 		gtkconv_set_unseen(gtkconv, unseen);
 	}
 
+#if 0
 	if (!(flags & PURPLE_MESSAGE_RECV) && (conv->features & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY))
 	{
 		/* Restore the smiley-data */
 		pidgin_themes_smiley_themeize(gtkconv->webview);
 	}
+#endif
 
 	purple_signal_emit(pidgin_conversations_get_handle(),
 		(type == PURPLE_CONV_TYPE_IM ? "displayed-im-msg" : "displayed-chat-msg"),
@@ -6715,8 +7042,10 @@ pidgin_conv_update_fields(PurpleConversa
 		}
 	}
 
+#if 0
 	if (fields & PIDGIN_CONV_SMILEY_THEME)
 		pidgin_themes_smiley_themeize(PIDGIN_CONVERSATION(conv)->webview);
+#endif
 
 	if ((fields & PIDGIN_CONV_COLORIZE_TITLE) ||
 			(fields & PIDGIN_CONV_SET_TITLE) ||
============================================================
--- pidgin/gtkconv.h	8d07a686687532827af82d88291a9255f5a8372a
+++ pidgin/gtkconv.h	770f8553da65a89ad578903abd7f0732c250aec6
@@ -65,6 +65,7 @@ enum {
 #include "pidgin.h"
 #include "conversation.h"
 #include "gtkconvwin.h"
+#include "gtkconv-theme.h"
 
 /**************************************************************************
  * @name Structures
@@ -95,6 +96,8 @@ struct _PidginConversation
 	GtkWidget *tabby;
 	GtkWidget *menu_tabby;
 
+	PidginConvTheme *theme;
+	PurpleMessageFlags last_flags;
 	GtkWidget *webview;
 	GtkTextBuffer *entry_buffer;
 	GtkWidget *entry;
============================================================
--- pidgin/gtkconv-theme.c	8f1a1f367f4e464a9d324f00efb837a07b7a168b
+++ pidgin/gtkconv-theme.c	334f181aa885e5d714d1684c8768bd3479415a65
@@ -34,9 +34,6 @@
 #include <stdlib.h>
 #include <string.h>
 
-/* GObject data keys - this will probably go away soon... */
-#define MESSAGE_STYLE_KEY "message-style"
-
 #define PIDGIN_CONV_THEME_GET_PRIVATE(Gobject) \
 	(G_TYPE_INSTANCE_GET_PRIVATE((Gobject), PIDGIN_TYPE_CONV_THEME, PidginConvThemePrivate))
 
@@ -493,160 +490,6 @@ get_outgoing_next_context_html(PidginCon
 	return priv->outgoing_next_context_html;
 }
 
-static char *
-replace_header_tokens(const char *text, PurpleConversation *conv)
-{
-	GString *str = g_string_new(NULL);
-	const char *cur = text;
-	const char *prev = cur;
-
-	if (text == NULL)
-		return NULL;
-
-	while ((cur = strchr(cur, '%'))) {
-		const char *replace = NULL;
-		char *fin = NULL;
-
-		if (!strncmp(cur, "%chatName%", strlen("%chatName%"))) {
-			replace = conv->name;
-		} else if (!strncmp(cur, "%sourceName%", strlen("%sourceName%"))) {
-			replace = purple_account_get_alias(conv->account);
-			if (replace == NULL)
-				replace = purple_account_get_username(conv->account);
-		} else if (!strncmp(cur, "%destinationName%", strlen("%destinationName%"))) {
-			PurpleBuddy *buddy = purple_find_buddy(conv->account, conv->name);
-			if (buddy) {
-				replace = purple_buddy_get_alias(buddy);
-			} else {
-				replace = conv->name;
-			}
-		} else if (!strncmp(cur, "%incomingIconPath%", strlen("%incomingIconPath%"))) {
-			PurpleBuddyIcon *icon = purple_conv_im_get_icon(PURPLE_CONV_IM(conv));
-			replace = purple_buddy_icon_get_full_path(icon);
-		} else if (!strncmp(cur, "%outgoingIconPath%", strlen("%outgoingIconPath%"))) {
-		} else if (!strncmp(cur, "%timeOpened", strlen("%timeOpened"))) {
-			char *format = NULL;
-			if (*(cur + strlen("%timeOpened")) == '{') {
-				const char *start = cur + strlen("%timeOpened") + 1;
-				char *end = strstr(start, "}%");
-				if (!end) /* Invalid string */
-					continue;
-				format = g_strndup(start, end - start);
-				fin = end + 1;
-			}
-			replace = purple_utf8_strftime(format ? format : "%X", NULL);
-			g_free(format);
-		} else {
-			continue;
-		}
-
-		/* Here we have a replacement to make */
-		g_string_append_len(str, prev, cur - prev);
-		g_string_append(str, replace);
-
-		/* And update the pointers */
-		if (fin) {
-			prev = cur = fin + 1;
-		} else {
-			prev = cur = strchr(cur + 1, '%') + 1;
-		}
-	}
-
-	/* And wrap it up */
-	g_string_append(str, prev);
-	return g_string_free(str, FALSE);
-}
-
-static char *
-replace_template_tokens(PidginConvTheme *theme, const char *text, const char *header, const char *footer)
-{
-	PidginConvThemePrivate *priv = PIDGIN_CONV_THEME_GET_PRIVATE(theme);
-	GString *str = g_string_new(NULL);
-	const char *themedir;
-
-	char **ms = g_strsplit(text, "%@", 6);
-	char *base = NULL;
-	char *csspath = pidgin_conversation_theme_get_css(theme);
-	if (ms[0] == NULL || ms[1] == NULL || ms[2] == NULL || ms[3] == NULL || ms[4] == NULL || ms[5] == NULL) {
-		g_strfreev(ms);
-		g_string_free(str, TRUE);
-		return NULL;
-	}
-
-	themedir = purple_theme_get_dir(PURPLE_THEME(theme));
-
-	g_string_append(str, ms[0]);
-	g_string_append(str, "file://");
-	base = g_build_filename(themedir, "Contents", "Resources", "Template.html", NULL);
-	g_string_append(str, base);
-	g_free(base);
-
-	g_string_append(str, ms[1]);
-
-	g_string_append(str, get_basestyle_css(priv, themedir));
-
-	g_string_append(str, ms[2]);
-
-	g_string_append(str, "file://");
-	g_string_append(str, csspath);
-
-	g_string_append(str, ms[3]);
-	if (header)
-		g_string_append(str, header);
-	g_string_append(str, ms[4]);
-	if (footer)
-		g_string_append(str, footer);
-	g_string_append(str, ms[5]);
-
-	g_strfreev(ms);
-	g_free(csspath);
-	return g_string_free(str, FALSE);
-}
-
-static void
-set_theme_webkit_settings(WebKitWebView *webview, PidginConvTheme *theme)
-{
-	PidginConvThemePrivate *priv = PIDGIN_CONV_THEME_GET_PRIVATE(theme);
-	WebKitWebSettings *settings;
-	const GValue *val;
-
-	g_object_get(G_OBJECT(webview), "settings", &settings, NULL);
-
-	val = get_key(priv, "DefaultFontFamily", TRUE);
-	if (val && G_VALUE_HOLDS_STRING(val))
-		g_object_set(G_OBJECT(settings), "default-font-family", g_value_get_string(val), NULL);
-
-	val = get_key(priv, "DefaultFontSize", TRUE);
-	if (val && G_VALUE_HOLDS_INT(val))
-		g_object_set(G_OBJECT(settings), "default-font-size", GINT_TO_POINTER(g_value_get_int(val)), NULL);
-
-	val = get_key(priv, "DefaultBackgroundIsTransparent", TRUE);
-	if (val && G_VALUE_HOLDS_BOOLEAN(val))
-		/* this does not work :( */
-		webkit_web_view_set_transparent(webview, g_value_get_boolean(val));
-}
-
-/*
- * The style specification says that if the conversation is a group
- * chat then the <div id="Chat"> element will be given a class
- * 'groupchat'. I can't add another '%@' in Template.html because
- * that breaks style-specific Template.html's. I have to either use libxml
- * or conveniently play with WebKit's javascript engine. The javascript
- * engine should work, but it's not an identical behavior.
- */
-static void
-webkit_set_groupchat(GtkWebView *webview)
-{
-	gtk_webview_safe_execute_script(webview, "document.getElementById('Chat').className = 'groupchat'");
-}
-
-static void
-webkit_on_webview_destroy(GtkObject *object, gpointer data)
-{
-	g_object_unref(G_OBJECT(data));
-	g_object_set_data(G_OBJECT(object), MESSAGE_STYLE_KEY, NULL);
-}
-
 /*****************************************************************************
  * Public API functions
  *****************************************************************************/
@@ -791,33 +634,25 @@ pidgin_conversation_theme_get_variants(P
 	return priv->variants;
 }
 
-PidginConvTheme *
-pidgin_conversation_theme_copy(const PidginConvTheme *theme)
+char *
+pidgin_conversation_theme_get_template_path(PidginConvTheme *theme)
 {
-	PidginConvTheme *ret;
-	PidginConvThemePrivate *old, *new;
+	const char *dir;
+	char *filename;
 
-	old = PIDGIN_CONV_THEME_GET_PRIVATE(theme);
-	ret = g_object_new(PIDGIN_TYPE_CONV_THEME, "directory", purple_theme_get_dir(PURPLE_THEME(theme)), NULL);
-	new = PIDGIN_CONV_THEME_GET_PRIVATE(ret);
+	dir = purple_theme_get_dir(PURPLE_THEME(theme));
+	filename = g_build_filename(dir, "Contents", "Resources", "Template.html", NULL);
 
-	new->variant = g_strdup(old->variant);
+	if (!g_file_test(filename, G_FILE_TEST_EXISTS)) {
+		g_free(filename);
+		filename = g_build_filename(DATADIR, "pidgin", "webkit", "Template.html", NULL);
+	}
 
-	new->template_html = g_strdup(old->template_html);
-	new->header_html = g_strdup(old->header_html);
-	new->footer_html = g_strdup(old->footer_html);
-	new->incoming_content_html = g_strdup(old->incoming_content_html);
-	new->outgoing_content_html = g_strdup(old->outgoing_content_html);
-	new->incoming_next_content_html = g_strdup(old->incoming_next_content_html);
-	new->outgoing_next_content_html = g_strdup(old->outgoing_next_content_html);
-	new->status_html = g_strdup(old->status_html);
-	new->basestyle_css = g_strdup(old->basestyle_css);
-
-	return ret;
+	return filename;
 }
 
 char *
-pidgin_conversation_theme_get_css(PidginConvTheme *theme)
+pidgin_conversation_theme_get_css_path(PidginConvTheme *theme)
 {
 	PidginConvThemePrivate *priv;
 	const char *dir;
@@ -835,66 +670,3 @@ pidgin_conversation_theme_get_css(Pidgin
 	}
 }
 
-/**
- * Called when either a new PurpleConversation is created
- * or when a PidginConversation changes its active PurpleConversation
- * This will not change the theme if the theme is already set.
- * (This is to prevent accidental theme changes if a new
- * PurpleConversation gets added.
- *
- * FIXME: it's not at all clear to me as to how
- * Adium themes handle the case when the PurpleConversation
- * changes.
- */
-void
-pidgin_conversation_theme_apply(PidginConvTheme *theme, PurpleConversation *conv)
-{
-	GtkWidget *webkit = PIDGIN_CONVERSATION(conv)->webview;
-	const char *themedir;
-	char *header, *footer;
-	char *template;
-	char *basedir;
-	char *baseuri;
-	PidginConvTheme *oldTheme;
-	PidginConvTheme *copy;
-	PidginConvThemePrivate *priv;
-
-	priv = PIDGIN_CONV_THEME_GET_PRIVATE(theme);
-
-	oldTheme = g_object_get_data(G_OBJECT(webkit), MESSAGE_STYLE_KEY);
-	if (oldTheme)
-		return;
-
-	g_assert(theme);
-
-	themedir = purple_theme_get_dir(PURPLE_THEME(theme));
-
-	header = replace_header_tokens(get_header_html(priv, themedir), conv);
-	footer = replace_header_tokens(get_footer_html(priv, themedir), conv);
-	template = replace_template_tokens(theme, get_template_html(priv, themedir), header, footer);
-
-	g_assert(template);
-
-	purple_debug_info("webkit", "template: %s\n", template);
-
-	set_theme_webkit_settings(WEBKIT_WEB_VIEW(webkit), theme);
-	basedir = g_build_filename(themedir, "Contents", "Resources", "Template.html", NULL);
-	baseuri = g_strdup_printf("file://%s", basedir);
-	webkit_web_view_load_string(WEBKIT_WEB_VIEW(webkit), template, "text/html", "UTF-8", baseuri);
-
-	copy = pidgin_conversation_theme_copy(theme);
-	g_object_set_data(G_OBJECT(webkit), MESSAGE_STYLE_KEY, copy);
-
-	g_object_unref(G_OBJECT(theme));
-	/* I need to unref this style when the webkit object destroys */
-	g_signal_connect(G_OBJECT(webkit), "destroy", G_CALLBACK(webkit_on_webview_destroy), copy);
-
-	if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT)
-		webkit_set_groupchat(GTK_WEBVIEW(webkit));
-	g_free(basedir);
-	g_free(baseuri);
-	g_free(header);
-	g_free(footer);
-	g_free(template);
-}
-
============================================================
--- pidgin/gtkconv-theme.h	262be5c04740c99e11df7777c63d93b6114de341
+++ pidgin/gtkconv-theme.h	3703ba487e76411f439a1efa979d4467d0b1c0a3
@@ -173,13 +173,24 @@ const GList *pidgin_conversation_theme_g
  */
 const GList *pidgin_conversation_theme_get_variants(PidginConvTheme *theme);
 
-PidginConvTheme *pidgin_conversation_theme_copy(const PidginConvTheme *theme);
+/**
+ * Get the path to the template HTML file.
+ *
+ * @param theme The conversation theme
+ *
+ * @return The path to the HTML file.
+ */
+char *pidgin_conversation_theme_get_template_path(PidginConvTheme *theme);
 
-char *pidgin_conversation_theme_get_css(PidginConvTheme *theme);
+/**
+ * Get the path to the current variant CSS file.
+ *
+ * @param theme The conversation theme
+ *
+ * @return The path to the CSS file.
+ */
+char *pidgin_conversation_theme_get_css_path(PidginConvTheme *theme);
 
-void
-pidgin_conversation_theme_apply(PidginConvTheme *theme, PurpleConversation *conv);
-
 G_END_DECLS
 #endif /* PIDGIN_CONV_THEME_H */
 


More information about the Commits mailing list