Wed, 02 Apr 2014 02:15:56 +0200
Custom smileys: parse and display in toolbar
--- a/libpurple/smiley-custom.c Wed Apr 02 01:08:17 2014 +0200 +++ b/libpurple/smiley-custom.c Wed Apr 02 02:15:56 2014 +0200 @@ -22,6 +22,7 @@ #include "smiley-custom.h" #include "debug.h" +#include "smiley-list.h" #include <glib/gstdio.h> @@ -31,7 +32,7 @@ static gchar *smileys_dir; static gchar *smileys_index; -static PurpleTrie *smileys_trie; +static PurpleSmileyList *smileys_list; static GHashTable *smileys_table; static gboolean disable_write = FALSE; @@ -83,6 +84,7 @@ g_hash_table_insert(smileys_table, g_strdup(shortcut), smiley); + purple_smiley_list_add(smileys_list, smiley); } smiley_node = purple_xmlnode_get_next_twin(smiley_node); @@ -216,6 +218,7 @@ g_free(file_path); g_hash_table_insert(smileys_table, g_strdup(shortcut), smiley); + purple_smiley_list_add(smileys_list, smiley); purple_smiley_custom_save(); return smiley; @@ -239,6 +242,7 @@ } g_unlink(purple_smiley_get_path(smiley)); + purple_smiley_list_remove(smileys_list, smiley); g_hash_table_remove(smileys_table, smiley_shortcut); purple_smiley_custom_save(); } @@ -252,7 +256,9 @@ PurpleTrie * purple_smiley_custom_get_trie(void) { - return smileys_trie; + if (g_hash_table_size(smileys_table) == 0) + return NULL; + return purple_smiley_list_get_trie(smileys_list); } @@ -267,7 +273,7 @@ SMILEYS_DEFAULT_FOLDER, NULL); smileys_index = g_build_filename(purple_user_dir(), SMILEYS_INDEX_FILE, NULL); - smileys_trie = purple_trie_new(); + smileys_list = purple_smiley_list_new(); smileys_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_object_unref); @@ -279,6 +285,6 @@ { g_free(smileys_dir); g_free(smileys_index); - g_object_unref(smileys_trie); + g_object_unref(smileys_list); g_hash_table_destroy(smileys_table); }
--- a/libpurple/smiley-list.c Wed Apr 02 01:08:17 2014 +0200 +++ b/libpurple/smiley-list.c Wed Apr 02 02:15:56 2014 +0200 @@ -23,6 +23,7 @@ #include "dbus-maybe.h" #include "debug.h" +#include "smiley-parser.h" #include "trie.h" #define PURPLE_SMILEY_LIST_GET_PRIVATE(obj) \ @@ -94,6 +95,8 @@ PurpleSmileyListPrivate *priv = PURPLE_SMILEY_LIST_GET_PRIVATE(list); const gchar *smiley_path; gboolean succ; + gchar *tmp = NULL; + const gchar *shortcut; g_return_val_if_fail(priv != NULL, FALSE); g_return_val_if_fail(PURPLE_IS_SMILEY(smiley), FALSE); @@ -104,8 +107,11 @@ return FALSE; } - succ = purple_trie_add(priv->trie, - purple_smiley_get_shortcut(smiley), smiley); + shortcut = purple_smiley_get_shortcut(smiley); + if (purple_smiley_parse_escape()) + shortcut = tmp = g_markup_escape_text(shortcut, -1); + succ = purple_trie_add(priv->trie, shortcut, smiley); + g_free(tmp); if (!succ) return FALSE;
--- a/libpurple/smiley-parser.c Wed Apr 02 01:08:17 2014 +0200 +++ b/libpurple/smiley-parser.c Wed Apr 02 02:15:56 2014 +0200 @@ -21,8 +21,32 @@ #include "smiley-parser.h" +#include "smiley-custom.h" #include "smiley-theme.h" +static gboolean escape_checked = FALSE; +static gboolean escape_value; + +gboolean +purple_smiley_parse_escape(void) +{ + GHashTable *ui_info; + + if (escape_checked) + return escape_value; + + ui_info = purple_core_get_ui_info(); + if (!ui_info) + escape_value = FALSE; + else { + escape_value = GPOINTER_TO_INT(g_hash_table_lookup(ui_info, + "smiley-parser-escape")); + } + + escape_checked = TRUE; + return escape_value; +} + static gboolean purple_smiley_parse_cb(GString *out, const gchar *word, gpointer _smiley, gpointer _unused) { @@ -38,24 +62,42 @@ purple_smiley_parse(const gchar *message, gpointer ui_data) { PurpleSmileyTheme *theme; - PurpleSmileyList *theme_smileys; - PurpleTrie *theme_trie; + PurpleSmileyList *theme_smileys = NULL; + PurpleTrie *theme_trie = NULL, *custom_trie; + GSList *tries = NULL, tries_theme, tries_custom; if (message == NULL || message[0] == '\0') return g_strdup(message); + custom_trie = purple_smiley_custom_get_trie(); + theme = purple_smiley_theme_get_current(); - if (theme == NULL) - return g_strdup(message); + if (theme != NULL) + theme_smileys = purple_smiley_theme_get_smileys(theme, ui_data); - theme_smileys = purple_smiley_theme_get_smileys(theme, ui_data); - if (theme_smileys == NULL) + if (theme_smileys != NULL) + theme_trie = purple_smiley_list_get_trie(theme_smileys); + + if (theme_trie == NULL && custom_trie == NULL) return g_strdup(message); - theme_trie = purple_smiley_list_get_trie(theme_smileys); - g_return_val_if_fail(theme_trie != NULL, g_strdup(message)); + /* Create a tries list on 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; + if (theme_trie != NULL) { + if (tries) + tries->next = &tries_theme; + else + tries = &tries_theme; + } + + /* XXX: should we parse custom smileys, + * if protocol doesn't support it? */ /* TODO: don't replace text within tags, ie. <span style=":)"> */ - return purple_trie_replace(theme_trie, message, + return purple_trie_multi_replace(tries, message, purple_smiley_parse_cb, NULL); }
--- a/libpurple/smiley-parser.h Wed Apr 02 01:08:17 2014 +0200 +++ b/libpurple/smiley-parser.h Wed Apr 02 02:15:56 2014 +0200 @@ -24,6 +24,9 @@ #include "purple.h" +gboolean +purple_smiley_parse_escape(void); + gchar * purple_smiley_parse(const gchar *message, gpointer ui_data);
--- a/pidgin/gtkwebview.c Wed Apr 02 01:08:17 2014 +0200 +++ b/pidgin/gtkwebview.c Wed Apr 02 02:15:56 2014 +0200 @@ -1884,7 +1884,8 @@ PidginWebViewPriv *priv = PIDGIN_WEBVIEW_GET_PRIVATE(webview); g_return_if_fail(priv != NULL); - g_return_if_fail(priv->toolbar != NULL); + if (priv->toolbar == NULL) + return; pidgin_webviewtoolbar_switch_active_conversation(priv->toolbar, conv); }
--- a/pidgin/gtkwebviewtoolbar.c Wed Apr 02 01:08:17 2014 +0200 +++ b/pidgin/gtkwebviewtoolbar.c Wed Apr 02 02:15:56 2014 +0200 @@ -27,6 +27,7 @@ #include "prefs.h" #include "request.h" #include "pidginstock.h" +#include "smiley-custom.h" #include "smiley-list.h" #include "util.h" #include "debug.h" @@ -821,13 +822,11 @@ { PidginWebViewToolbarPriv *priv = PIDGIN_WEBVIEWTOOLBAR_GET_PRIVATE(toolbar); PurpleSmileyList *smileys_from_theme; - GList *unique_smileys; + GList *theme_smileys, *custom_smileys = NULL; + PidginWebViewButtons webview_format; GtkWidget *dialog, *vbox; GtkWidget *smiley_table = NULL; -#if 0 - const GSList *custom_smileys = NULL; -#endif gboolean supports_custom = FALSE; GtkRequisition req; GtkWidget *scrolled, *viewport; @@ -838,36 +837,30 @@ return; } + webview_format = pidgin_webview_get_format_functions( + PIDGIN_WEBVIEW(toolbar->webview)); + smileys_from_theme = pidgin_smiley_theme_for_conv(priv->active_conv); - unique_smileys = purple_smiley_list_get_unique(smileys_from_theme); + theme_smileys = purple_smiley_list_get_unique(smileys_from_theme); /* TODO: remove hidden */ -#if 0 - supports_custom = (pidgin_webview_get_format_functions(PIDGIN_WEBVIEW(toolbar->webview)) & PIDGIN_WEBVIEW_CUSTOM_SMILEY); - if (toolbar->webview && supports_custom) { - const GSList *iterator = NULL; - custom_smileys = pidgin_smileys_get_all(); - - for (iterator = custom_smileys ; iterator ; - iterator = g_slist_next(iterator)) { - PidginWebViewSmiley *smiley = (PidginWebViewSmiley *)iterator->data; - unique_smileys = g_slist_prepend(unique_smileys, smiley); - } - } -#endif + supports_custom = (webview_format & PIDGIN_WEBVIEW_CUSTOM_SMILEY); + if (supports_custom) + custom_smileys = purple_smiley_custom_get_all(); dialog = pidgin_create_dialog(_("Smile!"), 0, "smiley_dialog", FALSE); gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_MOUSE); vbox = pidgin_dialog_get_vbox_with_properties(GTK_DIALOG(dialog), FALSE, 0); - if (unique_smileys != NULL) { + if (theme_smileys != NULL || custom_smileys != NULL) { struct smiley_button_list *ls; int max_line_width, num_lines, button_width = 0; /* We use hboxes packed in a vbox */ ls = NULL; max_line_width = 0; - num_lines = floor(sqrt(g_list_length(unique_smileys))); + num_lines = floor(sqrt(g_list_length(theme_smileys) + + g_list_length(custom_smileys))); smiley_table = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); if (supports_custom) { @@ -884,12 +877,12 @@ #if 0 /* create list of smileys sorted by height */ - while (unique_smileys) { - PidginWebViewSmiley *smiley = (PidginWebViewSmiley *)unique_smileys->data; + while (theme_smileys) { + PidginWebViewSmiley *smiley = (PidginWebViewSmiley *)theme_smileys->data; if (!pidgin_webview_smiley_get_hidden(smiley)) { ls = sort_smileys(ls, toolbar, &max_line_width, smiley); } - unique_smileys = g_slist_delete_link(unique_smileys, unique_smileys); + theme_smileys = g_slist_delete_link(theme_smileys, theme_smileys); } #else max_line_width = 300; @@ -899,14 +892,14 @@ max_line_width = MAX(button_width, max_line_width / num_lines); /* pack buttons of the list */ - add_smiley_list(toolbar, smiley_table, unique_smileys, max_line_width); -#if 0 + add_smiley_list(toolbar, smiley_table, theme_smileys, max_line_width); if (supports_custom) { - gtk_box_pack_start(GTK_BOX(smiley_table), gtk_separator_new(GTK_ORIENTATION_HORIZONTAL), TRUE, FALSE, 0); - add_smiley_list(smiley_table, ls, max_line_width, TRUE); + gtk_box_pack_start(GTK_BOX(smiley_table), + gtk_separator_new(GTK_ORIENTATION_HORIZONTAL), + TRUE, FALSE, 0); + add_smiley_list(toolbar, smiley_table, + custom_smileys, max_line_width); } -#endif - g_list_free(unique_smileys); gtk_widget_add_events(dialog, GDK_KEY_PRESS_MASK); } else { @@ -915,6 +908,9 @@ g_signal_connect(G_OBJECT(dialog), "button-press-event", (GCallback)smiley_dialog_input_cb, toolbar); } + g_list_free(theme_smileys); + g_list_free(custom_smileys); + scrolled = pidgin_make_scrollable(smiley_table, GTK_POLICY_NEVER, GTK_POLICY_NEVER, GTK_SHADOW_NONE, -1, -1); gtk_box_pack_start(GTK_BOX(vbox), scrolled, TRUE, TRUE, 0); gtk_widget_show(smiley_table);
--- a/pidgin/libpidgin.c Wed Apr 02 01:08:17 2014 +0200 +++ b/pidgin/libpidgin.c Wed Apr 02 02:15:56 2014 +0200 @@ -354,6 +354,8 @@ */ g_hash_table_insert(ui_info, "prpl-aim-distid", GINT_TO_POINTER(1550)); g_hash_table_insert(ui_info, "prpl-icq-distid", GINT_TO_POINTER(1550)); + + g_hash_table_insert(ui_info, "smiley-parser-escape", GINT_TO_POINTER(TRUE)); } return ui_info;