From 9ce98f98818e2ef3d055185747dc540e2650309d Mon Sep 17 00:00:00 2001 From: Danielle Madeley Date: Wed, 18 May 2011 12:51:43 +1000 Subject: Add 'token' property to EmpathyMessage This allows us to pass the 'message-token' from the TpMessage through to the chat-view. --- libempathy/empathy-message.c | 30 ++++++++++++++++++++++++++++++ libempathy/empathy-message.h | 1 + 2 files changed, 31 insertions(+) diff --git a/libempathy/empathy-message.c b/libempathy/empathy-message.c index 15999dcdd..7bb26d0d0 100644 --- a/libempathy/empathy-message.c +++ b/libempathy/empathy-message.c @@ -46,6 +46,7 @@ typedef struct { TpChannelTextMessageType type; EmpathyContact *sender; EmpathyContact *receiver; + gchar *token; gchar *body; gint64 timestamp; gboolean is_backlog; @@ -71,6 +72,7 @@ enum { PROP_TYPE, PROP_SENDER, PROP_RECEIVER, + PROP_TOKEN, PROP_BODY, PROP_TIMESTAMP, PROP_IS_BACKLOG, @@ -112,6 +114,13 @@ empathy_message_class_init (EmpathyMessageClass *class) "The receiver of the message", 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_BODY, g_param_spec_string ("body", @@ -184,6 +193,7 @@ empathy_message_finalize (GObject *object) g_object_unref (priv->receiver); } + g_free (priv->token); g_free (priv->body); G_OBJECT_CLASS (empathy_message_parent_class)->finalize (object); @@ -209,6 +219,9 @@ 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_BODY: g_value_set_string (value, priv->body); break; @@ -252,6 +265,10 @@ 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_BODY: g_assert (priv->body == NULL); /* construct only */ priv->body = g_value_dup_string (value); @@ -435,6 +452,18 @@ empathy_message_set_receiver (EmpathyMessage *message, EmpathyContact *contact) g_object_notify (G_OBJECT (message), "receiver"); } +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_body (EmpathyMessage *message) { @@ -643,6 +672,7 @@ empathy_message_new_from_tp_message (TpMessage *tp_msg, message = g_object_new (EMPATHY_TYPE_MESSAGE, "body", body, + "token", tp_message_get_token (tp_msg), "type", tp_message_get_message_type (tp_msg), "timestamp", tp_message_get_received_timestamp (tp_msg), "flags", flags, diff --git a/libempathy/empathy-message.h b/libempathy/empathy-message.h index 7508cb08e..cbbc6e255 100644 --- a/libempathy/empathy-message.h +++ b/libempathy/empathy-message.h @@ -67,6 +67,7 @@ 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); gint64 empathy_message_get_timestamp (EmpathyMessage *message); gboolean empathy_message_is_backlog (EmpathyMessage *message); gboolean empathy_message_is_incoming (EmpathyMessage *message); -- cgit v1.2.1 From 04e06bd134669152715ea52a33193c50f0ed0d87 Mon Sep 17 00:00:00 2001 From: Danielle Madeley Date: Fri, 20 May 2011 11:34:31 +1000 Subject: Add 'supersedes' property to EmpathyMessage It would be nice to remove EmpathyMessage, because now that TpMessages are a GObject, EmpathyMessage is just an empty abstraction layer that we have to keep punching through. --- libempathy/empathy-message.c | 42 ++++++++++++++++++++++++++++++++++++++++++ libempathy/empathy-message.h | 2 ++ 2 files changed, 44 insertions(+) diff --git a/libempathy/empathy-message.c b/libempathy/empathy-message.c index 7bb26d0d0..4d25b30ae 100644 --- a/libempathy/empathy-message.c +++ b/libempathy/empathy-message.c @@ -47,6 +47,7 @@ typedef struct { EmpathyContact *sender; EmpathyContact *receiver; gchar *token; + gchar *supersedes; gchar *body; gint64 timestamp; gboolean is_backlog; @@ -73,6 +74,7 @@ enum { PROP_SENDER, PROP_RECEIVER, PROP_TOKEN, + PROP_SUPERSEDES, PROP_BODY, PROP_TIMESTAMP, PROP_IS_BACKLOG, @@ -121,6 +123,13 @@ empathy_message_class_init (EmpathyMessageClass *class) "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", @@ -194,6 +203,7 @@ empathy_message_finalize (GObject *object) } g_free (priv->token); + g_free (priv->supersedes); g_free (priv->body); G_OBJECT_CLASS (empathy_message_parent_class)->finalize (object); @@ -222,6 +232,9 @@ message_get_property (GObject *object, 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; @@ -269,6 +282,10 @@ message_set_property (GObject *object, 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); @@ -464,6 +481,30 @@ empathy_message_get_token (EmpathyMessage *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) { @@ -673,6 +714,7 @@ empathy_message_new_from_tp_message (TpMessage *tp_msg, 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), "flags", flags, diff --git a/libempathy/empathy-message.h b/libempathy/empathy-message.h index cbbc6e255..16c9e62e1 100644 --- a/libempathy/empathy-message.h +++ b/libempathy/empathy-message.h @@ -68,6 +68,8 @@ void empathy_message_set_receiver (EmpathyMessage 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); gboolean empathy_message_is_backlog (EmpathyMessage *message); gboolean empathy_message_is_incoming (EmpathyMessage *message); -- cgit v1.2.1 From e15d6b9eef9e7d1f2841e0aff52261e56d52bbfb Mon Sep 17 00:00:00 2001 From: Danielle Madeley Date: Wed, 18 May 2011 12:52:29 +1000 Subject: Add edit_message() method to ChatView iface --- libempathy-gtk/empathy-chat-view.c | 12 ++++++++++++ libempathy-gtk/empathy-chat-view.h | 4 ++++ 2 files changed, 16 insertions(+) diff --git a/libempathy-gtk/empathy-chat-view.c b/libempathy-gtk/empathy-chat-view.c index ada669885..4002e8b31 100644 --- a/libempathy-gtk/empathy-chat-view.c +++ b/libempathy-gtk/empathy-chat-view.c @@ -83,6 +83,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 96365a618..05360e047 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); @@ -75,6 +77,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); -- cgit v1.2.1 From fcbb1d6512afb91b318781f70b59901a239402af Mon Sep 17 00:00:00 2001 From: Danielle Madeley Date: Wed, 18 May 2011 15:56:40 +1000 Subject: Pass edited messages through to the ChatView --- libempathy-gtk/empathy-chat.c | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/libempathy-gtk/empathy-chat.c b/libempathy-gtk/empathy-chat.c index fd43473dd..922fcfc86 100644 --- a/libempathy-gtk/empathy-chat.c +++ b/libempathy-gtk/empathy-chat.c @@ -1172,23 +1172,36 @@ chat_message_received (EmpathyChat *chat, gboolean pending) { EmpathyChatPriv *priv = GET_PRIV (chat); - EmpathyContact *sender; - sender = empathy_message_get_sender (message); + if (empathy_message_is_edit (message)) { + DEBUG ("Editing message '%s' to '%s'", + empathy_message_get_supersedes (message), + empathy_message_get_body (message)); - DEBUG ("Appending new message from %s (%d)", - empathy_contact_get_alias (sender), - empathy_contact_get_handle (sender)); + empathy_chat_view_edit_message (chat->view, message); - empathy_chat_view_append_message (chat->view, message); + /* FIXME: do we need to do things like edit the chat state? */ + } else { + EmpathyContact *sender; + + sender = empathy_message_get_sender (message); + + 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); + + /* 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); + priv->unread_messages++; + g_signal_emit (chat, signals[NEW_MESSAGE], 0, message, pending); + } } static void -- cgit v1.2.1 From 72d86515da906e3c867eff6abd309a8a03a38534 Mon Sep 17 00:00:00 2001 From: Danielle Madeley Date: Wed, 18 May 2011 15:57:55 +1000 Subject: [theme-adium] wrap the messages in so we can find them again This will enable our DOM manipulation --- libempathy-gtk/empathy-theme-adium.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/libempathy-gtk/empathy-theme-adium.c b/libempathy-gtk/empathy-theme-adium.c index 88672554f..712c2fbc5 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, + "", + token); + empathy_string_parser_substr (text, -1, parsers, string); + if (!tp_str_empty (token)) + g_string_append (string, ""); + 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); -- cgit v1.2.1 From 3c402461dd7eb5776f81ecd6d31b6f663315bc26 Mon Sep 17 00:00:00 2001 From: Danielle Madeley Date: Wed, 18 May 2011 16:04:26 +1000 Subject: [theme-adium] implement edit_message() This is done via DOM manipulation, we find the id for the tag we wrapped the message in in the previous commit. We then replace the innerHTML with the new message. This requires a version of WebKitGtk 1.3.x, but I'm not precisely sure what. I used WebKitGtk 1.4.0, but natty only has 1.3.13, so we'll try setting that as the dep. Need to somehow mark a message as edited. Could set a class on it, but that requires support in the theme. Need inspiration here. --- configure.ac | 2 +- libempathy-gtk/empathy-theme-adium.c | 64 +++++++++++++++++++++++++++++++++++- 2 files changed, 64 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index e4cb024f4..3b2618379 100644 --- a/configure.ac +++ b/configure.ac @@ -54,7 +54,7 @@ LIBCHAMPLAIN_GTK_REQUIRED=0.7.1 LIBCHAMPLAIN_REQUIRED=0.7.1 NAUTILUS_SENDTO_REQUIRED=2.31.7 NETWORK_MANAGER_REQUIRED=0.7.0 -WEBKIT_REQUIRED=1.1.15 +WEBKIT_REQUIRED=1.3.13 GNOME_CONTROL_CENTER_GTK3_REQUIRED=2.31.4 # telepathy-yell diff --git a/libempathy-gtk/empathy-theme-adium.c b/libempathy-gtk/empathy-theme-adium.c index 712c2fbc5..05758ed9d 100644 --- a/libempathy-gtk/empathy-theme-adium.c +++ b/libempathy-gtk/empathy-theme-adium.c @@ -642,6 +642,63 @@ theme_adium_append_event (EmpathyChatView *view, g_free (str_escaped); } +static void +theme_adium_edit_message (EmpathyChatView *view, + EmpathyMessage *message) +{ + EmpathyThemeAdiumPriv *priv = GET_PRIV (view); + WebKitDOMDocument *doc; + WebKitDOMElement *span; + gchar *id, *parsed_body; + 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 + * element, and we don't want nested 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 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) @@ -852,6 +909,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; @@ -882,7 +940,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); } -- cgit v1.2.1 From a35ae7f145d2eacaa4c087cb9f2e72f3346e24fb Mon Sep 17 00:00:00 2001 From: Danielle Madeley Date: Fri, 20 May 2011 13:02:22 +1000 Subject: Add a tooltip saying when the message was edited --- libempathy-gtk/empathy-theme-adium.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/libempathy-gtk/empathy-theme-adium.c b/libempathy-gtk/empathy-theme-adium.c index 05758ed9d..b20b43774 100644 --- a/libempathy-gtk/empathy-theme-adium.c +++ b/libempathy-gtk/empathy-theme-adium.c @@ -650,6 +650,7 @@ theme_adium_edit_message (EmpathyChatView *view, WebKitDOMDocument *doc; WebKitDOMElement *span; gchar *id, *parsed_body; + gchar *tooltip, *timestamp; GError *error = NULL; if (priv->pages_loading != 0) { @@ -686,8 +687,21 @@ theme_adium_edit_message (EmpathyChatView *view, 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); + goto finally; except: -- cgit v1.2.1 From 6b6c8f4d75a3bba7aa3bba735749ddd3795a9da1 Mon Sep 17 00:00:00 2001 From: Danielle Madeley Date: Fri, 20 May 2011 13:02:45 +1000 Subject: Add an icon to edited messages Currently this is using "format-text-direction-ltr" which is a crappy choice. We should ask for a better icon. Also, this should really be implemented as a class, so that the icon can change with the theme. Or be made part of the Adium theme, or something. Basically this is kludgey. --- libempathy-gtk/empathy-images.h | 2 ++ libempathy-gtk/empathy-theme-adium.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) 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-theme-adium.c b/libempathy-gtk/empathy-theme-adium.c index b20b43774..5a14902c9 100644 --- a/libempathy-gtk/empathy-theme-adium.c +++ b/libempathy-gtk/empathy-theme-adium.c @@ -651,6 +651,7 @@ theme_adium_edit_message (EmpathyChatView *view, WebKitDOMElement *span; gchar *id, *parsed_body; gchar *tooltip, *timestamp; + GtkIconInfo *icon_info; GError *error = NULL; if (priv->pages_loading != 0) { @@ -702,6 +703,33 @@ theme_adium_edit_message (EmpathyChatView *view, 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: -- cgit v1.2.1 From 24aaea403ecc327f8b7e8dfb8cd722c4a7196089 Mon Sep 17 00:00:00 2001 From: Danielle Madeley Date: Fri, 20 May 2011 15:25:46 +1000 Subject: Set 'token' and 'supersedes' for events from the logger --- configure.ac | 2 +- libempathy/empathy-message.c | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index 3b2618379..6476dd513 100644 --- a/configure.ac +++ b/configure.ac @@ -42,7 +42,7 @@ LIBCANBERRA_GTK_REQUIRED=0.4 LIBNOTIFY_REQUIRED=0.7.0 TELEPATHY_FARSIGHT_REQUIRED=0.0.14 TELEPATHY_GLIB_REQUIRED=0.14.1 -TELEPATHY_LOGGER=0.2.8 +TELEPATHY_LOGGER=0.2.9.1 UNIQUE_REQUIRED=1.1.2 # Optionnal deps diff --git a/libempathy/empathy-message.c b/libempathy/empathy-message.c index 4d25b30ae..a1b7ae0e5 100644 --- a/libempathy/empathy-message.c +++ b/libempathy/empathy-message.c @@ -318,7 +318,7 @@ empathy_message_from_tpl_log_event (TplEvent *logevent) TpAccount *account = NULL; TplEntity *receiver = NULL; TplEntity *sender = NULL; - gchar *body= NULL; + gchar *body = NULL; EmpathyContact *contact; g_return_val_if_fail (TPL_IS_EVENT (logevent), NULL); @@ -340,11 +340,14 @@ 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); + + body = g_strdup (tpl_text_event_get_message (textevent)); retval = g_object_new (EMPATHY_TYPE_MESSAGE, - "type", tpl_text_event_get_message_type (TPL_TEXT_EVENT (logevent)), + "type", tpl_text_event_get_message_type (textevent), + "token", tpl_text_event_get_message_token (textevent), + "supersedes", tpl_text_event_get_supersedes_token (textevent), "body", body, "timestamp", tpl_event_get_timestamp (logevent), "is-backlog", TRUE, -- cgit v1.2.1 From 37ce3315fa4a2a1b12aaf78890b6fe12ab5c81a9 Mon Sep 17 00:00:00 2001 From: Danielle Madeley Date: Fri, 20 May 2011 15:25:58 +1000 Subject: Get the original message from the logger so we can supersede it Strictly, we don't need to do this, we could just use the supersedes-token as the message-token and we'd still be able to edit the messages in the future, but this way we get the nice pretty annotation saying that we edited it and when. --- configure.ac | 2 +- libempathy-gtk/empathy-chat.c | 23 ++++++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 6476dd513..2a60815c9 100644 --- a/configure.ac +++ b/configure.ac @@ -33,7 +33,7 @@ AC_COPYRIGHT([ # Hardp deps FOLKS_REQUIRED=0.4.0 GCONF_REQUIRED=1.2.0 -GLIB_REQUIRED=2.27.2 +GLIB_REQUIRED=2.28.0 GNUTLS_REQUIRED=2.8.5 GSTREAMER_REQUIRED=0.10.32 GTK_REQUIRED=2.22.0 diff --git a/libempathy-gtk/empathy-chat.c b/libempathy-gtk/empathy-chat.c index 922fcfc86..8384b3ef1 100644 --- a/libempathy-gtk/empathy-chat.c +++ b/libempathy-gtk/empathy-chat.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -2052,12 +2053,32 @@ got_filtered_messages_cb (GObject *manager, for (l = messages; l; l = g_list_next (l)) { EmpathyMessage *message; + GList *supersedes; g_assert (TPL_IS_EVENT (l->data)); + /* we need the last message this one supersedes, which is the + * the original */ + supersedes = tpl_text_event_dup_supersedes (l->data); + + if (supersedes != NULL) { + message = empathy_message_from_tpl_log_event ( + g_list_last (supersedes)->data); + empathy_chat_view_append_message (chat->view, message); + + g_object_unref (message); + } + + g_list_free_full (supersedes, g_object_unref); + + /* append the latest message */ 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)) + empathy_chat_view_edit_message (chat->view, message); + else + empathy_chat_view_append_message (chat->view, message); + g_object_unref (message); } g_list_free (messages); -- cgit v1.2.1 From 044b8a712d1b6c411c887c5c56bb3fdb8ce8de53 Mon Sep 17 00:00:00 2001 From: Danielle Madeley Date: Fri, 20 May 2011 15:38:06 +1000 Subject: Set the edited icon for edited messages in the log viewer --- libempathy-gtk/empathy-log-window.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libempathy-gtk/empathy-log-window.c b/libempathy-gtk/empathy-log-window.c index 9b094652d..e3505cd9b 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; } -- cgit v1.2.1 From ff02952a9eb91630317752d9d5e078b1e7713d35 Mon Sep 17 00:00:00 2001 From: Danielle Madeley Date: Thu, 26 May 2011 12:18:36 +1000 Subject: Add 'original-timestamp' to EmpathyMessage --- libempathy/empathy-message.c | 38 +++++++++++++++++++++++++++++++++++--- libempathy/empathy-message.h | 1 + 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/libempathy/empathy-message.c b/libempathy/empathy-message.c index a1b7ae0e5..e1b168b1c 100644 --- a/libempathy/empathy-message.c +++ b/libempathy/empathy-message.c @@ -50,6 +50,7 @@ typedef struct { gchar *supersedes; gchar *body; gint64 timestamp; + gint64 original_timestamp; gboolean is_backlog; guint id; gboolean incoming; @@ -77,6 +78,7 @@ enum { PROP_SUPERSEDES, PROP_BODY, PROP_TIMESTAMP, + PROP_ORIGINAL_TIMESTAMP, PROP_IS_BACKLOG, PROP_INCOMING, PROP_FLAGS, @@ -146,6 +148,13 @@ empathy_message_class_init (EmpathyMessageClass *class) G_MININT64, G_MAXINT64, 0, 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", @@ -241,6 +250,9 @@ message_get_property (GObject *object, 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; @@ -295,6 +307,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; @@ -350,6 +365,7 @@ empathy_message_from_tpl_log_event (TplEvent *logevent) "supersedes", tpl_text_event_get_supersedes_token (textevent), "body", body, "timestamp", tpl_event_get_timestamp (logevent), + "original-timestamp", tpl_text_event_get_original_timestamp (textevent), "is-backlog", TRUE, NULL); @@ -532,6 +548,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) { @@ -709,17 +737,23 @@ empathy_message_new_from_tp_message (TpMessage *tp_msg, gchar *body; TpChannelTextMessageFlags flags; guint id; + 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, @@ -729,9 +763,7 @@ empathy_message_new_from_tp_message (TpMessage *tp_msg, /* FIXME: this is pretty low level, ideally we shouldn't have to use the * ID directly but we don't use TpTextChannel's ack API everywhere yet. */ - id = tp_asv_get_uint32 (tp_message_peek (tp_msg, 0), - "pending-message-id", NULL); - + id = tp_asv_get_uint32 (part, "pending-message-id", NULL); priv->id = id; g_free (body); diff --git a/libempathy/empathy-message.h b/libempathy/empathy-message.h index 16c9e62e1..9c24f6365 100644 --- a/libempathy/empathy-message.h +++ b/libempathy/empathy-message.h @@ -71,6 +71,7 @@ const gchar * empathy_message_get_token (EmpathyMessage 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); -- cgit v1.2.1 From 4b356e81f38ed18ef383a41d1f7c9774d07c9bfe Mon Sep 17 00:00:00 2001 From: Danielle Madeley Date: Wed, 25 May 2011 17:10:12 +1000 Subject: Replace tpl_text_event_dup_supersedes() with synthetic message This allows us to handle the case where we get b-supersedes-a, but we've lost the original message a. --- libempathy-gtk/empathy-chat.c | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/libempathy-gtk/empathy-chat.c b/libempathy-gtk/empathy-chat.c index 8384b3ef1..49bfa5c39 100644 --- a/libempathy-gtk/empathy-chat.c +++ b/libempathy-gtk/empathy-chat.c @@ -2053,31 +2053,37 @@ got_filtered_messages_cb (GObject *manager, for (l = messages; l; l = g_list_next (l)) { EmpathyMessage *message; - GList *supersedes; - g_assert (TPL_IS_EVENT (l->data)); - - /* we need the last message this one supersedes, which is the - * the original */ - supersedes = tpl_text_event_dup_supersedes (l->data); - - if (supersedes != NULL) { - message = empathy_message_from_tpl_log_event ( - g_list_last (supersedes)->data); - empathy_chat_view_append_message (chat->view, message); - - g_object_unref (message); - } - g_list_free_full (supersedes, g_object_unref); + g_assert (TPL_IS_EVENT (l->data)); - /* append the latest message */ message = empathy_message_from_tpl_log_event (l->data); g_object_unref (l->data); - if (empathy_message_is_edit (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); - else + + g_object_unref (syn_msg); + } else { + /* append the latest message */ empathy_chat_view_append_message (chat->view, message); + } g_object_unref (message); } -- cgit v1.2.1 From ac61158fcb011e8a05d48fd35c191c82511c6fa6 Mon Sep 17 00:00:00 2001 From: Danielle Madeley Date: Wed, 25 May 2011 17:13:52 +1000 Subject: Reset the chat state after receiving an edited message --- libempathy-gtk/empathy-chat.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/libempathy-gtk/empathy-chat.c b/libempathy-gtk/empathy-chat.c index 49bfa5c39..6b89024d7 100644 --- a/libempathy-gtk/empathy-chat.c +++ b/libempathy-gtk/empathy-chat.c @@ -1173,6 +1173,9 @@ chat_message_received (EmpathyChat *chat, gboolean pending) { EmpathyChatPriv *priv = GET_PRIV (chat); + EmpathyContact *sender; + + sender = empathy_message_get_sender (message); if (empathy_message_is_edit (message)) { DEBUG ("Editing message '%s' to '%s'", @@ -1180,13 +1183,7 @@ chat_message_received (EmpathyChat *chat, empathy_message_get_body (message)); empathy_chat_view_edit_message (chat->view, message); - - /* FIXME: do we need to do things like edit the chat state? */ } else { - EmpathyContact *sender; - - sender = empathy_message_get_sender (message); - DEBUG ("Appending new message '%s' from %s (%d)", empathy_message_get_token (message), empathy_contact_get_alias (sender), @@ -1194,15 +1191,15 @@ chat_message_received (EmpathyChat *chat, empathy_chat_view_append_message (chat->view, message); - /* 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); } + + /* 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 -- cgit v1.2.1 From 0c4409047369fabaa81315a65a603d8147565a6f Mon Sep 17 00:00:00 2001 From: Danielle Madeley Date: Fri, 27 May 2011 10:31:57 +1000 Subject: Update for new TPL API, we now get timestamp and edit_timestamp This makes it backwards to what we get in Telepathy, but we can manage by translating it into the Telepathy form. --- libempathy/empathy-message.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/libempathy/empathy-message.c b/libempathy/empathy-message.c index e1b168b1c..57bdaeae9 100644 --- a/libempathy/empathy-message.c +++ b/libempathy/empathy-message.c @@ -356,16 +356,34 @@ empathy_message_from_tpl_log_event (TplEvent *logevent) if (TPL_IS_TEXT_EVENT (logevent)) { TplTextEvent *textevent = TPL_TEXT_EVENT (logevent); + const gchar *supersedes; + gint64 timestamp; + gint64 original_timestamp = 0; + + 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)); retval = g_object_new (EMPATHY_TYPE_MESSAGE, "type", tpl_text_event_get_message_type (textevent), "token", tpl_text_event_get_message_token (textevent), - "supersedes", tpl_text_event_get_supersedes_token (textevent), + "supersedes", supersedes, "body", body, - "timestamp", tpl_event_get_timestamp (logevent), - "original-timestamp", tpl_text_event_get_original_timestamp (textevent), + "timestamp", timestamp, + "original-timestamp", original_timestamp, "is-backlog", TRUE, NULL); -- cgit v1.2.1 From 8b452ff5ccbc7643c63a6ecda90bea4dcf899284 Mon Sep 17 00:00:00 2001 From: Danielle Madeley Date: Fri, 27 May 2011 11:38:31 +1000 Subject: Bump to released TPL version 0.2.10 --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 2a60815c9..95ebddcc2 100644 --- a/configure.ac +++ b/configure.ac @@ -42,7 +42,7 @@ LIBCANBERRA_GTK_REQUIRED=0.4 LIBNOTIFY_REQUIRED=0.7.0 TELEPATHY_FARSIGHT_REQUIRED=0.0.14 TELEPATHY_GLIB_REQUIRED=0.14.1 -TELEPATHY_LOGGER=0.2.9.1 +TELEPATHY_LOGGER=0.2.10 UNIQUE_REQUIRED=1.1.2 # Optionnal deps -- cgit v1.2.1