From eb36cae56aec0cd245d693ebf2bcb4ce20fb458b Mon Sep 17 00:00:00 2001 From: Danielle Madeley Date: Mon, 21 Dec 2009 12:51:02 +1100 Subject: Refactor MUC upgrading to be a feature of TpChat->add() Add a method to be able to tell whether a given TpChat supports you calling add() on it. --- libempathy/empathy-tp-chat.c | 109 +++++++++++++++++++++++++++++++++++++------ libempathy/empathy-tp-chat.h | 1 + src/empathy-chat-window.c | 84 ++++----------------------------- 3 files changed, 107 insertions(+), 87 deletions(-) diff --git a/libempathy/empathy-tp-chat.c b/libempathy/empathy-tp-chat.c index e53caefec..381095efc 100644 --- a/libempathy/empathy-tp-chat.c +++ b/libempathy/empathy-tp-chat.c @@ -23,15 +23,15 @@ #include -#include -#include -#include -#include +#include + +#include #include "empathy-tp-chat.h" #include "empathy-tp-contact-factory.h" #include "empathy-contact-monitor.h" #include "empathy-contact-list.h" +#include "empathy-dispatcher.h" #include "empathy-marshal.h" #include "empathy-time.h" #include "empathy-utils.h" @@ -60,6 +60,7 @@ typedef struct { * (channel doesn't implement the Password interface) */ gboolean got_password_flags; gboolean ready; + gboolean can_upgrade_to_muc; } EmpathyTpChatPriv; static void tp_chat_iface_init (EmpathyContactListIface *iface); @@ -117,17 +118,54 @@ tp_chat_add (EmpathyContactList *list, const gchar *message) { EmpathyTpChatPriv *priv = GET_PRIV (list); - TpHandle handle; - GArray handles = {(gchar *) &handle, 1}; - g_return_if_fail (EMPATHY_IS_TP_CHAT (list)); - g_return_if_fail (EMPATHY_IS_CONTACT (contact)); + if (tp_proxy_has_interface_by_id (priv->channel, + TP_IFACE_QUARK_CHANNEL_INTERFACE_GROUP)) { + TpHandle handle; + GArray handles = {(gchar *) &handle, 1}; - handle = empathy_contact_get_handle (contact); - tp_cli_channel_interface_group_call_add_members (priv->channel, -1, - &handles, NULL, - NULL, NULL, NULL, - NULL); + g_return_if_fail (EMPATHY_IS_TP_CHAT (list)); + g_return_if_fail (EMPATHY_IS_CONTACT (contact)); + + handle = empathy_contact_get_handle (contact); + tp_cli_channel_interface_group_call_add_members (priv->channel, + -1, &handles, NULL, NULL, NULL, NULL, NULL); + } else if (priv->can_upgrade_to_muc) { + EmpathyDispatcher *dispatcher; + TpConnection *connection; + GHashTable *props; + const char *object_path; + GPtrArray channels = { (gpointer *) &object_path, 1 }; + const char *invitees[2] = { NULL, }; + + dispatcher = empathy_dispatcher_dup_singleton (); + connection = tp_channel_borrow_connection (priv->channel); + + invitees[0] = empathy_contact_get_id (contact); + object_path = tp_proxy_get_object_path (priv->channel); + + props = tp_asv_new ( + TP_IFACE_CHANNEL ".ChannelType", G_TYPE_STRING, + TP_IFACE_CHANNEL_TYPE_TEXT, + TP_IFACE_CHANNEL ".TargetHandleType", G_TYPE_UINT, + TP_HANDLE_TYPE_NONE, + EMP_IFACE_CHANNEL_INTERFACE_CONFERENCE ".InitialChannels", + TP_ARRAY_TYPE_OBJECT_PATH_LIST, &channels, + EMP_IFACE_CHANNEL_INTERFACE_CONFERENCE ".InitialInviteeIDs", + G_TYPE_STRV, invitees, + /* FIXME: InvitationMessage ? */ + NULL); + + /* Although this is a MUC, it's anonymous, so CreateChannel is + * valid. + * props now belongs to EmpathyDispatcher, don't free it */ + empathy_dispatcher_create_channel (dispatcher, connection, + props, NULL, NULL); + + g_object_unref (dispatcher); + } else { + g_warning ("Cannot add to this channel"); + } } static void @@ -1219,9 +1257,14 @@ tp_chat_constructor (GType type, handles->len, (TpHandle *) handles->data, tp_chat_got_added_contacts_cb, NULL, NULL, chat); + priv->can_upgrade_to_muc = FALSE; + g_signal_connect (priv->channel, "group-members-changed", G_CALLBACK (tp_chat_group_members_changed_cb), chat); } else { + EmpathyDispatcher *dispatcher = empathy_dispatcher_dup_singleton (); + GList *list, *ptr; + /* Get the self contact from the connection's self handle */ handle = tp_connection_get_self_handle (connection); empathy_tp_contact_factory_get_from_handle (priv->factory, @@ -1233,6 +1276,25 @@ tp_chat_constructor (GType type, empathy_tp_contact_factory_get_from_handle (priv->factory, handle, tp_chat_got_remote_contact_cb, NULL, NULL, chat); + + list = empathy_dispatcher_find_requestable_channel_classes ( + dispatcher, connection, + tp_channel_get_channel_type (priv->channel), + TP_HANDLE_TYPE_ROOM, NULL); + + for (ptr = list; ptr; ptr = ptr->next) { + GValueArray *array = ptr->data; + const char **oprops = g_value_get_boxed ( + g_value_array_get_nth (array, 1)); + + if (tp_strv_contains (oprops, EMP_IFACE_CHANNEL_INTERFACE_CONFERENCE ".InitialChannels")) { + priv->can_upgrade_to_muc = TRUE; + break; + } + } + + g_list_free (list); + g_object_unref (dispatcher); } if (tp_proxy_has_interface_by_id (priv->channel, @@ -1714,3 +1776,24 @@ empathy_tp_chat_provide_password_finish (EmpathyTpChat *self, return TRUE; } + +/** + * empathy_tp_chat_can_add_contact: + * + * Returns: %TRUE if empathy_contact_list_add() will work for this channel. + * That is if this chat is a 1-to-1 channel that can be upgraded to + * a MUC using the Conference interface or if the channel is a MUC. + */ +gboolean +empathy_tp_chat_can_add_contact (EmpathyTpChat *self) +{ + EmpathyTpChatPriv *priv; + + g_return_val_if_fail (EMPATHY_IS_TP_CHAT (self), FALSE); + + priv = GET_PRIV (self); + + return priv->can_upgrade_to_muc || + tp_proxy_has_interface_by_id (priv->channel, + TP_IFACE_QUARK_CHANNEL_INTERFACE_GROUP);; +} diff --git a/libempathy/empathy-tp-chat.h b/libempathy/empathy-tp-chat.h index 940c36095..6b5fc8d0b 100644 --- a/libempathy/empathy-tp-chat.h +++ b/libempathy/empathy-tp-chat.h @@ -96,6 +96,7 @@ void empathy_tp_chat_provide_password_async (EmpathyTpChat *chat, gboolean empathy_tp_chat_provide_password_finish (EmpathyTpChat *chat, GAsyncResult *result, GError **error); +gboolean empathy_tp_chat_can_add_contact (EmpathyTpChat *self); G_END_DECLS diff --git a/src/empathy-chat-window.c b/src/empathy-chat-window.c index 5e0ad049c..67bf7d9e7 100644 --- a/src/empathy-chat-window.c +++ b/src/empathy-chat-window.c @@ -39,7 +39,6 @@ #include #include -#include #include #include #include @@ -55,8 +54,6 @@ #include #include -#include - #include "empathy-chat-window.h" #include "empathy-about-dialog.h" #include "empathy-invite-participant-dialog.h" @@ -822,51 +819,6 @@ chat_window_contacts_toggled_cb (GtkToggleAction *toggle_action, empathy_chat_set_show_contacts (priv->current_chat, active); } -static void -chat_window_upgrade_to_muc (EmpathyChat *chat, - const char *id) -{ - EmpathyDispatcher *dispatcher = empathy_dispatcher_dup_singleton (); - EmpathyTpChat *tp_chat; - TpConnection *connection; - TpChannel *channel; - GHashTable *props; - GPtrArray *channels; - char *invitees[3] = { NULL, }; - - tp_chat = empathy_chat_get_tp_chat (chat); - connection = empathy_tp_chat_get_connection (tp_chat); - channel = empathy_tp_chat_get_channel (tp_chat); - - /* Ensure a MUC channel */ - channels = g_ptr_array_sized_new (1); - g_ptr_array_add (channels, (char *) tp_proxy_get_object_path (channel)); - - invitees[0] = (char *) tp_channel_get_identifier (channel); - invitees[1] = (char *) id; - - props = tp_asv_new ( - TP_IFACE_CHANNEL ".ChannelType", G_TYPE_STRING, - TP_IFACE_CHANNEL_TYPE_TEXT, - TP_IFACE_CHANNEL ".TargetHandleType", G_TYPE_UINT, - TP_HANDLE_TYPE_NONE, - EMP_IFACE_CHANNEL_INTERFACE_CONFERENCE ".InitialChannels", - TP_ARRAY_TYPE_OBJECT_PATH_LIST, channels, - EMP_IFACE_CHANNEL_INTERFACE_CONFERENCE ".InitialInviteeIDs", - G_TYPE_STRV, invitees, - /* FIXME: InvitationMessage ? */ - NULL); - - /* Although this is a MUC, it's anonymous, so CreateChannel is valid */ - /* props now belongs to EmpathyDispatcher, don't free it */ - empathy_dispatcher_create_channel (dispatcher, connection, - props, NULL, NULL); - - g_ptr_array_free (channels, TRUE); - - g_object_unref (dispatcher); -} - static void got_contact_cb (EmpathyTpContactFactory *factory, EmpathyContact *contact, @@ -876,13 +828,10 @@ got_contact_cb (EmpathyTpContactFactory *factory, { EmpathyTpChat *tp_chat = EMPATHY_TP_CHAT (user_data); - if (error != NULL) - { + if (error != NULL) { DEBUG ("Failed: %s", error->message); return; - } - else - { + } else { empathy_contact_list_add (EMPATHY_CONTACT_LIST (tp_chat), contact, _("Inviting you to this room")); } @@ -913,35 +862,22 @@ chat_window_invite_participant_activate_cb (GtkAction *action, response = gtk_dialog_run (GTK_DIALOG (dialog)); - if (response == GTK_RESPONSE_ACCEPT) - { + if (response == GTK_RESPONSE_ACCEPT) { + TpConnection *connection; + EmpathyTpContactFactory *factory; const char *id; - TpHandleType handle_type; id = empathy_contact_selector_dialog_get_selected ( EMPATHY_CONTACT_SELECTOR_DIALOG (dialog), NULL); if (EMP_STR_EMPTY (id)) goto out; - tp_channel_get_handle (channel, &handle_type); - - if (handle_type == TP_HANDLE_TYPE_CONTACT) - { - chat_window_upgrade_to_muc (priv->current_chat, id); - } - else - { - TpConnection *connection; - EmpathyTpContactFactory *factory; + connection = tp_channel_borrow_connection (channel); + factory = empathy_tp_contact_factory_dup_singleton (connection); - connection = tp_channel_borrow_connection (channel); - factory = empathy_tp_contact_factory_dup_singleton (connection); + empathy_tp_contact_factory_get_from_id (factory, id, + got_contact_cb, tp_chat, NULL, NULL); - empathy_tp_contact_factory_get_from_id (factory, id, - got_contact_cb, tp_chat, NULL, NULL); - - - g_object_unref (factory); - } + g_object_unref (factory); } out: -- cgit v1.2.3