<commit_before>/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
 * Copyright (C) 2007-2008 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: <NAME> <<EMAIL>>
 */

#include <config.h>

#include <string.h>

#include <telepathy-glib/channel.h>
#include <telepathy-glib/dbus.h>
#include <telepathy-glib/util.h>
#include <telepathy-glib/interfaces.h>

#include "empathy-tp-chat.h"
#include "empathy-tp-contact-factory.h"
#include "empathy-contact-monitor.h"
#include "empathy-contact-list.h"
#include "empathy-marshal.h"
#include "empathy-time.h"
#include "empathy-utils.h"

#define DEBUG_FLAG EMPATHY_DEBUG_TP | EMPATHY_DEBUG_CHAT
#include "empathy-debug.h"

#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyTpChat)
typedef struct {
	gboolean               dispose_has_run;
	EmpathyTpContactFactory *factory;
	EmpathyContactMonitor *contact_monitor;
	EmpathyContact        *user;
	EmpathyContact        *remote_contact;
	GList                 *members;
	TpChannel             *channel;
	gboolean               listing_pending_messages;
	/* Queue of messages not signalled yet */
	GQueue                *messages_queue;
	/* Queue of messages signalled but not acked yet */
	GQueue                *pending_messages_queue;
	gboolean               had_properties_list;
	GPtrArray             *properties;
	gboolean               ready;
} EmpathyTpChatPriv;

typedef struct {
	gchar          *name;
	guint           id;
	TpPropertyFlags flags;
	GValue         *value;
} TpChatProperty;

static void tp_chat_iface_init         (EmpathyContactListIface *iface);

enum {
	PROP_0,
	PROP_CHANNEL,
	PROP_REMOTE_CONTACT,
	PROP_READY,
};

enum {
	MESSAGE_RECEIVED,
	SEND_ERROR,
	CHAT_STATE_CHANGED,
	PROPERTY_CHANGED,
	DESTROY,
	LAST_SIGNAL
};

static guint signals[LAST_SIGNAL];

G_DEFINE_TYPE_WITH_CODE (EmpathyTpChat, empathy_tp_chat, G_TYPE_OBJECT,
			 G_IMPLEMENT_INTERFACE (EMPATHY_TYPE_CONTACT_LIST,
						tp_chat_iface_init));

static void acknowledge_messages (EmpathyTpChat *chat, GArray *ids);

static void
tp_chat_invalidated_cb (TpProxy       *proxy,
			guint          domain,
			gint           code,
			gchar         *message,
			EmpathyTpChat *chat)
{
	DEBUG ("Channel invalidated: %s", message);
	g_signal_emit (chat, signals[DESTROY], 0);
}

static void
tp_chat_async_cb (TpChannel *proxy,
		  const GError *error,
		  gpointer user_data,
		  GObject *weak_object)
{
	if (error) {
		DEBUG ("Error %s: %s", (gchar *) user_data, error->message);
	}
}

static void
tp_chat_add (EmpathyContactList *list,
	     EmpathyContact     *contact,
	     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));

	handle = empathy_contact_get_handle (contact);
	tp_cli_channel_interface_group_call_add_members (priv->channel, -1,
							 &handles, NULL,
							 NULL, NULL, NULL,
							 NULL);
}

static void
tp_chat_remove (EmpathyContactList *list,
		EmpathyContact     *contact,
		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));

	handle = empathy_contact_get_handle (contact);
	tp_cli_channel_interface_group_call_remove_members (priv->channel, -1,
							    &handles, NULL,
							    NULL, NULL, NULL,
							    NULL);
}

static GList *
tp_chat_get_members (EmpathyContactList *list)
{
	EmpathyTpChatPriv *priv = GET_PRIV (list);
	GList             *members = NULL;

	g_return_val_if_fail (EMPATHY_IS_TP_CHAT (list), NULL);

	if (priv->members) {
		members = g_list_copy (priv->members);
		g_list_foreach (members, (GFunc) g_object_ref, NULL);
	} else {
		members = g_list_prepend (members, g_object_ref (priv->user));
		members = g_list_prepend (members, g_object_ref (priv->remote_contact));
	}<commit_msg>Check if the remote-contact is actually there before putting it on the list<commit_after>/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
 * Copyright (C) 2007-2008 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: <NAME> <<EMAIL>>
 */

#include <config.h>

#include <string.h>

#include <telepathy-glib/channel.h>
#include <telepathy-glib/dbus.h>
#include <telepathy-glib/util.h>
#include <telepathy-glib/interfaces.h>

#include "empathy-tp-chat.h"
#include "empathy-tp-contact-factory.h"
#include "empathy-contact-monitor.h"
#include "empathy-contact-list.h"
#include "empathy-marshal.h"
#include "empathy-time.h"
#include "empathy-utils.h"

#define DEBUG_FLAG EMPATHY_DEBUG_TP | EMPATHY_DEBUG_CHAT
#include "empathy-debug.h"

#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyTpChat)
typedef struct {
	gboolean               dispose_has_run;
	EmpathyTpContactFactory *factory;
	EmpathyContactMonitor *contact_monitor;
	EmpathyContact        *user;
	EmpathyContact        *remote_contact;
	GList                 *members;
	TpChannel             *channel;
	gboolean               listing_pending_messages;
	/* Queue of messages not signalled yet */
	GQueue                *messages_queue;
	/* Queue of messages signalled but not acked yet */
	GQueue                *pending_messages_queue;
	gboolean               had_properties_list;
	GPtrArray             *properties;
	gboolean               ready;
} EmpathyTpChatPriv;

typedef struct {
	gchar          *name;
	guint           id;
	TpPropertyFlags flags;
	GValue         *value;
} TpChatProperty;

static void tp_chat_iface_init         (EmpathyContactListIface *iface);

enum {
	PROP_0,
	PROP_CHANNEL,
	PROP_REMOTE_CONTACT,
	PROP_READY,
};

enum {
	MESSAGE_RECEIVED,
	SEND_ERROR,
	CHAT_STATE_CHANGED,
	PROPERTY_CHANGED,
	DESTROY,
	LAST_SIGNAL
};

static guint signals[LAST_SIGNAL];

G_DEFINE_TYPE_WITH_CODE (EmpathyTpChat, empathy_tp_chat, G_TYPE_OBJECT,
			 G_IMPLEMENT_INTERFACE (EMPATHY_TYPE_CONTACT_LIST,
						tp_chat_iface_init));

static void acknowledge_messages (EmpathyTpChat *chat, GArray *ids);

static void
tp_chat_invalidated_cb (TpProxy       *proxy,
			guint          domain,
			gint           code,
			gchar         *message,
			EmpathyTpChat *chat)
{
	DEBUG ("Channel invalidated: %s", message);
	g_signal_emit (chat, signals[DESTROY], 0);
}

static void
tp_chat_async_cb (TpChannel *proxy,
		  const GError *error,
		  gpointer user_data,
		  GObject *weak_object)
{
	if (error) {
		DEBUG ("Error %s: %s", (gchar *) user_data, error->message);
	}
}

static void
tp_chat_add (EmpathyContactList *list,
	     EmpathyContact     *contact,
	     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));

	handle = empathy_contact_get_handle (contact);
	tp_cli_channel_interface_group_call_add_members (priv->channel, -1,
							 &handles, NULL,
							 NULL, NULL, NULL,
							 NULL);
}

static void
tp_chat_remove (EmpathyContactList *list,
		EmpathyContact     *contact,
		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));

	handle = empathy_contact_get_handle (contact);
	tp_cli_channel_interface_group_call_remove_members (priv->channel, -1,
							    &handles, NULL,
							    NULL, NULL, NULL,
							    NULL);
}

static GList *
tp_chat_get_members (EmpathyContactList *list)
{
	EmpathyTpChatPriv *priv = GET_PRIV (list);
	GList             *members = NULL;

	g_return_val_if_fail (EMPATHY_IS_TP_CHAT (list), NULL);

	if (priv->members) {
		members = g_list_copy (priv->members);
		g_list_foreach (members, (GFunc) g_object_ref, NULL);
	} else {
		members = g_list_prepend (members, g_object_ref (priv->user));
		if (priv->remote_contact != NULL)
			members = g_list_prepend (members, g_object_ref (priv->remote_contact));
	}
{'fraction_non_alphanumeric': 0.09612386989504312, 'fraction_numerical': 0.006027226436662163, 'mean_word_length': 3.531073446327684, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 36, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '897935', 'n_tokens_mistral': 3503, 'n_tokens_neox': 3223, 'n_words': 847}