[empathy: 12/17] Refactor MUC upgrading to be a feature of TpChat->add()



commit eb36cae56aec0cd245d693ebf2bcb4ce20fb458b
Author: Danielle Madeley <danielle madeley collabora co uk>
Date:   Mon Dec 21 12:51:02 2009 +1100

    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 e53caef..381095e 100644
--- a/libempathy/empathy-tp-chat.c
+++ b/libempathy/empathy-tp-chat.c
@@ -23,15 +23,15 @@
 
 #include <string.h>
 
-#include <telepathy-glib/channel.h>
-#include <telepathy-glib/dbus.h>
-#include <telepathy-glib/util.h>
-#include <telepathy-glib/interfaces.h>
+#include <telepathy-glib/telepathy-glib.h>
+
+#include <extensions/extensions.h>
 
 #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 940c360..6b5fc8d 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 5e0ad04..67bf7d9 100644
--- a/src/empathy-chat-window.c
+++ b/src/empathy-chat-window.c
@@ -39,7 +39,6 @@
 
 #include <libempathy/empathy-contact.h>
 #include <libempathy/empathy-message.h>
-#include <libempathy/empathy-dispatcher.h>
 #include <libempathy/empathy-chatroom-manager.h>
 #include <libempathy/empathy-utils.h>
 #include <libempathy/empathy-tp-contact-factory.h>
@@ -55,8 +54,6 @@
 #include <libempathy-gtk/empathy-ui-utils.h>
 #include <libempathy-gtk/empathy-notify-manager.h>
 
-#include <extensions/extensions.h>
-
 #include "empathy-chat-window.h"
 #include "empathy-about-dialog.h"
 #include "empathy-invite-participant-dialog.h"
@@ -823,51 +820,6 @@ chat_window_contacts_toggled_cb (GtkToggleAction   *toggle_action,
 }
 
 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,
                 const GError            *error,
@@ -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:



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]