diff options
-rw-r--r-- | configure.ac | 2 | ||||
-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 | 69 | ||||
-rw-r--r-- | libempathy-gtk/empathy-images.h | 2 | ||||
-rw-r--r-- | libempathy-gtk/empathy-log-window.c | 9 | ||||
-rw-r--r-- | libempathy-gtk/empathy-theme-adium.c | 191 | ||||
-rw-r--r-- | libempathy/empathy-message.c | 138 | ||||
-rw-r--r-- | libempathy/empathy-message.h | 4 |
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); |