/dev/tomkiewicz/new-smileys: 25085b485441: Remote smileys: parse...

Tomasz Wasilczyk twasilczyk at pidgin.im
Fri Apr 4 08:47:19 EDT 2014


Changeset: 25085b4854410227b7d378c596463f2dec31224f
Author:	 Tomasz Wasilczyk <twasilczyk at pidgin.im>
Date:	 2014-04-04 14:47 +0200
Branch:	 default
URL: https://hg.pidgin.im/dev/tomkiewicz/new-smileys/rev/25085b485441

Description:

Remote smileys: parse them too

diffstat:

 libpurple/smiley-list.c   |   3 +-
 libpurple/smiley-parser.c |  55 +++++++++++++++++++++++++++++++++++-----------
 libpurple/smiley-parser.h |  10 +++++++-
 pidgin/gtkconv.c          |  34 ++++++++++++++++++++++++++++-
 4 files changed, 85 insertions(+), 17 deletions(-)

diffs (204 lines):

diff --git a/libpurple/smiley-list.c b/libpurple/smiley-list.c
--- a/libpurple/smiley-list.c
+++ b/libpurple/smiley-list.c
@@ -127,6 +127,8 @@ purple_smiley_list_add(PurpleSmileyList 
 	g_object_set_data(G_OBJECT(smiley), "purple-smiley-list-elem",
 		priv->smileys_end);
 
+	g_hash_table_insert(priv->shortcut_map, g_strdup(shortcut), smiley);
+
 	smiley_path = purple_smiley_get_path(smiley);
 
 	/* TODO: add to the table, when smiley sets the path */
@@ -137,7 +139,6 @@ purple_smiley_list_add(PurpleSmileyList 
 		g_hash_table_insert(priv->path_map,
 			g_strdup(smiley_path), smiley);
 	}
-	g_hash_table_insert(priv->shortcut_map, g_strdup(shortcut), smiley);
 
 	return TRUE;
 }
diff --git a/libpurple/smiley-parser.c b/libpurple/smiley-parser.c
--- a/libpurple/smiley-parser.c
+++ b/libpurple/smiley-parser.c
@@ -24,6 +24,12 @@
 #include "smiley-custom.h"
 #include "smiley-theme.h"
 
+typedef struct
+{
+	PurpleSmileyParseCb cb;
+	gpointer ui_data;
+} PurpleSmileyParseData;
+
 static gboolean escape_checked = FALSE;
 static gboolean escape_value;
 
@@ -48,48 +54,66 @@ purple_smiley_parse_escape(void)
 }
 
 static gboolean purple_smiley_parse_cb(GString *out, const gchar *word,
-	gpointer _smiley, gpointer _unused)
+	gpointer _smiley, gpointer _parse_data)
 {
+	PurpleSmileyParseData *parse_data = _parse_data;
 	PurpleSmiley *smiley = _smiley;
 
-	g_string_append_printf(out, "<img alt=\"%s\" src=\"%s\" />",
-		word, purple_smiley_get_path(smiley));
+	parse_data->cb(out, smiley, parse_data->ui_data);
 
 	return TRUE;
 }
 
 gchar *
-purple_smiley_parse(const gchar *message, gpointer ui_data)
+purple_smiley_parse(PurpleConversation *conv, const gchar *message,
+	PurpleSmileyParseCb cb, gpointer ui_data)
 {
 	PurpleSmileyTheme *theme;
-	PurpleSmileyList *theme_smileys = NULL;
-	PurpleTrie *theme_trie = NULL, *custom_trie;
-	GSList *tries = NULL, tries_theme, tries_custom;
+	PurpleSmileyList *theme_smileys = NULL, *remote_smileys = NULL;
+	PurpleTrie *theme_trie = NULL, *custom_trie, *remote_trie = NULL;
+	GSList *tries = NULL, tries_theme, tries_custom, tries_remote;
+	PurpleSmileyParseData parse_data;
 
 	if (message == NULL || message[0] == '\0')
 		return g_strdup(message);
 
+	/* get remote smileys */
+	remote_smileys = purple_conversation_get_remote_smileys(conv);
+	if (remote_smileys)
+		remote_trie = purple_smiley_list_get_trie(remote_smileys);
+	if (remote_trie && purple_trie_get_size(remote_trie) == 0)
+		remote_trie = NULL;
+
+	/* get custom smileys */
 	custom_trie = purple_smiley_list_get_trie(
 		purple_smiley_custom_get_list());
 	if (purple_trie_get_size(custom_trie) == 0)
 		custom_trie = NULL;
 
+	/* get theme smileys */
 	theme = purple_smiley_theme_get_current();
 	if (theme != NULL)
 		theme_smileys = purple_smiley_theme_get_smileys(theme, ui_data);
-
 	if (theme_smileys != NULL)
 		theme_trie = purple_smiley_list_get_trie(theme_smileys);
 
-	if (theme_trie == NULL && custom_trie == NULL)
+	/* we have absolutely no smileys */
+	if (theme_trie == NULL && custom_trie == NULL && remote_trie == NULL)
 		return g_strdup(message);
 
-	/* Create a tries list on stack. */
+	/* Create a tries list on the stack. */
 	tries_theme.data = theme_trie;
 	tries_custom.data = custom_trie;
-	tries_theme.next = tries_custom.next = NULL;
-	if (custom_trie != NULL)
-		tries = &tries_custom;
+	tries_remote.data = remote_trie;
+	tries_theme.next = tries_custom.next = tries_remote.next = NULL;
+	if (remote_trie != NULL)
+		tries = &tries_remote;
+	if (custom_trie != NULL) {
+		if (tries)
+			tries->next = &tries_custom;
+		else
+			tries = &tries_custom;
+	}
 	if (theme_trie != NULL) {
 		if (tries)
 			tries->next = &tries_theme;
@@ -100,9 +124,12 @@ purple_smiley_parse(const gchar *message
 	/* XXX: should we parse custom smileys,
 	 * if protocol doesn't support it? */
 
+	parse_data.cb = cb;
+	parse_data.ui_data = ui_data;
+
 	/* TODO: don't replace text within tags, ie. <span style=":)"> */
 	/* TODO: parse greedily (as much as possible) when PurpleTrie
 	 * provides support for it. */
 	return purple_trie_multi_replace(tries, message,
-		purple_smiley_parse_cb, NULL);
+		purple_smiley_parse_cb, &parse_data);
 }
diff --git a/libpurple/smiley-parser.h b/libpurple/smiley-parser.h
--- a/libpurple/smiley-parser.h
+++ b/libpurple/smiley-parser.h
@@ -24,10 +24,18 @@
 
 #include "purple.h"
 
+typedef void (*PurpleSmileyParseCb)(GString *out, PurpleSmiley *smiley,
+	gpointer ui_data);
+
 gboolean
 purple_smiley_parse_escape(void);
 
+/* XXX: this shouldn't be a conv for incoming messages - see
+ * PurpleConversationPrivate#remote_smileys.
+ * For outgoing, we could pass conv in ui_data (or something).
+ */
 gchar *
-purple_smiley_parse(const gchar *message, gpointer ui_data);
+purple_smiley_parse(PurpleConversation *conv, const gchar *message,
+	PurpleSmileyParseCb cb, gpointer ui_data);
 
 #endif /* _PURPLE_SMILEY_PARSER_H_ */
diff --git a/pidgin/gtkconv.c b/pidgin/gtkconv.c
--- a/pidgin/gtkconv.c
+++ b/pidgin/gtkconv.c
@@ -6591,6 +6591,37 @@ replace_message_tokens(
 }
 
 static void
+pidgin_conv_write_smiley(GString *out, PurpleSmiley *smiley,
+	gpointer _proto_name)
+{
+#if 0
+	const gchar *proto_name = _proto_name;
+#endif
+	gchar *escaped_shortcut;
+
+	escaped_shortcut = g_markup_escape_text(
+		purple_smiley_get_shortcut(smiley), -1);
+
+	if (purple_smiley_is_ready(smiley)) {
+		/* XXX: purple_smiley_get_path(smiley) may be NULL
+		 * (for remote smileys) */
+		g_string_append_printf(out, "<img alt=\"%s\" src=\"%s\" />",
+			escaped_shortcut, purple_smiley_get_path(smiley));
+	} else {
+		/* TODO: remove this background, maybe put something into css file? */
+		g_string_append_printf(out,
+			"<span class=\"pending-smiley\" style=\"background: #ccc\">%s</span>",
+			escaped_shortcut);
+		/* TODO: watch for "is-ready" state changes
+		 * (it's not possible without conv handle here) */
+		/* XXX: avoid race condition between is-ready
+		 * call and html being pasted */
+	}
+
+	g_free(escaped_shortcut);
+}
+
+static void
 pidgin_conv_write_conv(PurpleConversation *conv, const char *name, const char *alias,
 						const char *message, PurpleMessageFlags flags,
 						time_t mtime)
@@ -6716,7 +6747,8 @@ pidgin_conv_write_conv(PurpleConversatio
 	gtkconv->last_flags = flags;
 	gtkconv->last_conversed = conv;
 
-	smileyed = purple_smiley_parse(displaying,
+	smileyed = purple_smiley_parse(conv, displaying,
+		pidgin_conv_write_smiley,
 		(gpointer)purple_account_get_protocol_name(account));
 	msg = replace_message_tokens(message_html, conv, name, alias, smileyed, flags, mtime);
 	escape = pidgin_webview_quote_js_string(msg ? msg : "");



More information about the Commits mailing list