diff options
Diffstat (limited to 'libempathy')
-rw-r--r-- | libempathy/Makefile.am | 2 | ||||
-rw-r--r-- | libempathy/empathy-account-settings.c | 1 | ||||
-rw-r--r-- | libempathy/empathy-gsettings.h | 2 | ||||
-rw-r--r-- | libempathy/empathy-individual-manager.c | 95 | ||||
-rw-r--r-- | libempathy/empathy-individual-manager.h | 7 | ||||
-rw-r--r-- | libempathy/empathy-message.c | 69 | ||||
-rw-r--r-- | libempathy/empathy-message.h | 1 | ||||
-rw-r--r-- | libempathy/empathy-pkg-kit.c | 161 | ||||
-rw-r--r-- | libempathy/empathy-pkg-kit.h | 38 | ||||
-rw-r--r-- | libempathy/empathy-presence-manager.c | 70 | ||||
-rw-r--r-- | libempathy/empathy-time.c | 155 | ||||
-rw-r--r-- | libempathy/empathy-time.h | 24 | ||||
-rw-r--r-- | libempathy/empathy-tp-chat.c | 45 | ||||
-rw-r--r-- | libempathy/empathy-tp-chat.h | 1 | ||||
-rw-r--r-- | libempathy/empathy-tp-streamed-media.c | 2 | ||||
-rw-r--r-- | libempathy/empathy-utils.c | 26 | ||||
-rw-r--r-- | libempathy/empathy-utils.h | 3 |
17 files changed, 474 insertions, 228 deletions
diff --git a/libempathy/Makefile.am b/libempathy/Makefile.am index ca02a18d3..cc288bfa8 100644 --- a/libempathy/Makefile.am +++ b/libempathy/Makefile.am @@ -51,6 +51,7 @@ libempathy_headers = \ empathy-keyring.h \ empathy-location.h \ empathy-message.h \ + empathy-pkg-kit.h \ empathy-request-util.h \ empathy-server-sasl-handler.h \ empathy-server-tls-handler.h \ @@ -91,6 +92,7 @@ libempathy_handwritten_source = \ empathy-irc-server.c \ empathy-keyring.c \ empathy-message.c \ + empathy-pkg-kit.c \ empathy-request-util.c \ empathy-server-sasl-handler.c \ empathy-server-tls-handler.c \ diff --git a/libempathy/empathy-account-settings.c b/libempathy/empathy-account-settings.c index cf269bdc8..4d9795686 100644 --- a/libempathy/empathy-account-settings.c +++ b/libempathy/empathy-account-settings.c @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "config.h" #include <stdio.h> #include <stdlib.h> diff --git a/libempathy/empathy-gsettings.h b/libempathy/empathy-gsettings.h index ad55a9442..fd05141ac 100644 --- a/libempathy/empathy-gsettings.h +++ b/libempathy/empathy-gsettings.h @@ -66,6 +66,7 @@ G_BEGIN_DECLS #define EMPATHY_PREFS_CHAT_AVATAR_IN_ICON "avatar-in-icon" #define EMPATHY_PREFS_CHAT_WEBKIT_DEVELOPER_TOOLS "enable-webkit-developer-tools" #define EMPATHY_PREFS_CHAT_ROOM_LAST_ACCOUNT "room-last-account" +#define EMPATHY_PREFS_CHAT_SEND_CHAT_STATES "send-chat-states" #define EMPATHY_PREFS_UI_SCHEMA EMPATHY_PREFS_SCHEMA ".ui" #define EMPATHY_PREFS_UI_SEPARATE_CHAT_WINDOWS "separate-chat-windows" @@ -77,6 +78,7 @@ G_BEGIN_DECLS #define EMPATHY_PREFS_UI_COMPACT_CONTACT_LIST "compact-contact-list" #define EMPATHY_PREFS_UI_CHAT_WINDOW_PANED_POS "chat-window-paned-pos" #define EMPATHY_PREFS_UI_SHOW_OFFLINE "show-offline" +#define EMPATHY_PREFS_UI_SHOW_GROUPS "show-groups" #define EMPATHY_PREFS_CONTACTS_SCHEMA EMPATHY_PREFS_SCHEMA ".contacts" #define EMPATHY_PREFS_CONTACTS_SORT_CRITERIUM "sort-criterium" diff --git a/libempathy/empathy-individual-manager.c b/libempathy/empathy-individual-manager.c index b391d3ca9..68b094ef1 100644 --- a/libempathy/empathy-individual-manager.c +++ b/libempathy/empathy-individual-manager.c @@ -50,6 +50,7 @@ typedef struct { FolksIndividualAggregator *aggregator; GHashTable *individuals; /* Individual.id -> Individual */ + gboolean contacts_loaded; } EmpathyIndividualManagerPriv; enum @@ -57,6 +58,7 @@ enum FAVOURITES_CHANGED, GROUPS_CHANGED, MEMBERS_CHANGED, + CONTACTS_LOADED, LAST_SIGNAL }; @@ -334,11 +336,42 @@ empathy_individual_manager_class_init (EmpathyIndividualManagerClass *klass) G_TYPE_NONE, 4, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_UINT); + signals[CONTACTS_LOADED] = + g_signal_new ("contacts-loaded", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + g_cclosure_marshal_generic, + G_TYPE_NONE, + 0); + g_type_class_add_private (object_class, sizeof (EmpathyIndividualManagerPriv)); } static void +aggregator_is_quiescent_notify_cb (FolksIndividualAggregator *aggregator, + GParamSpec *spec, + EmpathyIndividualManager *self) +{ + EmpathyIndividualManagerPriv *priv = GET_PRIV (self); + gboolean is_quiescent; + + if (priv->contacts_loaded) + return; + + g_object_get (aggregator, "is-quiescent", &is_quiescent, NULL); + + if (!is_quiescent) + return; + + priv->contacts_loaded = TRUE; + + g_signal_emit (self, signals[CONTACTS_LOADED], 0); +} + +static void empathy_individual_manager_init (EmpathyIndividualManager *self) { EmpathyIndividualManagerPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (self, @@ -351,6 +384,8 @@ empathy_individual_manager_init (EmpathyIndividualManager *self) priv->aggregator = folks_individual_aggregator_new (); g_signal_connect (priv->aggregator, "individuals-changed-detailed", G_CALLBACK (aggregator_individuals_changed_cb), self); + g_signal_connect (priv->aggregator, "notify::is-quiescent", + G_CALLBACK (aggregator_is_quiescent_notify_cb), self); folks_individual_aggregator_prepare (priv->aggregator, NULL, NULL); } @@ -720,3 +755,63 @@ empathy_individual_manager_unlink_individual (EmpathyIndividualManager *self, folks_individual_aggregator_unlink_individual (priv->aggregator, individual, (GAsyncReadyCallback) unlink_individual_cb, NULL); } + +gboolean +empathy_individual_manager_get_contacts_loaded (EmpathyIndividualManager *self) +{ + EmpathyIndividualManagerPriv *priv = GET_PRIV (self); + + return priv->contacts_loaded; +} + +static gboolean +individual_has_contact (FolksIndividual *individual, + TpContact *contact) +{ + GeeSet *personas; + GeeIterator *iter; + gboolean found = FALSE; + + personas = folks_individual_get_personas (individual); + iter = gee_iterable_iterator (GEE_ITERABLE (personas)); + + while (!found && gee_iterator_next (iter)) + { + TpfPersona *persona = gee_iterator_get (iter); + + if (TPF_IS_PERSONA (persona)) + { + TpContact *c = tpf_persona_get_contact (persona); + + if (c == contact) + found = TRUE; + } + + g_clear_object (&persona); + } + + g_clear_object (&iter); + + return found; +} + +/* Try finding a FolksIndividual containing @contact as one of his persona */ +FolksIndividual * +empathy_individual_manager_lookup_by_contact (EmpathyIndividualManager *self, + TpContact *contact) +{ + EmpathyIndividualManagerPriv *priv = GET_PRIV (self); + GHashTableIter iter; + gpointer value; + + g_hash_table_iter_init (&iter, priv->individuals); + while (g_hash_table_iter_next (&iter, NULL, &value)) + { + FolksIndividual *individual = value; + + if (individual_has_contact (individual, contact)) + return individual; + } + + return NULL; +} diff --git a/libempathy/empathy-individual-manager.h b/libempathy/empathy-individual-manager.h index 0d5cc74d4..08a1faade 100644 --- a/libempathy/empathy-individual-manager.h +++ b/libempathy/empathy-individual-manager.h @@ -90,5 +90,12 @@ void empathy_individual_manager_set_blocked (EmpathyIndividualManager *self, gboolean blocked, gboolean abusive); +gboolean empathy_individual_manager_get_contacts_loaded ( + EmpathyIndividualManager *self); + +FolksIndividual * empathy_individual_manager_lookup_by_contact ( + EmpathyIndividualManager *self, + TpContact *contact); + G_END_DECLS #endif /* __EMPATHY_INDIVIDUAL_MANAGER_H__ */ diff --git a/libempathy/empathy-message.c b/libempathy/empathy-message.c index 995f49ab7..6111bcd8c 100644 --- a/libempathy/empathy-message.c +++ b/libempathy/empathy-message.c @@ -633,75 +633,6 @@ empathy_message_is_backlog (EmpathyMessage *message) return priv->is_backlog; } -#define IS_SEPARATOR(ch) (ch == ' ' || ch == ',' || ch == '.' || ch == ':') -gboolean -empathy_message_should_highlight (EmpathyMessage *message) -{ - EmpathyContact *contact; - const gchar *msg, *to; - gchar *cf_msg, *cf_to; - gchar *ch; - gboolean ret_val; - TpChannelTextMessageFlags flags; - - g_return_val_if_fail (EMPATHY_IS_MESSAGE (message), FALSE); - - ret_val = FALSE; - - msg = empathy_message_get_body (message); - if (!msg) { - return FALSE; - } - - contact = empathy_message_get_receiver (message); - if (!contact || !empathy_contact_is_user (contact)) { - return FALSE; - } - - to = empathy_contact_get_alias (contact); - if (!to) { - return FALSE; - } - - flags = empathy_message_get_flags (message); - if (flags & TP_CHANNEL_TEXT_MESSAGE_FLAG_SCROLLBACK) { - /* FIXME: Ideally we shouldn't highlight scrollback messages only if they - * have already been received by the user before (and so are in the logs) */ - return FALSE; - } - - cf_msg = g_utf8_casefold (msg, -1); - cf_to = g_utf8_casefold (to, -1); - - ch = strstr (cf_msg, cf_to); - if (ch == NULL) { - goto finished; - } - if (ch != cf_msg) { - /* Not first in the message */ - if (!IS_SEPARATOR (*(ch - 1))) { - goto finished; - } - } - - ch = ch + strlen (cf_to); - if (ch >= cf_msg + strlen (cf_msg)) { - ret_val = TRUE; - goto finished; - } - - if (IS_SEPARATOR (*ch)) { - ret_val = TRUE; - goto finished; - } - -finished: - g_free (cf_msg); - g_free (cf_to); - - return ret_val; -} - TpChannelTextMessageType empathy_message_type_from_str (const gchar *type_str) { diff --git a/libempathy/empathy-message.h b/libempathy/empathy-message.h index 0c27c09e9..81da7bf43 100644 --- a/libempathy/empathy-message.h +++ b/libempathy/empathy-message.h @@ -77,7 +77,6 @@ gint64 empathy_message_get_original_timestamp (EmpathyMessage gboolean empathy_message_is_backlog (EmpathyMessage *message); gboolean empathy_message_is_incoming (EmpathyMessage *message); -gboolean empathy_message_should_highlight (EmpathyMessage *message); TpChannelTextMessageType empathy_message_type_from_str (const gchar *type_str); const gchar * empathy_message_type_to_str (TpChannelTextMessageType type); diff --git a/libempathy/empathy-pkg-kit.c b/libempathy/empathy-pkg-kit.c new file mode 100644 index 000000000..259cd7f7d --- /dev/null +++ b/libempathy/empathy-pkg-kit.c @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2012 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Guillaume Desmottes <guillaume.desmottes@collabora.com> + */ + +#include "config.h" + +#include <libempathy/empathy-pkg-kit.h> + +typedef struct +{ + guint xid; + gchar **packages; + gchar *options; + + GSimpleAsyncResult *result; + GCancellable *cancellable; +} InstallCtx; + +static InstallCtx * +install_ctx_new (guint xid, + const gchar **packages, + const gchar *options, + GSimpleAsyncResult *result, + GCancellable *cancellable) +{ + InstallCtx *ctx = g_slice_new (InstallCtx); + + ctx->xid = xid; + ctx->packages = g_strdupv ((gchar **) packages); + ctx->options = g_strdup (options); + ctx->result = g_object_ref (result); + ctx->cancellable = cancellable != NULL ? g_object_ref (cancellable) : NULL; + return ctx; +} + +static void +install_ctx_free (InstallCtx *ctx) +{ + g_free (ctx->packages); + g_free (ctx->options); + g_object_unref (ctx->result); + g_slice_free (InstallCtx, ctx); +} + +static void +install_ctx_complete (InstallCtx *ctx) +{ + g_simple_async_result_complete (ctx->result); + install_ctx_free (ctx); +} + +static void +install_ctx_failed (InstallCtx *ctx, + GError *error) +{ + g_simple_async_result_take_error (ctx->result, error); + install_ctx_complete (ctx); +} + +static void +install_package_names_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + InstallCtx *ctx = user_data; + GError *error = NULL; + GVariant *res; + + res = g_dbus_proxy_call_finish (G_DBUS_PROXY (source), result, &error); + if (res == NULL) + { + install_ctx_failed (ctx, error); + return; + } + + install_ctx_complete (ctx); + + g_variant_unref (res); +} + +static void +pkg_kit_proxy_new_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + InstallCtx *ctx = user_data; + GError *error = NULL; + GDBusProxy *proxy; + + proxy = g_dbus_proxy_new_for_bus_finish (result, &error); + if (proxy == NULL) + { + install_ctx_failed (ctx, error); + return; + } + + g_dbus_proxy_call (proxy, "InstallPackageNames", + g_variant_new ("(u^a&ss)", ctx->xid, ctx->packages, ctx->options), + G_DBUS_CALL_FLAGS_NONE, -1, NULL, install_package_names_cb, ctx); + + g_object_unref (proxy); +} + +/* Ideally this should live in PackageKit (fdo #45741) */ +void +empathy_pkg_kit_install_packages_async ( + guint xid, + const gchar **packages, + const gchar *options, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + InstallCtx *ctx; + GSimpleAsyncResult *result; + + result = g_simple_async_result_new (NULL, callback, user_data, + empathy_pkg_kit_install_packages_async); + + ctx = install_ctx_new (xid, packages, options != NULL ? options : "", + result, cancellable); + + g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, NULL, + "org.freedesktop.PackageKit", + "/org/freedesktop/PackageKit", + "org.freedesktop.PackageKit.Modify", + NULL, pkg_kit_proxy_new_cb, ctx); + + g_object_unref (result); +} + +gboolean +empathy_pkg_kit_install_packages_finish (GAsyncResult *result, + GError **error) +{ + g_return_val_if_fail (g_simple_async_result_is_valid (result, NULL, + empathy_pkg_kit_install_packages_async), FALSE); + + if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), + error)) + return FALSE; + + return TRUE; +} diff --git a/libempathy/empathy-pkg-kit.h b/libempathy/empathy-pkg-kit.h new file mode 100644 index 000000000..b824d768e --- /dev/null +++ b/libempathy/empathy-pkg-kit.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2012 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Guillaume Desmottes <guillaume.desmottes@collabora.com> + */ + +#ifndef __EMPATHY_PKG_KIT__ +#define __EMPATHY_PKG_KIT__ + +#include <glib.h> +#include <gio/gio.h> + +void empathy_pkg_kit_install_packages_async ( + guint xid, + const gchar **packages, + const gchar *options, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); + +gboolean empathy_pkg_kit_install_packages_finish (GAsyncResult *result, + GError **error); + +#endif diff --git a/libempathy/empathy-presence-manager.c b/libempathy/empathy-presence-manager.c index 67867f96d..22af1ec7b 100644 --- a/libempathy/empathy-presence-manager.c +++ b/libempathy/empathy-presence-manager.c @@ -32,7 +32,6 @@ #include <telepathy-glib/util.h> #include "empathy-utils.h" -#include "empathy-connectivity.h" #define DEBUG_FLAG EMPATHY_DEBUG_OTHER #include "empathy-debug.h" @@ -47,7 +46,6 @@ struct _EmpathyPresenceManagerPrivate { DBusGProxy *gs_proxy; - EmpathyConnectivity *connectivity; gboolean ready; @@ -56,8 +54,6 @@ struct _EmpathyPresenceManagerPrivate gboolean auto_away; TpConnectionPresenceType away_saved_state; - TpConnectionPresenceType saved_state; - gchar *saved_status; gboolean is_idle; guint ext_away_timeout; @@ -175,9 +171,8 @@ session_status_changed_cb (DBusGProxy *gs_proxy, is_idle ? "yes" : "no"); if (!self->priv->auto_away || - (self->priv->saved_state == TP_CONNECTION_PRESENCE_TYPE_UNSET && - (self->priv->state <= TP_CONNECTION_PRESENCE_TYPE_OFFLINE || - self->priv->state == TP_CONNECTION_PRESENCE_TYPE_HIDDEN))) + (self->priv->state <= TP_CONNECTION_PRESENCE_TYPE_OFFLINE || + self->priv->state == TP_CONNECTION_PRESENCE_TYPE_HIDDEN)) { /* We don't want to go auto away OR we explicitely asked to be * offline, nothing to do here */ @@ -192,13 +187,7 @@ session_status_changed_cb (DBusGProxy *gs_proxy, ext_away_start (self); - if (self->priv->saved_state != TP_CONNECTION_PRESENCE_TYPE_UNSET) - /* We are disconnected, when coming back from away - * we want to restore the presence before the - * disconnection. */ - self->priv->away_saved_state = self->priv->saved_state; - else - self->priv->away_saved_state = self->priv->state; + self->priv->away_saved_state = self->priv->state; new_state = TP_CONNECTION_PRESENCE_TYPE_AWAY; if (self->priv->state == TP_CONNECTION_PRESENCE_TYPE_EXTENDED_AWAY) @@ -241,37 +230,6 @@ session_status_changed_cb (DBusGProxy *gs_proxy, } static void -state_change_cb (EmpathyConnectivity *connectivity, - gboolean new_online, - EmpathyPresenceManager *self) -{ - if (!new_online) - { - /* We are no longer connected */ - DEBUG ("Disconnected: Save state %d (%s)", - self->priv->state, self->priv->status); - self->priv->saved_state = self->priv->state; - g_free (self->priv->saved_status); - self->priv->saved_status = g_strdup (self->priv->status); - empathy_presence_manager_set_state (self, - TP_CONNECTION_PRESENCE_TYPE_OFFLINE); - } - else if (new_online - && self->priv->saved_state != TP_CONNECTION_PRESENCE_TYPE_UNSET) - { - /* We are now connected */ - DEBUG ("Reconnected: Restore state %d (%s)", - self->priv->saved_state, self->priv->saved_status); - empathy_presence_manager_set_presence (self, - self->priv->saved_state, - self->priv->saved_status); - self->priv->saved_state = TP_CONNECTION_PRESENCE_TYPE_UNSET; - g_free (self->priv->saved_status); - self->priv->saved_status = NULL; - } -} - -static void presence_manager_dispose (GObject *object) { EmpathyPresenceManager *self = (EmpathyPresenceManager *) object; @@ -279,7 +237,6 @@ presence_manager_dispose (GObject *object) tp_clear_object (&self->priv->gs_proxy); tp_clear_object (&self->priv->manager); - tp_clear_object (&self->priv->connectivity); tp_clear_pointer (&self->priv->connect_times, g_hash_table_unref); next_away_stop (EMPATHY_PRESENCE_MANAGER (object)); @@ -530,11 +487,6 @@ empathy_presence_manager_init (EmpathyPresenceManager *self) g_object_unref (dbus); - self->priv->connectivity = empathy_connectivity_dup_singleton (); - - tp_g_signal_connect_object (self->priv->connectivity, - "state-change", G_CALLBACK (state_change_cb), self, 0); - self->priv->connect_times = g_hash_table_new (g_direct_hash, g_direct_equal); } @@ -609,22 +561,6 @@ empathy_presence_manager_set_presence (EmpathyPresenceManager *self, if (!tp_strdiff (status, default_status)) status = NULL; - if (state != TP_CONNECTION_PRESENCE_TYPE_OFFLINE && - !empathy_connectivity_is_online (self->priv->connectivity)) - { - DEBUG ("Empathy is not online"); - - self->priv->saved_state = state; - if (tp_strdiff (self->priv->status, status)) - { - g_free (self->priv->saved_status); - self->priv->saved_status = NULL; - if (!EMP_STR_EMPTY (status)) - self->priv->saved_status = g_strdup (status); - } - return; - } - empathy_presence_manager_do_set_presence (self, state, status); } diff --git a/libempathy/empathy-time.c b/libempathy/empathy-time.c index 5144fa4d8..fb699f09c 100644 --- a/libempathy/empathy-time.c +++ b/libempathy/empathy-time.c @@ -1,7 +1,6 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * Copyright (C) 2003-2007 Imendio AB - * Copyright (C) 2007-2010 Collabora Ltd. + * Copyright (C) 2007-2012 Collabora Ltd. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -34,110 +33,116 @@ gint64 empathy_time_get_current (void) { - GDateTime *now; - gint64 result; + GDateTime *now; + gint64 result; - now = g_date_time_new_now_utc (); - result = g_date_time_to_unix (now); - g_date_time_unref (now); + now = g_date_time_new_now_utc (); + result = g_date_time_to_unix (now); + g_date_time_unref (now); - return result; + return result; } -/* Converts the UTC timestamp to a string, also in UTC. Returns NULL on failure. */ +/* Converts the UTC timestamp to a string, also in UTC. + * Returns NULL on failure. */ gchar * -empathy_time_to_string_utc (gint64 t, - const gchar *format) +empathy_time_to_string_utc (gint64 t, + const gchar *format) { - GDateTime *d; - char *result; + GDateTime *d; + char *result; - g_return_val_if_fail (format != NULL, NULL); + g_return_val_if_fail (format != NULL, NULL); - d = g_date_time_new_from_unix_utc (t); - result = g_date_time_format (d, format); - g_date_time_unref (d); + d = g_date_time_new_from_unix_utc (t); + result = g_date_time_format (d, format); + g_date_time_unref (d); - return result; + return result; } -/* Converts the UTC timestamp to a string, in local time. Returns NULL on failure. */ +/* Converts the UTC timestamp to a string, in local time. + * Returns NULL on failure. */ gchar * empathy_time_to_string_local (gint64 t, - const gchar *format) + const gchar *format) { - GDateTime *d, *local; - gchar *result; + GDateTime *d, *local; + gchar *result; - g_return_val_if_fail (format != NULL, NULL); + g_return_val_if_fail (format != NULL, NULL); - d = g_date_time_new_from_unix_utc (t); - local = g_date_time_to_local (d); - g_date_time_unref (d); + d = g_date_time_new_from_unix_utc (t); + local = g_date_time_to_local (d); + g_date_time_unref (d); - result = g_date_time_format (local, format); - g_date_time_unref (local); + result = g_date_time_format (local, format); + g_date_time_unref (local); - return result; + return result; } gchar * empathy_duration_to_string (guint seconds) { - if (seconds < 60) { - return g_strdup_printf (ngettext ("%d second ago", - "%d seconds ago", seconds), seconds); - } - else if (seconds < (60 * 60)) { - seconds /= 60; - return g_strdup_printf (ngettext ("%d minute ago", - "%d minutes ago", seconds), seconds); - } - else if (seconds < (60 * 60 * 24)) { - seconds /= 60 * 60; - return g_strdup_printf (ngettext ("%d hour ago", - "%d hours ago", seconds), seconds); - } - else if (seconds < (60 * 60 * 24 * 7)) { - seconds /= 60 * 60 * 24; - return g_strdup_printf (ngettext ("%d day ago", - "%d days ago", seconds), seconds); - } - else if (seconds < (60 * 60 * 24 * 30)) { - seconds /= 60 * 60 * 24 * 7; - return g_strdup_printf (ngettext ("%d week ago", - "%d weeks ago", seconds), seconds); - } - else { - seconds /= 60 * 60 * 24 * 30; - return g_strdup_printf (ngettext ("%d month ago", - "%d months ago", seconds), seconds); - } + if (seconds < 60) + { + return g_strdup_printf (ngettext ("%d second ago", + "%d seconds ago", seconds), seconds); + } + else if (seconds < (60 * 60)) + { + seconds /= 60; + return g_strdup_printf (ngettext ("%d minute ago", + "%d minutes ago", seconds), seconds); + } + else if (seconds < (60 * 60 * 24)) + { + seconds /= 60 * 60; + return g_strdup_printf (ngettext ("%d hour ago", + "%d hours ago", seconds), seconds); + } + else if (seconds < (60 * 60 * 24 * 7)) + { + seconds /= 60 * 60 * 24; + return g_strdup_printf (ngettext ("%d day ago", + "%d days ago", seconds), seconds); + } + else if (seconds < (60 * 60 * 24 * 30)) + { + seconds /= 60 * 60 * 24 * 7; + return g_strdup_printf (ngettext ("%d week ago", + "%d weeks ago", seconds), seconds); + } + else + { + seconds /= 60 * 60 * 24 * 30; + return g_strdup_printf (ngettext ("%d month ago", + "%d months ago", seconds), seconds); + } } gchar * empathy_time_to_string_relative (gint64 t) { - GDateTime *now, *then; - gint seconds; - GTimeSpan delta; - gchar *result; + GDateTime *now, *then; + gint seconds; + GTimeSpan delta; + gchar *result; - now = g_date_time_new_now_utc (); - then = g_date_time_new_from_unix_utc (t); + now = g_date_time_new_now_utc (); + then = g_date_time_new_from_unix_utc (t); - delta = g_date_time_difference (now, then); - seconds = delta / G_TIME_SPAN_SECOND; + delta = g_date_time_difference (now, then); + seconds = delta / G_TIME_SPAN_SECOND; - if (seconds > 0) { - result = empathy_duration_to_string (seconds); - } - else { - result = g_strdup (_("in the future")); - } + if (seconds > 0) + result = empathy_duration_to_string (seconds); + else + result = g_strdup (_("in the future")); - g_date_time_unref (now); - g_date_time_unref (then); + g_date_time_unref (now); + g_date_time_unref (then); - return result; + return result; } diff --git a/libempathy/empathy-time.h b/libempathy/empathy-time.h index 3a22adeee..59bd9269b 100644 --- a/libempathy/empathy-time.h +++ b/libempathy/empathy-time.h @@ -1,7 +1,6 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* * Copyright (C) 2004 Imendio AB - * Copyright (C) 2007-2010 Collabora Ltd. + * Copyright (C) 2007-2012 Collabora Ltd. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -30,20 +29,17 @@ G_BEGIN_DECLS -/* - * Translators: use your locale preferred time format. - * The fields follow the strftime standard: - * look at the manual if you need help (man strftime) - */ -#define EMPATHY_TIME_FORMAT_DISPLAY_SHORT _("%H:%M") -#define EMPATHY_DATE_FORMAT_DISPLAY_SHORT _("%a %d %b %Y") -#define EMPATHY_TIME_DATE_FORMAT_DISPLAY_SHORT _("%a %d %b %Y, %H:%M") +/* FIXME: ideally we should only display the hour and minutes but + * there is no localized format for that (bgo #668323) */ +#define EMPATHY_TIME_FORMAT_DISPLAY_SHORT "%X" +#define EMPATHY_DATE_FORMAT_DISPLAY_SHORT "%a %d %b %Y" +#define EMPATHY_TIME_DATE_FORMAT_DISPLAY_SHORT "%a %d %b %Y, %X" gint64 empathy_time_get_current (void); -gchar *empathy_time_to_string_utc (gint64 t, - const gchar *format); -gchar *empathy_time_to_string_local (gint64 t, - const gchar *format); +gchar *empathy_time_to_string_utc (gint64 t, + const gchar *format); +gchar *empathy_time_to_string_local (gint64 t, + const gchar *format); gchar *empathy_time_to_string_relative (gint64 t); gchar *empathy_duration_to_string (guint seconds); diff --git a/libempathy/empathy-tp-chat.c b/libempathy/empathy-tp-chat.c index 96eda77b8..4e26a769b 100644 --- a/libempathy/empathy-tp-chat.c +++ b/libempathy/empathy-tp-chat.c @@ -51,6 +51,7 @@ struct _EmpathyTpChatPrivate { gboolean supports_subject; gboolean can_set_subject; gchar *subject; + gchar *subject_actor; /* Room config (for now, we only track the title and don't support * setting it) */ @@ -69,6 +70,7 @@ static void tp_chat_iface_init (EmpathyContactListIface *iface); enum { PROP_0, PROP_ACCOUNT, + PROP_SELF_CONTACT, PROP_REMOTE_CONTACT, PROP_N_MESSAGES_SENDING, PROP_TITLE, @@ -608,12 +610,26 @@ update_subject (EmpathyTpChat *self, subject = tp_asv_get_string (properties, "Subject"); if (subject != NULL) { + const gchar *actor; + g_free (priv->subject); priv->subject = g_strdup (subject); + + /* If the actor is included with this update, use it; + * otherwise, clear it to avoid showing stale information. + * Why might it not be included? When you join an IRC channel, + * you get a pair of messages: first, the current topic; next, + * who set it, and when. Idle reports these in two separate + * signals. + */ + actor = tp_asv_get_string (properties, "Actor"); + g_free (priv->subject_actor); + priv->subject_actor = g_strdup (actor); + g_object_notify (G_OBJECT (self), "subject"); } - /* TODO: track Actor and Timestamp. */ + /* TODO: track Timestamp. */ } static void @@ -732,6 +748,14 @@ empathy_tp_chat_get_subject (EmpathyTpChat *self) return priv->subject; } +const gchar * +empathy_tp_chat_get_subject_actor (EmpathyTpChat *self) +{ + EmpathyTpChatPrivate *priv = self->priv; + + return priv->subject_actor; +} + static void tp_chat_dispose (GObject *object) { @@ -767,6 +791,7 @@ tp_chat_finalize (GObject *object) g_free (self->priv->title); g_free (self->priv->subject); + g_free (self->priv->subject_actor); G_OBJECT_CLASS (empathy_tp_chat_parent_class)->finalize (object); } @@ -948,6 +973,7 @@ tp_chat_got_renamed_contacts_cb (TpConnection *connection, /* We change our nick */ tp_clear_object (&self->priv->user); self->priv->user = g_object_ref (new); + g_object_notify (chat, "self-contact"); } check_almost_ready (self); @@ -1068,6 +1094,7 @@ tp_chat_got_self_contact_cb (TpConnection *connection, self->priv->user = g_object_ref (contact); empathy_contact_set_is_user (self->priv->user, TRUE); + g_object_notify (chat, "self-contact"); check_almost_ready (self); } @@ -1083,6 +1110,9 @@ tp_chat_get_property (GObject *object, case PROP_ACCOUNT: g_value_set_object (value, self->priv->account); break; + case PROP_SELF_CONTACT: + g_value_set_object (value, self->priv->user); + break; case PROP_REMOTE_CONTACT: g_value_set_object (value, self->priv->remote_contact); break; @@ -1171,6 +1201,19 @@ empathy_tp_chat_class_init (EmpathyTpChatClass *klass) G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + /** + * EmpathyTpChat:self-contact: + * + * Not to be confused with TpChannel:group-self-contact. + */ + g_object_class_install_property (object_class, + PROP_SELF_CONTACT, + g_param_spec_object ("self-contact", + "The local contact", + "The EmpathyContact for the local user on this channel", + EMPATHY_TYPE_CONTACT, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_REMOTE_CONTACT, g_param_spec_object ("remote-contact", diff --git a/libempathy/empathy-tp-chat.h b/libempathy/empathy-tp-chat.h index cc1c16aaf..885479cb3 100644 --- a/libempathy/empathy-tp-chat.h +++ b/libempathy/empathy-tp-chat.h @@ -81,6 +81,7 @@ const gchar * empathy_tp_chat_get_title (EmpathyTpChat *self); gboolean empathy_tp_chat_supports_subject (EmpathyTpChat *self); const gchar * empathy_tp_chat_get_subject (EmpathyTpChat *self); +const gchar * empathy_tp_chat_get_subject_actor (EmpathyTpChat *self); gboolean empathy_tp_chat_can_set_subject (EmpathyTpChat *self); void empathy_tp_chat_set_subject (EmpathyTpChat *self, const gchar *subject); diff --git a/libempathy/empathy-tp-streamed-media.c b/libempathy/empathy-tp-streamed-media.c index 388b3aa00..f245dcfd5 100644 --- a/libempathy/empathy-tp-streamed-media.c +++ b/libempathy/empathy-tp-streamed-media.c @@ -20,6 +20,8 @@ * Xavier Claessens <xclaesse@gmail.com> */ +#include "config.h" + #include <string.h> #include <telepathy-glib/proxy-subclass.h> diff --git a/libempathy/empathy-utils.c b/libempathy/empathy-utils.c index 4b5738b7a..2f4c9edde 100644 --- a/libempathy/empathy-utils.c +++ b/libempathy/empathy-utils.c @@ -40,6 +40,8 @@ #include <folks/folks.h> #include <folks/folks-telepathy.h> +#include <dbus/dbus-protocol.h> + #include <telepathy-glib/account-manager.h> #include <telepathy-glib/connection.h> #include <telepathy-glib/channel.h> @@ -350,7 +352,7 @@ create_errors_to_message_hash (void) g_hash_table_insert (errors, TP_ERROR_STR_CONNECTION_LOST, _("Connection has been lost")); g_hash_table_insert (errors, TP_ERROR_STR_ALREADY_CONNECTED, - _("This resource is already connected to the server")); + _("This account is already connected to the server")); g_hash_table_insert (errors, TP_ERROR_STR_CONNECTION_REPLACED, _("Connection has been replaced by a new connection using the " "same resource")); @@ -369,6 +371,8 @@ create_errors_to_message_hash (void) "cryptography library")); g_hash_table_insert (errors, TP_ERROR_STR_SOFTWARE_UPGRADE_REQUIRED, _("Your software is too old")); + g_hash_table_insert (errors, DBUS_ERROR_NO_REPLY, + _("Internal error")); return errors; } @@ -1191,3 +1195,23 @@ empathy_create_individual_from_tp_contact (TpContact *contact) return individual; } + +/* Look for a FolksIndividual containing @contact as one of his persona + * and create one if needed */ +FolksIndividual * +empathy_ensure_individual_from_tp_contact (TpContact *contact) +{ + EmpathyIndividualManager *mgr; + FolksIndividual *individual; + + mgr = empathy_individual_manager_dup_singleton (); + individual = empathy_individual_manager_lookup_by_contact (mgr, contact); + + if (individual != NULL) + g_object_ref (individual); + else + individual = empathy_create_individual_from_tp_contact (contact); + + g_object_unref (mgr); + return individual; +} diff --git a/libempathy/empathy-utils.h b/libempathy/empathy-utils.h index ac5fef820..5ce8cc8cb 100644 --- a/libempathy/empathy-utils.h +++ b/libempathy/empathy-utils.h @@ -124,6 +124,9 @@ gboolean empathy_sasl_channel_supports_mechanism (TpChannel *channel, FolksIndividual * empathy_create_individual_from_tp_contact ( TpContact *contact); +FolksIndividual * empathy_ensure_individual_from_tp_contact ( + TpContact *contact); + /* Copied from wocky/wocky-utils.h */ #define empathy_implement_finish_void(source, tag) \ |