aboutsummaryrefslogtreecommitdiffstats
path: root/libempathy
diff options
context:
space:
mode:
Diffstat (limited to 'libempathy')
-rw-r--r--libempathy/Makefile.am2
-rw-r--r--libempathy/empathy-account-settings.c1
-rw-r--r--libempathy/empathy-gsettings.h2
-rw-r--r--libempathy/empathy-individual-manager.c95
-rw-r--r--libempathy/empathy-individual-manager.h7
-rw-r--r--libempathy/empathy-message.c69
-rw-r--r--libempathy/empathy-message.h1
-rw-r--r--libempathy/empathy-pkg-kit.c161
-rw-r--r--libempathy/empathy-pkg-kit.h38
-rw-r--r--libempathy/empathy-presence-manager.c70
-rw-r--r--libempathy/empathy-time.c155
-rw-r--r--libempathy/empathy-time.h24
-rw-r--r--libempathy/empathy-tp-chat.c45
-rw-r--r--libempathy/empathy-tp-chat.h1
-rw-r--r--libempathy/empathy-tp-streamed-media.c2
-rw-r--r--libempathy/empathy-utils.c26
-rw-r--r--libempathy/empathy-utils.h3
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) \