/pidgin/main: bc5253318167: Show smiley images in the input entr...
Tomasz Wasilczyk
twasilczyk at pidgin.im
Tue Apr 8 12:01:13 EDT 2014
Changeset: bc525331816791228c48650e79ddb38f4c605dff
Author: Tomasz Wasilczyk <twasilczyk at pidgin.im>
Date: 2014-04-08 18:01 +0200
Branch: default
URL: https://hg.pidgin.im/pidgin/main/rev/bc5253318167
Description:
Show smiley images in the input entry and fix some smiley and inline image issues
diffstat:
libpurple/protocols/gg/message-prpl.c | 4 +-
pidgin/gtkconv.c | 47 +++++++++++-------------------
pidgin/gtkwebview.c | 53 +++++++++++++++++++++++++++++++++-
pidgin/gtkwebview.h | 11 +++++++
pidgin/gtkwebviewtoolbar.c | 40 +++++++++++++++++++------
5 files changed, 112 insertions(+), 43 deletions(-)
diffs (truncated from 344 to 300 lines):
diff --git a/libpurple/protocols/gg/message-prpl.c b/libpurple/protocols/gg/message-prpl.c
--- a/libpurple/protocols/gg/message-prpl.c
+++ b/libpurple/protocols/gg/message-prpl.c
@@ -654,7 +654,7 @@ gchar * ggp_message_format_to_gg(PurpleC
if (style)
styles = ggp_html_css_attribs(style);
- if ((val = g_hash_table_lookup(styles,
+ if (styles && (val = g_hash_table_lookup(styles,
"background-color")) != NULL)
{
int color = ggp_html_decode_color(val);
@@ -662,7 +662,7 @@ gchar * ggp_message_format_to_gg(PurpleC
font_new->bgcolor = color;
}
- if ((val = g_hash_table_lookup(styles,
+ if (styles && (val = g_hash_table_lookup(styles,
"color")) != NULL)
{
int color = ggp_html_decode_color(val);
diff --git a/pidgin/gtkconv.c b/pidgin/gtkconv.c
--- a/pidgin/gtkconv.c
+++ b/pidgin/gtkconv.c
@@ -621,7 +621,7 @@ send_cb(GtkWidget *widget, PidginConvers
PurpleAccount *account;
PurpleConnection *gc;
PurpleMessageFlags flags = 0;
- char *buf, *clean;
+ char *buf;
account = purple_conversation_get_account(conv);
@@ -637,17 +637,13 @@ send_cb(GtkWidget *widget, PidginConvers
if (!purple_account_is_connected(account))
return;
+ if (pidgin_webview_is_empty(PIDGIN_WEBVIEW(gtkconv->entry)))
+ return;
+
buf = pidgin_webview_get_body_html(PIDGIN_WEBVIEW(gtkconv->entry));
- clean = pidgin_webview_get_body_text(PIDGIN_WEBVIEW(gtkconv->entry));
gtk_widget_grab_focus(gtkconv->entry);
- if (!*clean) {
- g_free(buf);
- g_free(clean);
- return;
- }
-
purple_idle_touch();
#if 0
@@ -678,7 +674,6 @@ send_cb(GtkWidget *widget, PidginConvers
purple_conversation_send_with_flags(conv, buf, flags);
}
- g_free(clean);
g_free(buf);
conversation_entry_clear(gtkconv);
@@ -1951,24 +1946,22 @@ gtkconv_cycle_focus(PidginConversation *
static void
update_typing_inserting(PidginConversation *gtkconv)
{
- gchar *text;
+ gboolean is_empty;
g_return_if_fail(gtkconv != NULL);
- text = pidgin_webview_get_body_text(PIDGIN_WEBVIEW(gtkconv->entry));
-
- got_typing_keypress(gtkconv, text[0] == '\0' || !strcmp(text, "\n"));
-
- g_free(text);
+ is_empty = pidgin_webview_is_empty(PIDGIN_WEBVIEW(gtkconv->entry));
+
+ got_typing_keypress(gtkconv, is_empty);
}
static gboolean
update_typing_deleting_cb(PidginConversation *gtkconv)
{
PurpleIMConversation *im = PURPLE_IM_CONVERSATION(gtkconv->active_conv);
- gchar *text = pidgin_webview_get_body_text(PIDGIN_WEBVIEW(gtkconv->entry));
-
- if (!*text || !strcmp(text, "\n")) {
+ gboolean is_empty = pidgin_webview_is_empty(PIDGIN_WEBVIEW(gtkconv->entry));
+
+ if (!is_empty) {
/* We deleted all the text, so turn off typing. */
purple_im_conversation_stop_send_typed_timeout(im);
@@ -1980,7 +1973,6 @@ update_typing_deleting_cb(PidginConversa
/* We're deleting, but not all of it, so it counts as typing. */
got_typing_keypress(gtkconv, FALSE);
}
- g_free(text);
return FALSE;
}
@@ -1988,16 +1980,14 @@ update_typing_deleting_cb(PidginConversa
static void
update_typing_deleting(PidginConversation *gtkconv)
{
- gchar *text;
+ gboolean is_empty;
g_return_if_fail(gtkconv != NULL);
- text = pidgin_webview_get_body_text(PIDGIN_WEBVIEW(gtkconv->entry));
-
- if (*text && strcmp(text, "\n"))
+ is_empty = pidgin_webview_is_empty(PIDGIN_WEBVIEW(gtkconv->entry));
+
+ if (!is_empty)
purple_timeout_add(0, (GSourceFunc)update_typing_deleting_cb, gtkconv);
-
- g_free(text);
}
static gboolean
@@ -4926,7 +4916,7 @@ entry_popup_menu_cb(PidginWebView *webvi
{
GtkWidget *menuitem;
PidginConversation *gtkconv = data;
- char *tmp;
+ gboolean is_empty;
g_return_if_fail(menu != NULL);
g_return_if_fail(gtkconv != NULL);
@@ -4934,10 +4924,9 @@ entry_popup_menu_cb(PidginWebView *webvi
menuitem = pidgin_new_item_from_stock(NULL, _("_Send"), NULL,
G_CALLBACK(send_cb), gtkconv,
0, 0, NULL);
- tmp = pidgin_webview_get_body_text(webview);
- if (!tmp || !*tmp)
+ is_empty = pidgin_webview_is_empty(webview);
+ if (is_empty)
gtk_widget_set_sensitive(menuitem, FALSE);
- g_free(tmp);
gtk_menu_shell_insert(GTK_MENU_SHELL(menu), menuitem, 0);
menuitem = gtk_separator_menu_item_new();
diff --git a/pidgin/gtkwebview.c b/pidgin/gtkwebview.c
--- a/pidgin/gtkwebview.c
+++ b/pidgin/gtkwebview.c
@@ -121,6 +121,9 @@ typedef struct _PidginWebViewPriv {
static WebKitWebViewClass *parent_class = NULL;
+static GRegex *smileys_re = NULL;
+static GRegex *empty_html_re = NULL;
+
/******************************************************************************
* Helpers
@@ -1256,6 +1259,14 @@ pidgin_webview_class_init(PidginWebViewC
purple_prefs_add_none(PIDGIN_PREFS_ROOT "/webview");
purple_prefs_add_bool(PIDGIN_PREFS_ROOT "/webview/inspector_enabled", FALSE);
+
+ g_return_if_fail(smileys_re == NULL);
+ g_return_if_fail(empty_html_re == NULL);
+ smileys_re = g_regex_new("<img[^>]* class=\"emoticon "
+ "[^\"^>]*\"[^>]*alt=\"([^\"^>]+)\"[^>]*>",
+ G_REGEX_DOTALL | G_REGEX_OPTIMIZE, 0, NULL);
+ empty_html_re = g_regex_new("<(?!img)[^>]*>",
+ G_REGEX_DOTALL | G_REGEX_OPTIMIZE, 0, NULL);
}
static void
@@ -1680,20 +1691,28 @@ pidgin_webview_get_head_html(PidginWebVi
return html;
}
+static gchar *
+pidgin_webview_strip_smileys(const gchar *text)
+{
+ return g_regex_replace(smileys_re, text, -1, 0, "\\1", 0, NULL);
+}
+
gchar *
pidgin_webview_get_body_html(PidginWebView *webview)
{
WebKitDOMDocument *doc;
WebKitDOMHTMLElement *body;
- gchar *html;
+ gchar *html, *stripped;
g_return_val_if_fail(webview != NULL, NULL);
doc = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview));
body = webkit_dom_document_get_body(doc);
html = webkit_dom_html_element_get_inner_html(body);
+ stripped = pidgin_webview_strip_smileys(html);
+ g_free(html);
- return html;
+ return stripped;
}
gchar *
@@ -1734,6 +1753,36 @@ pidgin_webview_get_selected_text(PidginW
return NULL;
}
+static gchar *
+pidgin_webview_strip_empty_html(const gchar *text)
+{
+ return g_regex_replace(empty_html_re, text, -1, 0, "", 0, NULL);
+}
+
+gboolean
+pidgin_webview_is_empty(PidginWebView *webview)
+{
+ gchar *html, *tmp;
+ gboolean is_empty;
+
+ g_return_val_if_fail(webview != NULL, TRUE);
+
+ html = pidgin_webview_get_body_html(webview);
+ tmp = purple_strreplace(html, " ", " ");
+ g_free(html);
+ html = tmp;
+
+ tmp = pidgin_webview_strip_empty_html(html);
+ g_free(html);
+ html = tmp;
+
+ g_strstrip(html);
+ is_empty = (html[0] == '\0');
+ g_free(html);
+
+ return is_empty;
+}
+
void
pidgin_webview_get_caret(PidginWebView *webview, WebKitDOMNode **container_ret,
glong *pos_ret)
diff --git a/pidgin/gtkwebview.h b/pidgin/gtkwebview.h
--- a/pidgin/gtkwebview.h
+++ b/pidgin/gtkwebview.h
@@ -415,6 +415,17 @@ gchar *pidgin_webview_get_body_text(Pidg
gchar *pidgin_webview_get_selected_text(PidginWebView *webview);
/**
+ * pidgin_webview_is_empty:
+ * @webview: the PidginWebView.
+ *
+ * Checks, if the @webview is empty.
+ *
+ * Returns %TRUES, if the @webview is empty, %FALSE otherwise.
+ */
+gboolean
+pidgin_webview_is_empty(PidginWebView *webview);
+
+/**
* pidgin_webview_get_caret:
* @webview: The PidginWebView
* @container_ret: A pointer to a pointer to a WebKitDOMNode. This pointer
diff --git a/pidgin/gtkwebviewtoolbar.c b/pidgin/gtkwebviewtoolbar.c
--- a/pidgin/gtkwebviewtoolbar.c
+++ b/pidgin/gtkwebviewtoolbar.c
@@ -702,15 +702,29 @@ close_smiley_dialog(PidginWebViewToolbar
static void
insert_smiley_text(GtkWidget *widget, PidginWebViewToolbar *toolbar)
{
- char *smiley_text, *escaped_smiley;
+ PurpleSmiley *smiley;
+ PurpleStoredImage *image;
+ int image_id;
+ gchar *escaped_smiley, *smiley_html;
+ const gchar *smiley_class;
- smiley_text = g_object_get_data(G_OBJECT(widget), "smiley_text");
- escaped_smiley = g_markup_escape_text(smiley_text, -1);
+ smiley = g_object_get_data(G_OBJECT(widget), "smiley");
+ smiley_class = g_object_get_data(G_OBJECT(widget), "smiley-class");
+ image = purple_smiley_get_image(smiley);
+ image_id = purple_imgstore_add_with_id(image);
+
+ escaped_smiley = g_markup_escape_text(
+ purple_smiley_get_shortcut(smiley), -1);
+ smiley_html = g_strdup_printf("<img src=\"" PURPLE_STORED_IMAGE_PROTOCOL
+ "%d\" class=\"emoticon %s-emoticon\" alt=\"%s\" title=\"%s\">",
+ image_id, smiley_class, escaped_smiley, escaped_smiley);
+
+ g_free(escaped_smiley);
pidgin_webview_append_html(PIDGIN_WEBVIEW(toolbar->webview),
- escaped_smiley);
+ smiley_html);
- g_free(escaped_smiley);
+ g_free(smiley_html);
close_smiley_dialog(toolbar);
}
More information about the Commits
mailing list