#include <config.h>
-#include <telepathy-glib/channel.h>
+#include <libmissioncontrol/mc-account.h>
+
#include <telepathy-glib/util.h>
#include <telepathy-glib/interfaces.h>
#include "empathy-tp-group.h"
#include "empathy-contact-factory.h"
-#include "empathy-debug.h"
#include "empathy-utils.h"
#include "empathy-marshal.h"
-#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
- EMPATHY_TYPE_TP_GROUP, EmpathyTpGroupPriv))
-
-#define DEBUG_DOMAIN "TpGroup"
+#define DEBUG_FLAG EMPATHY_DEBUG_TP
+#include "empathy-debug.h"
-struct _EmpathyTpGroupPriv {
- McAccount *account;
- TpChan *tp_chan;
+#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyTpGroup)
+typedef struct {
TpChannel *channel;
+ gboolean ready;
EmpathyContactFactory *factory;
+ McAccount *account;
gchar *group_name;
guint self_handle;
- gboolean ready;
GList *members;
GList *local_pendings;
GList *remote_pendings;
-};
-
-static void empathy_tp_group_class_init (EmpathyTpGroupClass *klass);
-static void empathy_tp_group_init (EmpathyTpGroup *group);
+} EmpathyTpGroupPriv;
enum {
MEMBER_ADDED,
enum {
PROP_0,
- PROP_ACCOUNT,
- PROP_TP_CHAN,
PROP_CHANNEL,
PROP_READY
};
actor_contact = tp_group_get_contact (group, actor);
- empathy_debug (DEBUG_DOMAIN, "Members changed for list %s:\n"
- " added-len=%d, current-len=%d\n"
- " removed-len=%d\n"
- " local-pending-len=%d, current-len=%d\n"
- " remote-pending-len=%d, current-len=%d",
- empathy_tp_group_get_name (group),
- added ? added->len : 0, g_list_length (priv->members),
- removed ? removed->len : 0,
- local_pending ? local_pending->len : 0,
- g_list_length (priv->local_pendings),
- remote_pending ? remote_pending->len : 0,
- g_list_length (priv->remote_pendings));
+ DEBUG ("Members changed for list %s:\n"
+ " added-len=%d, current-len=%d\n"
+ " removed-len=%d\n"
+ " local-pending-len=%d, current-len=%d\n"
+ " remote-pending-len=%d, current-len=%d",
+ priv->group_name, added ? added->len : 0,
+ g_list_length (priv->members), removed ? removed->len : 0,
+ local_pending ? local_pending->len : 0,
+ g_list_length (priv->local_pendings),
+ remote_pending ? remote_pending->len : 0,
+ g_list_length (priv->remote_pendings));
/* Contacts added */
contacts = tp_group_get_contacts (group, added);
g_object_unref (actor_contact);
}
- empathy_debug (DEBUG_DOMAIN, "Members changed done for list %s:\n"
- " members-len=%d\n"
- " local-pendings-len=%d\n"
- " remote-pendings-len=%d",
- empathy_tp_group_get_name (group),
- g_list_length (priv->members),
- g_list_length (priv->local_pendings),
- g_list_length (priv->remote_pendings));
+ DEBUG ("Members changed done for list %s:\n"
+ " members-len=%d\n"
+ " local-pendings-len=%d\n"
+ " remote-pendings-len=%d",
+ priv->group_name, g_list_length (priv->members),
+ g_list_length (priv->local_pendings),
+ g_list_length (priv->remote_pendings));
}
static void
EmpathyTpGroupPriv *priv = GET_PRIV (group);
if (error) {
- empathy_debug (DEBUG_DOMAIN, "Failed to get members: %s",
- error->message);
+ DEBUG ("Failed to get members: %s", error->message);
return;
}
0, /* actor */
0); /* reason */
- empathy_debug (DEBUG_DOMAIN, "Ready");
+ DEBUG ("Ready");
priv->ready = TRUE;
g_object_notify (group, "ready");
}
guint i = 0;
if (error) {
- empathy_debug (DEBUG_DOMAIN, "Failed to get local pendings: %s",
- error->message);
+ DEBUG ("Failed to get local pendings: %s", error->message);
return;
}
GObject *group)
{
if (error) {
- empathy_debug (DEBUG_DOMAIN, "Failed to get remote pendings: %s",
- error->message);
+ DEBUG ("Failed to get remote pendings: %s", error->message);
return;
}
0); /* reason */
}
+static void
+tp_group_inspect_handles_cb (TpConnection *connection,
+ const gchar **names,
+ const GError *error,
+ gpointer user_data,
+ GObject *group)
+{
+ EmpathyTpGroupPriv *priv = GET_PRIV (group);
+
+ if (error) {
+ DEBUG ("Failed to inspect channel handle: %s", error->message);
+ return;
+ }
+
+ priv->group_name = g_strdup (*names);
+}
+
static void
tp_group_invalidated_cb (TpProxy *proxy,
guint domain,
gchar *message,
EmpathyTpGroup *group)
{
- empathy_debug (DEBUG_DOMAIN, "Channel invalidated: %s", message);
+ DEBUG ("Channel invalidated: %s", message);
g_signal_emit (group, signals[DESTROY], 0);
}
GObject *group)
{
EmpathyTpGroupPriv *priv = GET_PRIV (group);
+ TpConnection *connection;
+ guint channel_handle;
+ guint channel_handle_type;
+ GArray *handles;
if (error) {
- empathy_debug (DEBUG_DOMAIN, "Failed to get self handle: %s",
- error->message);
+ DEBUG ("Failed to get self handle: %s", error->message);
return;
}
- /* GetMembers is called last, so it will be the last to get the reply,
- * so we'll be ready once that call return. */
priv->self_handle = handle;
tp_cli_channel_interface_group_connect_to_members_changed (priv->channel,
tp_group_members_changed_cb,
NULL, NULL,
group, NULL);
+
+ /* GetMembers is called last, so it will be the last to get the reply,
+ * so we'll be ready once that call return. */
+ g_object_get (priv->channel,
+ "connection", &connection,
+ "handle-type", &channel_handle_type,
+ "handle", &channel_handle,
+ NULL);
+ handles = g_array_sized_new (FALSE, FALSE, sizeof (guint), 1);
+ g_array_prepend_val (handles, channel_handle);
+ tp_cli_connection_call_inspect_handles (connection, -1,
+ channel_handle_type,
+ handles,
+ tp_group_inspect_handles_cb,
+ NULL, NULL,
+ group);
+ g_array_free (handles, TRUE);
+
tp_cli_channel_interface_group_call_get_local_pending_members_with_info
(priv->channel, -1,
tp_group_get_local_pending_cb,
EmpathyTpGroupPriv *priv = GET_PRIV (object);
EmpathyTpContactFactory *tp_factory;
- empathy_debug (DEBUG_DOMAIN, "finalize: %p", object);
+ DEBUG ("finalize: %p", object);
tp_factory = empathy_contact_factory_get_tp_factory (priv->factory, priv->account);
g_signal_handlers_disconnect_by_func (tp_factory, tp_group_factory_ready_cb, object);
- if (priv->tp_chan) {
- g_object_unref (priv->tp_chan);
- }
if (priv->channel) {
g_signal_handlers_disconnect_by_func (priv->channel,
tp_group_invalidated_cb,
static void
tp_group_constructed (GObject *group)
{
- EmpathyTpGroupPriv *priv = GET_PRIV (group);
- gboolean channel_ready;
-
- G_OBJECT_CLASS (empathy_tp_group_parent_class)->constructed (group);
+ EmpathyTpGroupPriv *priv = GET_PRIV (group);
+ gboolean channel_ready;
- priv->factory = empathy_contact_factory_new ();
+ priv->factory = empathy_contact_factory_dup_singleton ();
+ priv->account = empathy_channel_get_account (priv->channel);
g_signal_connect (priv->channel, "invalidated",
G_CALLBACK (tp_group_invalidated_cb),
EmpathyTpGroupPriv *priv = GET_PRIV (object);
switch (param_id) {
- case PROP_ACCOUNT:
- g_value_set_object (value, priv->account);
- break;
- case PROP_TP_CHAN:
- g_value_set_object (value, priv->tp_chan);
- break;
case PROP_CHANNEL:
g_value_set_object (value, priv->channel);
break;
+ case PROP_READY:
+ g_value_set_boolean (value, priv->ready);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
EmpathyTpGroupPriv *priv = GET_PRIV (object);
switch (param_id) {
- case PROP_ACCOUNT:
- priv->account = g_object_ref (g_value_get_object (value));
- break;
- case PROP_TP_CHAN:
- priv->tp_chan = g_object_ref (g_value_get_object (value));
- break;
case PROP_CHANNEL:
priv->channel = g_object_ref (g_value_get_object (value));
break;
object_class->get_property = tp_group_get_property;
object_class->set_property = tp_group_set_property;
- g_object_class_install_property (object_class,
- PROP_ACCOUNT,
- g_param_spec_object ("account",
- "channel Account",
- "The account associated with the channel",
- MC_TYPE_ACCOUNT,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY));
- g_object_class_install_property (object_class,
- PROP_TP_CHAN,
- g_param_spec_object ("tp-chan",
- "telepathy channel",
- "The old TpChan",
- TELEPATHY_CHAN_TYPE,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (object_class,
PROP_CHANNEL,
g_param_spec_object ("channel",
static void
empathy_tp_group_init (EmpathyTpGroup *group)
{
+ EmpathyTpGroupPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (group,
+ EMPATHY_TYPE_TP_GROUP, EmpathyTpGroupPriv);
+
+ group->priv = priv;
}
EmpathyTpGroup *
-empathy_tp_group_new (McAccount *account,
- TpChan *tp_chan)
+empathy_tp_group_new (TpChannel *channel)
{
- EmpathyTpGroup *group;
- TpChannel *channel;
- TpConnection *connection;
- MissionControl *mc;
-
- g_return_val_if_fail (MC_IS_ACCOUNT (account), NULL);
- g_return_val_if_fail (TELEPATHY_IS_CHAN (tp_chan), NULL);
-
- mc = empathy_mission_control_new ();
- connection = mission_control_get_tpconnection (mc, account, NULL);
- channel = tp_chan_dup_channel (tp_chan, connection, NULL);
-
- group = g_object_new (EMPATHY_TYPE_TP_GROUP,
- "account", account,
- "channel", channel,
- "tp-chan", tp_chan,
- NULL);
+ g_return_val_if_fail (TP_IS_CHANNEL (channel), NULL);
- g_object_unref (channel);
- g_object_unref (connection);
- g_object_unref (mc);
-
- return group;
+ return g_object_new (EMPATHY_TYPE_TP_GROUP,
+ "channel", channel,
+ NULL);
}
static void
gpointer user_data,
GObject *weak_object)
{
- const gchar *msg = user_data;
-
if (error) {
- empathy_debug (DEBUG_DOMAIN, "%s: %s", msg, error->message);
+ DEBUG ("%s: %s", (gchar*) user_data, error->message);
}
}
const gchar *
empathy_tp_group_get_name (EmpathyTpGroup *group)
{
- EmpathyTpGroupPriv *priv;
+ EmpathyTpGroupPriv *priv = GET_PRIV (group);
g_return_val_if_fail (EMPATHY_IS_TP_GROUP (group), NULL);
-
- priv = GET_PRIV (group);
-
- /* Lazy initialisation */
- if (!priv->group_name && priv->tp_chan->handle != 0) {
- priv->group_name = empathy_inspect_channel (priv->account, priv->tp_chan);
- }
+ g_return_val_if_fail (priv->ready, NULL);
return priv->group_name;
}
return tp_group_get_contact (group, priv->self_handle);
}
-const gchar *
-empathy_tp_group_get_object_path (EmpathyTpGroup *group)
+gboolean
+empathy_tp_group_is_member (EmpathyTpGroup *group,
+ EmpathyContact *contact)
{
- EmpathyTpGroupPriv *priv;
-
- g_return_val_if_fail (EMPATHY_IS_TP_GROUP (group), NULL);
+ EmpathyTpGroupPriv *priv = GET_PRIV (group);
- priv = GET_PRIV (group);
+ g_return_val_if_fail (EMPATHY_IS_TP_GROUP (group), FALSE);
+ g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), FALSE);
- return TP_PROXY (priv->channel)->object_path;
+ return g_list_find (priv->members, contact) != NULL;
}
-TpChan *
-empathy_tp_group_get_channel (EmpathyTpGroup *group)
+gboolean
+empathy_tp_group_is_ready (EmpathyTpGroup *group)
{
- EmpathyTpGroupPriv *priv;
-
- g_return_val_if_fail (EMPATHY_IS_TP_GROUP (group), NULL);
+ EmpathyTpGroupPriv *priv = GET_PRIV (group);
- priv = GET_PRIV (group);
+ g_return_val_if_fail (EMPATHY_IS_TP_GROUP (group), FALSE);
- return priv->tp_chan;
+ return priv->ready;
}
-gboolean
-empathy_tp_group_is_member (EmpathyTpGroup *group,
- EmpathyContact *contact)
+EmpathyPendingInfo *
+empathy_tp_group_get_invitation (EmpathyTpGroup *group,
+ EmpathyContact **remote_contact)
{
EmpathyTpGroupPriv *priv = GET_PRIV (group);
+ EmpathyContact *contact = NULL;
+ EmpathyPendingInfo *invitation = NULL;
+ GList *l;
g_return_val_if_fail (EMPATHY_IS_TP_GROUP (group), FALSE);
- g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), FALSE);
+ g_return_val_if_fail (priv->ready, NULL);
- return g_list_find (priv->members, contact) != NULL;
+ for (l = priv->local_pendings; l; l = l->next) {
+ EmpathyPendingInfo *info = l->data;
+
+ if (empathy_contact_is_user (info->member)) {
+ invitation = info;
+ break;
+ }
+ }
+
+ if (invitation) {
+ contact = invitation->actor;
+ }
+ if (!invitation) {
+ if (priv->remote_pendings) {
+ contact = priv->remote_pendings->data;
+ }
+ else if (priv->members) {
+ contact = priv->members->data;
+ }
+ }
+
+ if (remote_contact && contact) {
+ *remote_contact = g_object_ref (contact);
+ }
+
+ return invitation;
}
+TpChannelGroupFlags
+empathy_tp_group_get_flags (EmpathyTpGroup *self)
+{
+ EmpathyTpGroupPriv *priv = GET_PRIV (self);
+
+ g_return_val_if_fail (EMPATHY_IS_TP_GROUP (self), 0);
+
+ if (priv->channel == NULL)
+ return 0;
+
+ return tp_channel_group_get_flags (priv->channel);
+}