diff options
-rw-r--r-- | libempathy-gtk/empathy-chat-view.c | 11 | ||||
-rw-r--r-- | libempathy-gtk/empathy-chat-view.h | 4 | ||||
-rw-r--r-- | libempathy-gtk/empathy-chat.c | 66 | ||||
-rw-r--r-- | libempathy-gtk/empathy-chat.h | 4 | ||||
-rw-r--r-- | libempathy-gtk/empathy-theme-adium.c | 163 | ||||
-rw-r--r-- | libempathy/empathy-message.c | 55 | ||||
-rw-r--r-- | libempathy/empathy-message.h | 4 | ||||
-rw-r--r-- | libempathy/empathy-tp-chat.c | 113 | ||||
-rw-r--r-- | po/es.po | 320 | ||||
-rw-r--r-- | src/empathy-chat-manager.c | 62 | ||||
-rw-r--r-- | src/empathy-chat-window.c | 9 |
11 files changed, 564 insertions, 247 deletions
diff --git a/libempathy-gtk/empathy-chat-view.c b/libempathy-gtk/empathy-chat-view.c index 097215cfd..43d89dd78 100644 --- a/libempathy-gtk/empathy-chat-view.c +++ b/libempathy-gtk/empathy-chat-view.c @@ -212,3 +212,14 @@ empathy_chat_view_focus_toggled (EmpathyChatView *view, } } +void +empathy_chat_view_message_acknowledged (EmpathyChatView *view, + EmpathyMessage *message) +{ + g_return_if_fail (EMPATHY_IS_CHAT_VIEW (view)); + + if (EMPATHY_TYPE_CHAT_VIEW_GET_IFACE (view)->message_acknowledged) { + EMPATHY_TYPE_CHAT_VIEW_GET_IFACE (view)->message_acknowledged (view, message); + } +} + diff --git a/libempathy-gtk/empathy-chat-view.h b/libempathy-gtk/empathy-chat-view.h index 1af0721a3..73245c422 100644 --- a/libempathy-gtk/empathy-chat-view.h +++ b/libempathy-gtk/empathy-chat-view.h @@ -70,6 +70,8 @@ struct _EmpathyChatViewIface { void (*copy_clipboard) (EmpathyChatView *view); void (*focus_toggled) (EmpathyChatView *view, gboolean has_focus); + void (*message_acknowledged) (EmpathyChatView *view, + EmpathyMessage *message); }; GType empathy_chat_view_get_type (void) G_GNUC_CONST; @@ -101,6 +103,8 @@ void empathy_chat_view_highlight (EmpathyChatView *view, void empathy_chat_view_copy_clipboard (EmpathyChatView *view); void empathy_chat_view_focus_toggled (EmpathyChatView *view, gboolean has_focus); +void empathy_chat_view_message_acknowledged (EmpathyChatView *view, + EmpathyMessage *message); G_END_DECLS diff --git a/libempathy-gtk/empathy-chat.c b/libempathy-gtk/empathy-chat.c index 034cd9ea7..79411e74d 100644 --- a/libempathy-gtk/empathy-chat.c +++ b/libempathy-gtk/empathy-chat.c @@ -174,6 +174,7 @@ enum { PROP_SHOW_CONTACTS, PROP_SMS_CHANNEL, PROP_N_MESSAGES_SENDING, + PROP_NB_UNREAD_MESSAGES, }; static guint signals[LAST_SIGNAL] = { 0 }; @@ -220,6 +221,10 @@ chat_get_property (GObject *object, g_value_set_uint (value, empathy_chat_get_n_messages_sending (chat)); break; + case PROP_NB_UNREAD_MESSAGES: + g_value_set_uint (value, + empathy_chat_get_nb_unread_messages (chat)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); break; @@ -1326,7 +1331,11 @@ chat_message_received (EmpathyChat *chat, TP_CHANNEL_CHAT_STATE_ACTIVE, chat); - priv->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); } @@ -1339,6 +1348,20 @@ chat_message_received_cb (EmpathyTpChat *tp_chat, } static void +chat_message_acknowledged_cb (EmpathyTpChat *tp_chat, + EmpathyMessage *message, + EmpathyChat *chat) +{ + EmpathyChatPriv *priv = GET_PRIV (chat); + + empathy_chat_view_message_acknowledged (chat->view, + message); + + priv->unread_messages--; + g_object_notify (G_OBJECT (chat), "nb-unread-messages"); +} + +static void chat_send_error_cb (EmpathyTpChat *tp_chat, const gchar *message_body, TpChannelTextSendError error_code, @@ -2927,6 +2950,8 @@ chat_finalize (GObject *object) g_signal_handlers_disconnect_by_func (priv->tp_chat, chat_message_received_cb, chat); g_signal_handlers_disconnect_by_func (priv->tp_chat, + chat_message_acknowledged_cb, chat); + g_signal_handlers_disconnect_by_func (priv->tp_chat, chat_send_error_cb, chat); g_signal_handlers_disconnect_by_func (priv->tp_chat, chat_state_changed_cb, chat); @@ -3062,6 +3087,14 @@ empathy_chat_class_init (EmpathyChatClass *klass) 0, G_MAXUINT, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (object_class, + PROP_NB_UNREAD_MESSAGES, + g_param_spec_uint ("nb-unread-messages", + "Num Unread Messages", + "The number of unread messages", + 0, G_MAXUINT, 0, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); + signals[COMPOSING] = g_signal_new ("composing", G_OBJECT_CLASS_TYPE (object_class), @@ -3630,6 +3663,9 @@ empathy_chat_set_tp_chat (EmpathyChat *chat, g_signal_connect (tp_chat, "message-received", G_CALLBACK (chat_message_received_cb), chat); + g_signal_connect (tp_chat, "message_acknowledged", + G_CALLBACK (chat_message_acknowledged_cb), + chat); g_signal_connect (tp_chat, "send-error", G_CALLBACK (chat_send_error_cb), chat); @@ -3957,12 +3993,9 @@ empathy_chat_messages_read (EmpathyChat *self) if (priv->retrieving_backlogs) return; - if (priv->tp_chat != NULL ) { + if (priv->tp_chat != NULL) { empathy_tp_chat_acknowledge_all_messages (priv->tp_chat); } - priv->unread_messages = 0; - - empathy_chat_view_focus_toggled (self->view, TRUE); } /* Return TRUE if on of the contacts in this chat is composing */ @@ -4003,3 +4036,26 @@ empathy_chat_get_n_messages_sending (EmpathyChat *self) return n_messages; } } + +gchar * +empathy_chat_dup_text (EmpathyChat *self) +{ + GtkTextBuffer *buffer; + GtkTextIter start, end; + + buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (self->input_text_view)); + + gtk_text_buffer_get_bounds (buffer, &start, &end); + return gtk_text_buffer_get_text (buffer, &start, &end, FALSE); +} + +void +empathy_chat_set_text (EmpathyChat *self, + const gchar *text) +{ + GtkTextBuffer *buffer; + + buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (self->input_text_view)); + + gtk_text_buffer_set_text (buffer, text, -1); +} diff --git a/libempathy-gtk/empathy-chat.h b/libempathy-gtk/empathy-chat.h index 47892d6c9..4b0540b20 100644 --- a/libempathy-gtk/empathy-chat.h +++ b/libempathy-gtk/empathy-chat.h @@ -97,6 +97,10 @@ gboolean empathy_chat_is_composing (EmpathyChat *chat); gboolean empathy_chat_is_sms_channel (EmpathyChat *self); guint empathy_chat_get_n_messages_sending (EmpathyChat *self); +gchar * empathy_chat_dup_text (EmpathyChat *self); +void empathy_chat_set_text (EmpathyChat *self, + const gchar *text); + G_END_DECLS #endif /* __EMPATHY_CHAT_H__ */ diff --git a/libempathy-gtk/empathy-theme-adium.c b/libempathy-gtk/empathy-theme-adium.c index 06410c528..b62b017c9 100644 --- a/libempathy-gtk/empathy-theme-adium.c +++ b/libempathy-gtk/empathy-theme-adium.c @@ -61,6 +61,9 @@ typedef struct { guint pages_loading; /* Queue of GValue* containing an EmpathyMessage or string */ GQueue message_queue; + /* Queue of owned gchar* of message token to remove unread + * marker for when we lose focus. */ + GQueue acked_messages; GtkWidget *inspector_window; GSettings *gsettings_chat; gboolean has_focus; @@ -569,32 +572,10 @@ theme_adium_append_event_escaped (EmpathyChatView *view, } static void -theme_adium_remove_focus_marks (EmpathyThemeAdium *theme) +theme_adium_remove_focus_marks (EmpathyThemeAdium *theme, + WebKitDOMNodeList *nodes) { - EmpathyThemeAdiumPriv *priv = GET_PRIV (theme); - WebKitDOMDocument *dom; - WebKitDOMNodeList *nodes; guint i; - GError *error = NULL; - - if (!priv->has_unread_message) - return; - - priv->has_unread_message = FALSE; - - dom = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (theme)); - if (dom == NULL) { - return; - } - - /* Get all nodes with focus class */ - nodes = webkit_dom_document_query_selector_all (dom, ".focus", &error); - if (nodes == NULL) { - DEBUG ("Error getting focus nodes: %s", - error ? error->message : "No error"); - g_clear_error (&error); - return; - } /* Remove focus and firstFocus class */ for (i = 0; i < webkit_dom_node_list_get_length (nodes); i++) { @@ -632,12 +613,43 @@ theme_adium_remove_focus_marks (EmpathyThemeAdium *theme) } static void +theme_adium_remove_all_focus_marks (EmpathyThemeAdium *theme) +{ + EmpathyThemeAdiumPriv *priv = GET_PRIV (theme); + WebKitDOMDocument *dom; + WebKitDOMNodeList *nodes; + GError *error = NULL; + + if (!priv->has_unread_message) + return; + + priv->has_unread_message = FALSE; + + dom = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (theme)); + if (dom == NULL) { + return; + } + + /* Get all nodes with focus class */ + nodes = webkit_dom_document_query_selector_all (dom, ".focus", &error); + if (nodes == NULL) { + DEBUG ("Error getting focus nodes: %s", + error ? error->message : "No error"); + g_clear_error (&error); + return; + } + + theme_adium_remove_focus_marks (theme, nodes); +} + +static void theme_adium_append_message (EmpathyChatView *view, EmpathyMessage *msg) { EmpathyThemeAdium *theme = EMPATHY_THEME_ADIUM (view); EmpathyThemeAdiumPriv *priv = GET_PRIV (theme); EmpathyContact *sender; + TpMessage *tp_msg; TpAccount *account; gchar *body_escaped; const gchar *body; @@ -759,6 +771,20 @@ theme_adium_append_message (EmpathyChatView *view, * %status% - See %status% in theme_adium_append_html () */ + /* This is slightly a hack, but it's the only way to add + * arbitrary data to messages in the HTML. We add another + * class called "x-empathy-message-id-*" to the message. This + * way, we can remove the unread marker for this specific + * message later. */ + tp_msg = empathy_message_get_tp_message (msg); + if (tp_msg != NULL) { + gchar *tmp = tp_escape_as_identifier ( + tp_message_get_token (tp_msg)); + g_string_append_printf (message_classes, + " x-empathy-message-id-%s", tmp); + g_free (tmp); + } + /* Define javascript function to use */ if (consecutive) { func = priv->allow_scrolling ? "appendNextMessage" : "appendNextMessageNoScroll"; @@ -777,7 +803,7 @@ theme_adium_append_message (EmpathyChatView *view, } /* remove all the unread marks when we are sending a message */ - theme_adium_remove_focus_marks (theme); + theme_adium_remove_all_focus_marks (theme); } else { /* in */ if (is_backlog) { @@ -927,16 +953,93 @@ theme_adium_copy_clipboard (EmpathyChatView *view) } static void +theme_adium_remove_mark_from_message (EmpathyThemeAdium *self, + const gchar *token) +{ + WebKitDOMDocument *dom; + WebKitDOMNodeList *nodes; + gchar *class, *tmp; + GError *error = NULL; + + dom = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (self)); + if (dom == NULL) { + return; + } + + tmp = tp_escape_as_identifier (token); + class = g_strdup_printf (".x-empathy-message-id-%s", tmp); + g_free (tmp); + + /* Get all nodes with focus class */ + nodes = webkit_dom_document_query_selector_all (dom, class, &error); + g_free (class); + + if (nodes == NULL) { + DEBUG ("Error getting focus nodes: %s", + error ? error->message : "No error"); + g_clear_error (&error); + return; + } + + theme_adium_remove_focus_marks (self, nodes); +} + +static void +theme_adium_remove_acked_message_unread_mark_foreach (gpointer data, + gpointer user_data) +{ + EmpathyThemeAdium *self = user_data; + gchar *token = data; + + theme_adium_remove_mark_from_message (self, token); + g_free (token); +} + +static void theme_adium_focus_toggled (EmpathyChatView *view, gboolean has_focus) { - EmpathyThemeAdium *self = (EmpathyThemeAdium *) view; EmpathyThemeAdiumPriv *priv = GET_PRIV (view); priv->has_focus = has_focus; if (!priv->has_focus) { - theme_adium_remove_focus_marks (self); + /* We've lost focus, so let's make sure all the acked + * messages have lost their unread marker. */ + g_queue_foreach (&priv->acked_messages, + theme_adium_remove_acked_message_unread_mark_foreach, + view); + g_queue_clear (&priv->acked_messages); + + priv->has_unread_message = FALSE; + } +} + +static void +theme_adium_message_acknowledged (EmpathyChatView *view, + EmpathyMessage *message) +{ + EmpathyThemeAdium *self = (EmpathyThemeAdium *) view; + EmpathyThemeAdiumPriv *priv = GET_PRIV (view); + TpMessage *tp_msg; + + tp_msg = empathy_message_get_tp_message (message); + + if (tp_msg == NULL) { + return; } + + /* We only want to actually remove the unread marker if the + * view doesn't have focus. If we did it all the time we would + * never see the unread markers, ever! So, we'll queue these + * up, and when we lose focus, we'll remove the markers. */ + if (priv->has_focus) { + g_queue_push_tail (&priv->acked_messages, + g_strdup (tp_message_get_token (tp_msg))); + return; + } + + theme_adium_remove_mark_from_message (self, + tp_message_get_token (tp_msg)); } static void @@ -1059,6 +1162,7 @@ theme_adium_iface_init (EmpathyChatViewIface *iface) iface->highlight = theme_adium_highlight; iface->copy_clipboard = theme_adium_copy_clipboard; iface->focus_toggled = theme_adium_focus_toggled; + iface->message_acknowledged = theme_adium_message_acknowledged; } static void @@ -1124,6 +1228,11 @@ theme_adium_dispose (GObject *object) priv->inspector_window = NULL; } + if (priv->acked_messages.length > 0) { + g_queue_foreach (&priv->acked_messages, (GFunc) g_free, NULL); + g_queue_clear (&priv->acked_messages); + } + G_OBJECT_CLASS (empathy_theme_adium_parent_class)->dispose (object); } diff --git a/libempathy/empathy-message.c b/libempathy/empathy-message.c index 076a10053..25ec498ce 100644 --- a/libempathy/empathy-message.c +++ b/libempathy/empathy-message.c @@ -40,6 +40,7 @@ #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyMessage) typedef struct { + TpMessage *tp_message; TpChannelTextMessageType type; EmpathyContact *sender; EmpathyContact *receiver; @@ -73,6 +74,7 @@ enum { PROP_IS_BACKLOG, PROP_INCOMING, PROP_FLAGS, + PROP_TP_MESSAGE, }; static void @@ -153,6 +155,15 @@ 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_TP_MESSAGE, + g_param_spec_object ("tp-message", + "TpMessage", + "The TpMessage of this message", + TP_TYPE_MESSAGE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | + G_PARAM_CONSTRUCT_ONLY)); + g_type_class_add_private (object_class, sizeof (EmpathyMessagePriv)); } @@ -181,6 +192,10 @@ empathy_message_finalize (GObject *object) g_object_unref (priv->receiver); } + if (priv->tp_message) { + g_object_unref (priv->tp_message); + } + g_free (priv->body); G_OBJECT_CLASS (empathy_message_parent_class)->finalize (object); @@ -221,6 +236,9 @@ message_get_property (GObject *object, case PROP_FLAGS: g_value_set_uint (value, priv->flags); break; + case PROP_TP_MESSAGE: + g_value_set_object (value, priv->tp_message); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); break; @@ -267,6 +285,9 @@ message_set_property (GObject *object, case PROP_FLAGS: priv->flags = g_value_get_uint (value); break; + case PROP_TP_MESSAGE: + priv->tp_message = g_value_dup_object (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); break; @@ -342,6 +363,18 @@ empathy_message_from_tpl_log_event (TplEvent *logevent) return retval; } +TpMessage * +empathy_message_get_tp_message (EmpathyMessage *message) +{ + EmpathyMessagePriv *priv; + + g_return_val_if_fail (EMPATHY_IS_MESSAGE (message), NULL); + + priv = GET_PRIV (message); + + return priv->tp_message; +} + TpChannelTextMessageType empathy_message_get_tptype (EmpathyMessage *message) { @@ -563,16 +596,6 @@ empathy_message_type_to_str (TpChannelTextMessageType type) } } -guint -empathy_message_get_id (EmpathyMessage *message) -{ - EmpathyMessagePriv *priv = GET_PRIV (message); - - g_return_val_if_fail (EMPATHY_IS_MESSAGE (message), 0); - - return priv->id; -} - gboolean empathy_message_is_incoming (EmpathyMessage *message) { @@ -618,10 +641,8 @@ empathy_message_new_from_tp_message (TpMessage *tp_msg, gboolean incoming) { EmpathyMessage *message; - EmpathyMessagePriv *priv; gchar *body; TpChannelTextMessageFlags flags; - guint id; g_return_val_if_fail (TP_IS_MESSAGE (tp_msg), NULL); @@ -634,17 +655,9 @@ empathy_message_new_from_tp_message (TpMessage *tp_msg, "flags", flags, "is-backlog", flags & TP_CHANNEL_TEXT_MESSAGE_FLAG_SCROLLBACK, "incoming", incoming, + "tp-message", tp_msg, NULL); - priv = GET_PRIV (message); - - /* 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); - - priv->id = id; - g_free (body); return message; } diff --git a/libempathy/empathy-message.h b/libempathy/empathy-message.h index 7508cb08e..b20ceca16 100644 --- a/libempathy/empathy-message.h +++ b/libempathy/empathy-message.h @@ -59,6 +59,8 @@ EmpathyMessage * empathy_message_from_tpl_log_event (TplEvent EmpathyMessage * empathy_message_new_from_tp_message (TpMessage *tp_msg, gboolean incoming); +TpMessage * empathy_message_get_tp_message (EmpathyMessage *message); + TpChannelTextMessageType empathy_message_get_tptype (EmpathyMessage *message); EmpathyContact * empathy_message_get_sender (EmpathyMessage *message); void empathy_message_set_sender (EmpathyMessage *message, @@ -75,8 +77,6 @@ gboolean empathy_message_should_highlight (EmpathyMessage TpChannelTextMessageType empathy_message_type_from_str (const gchar *type_str); const gchar * empathy_message_type_to_str (TpChannelTextMessageType type); -guint empathy_message_get_id (EmpathyMessage *message); - gboolean empathy_message_equal (EmpathyMessage *message1, EmpathyMessage *message2); TpChannelTextMessageFlags empathy_message_get_flags (EmpathyMessage *message); diff --git a/libempathy/empathy-tp-chat.c b/libempathy/empathy-tp-chat.c index 8e6672eee..0541943b9 100644 --- a/libempathy/empathy-tp-chat.c +++ b/libempathy/empathy-tp-chat.c @@ -84,6 +84,7 @@ enum { CHAT_STATE_CHANGED, PROPERTY_CHANGED, DESTROY, + MESSAGE_ACKNOWLEDGED, LAST_SIGNAL }; @@ -93,8 +94,6 @@ G_DEFINE_TYPE_WITH_CODE (EmpathyTpChat, empathy_tp_chat, G_TYPE_OBJECT, G_IMPLEMENT_INTERFACE (EMPATHY_TYPE_CONTACT_LIST, tp_chat_iface_init)); -static void acknowledge_messages (EmpathyTpChat *chat, GArray *ids); - static void tp_chat_set_delivery_status (EmpathyTpChat *self, const gchar *token, @@ -453,6 +452,39 @@ message_received_cb (TpTextChannel *channel, handle_incoming_message (chat, message, FALSE); } +static gboolean +find_pending_message_func (gconstpointer a, + gconstpointer b) +{ + EmpathyMessage *msg = (EmpathyMessage *) a; + TpMessage *message = (TpMessage *) b; + + if (empathy_message_get_tp_message (msg) == message) + return 0; + + return -1; +} + +static void +pending_message_removed_cb (TpTextChannel *channel, + TpMessage *message, + EmpathyTpChat *chat) +{ + EmpathyTpChatPriv *priv = GET_PRIV (chat); + GList *m; + + m = g_queue_find_custom (priv->pending_messages_queue, message, + find_pending_message_func); + + if (m == NULL) + return; + + g_signal_emit (chat, signals[MESSAGE_ACKNOWLEDGED], 0, m->data); + + g_object_unref (m->data); + g_queue_delete_link (priv->pending_messages_queue, m); +} + static void message_sent_cb (TpTextChannel *channel, TpMessage *message, @@ -911,6 +943,8 @@ check_almost_ready (EmpathyTpChat *chat) tp_g_signal_connect_object (priv->channel, "message-received", G_CALLBACK (message_received_cb), chat, 0); + tp_g_signal_connect_object (priv->channel, "pending-message-removed", + G_CALLBACK (pending_message_removed_cb), chat, 0); list_pending_messages (chat); @@ -1632,6 +1666,16 @@ empathy_tp_chat_class_init (EmpathyTpChatClass *klass) G_TYPE_NONE, 0); + signals[MESSAGE_ACKNOWLEDGED] = + g_signal_new ("message-acknowledged", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, EMPATHY_TYPE_MESSAGE); + g_type_class_add_private (object_class, sizeof (EmpathyTpChatPriv)); } @@ -1793,84 +1837,51 @@ empathy_tp_chat_get_pending_messages (EmpathyTpChat *chat) return priv->pending_messages_queue->head; } -static void -acknowledge_messages (EmpathyTpChat *chat, GArray *ids) { - EmpathyTpChatPriv *priv = GET_PRIV (chat); - - tp_cli_channel_type_text_call_acknowledge_pending_messages ( - priv->channel, -1, ids, tp_chat_async_cb, - "acknowledging received message", NULL, G_OBJECT (chat)); -} - void empathy_tp_chat_acknowledge_message (EmpathyTpChat *chat, EmpathyMessage *message) { EmpathyTpChatPriv *priv = GET_PRIV (chat); - GArray *message_ids; - GList *m; - guint id; + TpMessage *tp_msg; g_return_if_fail (EMPATHY_IS_TP_CHAT (chat)); g_return_if_fail (priv->ready); if (!empathy_message_is_incoming (message)) - goto out; - - message_ids = g_array_sized_new (FALSE, FALSE, sizeof (guint), 1); - - id = empathy_message_get_id (message); - g_array_append_val (message_ids, id); - acknowledge_messages (chat, message_ids); - g_array_free (message_ids, TRUE); + return; -out: - m = g_queue_find (priv->pending_messages_queue, message); - g_assert (m != NULL); - g_queue_delete_link (priv->pending_messages_queue, m); - g_object_unref (message); + tp_msg = empathy_message_get_tp_message (message); + tp_text_channel_ack_message_async (TP_TEXT_CHANNEL (priv->channel), + tp_msg, NULL, NULL); } void empathy_tp_chat_acknowledge_messages (EmpathyTpChat *chat, const GSList *messages) { EmpathyTpChatPriv *priv = GET_PRIV (chat); - /* Copy messages as the messges list (probably is) our own */ - GSList *msgs = g_slist_copy ((GSList *) messages); - GSList *l; - guint length; - GArray *message_ids; + const GSList *l; + GList *messages_to_ack = NULL; g_return_if_fail (EMPATHY_IS_TP_CHAT (chat)); g_return_if_fail (priv->ready); - length = g_slist_length ((GSList *) messages); - - if (length == 0) + if (messages == NULL) return; - message_ids = g_array_sized_new (FALSE, FALSE, sizeof (guint), length); - - for (l = msgs; l != NULL; l = g_slist_next (l)) { - GList *m; - + for (l = messages; l != NULL; l = g_slist_next (l)) { EmpathyMessage *message = EMPATHY_MESSAGE (l->data); - m = g_queue_find (priv->pending_messages_queue, message); - g_assert (m != NULL); - g_queue_delete_link (priv->pending_messages_queue, m); - if (empathy_message_is_incoming (message)) { - guint id = empathy_message_get_id (message); - g_array_append_val (message_ids, id); + TpMessage *tp_msg = empathy_message_get_tp_message (message); + messages_to_ack = g_list_append (messages_to_ack, tp_msg); } - g_object_unref (message); } - if (message_ids->len > 0) - acknowledge_messages (chat, message_ids); + if (messages_to_ack != NULL) { + tp_text_channel_ack_messages_async (TP_TEXT_CHANNEL (priv->channel), + messages_to_ack, NULL, NULL); + } - g_array_free (message_ids, TRUE); - g_slist_free (msgs); + g_list_free (messages_to_ack); } void @@ -1,23 +1,23 @@ # translation of empathy.master.po to Español # Copyright (C) 2003 Free Software Foundation # This file is distributed under the same license as the Gossip package. -# Daniel Mustieles <daniel.mustieles@gmail.com>, 2010, 2011. # Jorge González <jorgegonz@svn.gnome.org>, 2007, 2008, 2009, 2010, 2011. +# Daniel Mustieles <daniel.mustieles@gmail.com>, 2010, 2011. # msgid "" msgstr "" "Project-Id-Version: empathy.master\n" "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?" "product=empathy&keywords=I18N+L10N&component=General\n" -"POT-Creation-Date: 2011-05-09 10:59+0000\n" -"PO-Revision-Date: 2011-05-09 14:23+0200\n" -"Last-Translator: Jorge González <jorgegonz@svn.gnome.org>\n" +"POT-Creation-Date: 2011-05-16 13:17+0000\n" +"PO-Revision-Date: 2011-05-16 17:07+0200\n" +"Last-Translator: Daniel Mustieles <daniel.mustieles@gmail.com>\n" "Language-Team: Español <gnome-es-list@gnome.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: KBabel 1.11.4\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" #: ../data/empathy.desktop.in.in.h:1 msgid "Chat on Google Talk, Facebook, MSN and many other chat services" @@ -700,49 +700,49 @@ msgstr "Google Talk" msgid "Facebook Chat" msgstr "Chat de Facebook" -#: ../libempathy/empathy-time.c:100 +#: ../libempathy/empathy-time.c:88 #, c-format msgid "%d second ago" msgid_plural "%d seconds ago" msgstr[0] "hace %d segundo" msgstr[1] "hace %d segundos" -#: ../libempathy/empathy-time.c:105 +#: ../libempathy/empathy-time.c:93 #, c-format msgid "%d minute ago" msgid_plural "%d minutes ago" msgstr[0] "hace %d minuto" msgstr[1] "hace %d minutos" -#: ../libempathy/empathy-time.c:110 +#: ../libempathy/empathy-time.c:98 #, c-format msgid "%d hour ago" msgid_plural "%d hours ago" msgstr[0] "hace %d hora" msgstr[1] "hace %d horas" -#: ../libempathy/empathy-time.c:115 +#: ../libempathy/empathy-time.c:103 #, c-format msgid "%d day ago" msgid_plural "%d days ago" msgstr[0] "hace %d día" msgstr[1] "hace %d días" -#: ../libempathy/empathy-time.c:120 +#: ../libempathy/empathy-time.c:108 #, c-format msgid "%d week ago" msgid_plural "%d weeks ago" msgstr[0] "hace %d semana" msgstr[1] "hace %d semanas" -#: ../libempathy/empathy-time.c:125 +#: ../libempathy/empathy-time.c:113 #, c-format msgid "%d month ago" msgid_plural "%d months ago" msgstr[0] "hace %d mes" msgstr[1] "hace %d meses" -#: ../libempathy/empathy-time.c:130 +#: ../libempathy/empathy-time.c:136 msgid "in the future" msgstr "en el futuro" @@ -1191,6 +1191,7 @@ msgid "STUN Server:" msgstr "Servidor STUN:" #: ../libempathy-gtk/empathy-account-widget-sip.ui.h:18 +#: ../libempathy-gtk/empathy-contact-widget.c:347 msgid "Server:" msgstr "Servidor:" @@ -1259,35 +1260,41 @@ msgstr "Todos los archivos" msgid "Click to enlarge" msgstr "Pulse para agrandar" -#: ../libempathy-gtk/empathy-chat.c:668 +#: ../libempathy-gtk/empathy-chat.c:669 msgid "Failed to open private chat" msgstr "Falló al abrir el chat privado" -#: ../libempathy-gtk/empathy-chat.c:733 +#: ../libempathy-gtk/empathy-chat.c:732 msgid "Topic not supported on this conversation" msgstr "El tema no está soportado en esta conversación" -#: ../libempathy-gtk/empathy-chat.c:739 +#: ../libempathy-gtk/empathy-chat.c:738 msgid "You are not allowed to change the topic" msgstr "No le está permitido cambiar el tema" -#: ../libempathy-gtk/empathy-chat.c:948 +#: ../libempathy-gtk/empathy-chat.c:945 +#, c-format +#| msgid "invalid contact" +msgid "“%s” is not a valid contact ID" +msgstr "%s no es un identificador de contacto válido" + +#: ../libempathy-gtk/empathy-chat.c:1002 msgid "/clear: clear all messages from the current conversation" msgstr "/clear: limpiar todos los mensajes de la conversación actual" -#: ../libempathy-gtk/empathy-chat.c:951 +#: ../libempathy-gtk/empathy-chat.c:1005 msgid "/topic <topic>: set the topic of the current conversation" msgstr "/topic <tema>: establecer el tema para la conversación actual" -#: ../libempathy-gtk/empathy-chat.c:954 +#: ../libempathy-gtk/empathy-chat.c:1008 msgid "/join <chat room ID>: join a new chat room" msgstr "/join <id de sala de chat>: unirse a una sala de chat nueva" -#: ../libempathy-gtk/empathy-chat.c:957 +#: ../libempathy-gtk/empathy-chat.c:1011 msgid "/j <chat room ID>: join a new chat room" msgstr "/j <id de sala de chat>: unirse a una sala de chat nueva" -#: ../libempathy-gtk/empathy-chat.c:962 +#: ../libempathy-gtk/empathy-chat.c:1015 msgid "" "/part [<chat room ID>] [<reason>]: leave the chat room, by default the " "current one" @@ -1295,23 +1302,23 @@ msgstr "" "/part [<ID de la sala de chat>] [<razón>]: abandonar la sala de chat, la " "actual de manera predeterminada" -#: ../libempathy-gtk/empathy-chat.c:967 +#: ../libempathy-gtk/empathy-chat.c:1019 msgid "/query <contact ID> [<message>]: open a private chat" msgstr "/query <id del contacto> [<mensaje>]: abrir un chat privado" -#: ../libempathy-gtk/empathy-chat.c:970 +#: ../libempathy-gtk/empathy-chat.c:1022 msgid "/msg <contact ID> <message>: open a private chat" msgstr "/msg <id del contacto> <mensaje>: abrir un chat privado" -#: ../libempathy-gtk/empathy-chat.c:973 +#: ../libempathy-gtk/empathy-chat.c:1025 msgid "/nick <nickname>: change your nickname on the current server" msgstr "/nick <apodo>: cambiar su apodo en el servidor actual" -#: ../libempathy-gtk/empathy-chat.c:976 +#: ../libempathy-gtk/empathy-chat.c:1028 msgid "/me <message>: send an ACTION message to the current conversation" msgstr "/me <mensaje>: enviar un mensaje de ACCIÓN a la conversación actual" -#: ../libempathy-gtk/empathy-chat.c:979 +#: ../libempathy-gtk/empathy-chat.c:1031 msgid "" "/say <message>: send <message> to the current conversation. This is used to " "send a message starting with a '/'. For example: \"/say /join is used to " @@ -1321,7 +1328,11 @@ msgstr "" "para enviar un mensaje comenzando por una «/». Por ejemplo: «/say /join se usa " "para unirse a una sala de chat nueva»" -#: ../libempathy-gtk/empathy-chat.c:984 +#: ../libempathy-gtk/empathy-chat.c:1036 +msgid "/whois <contact ID>: display information about a contact" +msgstr "/whois <ID del contacto>: mostrar información sobre un contacto" + +#: ../libempathy-gtk/empathy-chat.c:1039 msgid "" "/help [<command>]: show all supported commands. If <command> is defined, " "show its usage." @@ -1329,113 +1340,113 @@ msgstr "" "/help [<comando>]: mostrar todos los comandos soportados. Si <comando> está " "definido, muestra su uso." -#: ../libempathy-gtk/empathy-chat.c:994 +#: ../libempathy-gtk/empathy-chat.c:1049 #, c-format msgid "Usage: %s" msgstr "Uso: %s" -#: ../libempathy-gtk/empathy-chat.c:1033 +#: ../libempathy-gtk/empathy-chat.c:1088 msgid "Unknown command" msgstr "Comando desconocido" -#: ../libempathy-gtk/empathy-chat.c:1159 +#: ../libempathy-gtk/empathy-chat.c:1214 msgid "Unknown command; see /help for the available commands" msgstr "Comando desconocido; consulte /help para ver los comandos disponibles" #. translators: error used when user doesn't have enough credit on his #. * account to send the message. -#: ../libempathy-gtk/empathy-chat.c:1299 +#: ../libempathy-gtk/empathy-chat.c:1354 msgid "insufficient balance to send message" msgstr "no tiene balance suficiente para enviar el mensaje" -#: ../libempathy-gtk/empathy-chat.c:1301 +#: ../libempathy-gtk/empathy-chat.c:1356 msgid "not capable" msgstr "no es posible" -#: ../libempathy-gtk/empathy-chat.c:1308 +#: ../libempathy-gtk/empathy-chat.c:1363 msgid "offline" msgstr "desconectado" -#: ../libempathy-gtk/empathy-chat.c:1311 +#: ../libempathy-gtk/empathy-chat.c:1366 msgid "invalid contact" msgstr "contacto no válido" -#: ../libempathy-gtk/empathy-chat.c:1314 +#: ../libempathy-gtk/empathy-chat.c:1369 msgid "permission denied" msgstr "permiso denegado" -#: ../libempathy-gtk/empathy-chat.c:1317 +#: ../libempathy-gtk/empathy-chat.c:1372 msgid "too long message" msgstr "mensaje demasiado largo" -#: ../libempathy-gtk/empathy-chat.c:1320 +#: ../libempathy-gtk/empathy-chat.c:1375 msgid "not implemented" msgstr "no implementado" -#: ../libempathy-gtk/empathy-chat.c:1324 +#: ../libempathy-gtk/empathy-chat.c:1379 msgid "unknown" msgstr "desconocido" -#: ../libempathy-gtk/empathy-chat.c:1330 +#: ../libempathy-gtk/empathy-chat.c:1385 #, c-format msgid "Error sending message '%s': %s" msgstr "Error al enviar el mensaje «%s»: %s" -#: ../libempathy-gtk/empathy-chat.c:1334 +#: ../libempathy-gtk/empathy-chat.c:1389 #, c-format msgid "Error sending message: %s" msgstr "Error al enviar el mensaje: %s" -#: ../libempathy-gtk/empathy-chat.c:1395 ../src/empathy-chat-window.c:760 +#: ../libempathy-gtk/empathy-chat.c:1450 ../src/empathy-chat-window.c:760 msgid "Topic:" msgstr "Tema:" -#: ../libempathy-gtk/empathy-chat.c:1407 +#: ../libempathy-gtk/empathy-chat.c:1462 #, c-format msgid "Topic set to: %s" msgstr "El tema se ha establecido a: %s" -#: ../libempathy-gtk/empathy-chat.c:1409 +#: ../libempathy-gtk/empathy-chat.c:1464 msgid "No topic defined" msgstr "No se ha definido el tema" -#: ../libempathy-gtk/empathy-chat.c:1916 +#: ../libempathy-gtk/empathy-chat.c:1971 msgid "(No Suggestions)" msgstr "(Sin sugerencias)" #. translators: %s is the selected word -#: ../libempathy-gtk/empathy-chat.c:1984 +#: ../libempathy-gtk/empathy-chat.c:2039 #, c-format msgid "Add '%s' to Dictionary" msgstr "Añadir «%s» al diccionario" #. translators: first %s is the selected word, #. * second %s is the language name of the target dictionary -#: ../libempathy-gtk/empathy-chat.c:2021 +#: ../libempathy-gtk/empathy-chat.c:2076 #, c-format msgid "Add '%s' to %s Dictionary" msgstr "Añadir «%s» al diccionario de «%s»" -#: ../libempathy-gtk/empathy-chat.c:2078 +#: ../libempathy-gtk/empathy-chat.c:2133 msgid "Insert Smiley" msgstr "Insertar emoticono" #. send button -#: ../libempathy-gtk/empathy-chat.c:2096 +#: ../libempathy-gtk/empathy-chat.c:2151 #: ../libempathy-gtk/empathy-ui-utils.c:1808 msgid "_Send" msgstr "E_nviar" #. Spelling suggestions -#: ../libempathy-gtk/empathy-chat.c:2131 +#: ../libempathy-gtk/empathy-chat.c:2186 msgid "_Spelling Suggestions" msgstr "_Sugerencias ortográficas" -#: ../libempathy-gtk/empathy-chat.c:2220 +#: ../libempathy-gtk/empathy-chat.c:2275 msgid "Failed to retrieve recent logs" msgstr "Falló al recibir los registros recientes" -#: ../libempathy-gtk/empathy-chat.c:2331 +#: ../libempathy-gtk/empathy-chat.c:2386 #, c-format msgid "%s has disconnected" msgstr "%s se ha desconectado" @@ -1443,12 +1454,12 @@ msgstr "%s se ha desconectado" #. translators: reverse the order of these arguments #. * if the kicked should come before the kicker in your locale. #. -#: ../libempathy-gtk/empathy-chat.c:2338 +#: ../libempathy-gtk/empathy-chat.c:2393 #, c-format msgid "%1$s was kicked by %2$s" msgstr "%2$s expulsó a %1$s" -#: ../libempathy-gtk/empathy-chat.c:2341 +#: ../libempathy-gtk/empathy-chat.c:2396 #, c-format msgid "%s was kicked" msgstr "%s fue expulsado" @@ -1456,17 +1467,17 @@ msgstr "%s fue expulsado" #. translators: reverse the order of these arguments #. * if the banned should come before the banner in your locale. #. -#: ../libempathy-gtk/empathy-chat.c:2349 +#: ../libempathy-gtk/empathy-chat.c:2404 #, c-format msgid "%1$s was banned by %2$s" msgstr "%2$s vetó a %1$s" -#: ../libempathy-gtk/empathy-chat.c:2352 +#: ../libempathy-gtk/empathy-chat.c:2407 #, c-format msgid "%s was banned" msgstr "%s fue vetado" -#: ../libempathy-gtk/empathy-chat.c:2356 +#: ../libempathy-gtk/empathy-chat.c:2411 #, c-format msgid "%s has left the room" msgstr "%s ha dejado la sala" @@ -1476,69 +1487,69 @@ msgstr "%s ha dejado la sala" #. * given by the user living the room. If this poses a problem, #. * please let us know. :-) #. -#: ../libempathy-gtk/empathy-chat.c:2365 +#: ../libempathy-gtk/empathy-chat.c:2420 #, c-format msgid " (%s)" msgstr " (%s)" -#: ../libempathy-gtk/empathy-chat.c:2390 +#: ../libempathy-gtk/empathy-chat.c:2445 #, c-format msgid "%s has joined the room" msgstr "%s ha entrado en la sala" -#: ../libempathy-gtk/empathy-chat.c:2415 +#: ../libempathy-gtk/empathy-chat.c:2470 #, c-format msgid "%s is now known as %s" msgstr "Ahora %s se llama %s" -#: ../libempathy-gtk/empathy-chat.c:2554 +#: ../libempathy-gtk/empathy-chat.c:2609 #: ../src/empathy-streamed-media-window.c:1957 -#: ../src/empathy-event-manager.c:1116 +#: ../src/empathy-event-manager.c:1117 msgid "Disconnected" msgstr "Desconectado" #. Add message -#: ../libempathy-gtk/empathy-chat.c:3202 +#: ../libempathy-gtk/empathy-chat.c:3267 msgid "Would you like to store this password?" msgstr "¿Quiere guardar esta contraseña?" -#: ../libempathy-gtk/empathy-chat.c:3208 +#: ../libempathy-gtk/empathy-chat.c:3273 msgid "Remember" msgstr "Recordar" -#: ../libempathy-gtk/empathy-chat.c:3218 +#: ../libempathy-gtk/empathy-chat.c:3283 msgid "Not now" msgstr "Ahora no" -#: ../libempathy-gtk/empathy-chat.c:3262 +#: ../libempathy-gtk/empathy-chat.c:3327 msgid "Retry" msgstr "Volver a intentarlo" -#: ../libempathy-gtk/empathy-chat.c:3266 +#: ../libempathy-gtk/empathy-chat.c:3331 msgid "Wrong password; please try again:" msgstr "Contraseña incorrecta; inténtelo de nuevo:" #. Add message -#: ../libempathy-gtk/empathy-chat.c:3383 +#: ../libempathy-gtk/empathy-chat.c:3460 msgid "This room is protected by a password:" msgstr "Esta sala está protegida por contraseña:" -#: ../libempathy-gtk/empathy-chat.c:3410 +#: ../libempathy-gtk/empathy-chat.c:3487 msgid "Join" msgstr "Unirse" -#: ../libempathy-gtk/empathy-chat.c:3602 ../src/empathy-event-manager.c:1137 +#: ../libempathy-gtk/empathy-chat.c:3686 ../src/empathy-event-manager.c:1138 msgid "Connected" msgstr "Conectado" -#: ../libempathy-gtk/empathy-chat.c:3657 +#: ../libempathy-gtk/empathy-chat.c:3741 #: ../libempathy-gtk/empathy-log-window.c:650 msgid "Conversation" msgstr "Conversación" #. Translators: this string is a something like #. * "Escher Cat (SMS)" -#: ../libempathy-gtk/empathy-chat.c:3662 +#: ../libempathy-gtk/empathy-chat.c:3746 #, c-format msgid "%s (SMS)" msgstr "%s (SMS)" @@ -1580,13 +1591,13 @@ msgstr "Cuenta:" #. Copy Link Address menu item #: ../libempathy-gtk/empathy-chat-text-view.c:320 -#: ../libempathy-gtk/empathy-theme-adium.c:996 +#: ../libempathy-gtk/empathy-theme-adium.c:1002 msgid "_Copy Link Address" msgstr "_Copiar la dirección del enlace" #. Open Link menu item #: ../libempathy-gtk/empathy-chat-text-view.c:327 -#: ../libempathy-gtk/empathy-theme-adium.c:1003 +#: ../libempathy-gtk/empathy-theme-adium.c:1009 msgid "_Open Link" msgstr "_Abrir enlace" @@ -1701,58 +1712,58 @@ msgstr "_Bloquear contacto" msgid "_Chat" msgstr "_Chat" -#: ../libempathy-gtk/empathy-contact-menu.c:359 +#: ../libempathy-gtk/empathy-contact-menu.c:358 #: ../libempathy-gtk/empathy-individual-menu.c:625 msgctxt "menu item" msgid "_Audio Call" msgstr "Llamada de vo_z" -#: ../libempathy-gtk/empathy-contact-menu.c:390 +#: ../libempathy-gtk/empathy-contact-menu.c:389 #: ../libempathy-gtk/empathy-individual-menu.c:667 msgctxt "menu item" msgid "_Video Call" msgstr "Llamada de _vídeo" -#: ../libempathy-gtk/empathy-contact-menu.c:436 +#: ../libempathy-gtk/empathy-contact-menu.c:435 #: ../libempathy-gtk/empathy-individual-menu.c:710 #: ../src/empathy-main-window.ui.h:27 msgid "_Previous Conversations" msgstr "Conversaciones an_teriores" -#: ../libempathy-gtk/empathy-contact-menu.c:458 +#: ../libempathy-gtk/empathy-contact-menu.c:457 #: ../libempathy-gtk/empathy-individual-menu.c:751 msgid "Send File" msgstr "Enviar archivo" -#: ../libempathy-gtk/empathy-contact-menu.c:481 +#: ../libempathy-gtk/empathy-contact-menu.c:480 #: ../libempathy-gtk/empathy-individual-menu.c:793 msgid "Share My Desktop" msgstr "Compartir mi escritorio" -#: ../libempathy-gtk/empathy-contact-menu.c:521 -#: ../libempathy-gtk/empathy-contact-widget.c:1751 +#: ../libempathy-gtk/empathy-contact-menu.c:520 +#: ../libempathy-gtk/empathy-contact-widget.c:1890 #: ../libempathy-gtk/empathy-individual-menu.c:828 #: ../libempathy-gtk/empathy-individual-widget.c:1370 msgid "Favorite" msgstr "Favorita" -#: ../libempathy-gtk/empathy-contact-menu.c:550 +#: ../libempathy-gtk/empathy-contact-menu.c:549 #: ../libempathy-gtk/empathy-individual-menu.c:856 msgid "Infor_mation" msgstr "Infor_mación" -#: ../libempathy-gtk/empathy-contact-menu.c:596 +#: ../libempathy-gtk/empathy-contact-menu.c:595 msgctxt "Edit contact (contextual menu)" msgid "_Edit" msgstr "_Editar" -#: ../libempathy-gtk/empathy-contact-menu.c:650 +#: ../libempathy-gtk/empathy-contact-menu.c:649 #: ../libempathy-gtk/empathy-individual-menu.c:1037 #: ../src/empathy-chat-window.c:986 msgid "Inviting you to this room" msgstr "Invitándolo a esta sala" -#: ../libempathy-gtk/empathy-contact-menu.c:681 +#: ../libempathy-gtk/empathy-contact-menu.c:680 #: ../libempathy-gtk/empathy-individual-menu.c:1084 msgid "_Invite to Chat Room" msgstr "_Invitar a sala de chat" @@ -1778,153 +1789,180 @@ msgstr "No se encontraron contactos" msgid "Select a contact" msgstr "Seleccionar un contacto" -#: ../libempathy-gtk/empathy-contact-widget.c:295 +#: ../libempathy-gtk/empathy-contact-widget.c:336 #: ../libempathy-gtk/empathy-individual-widget.c:153 msgid "Full name:" msgstr "Nombre completo:" -#: ../libempathy-gtk/empathy-contact-widget.c:296 +#: ../libempathy-gtk/empathy-contact-widget.c:337 #: ../libempathy-gtk/empathy-individual-widget.c:154 msgid "Phone number:" msgstr "Número de teléfono:" -#: ../libempathy-gtk/empathy-contact-widget.c:297 +#: ../libempathy-gtk/empathy-contact-widget.c:338 #: ../libempathy-gtk/empathy-individual-widget.c:155 msgid "E-mail address:" msgstr "Dirección de correo-e:" -#: ../libempathy-gtk/empathy-contact-widget.c:298 +#: ../libempathy-gtk/empathy-contact-widget.c:339 #: ../libempathy-gtk/empathy-individual-widget.c:156 msgid "Website:" msgstr "Página web:" -#: ../libempathy-gtk/empathy-contact-widget.c:299 +#: ../libempathy-gtk/empathy-contact-widget.c:340 #: ../libempathy-gtk/empathy-individual-widget.c:157 msgid "Birthday:" msgstr "Cumpleaños:" -#: ../libempathy-gtk/empathy-contact-widget.c:762 +#. Note to translators: this is the caption for a string of the form "5 +#. * minutes ago", and refers to the time since the contact last interacted +#. * with their IM client. +#. +#: ../libempathy-gtk/empathy-contact-widget.c:346 +#| msgid "_Last Name:" +msgid "Last seen:" +msgstr "Última actividad:" + +#: ../libempathy-gtk/empathy-contact-widget.c:348 +#| msgid "Connected" +msgid "Connected from:" +msgstr "Conectado desde:" + +#. FIXME: once Idle implements SimplePresence using this information, we can +#. * and should bin this. +#. +#: ../libempathy-gtk/empathy-contact-widget.c:353 +#| msgid "Quit message:" +msgid "Away message:" +msgstr "Mensaje de ausencia:" + +#: ../libempathy-gtk/empathy-contact-widget.c:606 +#| msgid "Ca_ncel" +msgid "Channels:" +msgstr "Canales:" + +#: ../libempathy-gtk/empathy-contact-widget.c:901 #: ../libempathy-gtk/empathy-individual-widget.c:488 msgid "Country ISO Code:" msgstr "Código ISO de país:" -#: ../libempathy-gtk/empathy-contact-widget.c:764 +#: ../libempathy-gtk/empathy-contact-widget.c:903 #: ../libempathy-gtk/empathy-individual-widget.c:490 msgid "Country:" msgstr "País:" -#: ../libempathy-gtk/empathy-contact-widget.c:766 +#: ../libempathy-gtk/empathy-contact-widget.c:905 #: ../libempathy-gtk/empathy-individual-widget.c:492 msgid "State:" msgstr "Estado:" -#: ../libempathy-gtk/empathy-contact-widget.c:768 +#: ../libempathy-gtk/empathy-contact-widget.c:907 #: ../libempathy-gtk/empathy-individual-widget.c:494 msgid "City:" msgstr "Ciudad:" -#: ../libempathy-gtk/empathy-contact-widget.c:770 +#: ../libempathy-gtk/empathy-contact-widget.c:909 #: ../libempathy-gtk/empathy-individual-widget.c:496 msgid "Area:" msgstr "Área:" -#: ../libempathy-gtk/empathy-contact-widget.c:772 +#: ../libempathy-gtk/empathy-contact-widget.c:911 #: ../libempathy-gtk/empathy-individual-widget.c:498 msgid "Postal Code:" msgstr "Código postal:" -#: ../libempathy-gtk/empathy-contact-widget.c:774 +#: ../libempathy-gtk/empathy-contact-widget.c:913 #: ../libempathy-gtk/empathy-individual-widget.c:500 msgid "Street:" msgstr "Calle:" -#: ../libempathy-gtk/empathy-contact-widget.c:776 +#: ../libempathy-gtk/empathy-contact-widget.c:915 #: ../libempathy-gtk/empathy-individual-widget.c:502 msgid "Building:" msgstr "Edificio:" -#: ../libempathy-gtk/empathy-contact-widget.c:778 +#: ../libempathy-gtk/empathy-contact-widget.c:917 #: ../libempathy-gtk/empathy-individual-widget.c:504 msgid "Floor:" msgstr "Planta:" -#: ../libempathy-gtk/empathy-contact-widget.c:780 +#: ../libempathy-gtk/empathy-contact-widget.c:919 #: ../libempathy-gtk/empathy-individual-widget.c:506 msgid "Room:" msgstr "Habitación:" -#: ../libempathy-gtk/empathy-contact-widget.c:782 +#: ../libempathy-gtk/empathy-contact-widget.c:921 #: ../libempathy-gtk/empathy-individual-widget.c:508 msgid "Text:" msgstr "Texto:" -#: ../libempathy-gtk/empathy-contact-widget.c:784 +#: ../libempathy-gtk/empathy-contact-widget.c:923 #: ../libempathy-gtk/empathy-individual-widget.c:510 msgid "Description:" msgstr "Descripción:" -#: ../libempathy-gtk/empathy-contact-widget.c:786 +#: ../libempathy-gtk/empathy-contact-widget.c:925 #: ../libempathy-gtk/empathy-individual-widget.c:512 msgid "URI:" msgstr "URI:" -#: ../libempathy-gtk/empathy-contact-widget.c:788 +#: ../libempathy-gtk/empathy-contact-widget.c:927 #: ../libempathy-gtk/empathy-individual-widget.c:514 msgid "Accuracy Level:" msgstr "Nivel de precisión:" -#: ../libempathy-gtk/empathy-contact-widget.c:790 +#: ../libempathy-gtk/empathy-contact-widget.c:929 #: ../libempathy-gtk/empathy-individual-widget.c:516 msgid "Error:" msgstr "Error:" -#: ../libempathy-gtk/empathy-contact-widget.c:792 +#: ../libempathy-gtk/empathy-contact-widget.c:931 #: ../libempathy-gtk/empathy-individual-widget.c:518 msgid "Vertical Error (meters):" msgstr "Error vertical (metros):" -#: ../libempathy-gtk/empathy-contact-widget.c:794 +#: ../libempathy-gtk/empathy-contact-widget.c:933 #: ../libempathy-gtk/empathy-individual-widget.c:520 msgid "Horizontal Error (meters):" msgstr "Error horizontal (metros):" -#: ../libempathy-gtk/empathy-contact-widget.c:796 +#: ../libempathy-gtk/empathy-contact-widget.c:935 #: ../libempathy-gtk/empathy-individual-widget.c:522 msgid "Speed:" msgstr "Velocidad:" -#: ../libempathy-gtk/empathy-contact-widget.c:798 +#: ../libempathy-gtk/empathy-contact-widget.c:937 #: ../libempathy-gtk/empathy-individual-widget.c:524 msgid "Bearing:" msgstr "Retardo:" -#: ../libempathy-gtk/empathy-contact-widget.c:800 +#: ../libempathy-gtk/empathy-contact-widget.c:939 #: ../libempathy-gtk/empathy-individual-widget.c:526 msgid "Climb Speed:" msgstr "Velocidad de ascenso:" -#: ../libempathy-gtk/empathy-contact-widget.c:802 +#: ../libempathy-gtk/empathy-contact-widget.c:941 #: ../libempathy-gtk/empathy-individual-widget.c:528 msgid "Last Updated on:" msgstr "Actualizado por última vez:" -#: ../libempathy-gtk/empathy-contact-widget.c:804 +#: ../libempathy-gtk/empathy-contact-widget.c:943 #: ../libempathy-gtk/empathy-individual-widget.c:530 msgid "Longitude:" msgstr "Longitud_" -#: ../libempathy-gtk/empathy-contact-widget.c:806 +#: ../libempathy-gtk/empathy-contact-widget.c:945 #: ../libempathy-gtk/empathy-individual-widget.c:532 msgid "Latitude:" msgstr "Latitud:" -#: ../libempathy-gtk/empathy-contact-widget.c:808 +#: ../libempathy-gtk/empathy-contact-widget.c:947 #: ../libempathy-gtk/empathy-individual-widget.c:534 msgid "Altitude:" msgstr "Altitud:" -#: ../libempathy-gtk/empathy-contact-widget.c:861 -#: ../libempathy-gtk/empathy-contact-widget.c:876 +#: ../libempathy-gtk/empathy-contact-widget.c:1000 +#: ../libempathy-gtk/empathy-contact-widget.c:1015 #: ../libempathy-gtk/empathy-individual-widget.c:616 #: ../libempathy-gtk/empathy-individual-widget.c:631 #: ../src/empathy-preferences.ui.h:12 @@ -1932,23 +1970,23 @@ msgid "Location" msgstr "Ubicación geográfica" #. translators: format is "Location, $date" -#: ../libempathy-gtk/empathy-contact-widget.c:878 +#: ../libempathy-gtk/empathy-contact-widget.c:1017 #: ../libempathy-gtk/empathy-individual-widget.c:633 #, c-format msgid "%s, %s" msgstr "%s, %s" -#: ../libempathy-gtk/empathy-contact-widget.c:930 +#: ../libempathy-gtk/empathy-contact-widget.c:1069 #: ../libempathy-gtk/empathy-individual-widget.c:682 msgid "%B %e, %Y at %R UTC" msgstr "%e de %B de %Y a las %R UTC" -#: ../libempathy-gtk/empathy-contact-widget.c:1012 +#: ../libempathy-gtk/empathy-contact-widget.c:1151 #: ../libempathy-gtk/empathy-individual-widget.c:917 msgid "Save Avatar" msgstr "Guardar avatar" -#: ../libempathy-gtk/empathy-contact-widget.c:1068 +#: ../libempathy-gtk/empathy-contact-widget.c:1207 #: ../libempathy-gtk/empathy-individual-widget.c:975 msgid "Unable to save avatar" msgstr "No se pudo guardar el avatar" @@ -2225,17 +2263,17 @@ msgid "New Conversation" msgstr "Conversación nueva" #. add video toggle -#: ../libempathy-gtk/empathy-new-call-dialog.c:253 +#: ../libempathy-gtk/empathy-new-call-dialog.c:254 msgid "Send _Video" msgstr "Enviar _vídeo" #. add chat button -#: ../libempathy-gtk/empathy-new-call-dialog.c:261 +#: ../libempathy-gtk/empathy-new-call-dialog.c:262 msgid "C_all" msgstr "_Llamar" #. Tweak the dialog -#: ../libempathy-gtk/empathy-new-call-dialog.c:271 +#: ../libempathy-gtk/empathy-new-call-dialog.c:272 msgid "New Call" msgstr "Llamada nueva" @@ -2362,7 +2400,7 @@ msgstr "Guardar mensaje de estado _nuevo" msgid "Saved Status Messages" msgstr "Mensajes de estado guardados" -#: ../libempathy-gtk/empathy-theme-adium.c:1462 +#: ../libempathy-gtk/empathy-theme-adium.c:1468 msgid "Normal" msgstr "Normal" @@ -3432,90 +3470,90 @@ msgstr "Autoconectar" msgid "Manage Favorite Rooms" msgstr "Gestionar salas favoritas" -#: ../src/empathy-event-manager.c:504 +#: ../src/empathy-event-manager.c:505 msgid "Incoming video call" msgstr "Llamada de vídeo entrante" -#: ../src/empathy-event-manager.c:504 +#: ../src/empathy-event-manager.c:505 msgid "Incoming call" msgstr "Llamada entrante" -#: ../src/empathy-event-manager.c:508 +#: ../src/empathy-event-manager.c:509 #, c-format msgid "%s is video calling you. Do you want to answer?" msgstr "%s le está llamando con vídeo. ¿Quiere responder?" -#: ../src/empathy-event-manager.c:509 +#: ../src/empathy-event-manager.c:510 #, c-format msgid "%s is calling you. Do you want to answer?" msgstr "%s le está llamando. ¿Quiere responder?" -#: ../src/empathy-event-manager.c:512 ../src/empathy-event-manager.c:661 +#: ../src/empathy-event-manager.c:513 ../src/empathy-event-manager.c:662 #, c-format msgid "Incoming call from %s" msgstr "Llamada entrante de %s" -#: ../src/empathy-event-manager.c:537 +#: ../src/empathy-event-manager.c:538 msgid "_Reject" msgstr "_Rechazar" -#: ../src/empathy-event-manager.c:543 +#: ../src/empathy-event-manager.c:544 msgid "_Answer" msgstr "Re_spuesta" -#: ../src/empathy-event-manager.c:661 +#: ../src/empathy-event-manager.c:662 #, c-format msgid "Incoming video call from %s" msgstr "Llamada de vídeo entrante de %s" -#: ../src/empathy-event-manager.c:734 +#: ../src/empathy-event-manager.c:735 msgid "Room invitation" msgstr "Invitación a una sala" -#: ../src/empathy-event-manager.c:736 +#: ../src/empathy-event-manager.c:737 #, c-format msgid "Invitation to join %s" msgstr "Invitación para unirse a %s" -#: ../src/empathy-event-manager.c:743 +#: ../src/empathy-event-manager.c:744 #, c-format msgid "%s is inviting you to join %s" msgstr "%s le está invitando a unirse a %s" -#: ../src/empathy-event-manager.c:751 +#: ../src/empathy-event-manager.c:752 msgid "_Decline" msgstr "_Rechazar" -#: ../src/empathy-event-manager.c:756 +#: ../src/empathy-event-manager.c:757 #: ../src/empathy-new-chatroom-dialog.ui.h:7 msgid "_Join" msgstr "_Unirse" -#: ../src/empathy-event-manager.c:783 +#: ../src/empathy-event-manager.c:784 #, c-format msgid "%s invited you to join %s" msgstr "%s le ha invitado a unirse a %s" -#: ../src/empathy-event-manager.c:789 +#: ../src/empathy-event-manager.c:790 #, c-format msgid "You have been invited to join %s" msgstr "Le han invitado a unirse a %s" -#: ../src/empathy-event-manager.c:840 +#: ../src/empathy-event-manager.c:841 #, c-format msgid "Incoming file transfer from %s" msgstr "Transferencia de archivo entrante de %s" -#: ../src/empathy-event-manager.c:1010 ../src/empathy-main-window.c:377 +#: ../src/empathy-event-manager.c:1011 ../src/empathy-main-window.c:377 msgid "Password required" msgstr "Se requiere una contraseña" -#: ../src/empathy-event-manager.c:1066 +#: ../src/empathy-event-manager.c:1067 #, c-format msgid "%s would like permission to see when you are online" msgstr "%s quiere permiso para ver cuándo está en línea" -#: ../src/empathy-event-manager.c:1070 +#: ../src/empathy-event-manager.c:1071 #, c-format msgid "" "\n" diff --git a/src/empathy-chat-manager.c b/src/empathy-chat-manager.c index 28f639d4c..bf870c8cc 100644 --- a/src/empathy-chat-manager.c +++ b/src/empathy-chat-manager.c @@ -60,6 +60,11 @@ struct _EmpathyChatManagerPriv guint num_displayed_chat; + /* account path -> (GHashTable<(owned gchar *) contact ID + * -> (owned gchar *) non-NULL message>) + */ + GHashTable *messages; + TpBaseClient *handler; }; @@ -147,6 +152,8 @@ process_tp_chat (EmpathyChatManager *self, } else { + GHashTable *chats = NULL; + chat = empathy_chat_new (tp_chat); /* empathy_chat_new returns a floating reference as EmpathyChat is * a GtkWidget. This reference will be taken by a container @@ -160,6 +167,18 @@ process_tp_chat (EmpathyChatManager *self, g_signal_emit (self, signals[DISPLAYED_CHATS_CHANGED], 0, priv->num_displayed_chat); + /* Set the saved message in the channel if we have one. */ + chats = g_hash_table_lookup (priv->messages, + tp_proxy_get_object_path (account)); + + if (chats != NULL) + { + const gchar *msg = g_hash_table_lookup (chats, id); + + if (msg != NULL) + empathy_chat_set_text (chat, msg); + } + g_object_weak_ref ((GObject *) chat, chat_destroyed_cb, self); } empathy_chat_window_present_chat (chat, user_action_time); @@ -284,6 +303,8 @@ empathy_chat_manager_init (EmpathyChatManager *self) GError *error = NULL; priv->closed_queue = g_queue_new (); + priv->messages = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, (GDestroyNotify) g_hash_table_unref); dbus = tp_dbus_daemon_dup (&error); if (dbus == NULL) @@ -342,6 +363,8 @@ empathy_chat_manager_finalize (GObject *object) priv->closed_queue = NULL; } + tp_clear_pointer (&priv->messages, g_hash_table_unref); + tp_clear_object (&priv->handler); tp_clear_object (&priv->chatroom_mgr); @@ -433,6 +456,8 @@ empathy_chat_manager_closed_chat (EmpathyChatManager *self, { EmpathyChatManagerPriv *priv = GET_PRIV (self); ChatData *data; + GHashTable *chats; + gchar *message; data = chat_data_new (chat); @@ -443,6 +468,43 @@ empathy_chat_manager_closed_chat (EmpathyChatManager *self, g_signal_emit (self, signals[CLOSED_CHATS_CHANGED], 0, g_queue_get_length (priv->closed_queue)); + + /* If there was a message saved from last time it was closed + * (perhaps by accident?) save it to our hash table so it can be + * used again when the same chat pops up. Hot. */ + message = empathy_chat_dup_text (chat); + + chats = g_hash_table_lookup (priv->messages, + tp_proxy_get_object_path (data->account)); + + /* Don't create a new hash table if we don't already have one and we + * don't actually have a message to save. */ + if (chats == NULL && tp_str_empty (message)) + { + g_free (message); + return; + } + else if (chats == NULL && !tp_str_empty (message)) + { + chats = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, g_free); + + g_hash_table_insert (priv->messages, + g_strdup (tp_proxy_get_object_path (data->account)), + chats); + } + + if (tp_str_empty (message)) + { + g_hash_table_remove (chats, data->id); + /* might be '\0' */ + g_free (message); + } + else + { + /* takes ownership of message */ + g_hash_table_insert (chats, g_strdup (data->id), message); + } } void diff --git a/src/empathy-chat-window.c b/src/empathy-chat-window.c index e9298ddbf..d8a75cb0c 100644 --- a/src/empathy-chat-window.c +++ b/src/empathy-chat-window.c @@ -794,6 +794,7 @@ chat_window_update_chat_tab (EmpathyChat *chat) static void chat_window_chat_notify_cb (EmpathyChat *chat) { + EmpathyChatWindow *window; EmpathyContact *old_remote_contact; EmpathyContact *remote_contact = NULL; @@ -820,6 +821,11 @@ chat_window_chat_notify_cb (EmpathyChat *chat) } chat_window_update_chat_tab (chat); + + window = chat_window_find_chat (chat); + if (window != NULL) { + chat_window_update (window, FALSE); + } } static void @@ -2326,6 +2332,9 @@ empathy_chat_window_add_chat (EmpathyChatWindow *window, g_signal_connect (chat, "notify::n-messages-sending", G_CALLBACK (chat_window_chat_notify_cb), NULL); + g_signal_connect (chat, "notify::nb-unread-messages", + G_CALLBACK (chat_window_chat_notify_cb), + NULL); chat_window_chat_notify_cb (chat); gtk_notebook_append_page_menu (GTK_NOTEBOOK (priv->notebook), child, label, popup_label); |