aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanielle Madeley <danielle.madeley@collabora.co.uk>2011-06-20 18:06:48 +0800
committerDanielle Madeley <danielle.madeley@collabora.co.uk>2011-06-20 18:06:48 +0800
commit6e05d6a2c75fe87e76c509ba3bf73b4ab44e8a12 (patch)
tree526c466cd8e478ccf9f917c1e16af3df8f39c2d1
parent1b47c6c449aa0b884a1029871278396f1d6d6406 (diff)
parent4f4c33a6cab809bae137b9141e0c1697f951e9ec (diff)
downloadgsoc2013-empathy-6e05d6a2c75fe87e76c509ba3bf73b4ab44e8a12.tar
gsoc2013-empathy-6e05d6a2c75fe87e76c509ba3bf73b4ab44e8a12.tar.gz
gsoc2013-empathy-6e05d6a2c75fe87e76c509ba3bf73b4ab44e8a12.tar.bz2
gsoc2013-empathy-6e05d6a2c75fe87e76c509ba3bf73b4ab44e8a12.tar.lz
gsoc2013-empathy-6e05d6a2c75fe87e76c509ba3bf73b4ab44e8a12.tar.xz
gsoc2013-empathy-6e05d6a2c75fe87e76c509ba3bf73b4ab44e8a12.tar.zst
gsoc2013-empathy-6e05d6a2c75fe87e76c509ba3bf73b4ab44e8a12.zip
Merge branch 'message-editing-rebase'
-rw-r--r--configure.ac2
-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.c69
-rw-r--r--libempathy-gtk/empathy-images.h2
-rw-r--r--libempathy-gtk/empathy-log-window.c9
-rw-r--r--libempathy-gtk/empathy-theme-adium.c191
-rw-r--r--libempathy/empathy-message.c138
-rw-r--r--libempathy/empathy-message.h4
9 files changed, 392 insertions, 39 deletions
diff --git a/configure.ac b/configure.ac
index 8854750af..3f01672a3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -53,7 +53,7 @@ LIBCHAMPLAIN_GTK_REQUIRED=0.7.1
LIBCHAMPLAIN_REQUIRED=0.9
NAUTILUS_SENDTO_REQUIRED=2.90.0
NETWORK_MANAGER_REQUIRED=0.7.0
-WEBKIT_REQUIRED=1.3.2
+WEBKIT_REQUIRED=1.3.13
GNOME_CONTROL_CENTER_REQUIRED=2.31.4
# Use --enable-maintainer-mode to disable deprecated symbols,
diff --git a/libempathy-gtk/empathy-chat-view.c b/libempathy-gtk/empathy-chat-view.c
index 43d89dd78..49c384489 100644
--- a/libempathy-gtk/empathy-chat-view.c
+++ b/libempathy-gtk/empathy-chat-view.c
@@ -84,6 +84,18 @@ empathy_chat_view_append_event (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 73245c422..1fa44450a 100644
--- a/libempathy-gtk/empathy-chat-view.h
+++ b/libempathy-gtk/empathy-chat-view.h
@@ -46,6 +46,8 @@ struct _EmpathyChatViewIface {
EmpathyMessage *msg);
void (*append_event) (EmpathyChatView *view,
const gchar *str);
+ void (*edit_message) (EmpathyChatView *view,
+ EmpathyMessage *message);
void (*scroll) (EmpathyChatView *view,
gboolean allow_scrolling);
void (*scroll_down) (EmpathyChatView *view);
@@ -79,6 +81,8 @@ void empathy_chat_view_append_message (EmpathyChatView *view,
EmpathyMessage *msg);
void empathy_chat_view_append_event (EmpathyChatView *view,
const gchar *str);
+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 3c391c864..ecf849aaf 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-keyring.h>
@@ -1336,23 +1337,33 @@ 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));
- /* 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);
+ empathy_chat_view_append_message (chat->view, message);
- if (empathy_message_is_incoming (message)) {
- priv->unread_messages++;
- g_object_notify (G_OBJECT (chat), "nb-unread-messages");
+ if (empathy_message_is_incoming (message)) {
+ priv->unread_messages++;
+ g_object_notify (G_OBJECT (chat), "nb-unread-messages");
+ }
+
+ g_signal_emit (chat, signals[NEW_MESSAGE], 0, message, pending);
}
- 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);
}
static void
@@ -1373,8 +1384,10 @@ chat_message_acknowledged_cb (EmpathyTpChat *tp_chat,
empathy_chat_view_message_acknowledged (chat->view,
message);
- priv->unread_messages--;
- g_object_notify (G_OBJECT (chat), "nb-unread-messages");
+ if (!empathy_message_is_edit (message)) {
+ priv->unread_messages--;
+ g_object_notify (G_OBJECT (chat), "nb-unread-messages");
+ }
}
static void
@@ -2318,12 +2331,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 0761fd778..2962ad6a6 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 "call-start"
#define EMPATHY_IMAGE_CALL_MISSED "call-stop"
diff --git a/libempathy-gtk/empathy-log-window.c b/libempathy-gtk/empathy-log-window.c
index eee79ffb2..4d304c582 100644
--- a/libempathy-gtk/empathy-log-window.c
+++ b/libempathy-gtk/empathy-log-window.c
@@ -771,8 +771,15 @@ get_icon_for_event (TplEvent *event)
{
const gchar *icon = NULL;
+ 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;
+ }
#ifdef HAVE_CALL_LOGS
- if (TPL_IS_CALL_EVENT (event))
+ else if (TPL_IS_CALL_EVENT (event))
{
TplCallEvent *call = TPL_CALL_EVENT (event);
TplCallEndReason reason = tpl_call_event_get_end_reason (call);
diff --git a/libempathy-gtk/empathy-theme-adium.c b/libempathy-gtk/empathy-theme-adium.c
index 0370b9055..bb2b189ca 100644
--- a/libempathy-gtk/empathy-theme-adium.c
+++ b/libempathy-gtk/empathy-theme-adium.c
@@ -59,7 +59,7 @@ typedef struct {
gint64 last_timestamp;
gboolean last_is_backlog;
guint pages_loading;
- /* Queue of GValue* containing an EmpathyMessage or string */
+ /* Queue of QueuedItem*s containing an EmpathyMessage or string */
GQueue message_queue;
/* Queue of owned gchar* of message token to remove unread
* marker for when we lose focus. */
@@ -119,6 +119,45 @@ G_DEFINE_TYPE_WITH_CODE (EmpathyThemeAdium, empathy_theme_adium,
G_IMPLEMENT_INTERFACE (EMPATHY_TYPE_CHAT_VIEW,
theme_adium_iface_init));
+enum {
+ QUEUED_EVENT,
+ QUEUED_MESSAGE,
+ QUEUED_EDIT
+};
+
+typedef struct {
+ guint type;
+ EmpathyMessage *msg;
+ char *str;
+} QueuedItem;
+
+static QueuedItem *
+queue_item (GQueue *queue,
+ guint type,
+ EmpathyMessage *msg,
+ const char *str)
+{
+ QueuedItem *item = g_slice_new0 (QueuedItem);
+
+ item->type = type;
+ if (msg != NULL)
+ item->msg = g_object_ref (msg);
+ item->str = g_strdup (str);
+
+ g_queue_push_tail (queue, item);
+
+ return item;
+}
+
+static void
+free_queued_item (QueuedItem *item)
+{
+ tp_clear_object (&item->msg);
+ g_free (item->str);
+
+ g_slice_free (QueuedItem, item);
+}
+
static void
theme_adium_update_enable_webkit_developer_tools (EmpathyThemeAdium *theme)
{
@@ -315,7 +354,8 @@ static EmpathyStringParser string_parsers_with_smiley[] = {
static gchar *
theme_adium_parse_body (EmpathyThemeAdium *self,
- const gchar *text)
+ const gchar *text,
+ const gchar *token)
{
EmpathyThemeAdiumPriv *priv = GET_PRIV (self);
EmpathyStringParser *parsers;
@@ -332,8 +372,19 @@ theme_adium_parse_body (EmpathyThemeAdium *self,
* 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>");
+
/* Wrap body in order to make tabs and multiple spaces displayed
* properly. See bug #625745. */
g_string_prepend (string, "<div style=\"display: inline; "
@@ -817,7 +868,6 @@ theme_adium_append_message (EmpathyChatView *view,
TpMessage *tp_msg;
TpAccount *account;
gchar *body_escaped;
- const gchar *body;
const gchar *name;
const gchar *contact_id;
EmpathyAvatar *avatar;
@@ -832,9 +882,7 @@ theme_adium_append_message (EmpathyChatView *view,
gboolean action;
if (priv->pages_loading != 0) {
- GValue *value = tp_g_value_slice_new (EMPATHY_TYPE_MESSAGE);
- g_value_set_object (value, msg);
- g_queue_push_tail (&priv->message_queue, value);
+ queue_item (&priv->message_queue, QUEUED_MESSAGE, msg, NULL);
return;
}
@@ -846,8 +894,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 (theme, body);
+ body_escaped = theme_adium_parse_body (theme,
+ empathy_message_get_body (msg),
+ empathy_message_get_token (msg));
name = empathy_contact_get_alias (sender);
contact_id = empathy_contact_get_id (sender);
action = (empathy_message_get_tptype (msg) == TP_CHANNEL_TEXT_MESSAGE_TYPE_ACTION);
@@ -1005,8 +1054,7 @@ theme_adium_append_event (EmpathyChatView *view,
gchar *str_escaped;
if (priv->pages_loading != 0) {
- g_queue_push_tail (&priv->message_queue,
- tp_g_value_slice_new_string (str));
+ queue_item (&priv->message_queue, QUEUED_EVENT, NULL, str);
return;
}
@@ -1016,6 +1064,104 @@ theme_adium_append_event (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) {
+ queue_item (&priv->message_queue, QUEUED_EDIT, message, NULL);
+ 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_THEME_ADIUM (view),
+ 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)
{
@@ -1311,6 +1457,7 @@ theme_adium_iface_init (EmpathyChatViewIface *iface)
{
iface->append_message = theme_adium_append_message;
iface->append_event = theme_adium_append_event;
+ 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;
@@ -1341,18 +1488,26 @@ theme_adium_load_finished_cb (WebKitWebView *view,
/* Display queued messages */
for (l = priv->message_queue.head; l != NULL; l = l->next) {
- GValue *value = l->data;
+ QueuedItem *item = l->data;
- if (G_VALUE_HOLDS_OBJECT (value)) {
- theme_adium_append_message (chat_view,
- g_value_get_object (value));
- } else {
- theme_adium_append_event (chat_view,
- g_value_get_string (value));
+ switch (item->type)
+ {
+ case QUEUED_MESSAGE:
+ theme_adium_append_message (chat_view, item->msg);
+ break;
+
+ case QUEUED_EDIT:
+ theme_adium_edit_message (chat_view, item->msg);
+ break;
+
+ case QUEUED_EVENT:
+ theme_adium_append_event (chat_view, item->str);
+ break;
}
- tp_g_value_slice_free (value);
+ free_queued_item (item);
}
+
g_queue_clear (&priv->message_queue);
}
diff --git a/libempathy/empathy-message.c b/libempathy/empathy-message.c
index d9dfc9943..f175a45d3 100644
--- a/libempathy/empathy-message.c
+++ b/libempathy/empathy-message.c
@@ -49,8 +49,11 @@ typedef struct {
TpChannelTextMessageType type;
EmpathyContact *sender;
EmpathyContact *receiver;
+ gchar *token;
+ gchar *supersedes;
gchar *body;
gint64 timestamp;
+ gint64 original_timestamp;
gboolean is_backlog;
guint id;
gboolean incoming;
@@ -74,8 +77,11 @@ enum {
PROP_TYPE,
PROP_SENDER,
PROP_RECEIVER,
+ PROP_TOKEN,
+ PROP_SUPERSEDES,
PROP_BODY,
PROP_TIMESTAMP,
+ PROP_ORIGINAL_TIMESTAMP,
PROP_IS_BACKLOG,
PROP_INCOMING,
PROP_FLAGS,
@@ -117,6 +123,20 @@ empathy_message_class_init (EmpathyMessageClass *class)
EMPATHY_TYPE_CONTACT,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class,
+ PROP_TOKEN,
+ g_param_spec_string ("token",
+ "Message Token",
+ "The message-token",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (object_class,
+ PROP_SUPERSEDES,
+ g_param_spec_string ("supersedes",
+ "Supersedes Token",
+ "The message-token this message supersedes",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (object_class,
PROP_BODY,
g_param_spec_string ("body",
"Message Body",
@@ -133,6 +153,13 @@ empathy_message_class_init (EmpathyMessageClass *class)
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (object_class,
+ PROP_ORIGINAL_TIMESTAMP,
+ g_param_spec_int64 ("original-timestamp",
+ "Original Timestamp",
+ "Timestamp of the original message",
+ G_MININT64, G_MAXINT64, 0,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (object_class,
PROP_IS_BACKLOG,
g_param_spec_boolean ("is-backlog",
"History message",
@@ -201,6 +228,8 @@ empathy_message_finalize (GObject *object)
g_object_unref (priv->tp_message);
}
+ g_free (priv->token);
+ g_free (priv->supersedes);
g_free (priv->body);
G_OBJECT_CLASS (empathy_message_parent_class)->finalize (object);
@@ -226,12 +255,21 @@ message_get_property (GObject *object,
case PROP_RECEIVER:
g_value_set_object (value, priv->receiver);
break;
+ case PROP_TOKEN:
+ g_value_set_string (value, priv->token);
+ break;
+ case PROP_SUPERSEDES:
+ g_value_set_string (value, priv->supersedes);
+ break;
case PROP_BODY:
g_value_set_string (value, priv->body);
break;
case PROP_TIMESTAMP:
g_value_set_int64 (value, priv->timestamp);
break;
+ case PROP_ORIGINAL_TIMESTAMP:
+ g_value_set_int64 (value, priv->original_timestamp);
+ break;
case PROP_IS_BACKLOG:
g_value_set_boolean (value, priv->is_backlog);
break;
@@ -272,6 +310,14 @@ message_set_property (GObject *object,
empathy_message_set_receiver (EMPATHY_MESSAGE (object),
EMPATHY_CONTACT (g_value_get_object (value)));
break;
+ case PROP_TOKEN:
+ g_assert (priv->token == NULL); /* construct only */
+ priv->token = g_value_dup_string (value);
+ break;
+ case PROP_SUPERSEDES:
+ g_assert (priv->supersedes == NULL); /* construct only */
+ priv->supersedes = g_value_dup_string (value);
+ break;
case PROP_BODY:
g_assert (priv->body == NULL); /* construct only */
priv->body = g_value_dup_string (value);
@@ -281,6 +327,9 @@ message_set_property (GObject *object,
if (priv->timestamp <= 0)
priv->timestamp = empathy_time_get_current ();
break;
+ case PROP_ORIGINAL_TIMESTAMP:
+ priv->original_timestamp = g_value_get_int64 (value);
+ break;
case PROP_IS_BACKLOG:
priv->is_backlog = g_value_get_boolean (value);
break;
@@ -307,9 +356,11 @@ empathy_message_from_tpl_log_event (TplEvent *logevent)
TpAccount *account = NULL;
TplEntity *receiver = NULL;
TplEntity *sender = NULL;
- gchar *body= NULL;
+ gchar *body = NULL;
+ const gchar *token = NULL, *supersedes = NULL;
EmpathyContact *contact;
TpChannelTextMessageType type = TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL;
+ gint64 timestamp, original_timestamp = 0;
g_return_val_if_fail (TPL_IS_EVENT (logevent), NULL);
@@ -330,14 +381,34 @@ empathy_message_from_tpl_log_event (TplEvent *logevent)
g_object_unref (acc_man);
if (TPL_IS_TEXT_EVENT (logevent)) {
- body = g_strdup (tpl_text_event_get_message (
- TPL_TEXT_EVENT (logevent)));
+ TplTextEvent *textevent = TPL_TEXT_EVENT (logevent);
+
+ supersedes = tpl_text_event_get_supersedes_token (textevent);
+
+ /* tp-logger is kind of messy in that instead of having
+ * timestamp and original-timestamp like Telepathy it has
+ * timestamp (which is the original) and edited-timestamp,
+ * (which is when the message was edited) */
+ if (tp_str_empty (supersedes)) {
+ /* not an edited message */
+ timestamp = tpl_event_get_timestamp (logevent);
+ } else {
+ /* this is an edited event */
+ original_timestamp = tpl_event_get_timestamp (logevent);
+ timestamp = tpl_text_event_get_edit_timestamp (textevent);
+ }
+
+ body = g_strdup (tpl_text_event_get_message (textevent));
type = tpl_text_event_get_message_type (TPL_TEXT_EVENT (logevent));
+ token = tpl_text_event_get_message_token (textevent);
}
#ifdef HAVE_CALL_LOGS
else if (TPL_IS_CALL_EVENT (logevent)) {
TplCallEvent *call = TPL_CALL_EVENT (logevent);
+
+ timestamp = tpl_event_get_timestamp (logevent);
+
if (tpl_call_event_get_end_reason (call) == TPL_CALL_END_REASON_NO_ANSWER)
body = g_strdup_printf (_("Missed call from %s"),
tpl_entity_get_alias (tpl_event_get_sender (logevent)));
@@ -360,9 +431,12 @@ empathy_message_from_tpl_log_event (TplEvent *logevent)
retval = g_object_new (EMPATHY_TYPE_MESSAGE,
"type", type,
+ "token", token,
+ "supersedes", supersedes,
"body", body,
"is-backlog", TRUE,
- "timestamp", tpl_event_get_timestamp (logevent),
+ "timestamp", timestamp,
+ "original-timestamp", original_timestamp,
NULL);
if (receiver != NULL) {
@@ -474,6 +548,42 @@ empathy_message_set_receiver (EmpathyMessage *message, EmpathyContact *contact)
}
const gchar *
+empathy_message_get_token (EmpathyMessage *message)
+{
+ EmpathyMessagePriv *priv;
+
+ g_return_val_if_fail (EMPATHY_IS_MESSAGE (message), NULL);
+
+ priv = GET_PRIV (message);
+
+ return priv->token;
+}
+
+const gchar *
+empathy_message_get_supersedes (EmpathyMessage *message)
+{
+ EmpathyMessagePriv *priv;
+
+ g_return_val_if_fail (EMPATHY_IS_MESSAGE (message), NULL);
+
+ priv = GET_PRIV (message);
+
+ return priv->supersedes;
+}
+
+gboolean
+empathy_message_is_edit (EmpathyMessage *message)
+{
+ EmpathyMessagePriv *priv;
+
+ g_return_val_if_fail (EMPATHY_IS_MESSAGE (message), FALSE);
+
+ priv = GET_PRIV (message);
+
+ return !tp_str_empty (priv->supersedes);
+}
+
+const gchar *
empathy_message_get_body (EmpathyMessage *message)
{
EmpathyMessagePriv *priv;
@@ -497,6 +607,18 @@ empathy_message_get_timestamp (EmpathyMessage *message)
return priv->timestamp;
}
+gint64
+empathy_message_get_original_timestamp (EmpathyMessage *message)
+{
+ EmpathyMessagePriv *priv;
+
+ g_return_val_if_fail (EMPATHY_IS_MESSAGE (message), -1);
+
+ priv = GET_PRIV (message);
+
+ return priv->original_timestamp;
+}
+
gboolean
empathy_message_is_backlog (EmpathyMessage *message)
{
@@ -662,15 +784,23 @@ empathy_message_new_from_tp_message (TpMessage *tp_msg,
EmpathyMessage *message;
gchar *body;
TpChannelTextMessageFlags flags;
+ gint64 original_timestamp;
+ const GHashTable *part = tp_message_peek (tp_msg, 0);
g_return_val_if_fail (TP_IS_MESSAGE (tp_msg), NULL);
body = tp_message_to_text (tp_msg, &flags);
+ original_timestamp = tp_asv_get_int64 (part,
+ "original-message-received", NULL);
+
message = g_object_new (EMPATHY_TYPE_MESSAGE,
"body", body,
+ "token", tp_message_get_token (tp_msg),
+ "supersedes", tp_message_get_supersedes (tp_msg),
"type", tp_message_get_message_type (tp_msg),
"timestamp", tp_message_get_received_timestamp (tp_msg),
+ "original-timestamp", original_timestamp,
"flags", flags,
"is-backlog", flags & TP_CHANNEL_TEXT_MESSAGE_FLAG_SCROLLBACK,
"incoming", incoming,
diff --git a/libempathy/empathy-message.h b/libempathy/empathy-message.h
index b20ceca16..0c27c09e9 100644
--- a/libempathy/empathy-message.h
+++ b/libempathy/empathy-message.h
@@ -69,7 +69,11 @@ EmpathyContact * empathy_message_get_receiver (EmpathyMessage
void empathy_message_set_receiver (EmpathyMessage *message,
EmpathyContact *contact);
const gchar * empathy_message_get_body (EmpathyMessage *message);
+const gchar * empathy_message_get_token (EmpathyMessage *message);
+const gchar * empathy_message_get_supersedes (EmpathyMessage *message);
+gboolean empathy_message_is_edit (EmpathyMessage *message);
gint64 empathy_message_get_timestamp (EmpathyMessage *message);
+gint64 empathy_message_get_original_timestamp (EmpathyMessage *message);
gboolean empathy_message_is_backlog (EmpathyMessage *message);
gboolean empathy_message_is_incoming (EmpathyMessage *message);