aboutsummaryrefslogtreecommitdiffstats
path: root/libempathy-gtk
diff options
context:
space:
mode:
authorDanielle Madeley <danielle.madeley@collabora.co.uk>2011-05-27 09:51:03 +0800
committerDanielle Madeley <danielle.madeley@collabora.co.uk>2011-05-27 09:51:03 +0800
commit338a6e059140221da55fce7cb74a472fcf32ffb4 (patch)
tree5404f992d9efada0603b0bc43377e9f400be7f0b /libempathy-gtk
parentadcea193bbc45b44312b82742612ea7e9a0d786d (diff)
parent8b452ff5ccbc7643c63a6ecda90bea4dcf899284 (diff)
downloadgsoc2013-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.c12
-rw-r--r--libempathy-gtk/empathy-chat-view.h4
-rw-r--r--libempathy-gtk/empathy-chat.c55
-rw-r--r--libempathy-gtk/empathy-images.h2
-rw-r--r--libempathy-gtk/empathy-log-window.c7
-rw-r--r--libempathy-gtk/empathy-theme-adium.c126
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);
}