/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