X-Git-Url: https://git.0d.be/?p=empathy.git;a=blobdiff_plain;f=src%2Fempathy-chat-manager.c;h=279d7d8ff43bcdf31716067920e6a55f93aec8bd;hp=d8e573320160a59b14b0fa83af093e9d9fb5ba3b;hb=21674ad377f646ef1e242f7e4260ee2398a220be;hpb=c51c43f90643a4a5080ec1412229f0eb56ca9a34 diff --git a/src/empathy-chat-manager.c b/src/empathy-chat-manager.c index d8e57332..279d7d8f 100644 --- a/src/empathy-chat-manager.c +++ b/src/empathy-chat-manager.c @@ -17,23 +17,22 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include - -#include -#include -#include +#include "config.h" +#include "empathy-chat-manager.h" -#include +#include +#include +#include "empathy-chatroom-manager.h" #include "empathy-chat-window.h" +#include "empathy-request-util.h" +#include "empathy-ui-utils.h" +#include "extensions.h" #define DEBUG_FLAG EMPATHY_DEBUG_OTHER -#include +#include "empathy-debug.h" -#include "empathy-chat-manager.h" - -#include +#define CHAT_MANAGER_PATH "/org/gnome/Empathy/ChatManager" enum { CLOSED_CHATS_CHANGED, @@ -68,6 +67,11 @@ struct _EmpathyChatManagerPriv GHashTable *messages; TpBaseClient *handler; + + /* Cached to keep Folks in memory while empathy-chat is running; we don't + * want to reload it each time the last chat window is closed + * and re-opened. */ + EmpathyIndividualManager *individual_mgr; }; #define GET_PRIV(o) \ @@ -81,6 +85,7 @@ typedef struct TpAccount *account; gchar *id; gboolean room; + gboolean sms; } ChatData; static ChatData * @@ -93,6 +98,7 @@ chat_data_new (EmpathyChat *chat) data->account = g_object_ref (empathy_chat_get_account (chat)); data->id = g_strdup (empathy_chat_get_id (chat)); data->room = empathy_chat_is_room (chat); + data->sms = empathy_chat_is_sms_channel (chat); return data; } @@ -131,6 +137,36 @@ chat_destroyed_cb (gpointer data, priv->num_displayed_chat); } +static void +join_cb (GObject *source, + GAsyncResult *result, + gpointer user_data) +{ + TpChannel *channel = TP_CHANNEL (source); + GError *error = NULL; + + if (!tp_channel_join_finish (channel, result, &error)) + { + DEBUG ("Failed to join chat (%s): %s", + tp_channel_get_identifier (channel), error->message); + g_error_free (error); + } +} + +static void +individual_mgr_cb (EmpathyChatWindow *window, + GParamSpec *spec, + EmpathyChatManager *self) +{ + EmpathyChatManagerPriv *priv = GET_PRIV (self); + + if (priv->individual_mgr != NULL) + return; + + priv->individual_mgr = empathy_chat_window_get_individual_manager (window); + g_object_ref (priv->individual_mgr); +} + static void process_tp_chat (EmpathyChatManager *self, EmpathyTpChat *tp_chat, @@ -140,12 +176,13 @@ process_tp_chat (EmpathyChatManager *self, EmpathyChatManagerPriv *priv = GET_PRIV (self); EmpathyChat *chat = NULL; const gchar *id; + EmpathyChatWindow *window; id = empathy_tp_chat_get_id (tp_chat); if (!tp_str_empty (id)) { chat = empathy_chat_window_find_chat (account, id, - empathy_tp_chat_is_sms_channel (tp_chat)); + tp_text_channel_is_sms_channel ((TpTextChannel *) tp_chat)); } if (chat != NULL) @@ -183,69 +220,22 @@ process_tp_chat (EmpathyChatManager *self, g_object_weak_ref ((GObject *) chat, chat_destroyed_cb, self); } - empathy_chat_window_present_chat (chat, user_action_time); + + window = empathy_chat_window_present_chat (chat, user_action_time); + + if (priv->individual_mgr == NULL) + { + /* We want to cache it as soon it's created */ + tp_g_signal_connect_object (window, "notify::individual-manager", + G_CALLBACK (individual_mgr_cb), self, 0); + } if (empathy_tp_chat_is_invited (tp_chat, NULL)) { /* We have been invited to the room. Add ourself as member as this * channel has been approved. */ - empathy_tp_chat_join (tp_chat); + tp_channel_join_async (TP_CHANNEL (tp_chat), "", join_cb, self); } - - g_object_unref (tp_chat); -} - -typedef struct -{ - EmpathyChatManager *self; - EmpathyTpChat *tp_chat; - TpAccount *account; - gint64 user_action_time; - gulong sig_id; -} chat_ready_ctx; - -static chat_ready_ctx * -chat_ready_ctx_new (EmpathyChatManager *self, - EmpathyTpChat *tp_chat, - TpAccount *account, - gint64 user_action_time) -{ - chat_ready_ctx *ctx = g_slice_new0 (chat_ready_ctx); - - ctx->self = g_object_ref (self); - ctx->tp_chat = g_object_ref (tp_chat); - ctx->account = g_object_ref (account); - ctx->user_action_time = user_action_time; - return ctx; -} - -static void -chat_ready_ctx_free (chat_ready_ctx *ctx) -{ - g_object_unref (ctx->self); - g_object_unref (ctx->tp_chat); - g_object_unref (ctx->account); - - if (ctx->sig_id != 0) - g_signal_handler_disconnect (ctx->tp_chat, ctx->sig_id); - - g_slice_free (chat_ready_ctx, ctx); -} - -static void -tp_chat_ready_cb (GObject *object, - GParamSpec *spec, - gpointer user_data) -{ - EmpathyTpChat *tp_chat = EMPATHY_TP_CHAT (object); - chat_ready_ctx *ctx = user_data; - - if (!empathy_tp_chat_is_ready (tp_chat)) - return; - - process_tp_chat (ctx->self, tp_chat, ctx->account, ctx->user_action_time); - - chat_ready_ctx_free (ctx); } static void @@ -263,35 +253,21 @@ handle_channels (TpSimpleHandler *handler, for (l = channels; l != NULL; l = g_list_next (l)) { - TpChannel *channel = l->data; - EmpathyTpChat *tp_chat; + EmpathyTpChat *tp_chat = l->data; - if (tp_proxy_get_invalidated (channel) != NULL) + if (tp_proxy_get_invalidated (tp_chat) != NULL) continue; - if (!TP_IS_TEXT_CHANNEL (channel)) + if (!EMPATHY_IS_TP_CHAT (tp_chat)) { DEBUG ("Channel %s doesn't implement Messages; can't handle it", - tp_proxy_get_object_path (channel)); + tp_proxy_get_object_path (tp_chat)); continue; } - DEBUG ("Now handling channel %s", tp_proxy_get_object_path (channel)); - - tp_chat = empathy_tp_chat_new (account, channel); - - if (empathy_tp_chat_is_ready (tp_chat)) - { - process_tp_chat (self, tp_chat, account, user_action_time); - } - else - { - chat_ready_ctx *ctx = chat_ready_ctx_new (self, tp_chat, account, - user_action_time); + DEBUG ("Now handling channel %s", tp_proxy_get_object_path (tp_chat)); - ctx->sig_id = g_signal_connect (tp_chat, "notify::ready", - G_CALLBACK (tp_chat_ready_cb), ctx); - } + process_tp_chat (self, tp_chat, account, user_action_time); } tp_handle_channels_context_accept (context); @@ -301,34 +277,22 @@ static void empathy_chat_manager_init (EmpathyChatManager *self) { EmpathyChatManagerPriv *priv = GET_PRIV (self); - TpDBusDaemon *dbus; + TpAccountManager *am; 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) - { - g_critical ("Failed to get D-Bus daemon: %s", error->message); - g_error_free (error); - return; - } + am = tp_account_manager_dup (); priv->chatroom_mgr = empathy_chatroom_manager_dup_singleton (NULL); /* Text channels handler */ - priv->handler = tp_simple_handler_new (dbus, FALSE, FALSE, + priv->handler = tp_simple_handler_new_with_am (am, FALSE, FALSE, EMPATHY_CHAT_BUS_NAME_SUFFIX, FALSE, handle_channels, self, NULL); - /* EmpathyTpChat relies on these features being prepared */ - tp_base_client_add_connection_features_varargs (priv->handler, - TP_CONNECTION_FEATURE_CAPABILITIES, 0); - tp_base_client_add_channel_features_varargs (priv->handler, - TP_CHANNEL_FEATURE_CHAT_STATES, 0); - - g_object_unref (dbus); + g_object_unref (am); tp_base_client_take_handler_filter (priv->handler, tp_asv_new ( TP_PROP_CHANNEL_CHANNEL_TYPE, G_TYPE_STRING, TP_IFACE_CHANNEL_TYPE_TEXT, @@ -369,6 +333,7 @@ empathy_chat_manager_finalize (GObject *object) tp_clear_object (&priv->handler); tp_clear_object (&priv->chatroom_mgr); + tp_clear_object (&priv->individual_mgr); G_OBJECT_CLASS (empathy_chat_manager_parent_class)->finalize (object); } @@ -406,7 +371,7 @@ empathy_chat_manager_constructed (GObject *obj) if (dbus_daemon != NULL) { tp_dbus_daemon_register_object (dbus_daemon, - "/org/gnome/Empathy/ChatManager", obj); + CHAT_MANAGER_PATH, obj); g_object_unref (dbus_daemon); } @@ -428,7 +393,7 @@ empathy_chat_manager_class_init ( G_SIGNAL_RUN_LAST, 0, NULL, NULL, - g_cclosure_marshal_VOID__UINT, + g_cclosure_marshal_generic, G_TYPE_NONE, 1, G_TYPE_UINT, NULL); @@ -438,7 +403,7 @@ empathy_chat_manager_class_init ( G_SIGNAL_RUN_LAST, 0, NULL, NULL, - g_cclosure_marshal_VOID__UINT, + g_cclosure_marshal_generic, G_TYPE_NONE, 1, G_TYPE_UINT, NULL); @@ -526,8 +491,12 @@ empathy_chat_manager_undo_closed_chat (EmpathyChatManager *self, if (data->room) empathy_join_muc (data->account, data->id, timestamp); + else if (data->sms) + empathy_sms_contact_id (data->account, data->id, timestamp, + NULL, NULL); else - empathy_chat_with_contact_id (data->account, data->id, timestamp); + empathy_chat_with_contact_id (data->account, data->id, timestamp, + NULL, NULL); g_signal_emit (self, signals[CLOSED_CHATS_CHANGED], 0, g_queue_get_length (priv->closed_queue)); @@ -579,7 +548,7 @@ empathy_chat_manager_call_undo_closed_chat (void) "dbus-daemon", dbus_daemon, "dbus-connection", tp_proxy_get_dbus_connection (TP_PROXY (dbus_daemon)), "bus-name", EMPATHY_CHAT_BUS_NAME, - "object-path", "/org/gnome/Empathy/ChatManager", + "object-path", CHAT_MANAGER_PATH, NULL); tp_proxy_add_interface_by_id (proxy, EMP_IFACE_QUARK_CHAT_MANAGER);