diff options
author | Danielle Madeley <danielle.madeley@collabora.co.uk> | 2011-05-27 09:51:03 +0800 |
---|---|---|
committer | Danielle Madeley <danielle.madeley@collabora.co.uk> | 2011-05-27 09:51:03 +0800 |
commit | 338a6e059140221da55fce7cb74a472fcf32ffb4 (patch) | |
tree | 5404f992d9efada0603b0bc43377e9f400be7f0b /libempathy-gtk | |
parent | adcea193bbc45b44312b82742612ea7e9a0d786d (diff) | |
parent | 8b452ff5ccbc7643c63a6ecda90bea4dcf899284 (diff) | |
download | gsoc2013-empathy-338a6e059140221da55fce7cb74a472fcf32ffb4.tar gsoc2013-empathy-338a6e059140221da55fce7cb74a472fcf32ffb4.tar.gz gsoc2013-empathy-338a6e059140221da55fce7cb74a472fcf32ffb4.tar.bz2 gsoc2013-empathy-338a6e059140221da55fce7cb74a472fcf32ffb4.tar.lz gsoc2013-empathy-338a6e059140221da55fce7cb74a472fcf32ffb4.tar.xz gsoc2013-empathy-338a6e059140221da55fce7cb74a472fcf32ffb4.tar.zst gsoc2013-empathy-338a6e059140221da55fce7cb74a472fcf32ffb4.zip |
Merge branch 'message-editing-48-more' into empathy-skype
Diffstat (limited to 'libempathy-gtk')
-rw-r--r-- | libempathy-gtk/empathy-chat-view.c | 12 | ||||
-rw-r--r-- | libempathy-gtk/empathy-chat-view.h | 4 | ||||
-rw-r--r-- | libempathy-gtk/empathy-chat.c | 55 | ||||
-rw-r--r-- | libempathy-gtk/empathy-images.h | 2 | ||||
-rw-r--r-- | libempathy-gtk/empathy-log-window.c | 7 | ||||
-rw-r--r-- | libempathy-gtk/empathy-theme-adium.c | 126 |
6 files changed, 192 insertions, 14 deletions
diff --git a/libempathy-gtk/empathy-chat-view.c b/libempathy-gtk/empathy-chat-view.c index 720ff2bbf..b1579c815 100644 --- a/libempathy-gtk/empathy-chat-view.c +++ b/libempathy-gtk/empathy-chat-view.c @@ -100,6 +100,18 @@ empathy_chat_view_append_event_markup (EmpathyChatView *view, } void +empathy_chat_view_edit_message (EmpathyChatView *view, + EmpathyMessage *message) +{ + g_return_if_fail (EMPATHY_IS_CHAT_VIEW (view)); + + if (EMPATHY_TYPE_CHAT_VIEW_GET_IFACE (view)->edit_message) { + EMPATHY_TYPE_CHAT_VIEW_GET_IFACE (view)->edit_message ( + view, message); + } +} + +void empathy_chat_view_scroll (EmpathyChatView *view, gboolean allow_scrolling) { diff --git a/libempathy-gtk/empathy-chat-view.h b/libempathy-gtk/empathy-chat-view.h index d25797db5..f8ef15930 100644 --- a/libempathy-gtk/empathy-chat-view.h +++ b/libempathy-gtk/empathy-chat-view.h @@ -49,6 +49,8 @@ struct _EmpathyChatViewIface { void (*append_event_markup) (EmpathyChatView *view, const gchar *markup_text, const gchar *fallback_text); + void (*edit_message) (EmpathyChatView *view, + EmpathyMessage *message); void (*scroll) (EmpathyChatView *view, gboolean allow_scrolling); void (*scroll_down) (EmpathyChatView *view); @@ -81,6 +83,8 @@ void empathy_chat_view_append_event (EmpathyChatView *view, void empathy_chat_view_append_event_markup (EmpathyChatView *view, const gchar *markup_text, const gchar *fallback_text); +void empathy_chat_view_edit_message (EmpathyChatView *view, + EmpathyMessage *message); void empathy_chat_view_scroll (EmpathyChatView *view, gboolean allow_scrolling); void empathy_chat_view_scroll_down (EmpathyChatView *view); diff --git a/libempathy-gtk/empathy-chat.c b/libempathy-gtk/empathy-chat.c index 43ece8fac..eb915e95d 100644 --- a/libempathy-gtk/empathy-chat.c +++ b/libempathy-gtk/empathy-chat.c @@ -38,6 +38,7 @@ #include <telepathy-glib/account-manager.h> #include <telepathy-glib/util.h> #include <telepathy-logger/log-manager.h> +#include <telepathy-logger/text-event.h> #include <libempathy/empathy-contact-list.h> #include <libempathy/empathy-gsettings.h> #include <libempathy/empathy-utils.h> @@ -1178,19 +1179,29 @@ chat_message_received (EmpathyChat *chat, sender = empathy_message_get_sender (message); - DEBUG ("Appending new message from %s (%d)", - empathy_contact_get_alias (sender), - empathy_contact_get_handle (sender)); + if (empathy_message_is_edit (message)) { + DEBUG ("Editing message '%s' to '%s'", + empathy_message_get_supersedes (message), + empathy_message_get_body (message)); - empathy_chat_view_append_message (chat->view, message); + empathy_chat_view_edit_message (chat->view, message); + } else { + DEBUG ("Appending new message '%s' from %s (%d)", + empathy_message_get_token (message), + empathy_contact_get_alias (sender), + empathy_contact_get_handle (sender)); + + empathy_chat_view_append_message (chat->view, message); - /* We received a message so the contact is no longer composing */ + priv->unread_messages++; + g_signal_emit (chat, signals[NEW_MESSAGE], 0, message, pending); + } + + /* We received a message so the contact is no longer + * composing */ chat_state_changed_cb (priv->tp_chat, sender, TP_CHANNEL_CHAT_STATE_ACTIVE, chat); - - priv->unread_messages++; - g_signal_emit (chat, signals[NEW_MESSAGE], 0, message, pending); } static void @@ -2099,12 +2110,38 @@ got_filtered_messages_cb (GObject *manager, for (l = messages; l; l = g_list_next (l)) { EmpathyMessage *message; + g_assert (TPL_IS_EVENT (l->data)); message = empathy_message_from_tpl_log_event (l->data); g_object_unref (l->data); - empathy_chat_view_append_message (chat->view, message); + if (empathy_message_is_edit (message)) { + /* this is an edited message, create a synthetic event + * using the supersedes token and + * original-message-sent timestamp, that we can then + * replace */ + EmpathyMessage *syn_msg = g_object_new ( + EMPATHY_TYPE_MESSAGE, + "body", "", + "token", empathy_message_get_supersedes (message), + "type", empathy_message_get_tptype (message), + "timestamp", empathy_message_get_original_timestamp (message), + "incoming", empathy_message_is_incoming (message), + "is-backlog", TRUE, + "receiver", empathy_message_get_receiver (message), + "sender", empathy_message_get_sender (message), + NULL); + + empathy_chat_view_append_message (chat->view, syn_msg); + empathy_chat_view_edit_message (chat->view, message); + + g_object_unref (syn_msg); + } else { + /* append the latest message */ + empathy_chat_view_append_message (chat->view, message); + } + g_object_unref (message); } g_list_free (messages); diff --git a/libempathy-gtk/empathy-images.h b/libempathy-gtk/empathy-images.h index e2512d495..c4b8afbfb 100644 --- a/libempathy-gtk/empathy-images.h +++ b/libempathy-gtk/empathy-images.h @@ -46,6 +46,8 @@ G_BEGIN_DECLS #define EMPATHY_IMAGE_LOG "document-open-recent" #define EMPATHY_IMAGE_DOCUMENT_SEND "document-send" #define EMPATHY_IMAGE_AVATAR_DEFAULT "avatar-default" +/* FIXME: need a better icon! */ +#define EMPATHY_IMAGE_EDIT_MESSAGE "format-text-direction-ltr" #define EMPATHY_IMAGE_CALL_MISSED "call-start" #define EMPATHY_IMAGE_CALL_INCOMING "call-start" diff --git a/libempathy-gtk/empathy-log-window.c b/libempathy-gtk/empathy-log-window.c index 30d8ba732..9ad627f99 100644 --- a/libempathy-gtk/empathy-log-window.c +++ b/libempathy-gtk/empathy-log-window.c @@ -786,6 +786,13 @@ get_icon_for_event (TplEvent *event) else if (tpl_entity_get_entity_type (receiver) == TPL_ENTITY_SELF) icon = EMPATHY_IMAGE_CALL_INCOMING; } + else if (TPL_IS_TEXT_EVENT (event)) + { + TplTextEvent *text = TPL_TEXT_EVENT (event); + + if (!tp_str_empty (tpl_text_event_get_supersedes_token (text))) + icon = EMPATHY_IMAGE_EDIT_MESSAGE; + } return icon; } diff --git a/libempathy-gtk/empathy-theme-adium.c b/libempathy-gtk/empathy-theme-adium.c index d22ef2695..025835037 100644 --- a/libempathy-gtk/empathy-theme-adium.c +++ b/libempathy-gtk/empathy-theme-adium.c @@ -252,7 +252,8 @@ static EmpathyStringParser string_parsers_with_smiley[] = { }; static gchar * -theme_adium_parse_body (const gchar *text) +theme_adium_parse_body (const gchar *text, + const gchar *token) { EmpathyStringParser *parsers; GString *string; @@ -268,8 +269,19 @@ theme_adium_parse_body (const gchar *text) * by html tags. Also escape text to make sure html code is * displayed verbatim. */ string = g_string_sized_new (strlen (text)); + + /* wrap this in HTML that allows us to find the message for later + * editing */ + if (!tp_str_empty (token)) + g_string_append_printf (string, + "<span id=\"message-token-%s\">", + token); + empathy_string_parser_substr (text, -1, parsers, string); + if (!tp_str_empty (token)) + g_string_append (string, "</span>"); + g_object_unref (gsettings); return g_string_free (string, FALSE); @@ -437,7 +449,6 @@ theme_adium_append_message (EmpathyChatView *view, EmpathyContact *sender; TpAccount *account; gchar *body_escaped; - const gchar *body; const gchar *name; const gchar *contact_id; EmpathyAvatar *avatar; @@ -465,8 +476,9 @@ theme_adium_append_message (EmpathyChatView *view, if (service_name == NULL) service_name = tp_account_get_protocol (account); timestamp = empathy_message_get_timestamp (msg); - body = empathy_message_get_body (msg); - body_escaped = theme_adium_parse_body (body); + body_escaped = theme_adium_parse_body ( + empathy_message_get_body (msg), + empathy_message_get_token (msg)); name = empathy_contact_get_alias (sender); contact_id = empathy_contact_get_id (sender); @@ -639,6 +651,105 @@ theme_adium_append_event_markup (EmpathyChatView *view, } static void +theme_adium_edit_message (EmpathyChatView *view, + EmpathyMessage *message) +{ + EmpathyThemeAdiumPriv *priv = GET_PRIV (view); + WebKitDOMDocument *doc; + WebKitDOMElement *span; + gchar *id, *parsed_body; + gchar *tooltip, *timestamp; + GtkIconInfo *icon_info; + GError *error = NULL; + + if (priv->pages_loading != 0) { + priv->message_queue = g_list_prepend (priv->message_queue, + g_object_ref (message)); + return; + } + + id = g_strdup_printf ("message-token-%s", + empathy_message_get_supersedes (message)); + /* we don't pass a token here, because doing so will return another + * <span> element, and we don't want nested <span> elements */ + parsed_body = theme_adium_parse_body ( + empathy_message_get_body (message), NULL); + + /* find the element */ + doc = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view)); + span = webkit_dom_document_get_element_by_id (doc, id); + + if (span == NULL) { + DEBUG ("Failed to find id '%s'", id); + goto except; + } + + if (!WEBKIT_DOM_IS_HTML_ELEMENT (span)) { + DEBUG ("Not a HTML element"); + goto except; + } + + /* update the HTML */ + webkit_dom_html_element_set_inner_html (WEBKIT_DOM_HTML_ELEMENT (span), + parsed_body, &error); + + if (error != NULL) { + DEBUG ("Error setting new inner-HTML: %s", error->message); + g_error_free (error); + goto except; + } + + /* set a tooltip */ + timestamp = empathy_time_to_string_local ( + empathy_message_get_timestamp (message), + "%H:%M:%S"); + tooltip = g_strdup_printf (_("Message edited at %s"), timestamp); + + webkit_dom_html_element_set_title (WEBKIT_DOM_HTML_ELEMENT (span), + tooltip); + + g_free (tooltip); + g_free (timestamp); + + /* mark this message as edited */ + icon_info = gtk_icon_theme_lookup_icon (gtk_icon_theme_get_default (), + EMPATHY_IMAGE_EDIT_MESSAGE, 16, 0); + + if (icon_info != NULL) { + /* set the icon as a background image using CSS + * FIXME: the icon won't update in response to theme changes */ + gchar *style = g_strdup_printf ( + "background-image:url('%s');" + "background-repeat:no-repeat;" + "background-position:left center;" + "padding-left:19px;", /* 16px icon + 3px padding */ + gtk_icon_info_get_filename (icon_info)); + + webkit_dom_element_set_attribute (span, "style", style, &error); + + if (error != NULL) { + DEBUG ("Error setting element style: %s", + error->message); + g_clear_error (&error); + /* not fatal */ + } + + g_free (style); + gtk_icon_info_free (icon_info); + } + + goto finally; + +except: + DEBUG ("Could not find message to edit with: %s", + empathy_message_get_body (message)); + +finally: + g_free (id); + g_free (parsed_body); +} + +static void theme_adium_scroll (EmpathyChatView *view, gboolean allow_scrolling) { @@ -849,6 +960,7 @@ theme_adium_iface_init (EmpathyChatViewIface *iface) iface->append_message = theme_adium_append_message; iface->append_event = theme_adium_append_event; iface->append_event_markup = theme_adium_append_event_markup; + iface->edit_message = theme_adium_edit_message; iface->scroll = theme_adium_scroll; iface->scroll_down = theme_adium_scroll_down; iface->get_has_selection = theme_adium_get_has_selection; @@ -879,7 +991,11 @@ theme_adium_load_finished_cb (WebKitWebView *view, while (priv->message_queue) { EmpathyMessage *message = priv->message_queue->data; - theme_adium_append_message (chat_view, message); + if (empathy_message_is_edit (message)) + theme_adium_edit_message (chat_view, message); + else + theme_adium_append_message (chat_view, message); + priv->message_queue = g_list_remove (priv->message_queue, message); g_object_unref (message); } |