libpurple/chat.c

Thu, 01 Nov 2018 15:45:13 -0500

author
Mike Ruprecht <cmaiku@gmail.com>
date
Thu, 01 Nov 2018 15:45:13 -0500
changeset 39364
54439db24429
parent 39352
62bca2fe2e91
child 39665
2172e3b8eeef
permissions
-rw-r--r--

libpurple: Port self-contained code from g_type_class_add_private()

This patch ports the self-contained libpurple GObjects away from the
deprecated g_type_class_add_private() function in favor of the
G_DEFINE_TYPE_WITH_PRIVATE() macro.

/*
 * purple
 *
 * Purple is the legal property of its developers, whose names are too numerous
 * to list here.  Please refer to the COPYRIGHT file distributed with this
 * source distribution.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
 *
 */
#include "internal.h"
#include "chat.h"
#include "util.h"

typedef struct _PurpleChatPrivate       PurpleChatPrivate;

/* Private data for a chat node */
struct _PurpleChatPrivate {
	char *alias;              /* The display name of this chat.             */
	PurpleAccount *account;   /* The account this chat is attached to       */
	GHashTable *components;   /* the stuff the protocol needs to know to
	                             join the chat                              */

	gboolean is_constructed;  /* Indicates if the chat has finished being
	                             constructed.                               */
};

/* Chat property enums */
enum
{
	PROP_0,
	PROP_ALIAS,
	PROP_ACCOUNT,
	PROP_COMPONENTS,
	PROP_LAST
};

/******************************************************************************
 * Globals
 *****************************************************************************/
static GParamSpec *properties[PROP_LAST];

G_DEFINE_TYPE_WITH_PRIVATE(PurpleChat, purple_chat, PURPLE_TYPE_BLIST_NODE);

/******************************************************************************
 * API
 *****************************************************************************/

const char *purple_chat_get_name(PurpleChat *chat)
{
	PurpleChatPrivate *priv = purple_chat_get_instance_private(chat);

	g_return_val_if_fail(priv != NULL, NULL);

	if ((priv->alias != NULL) && (*priv->alias != '\0'))
		return priv->alias;

	return purple_chat_get_name_only(chat);
}

const char *purple_chat_get_name_only(PurpleChat *chat)
{
	char *ret = NULL;
	PurpleProtocol *protocol = NULL;
	PurpleChatPrivate *priv = purple_chat_get_instance_private(chat);

	g_return_val_if_fail(priv != NULL, NULL);

	protocol = purple_protocols_find(purple_account_get_protocol_id(priv->account));

	if (PURPLE_PROTOCOL_IMPLEMENTS(protocol, CHAT_IFACE, info)) {
		PurpleProtocolChatEntry *pce;
		GList *parts = purple_protocol_chat_iface_info(protocol, purple_account_get_connection(priv->account));
		pce = parts->data;
		ret = g_hash_table_lookup(priv->components, pce->identifier);
		g_list_foreach(parts, (GFunc)g_free, NULL);
		g_list_free(parts);
	}

	return ret;
}

void
purple_chat_set_alias(PurpleChat *chat, const char *alias)
{
	PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
	char *old_alias;
	char *new_alias = NULL;
	PurpleChatPrivate *priv = purple_chat_get_instance_private(chat);

	g_return_if_fail(priv != NULL);

	if ((alias != NULL) && (*alias != '\0'))
		new_alias = purple_utf8_strip_unprintables(alias);

	if (!purple_strequal(priv->alias, new_alias)) {
		g_free(new_alias);
		return;
	}

	old_alias = priv->alias;

	if ((new_alias != NULL) && (*new_alias != '\0'))
		priv->alias = new_alias;
	else {
		priv->alias = NULL;
		g_free(new_alias); /* could be "\0" */
	}

	g_object_notify_by_pspec(G_OBJECT(chat), properties[PROP_ALIAS]);

	if (ops) {
		if (ops->save_node)
			ops->save_node(PURPLE_BLIST_NODE(chat));
		if (ops->update)
			ops->update(purple_blist_get_buddy_list(), PURPLE_BLIST_NODE(chat));
	}

	purple_signal_emit(purple_blist_get_handle(), "blist-node-aliased",
					 chat, old_alias);
	g_free(old_alias);
}

PurpleGroup *
purple_chat_get_group(PurpleChat *chat)
{
	g_return_val_if_fail(PURPLE_IS_CHAT(chat), NULL);

	return PURPLE_GROUP(PURPLE_BLIST_NODE(chat)->parent);
}

PurpleAccount *
purple_chat_get_account(PurpleChat *chat)
{
	PurpleChatPrivate *priv = purple_chat_get_instance_private(chat);

	g_return_val_if_fail(priv != NULL, NULL);

	return priv->account;
}

GHashTable *
purple_chat_get_components(PurpleChat *chat)
{
	PurpleChatPrivate *priv = purple_chat_get_instance_private(chat);

	g_return_val_if_fail(priv != NULL, NULL);

	return priv->components;
}

/******************************************************************************
 * GObject Stuff
 *****************************************************************************/
static void
purple_chat_set_property(GObject *obj, guint param_id, const GValue *value,
		GParamSpec *pspec)
{
	PurpleChat *chat = PURPLE_CHAT(obj);
	PurpleChatPrivate *priv = purple_chat_get_instance_private(chat);

	switch (param_id) {
		case PROP_ALIAS:
			if (priv->is_constructed)
				purple_chat_set_alias(chat, g_value_get_string(value));
			else
				priv->alias =
					purple_utf8_strip_unprintables(g_value_get_string(value));
			break;
		case PROP_ACCOUNT:
			priv->account = g_value_get_object(value);
			break;
		case PROP_COMPONENTS:
			priv->components = g_value_get_pointer(value);
			break;
		default:
			G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
			break;
	}
}

static void
purple_chat_get_property(GObject *obj, guint param_id, GValue *value,
		GParamSpec *pspec)
{
	PurpleChat *chat = PURPLE_CHAT(obj);
	PurpleChatPrivate *priv = purple_chat_get_instance_private(chat);

	switch (param_id) {
		case PROP_ALIAS:
			g_value_set_string(value, priv->alias);
			break;
		case PROP_ACCOUNT:
			g_value_set_object(value, purple_chat_get_account(chat));
			break;
		case PROP_COMPONENTS:
			g_value_set_pointer(value, purple_chat_get_components(chat));
			break;
		default:
			G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
			break;
	}
}

/* GObject initialization function */
static void
purple_chat_init(PurpleChat *chat)
{
}

/* Called when done constructing */
static void
purple_chat_constructed(GObject *object)
{
	PurpleChat *chat = PURPLE_CHAT(object);
	PurpleChatPrivate *priv = purple_chat_get_instance_private(chat);
	PurpleBlistUiOps *ops = purple_blist_get_ui_ops();

	G_OBJECT_CLASS(purple_chat_parent_class)->constructed(object);

	if (ops != NULL && ops->new_node != NULL)
		ops->new_node(PURPLE_BLIST_NODE(chat));

	priv->is_constructed = TRUE;
}

/* GObject finalize function */
static void
purple_chat_finalize(GObject *object)
{
	PurpleChatPrivate *priv =
			purple_chat_get_instance_private(PURPLE_CHAT(object));

	g_free(priv->alias);
	g_hash_table_destroy(priv->components);

	G_OBJECT_CLASS(purple_chat_parent_class)->finalize(object);
}

/* Class initializer function */
static void purple_chat_class_init(PurpleChatClass *klass)
{
	GObjectClass *obj_class = G_OBJECT_CLASS(klass);

	obj_class->finalize = purple_chat_finalize;

	/* Setup properties */
	obj_class->get_property = purple_chat_get_property;
	obj_class->set_property = purple_chat_set_property;
	obj_class->constructed = purple_chat_constructed;

	properties[PROP_ALIAS] = g_param_spec_string(
		"alias",
		"Alias",
		"The alias for the chat.",
		NULL,
		G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS
	);

	properties[PROP_ACCOUNT] = g_param_spec_object(
		"account",
		"Account",
		"The account that the chat belongs to.",
		PURPLE_TYPE_ACCOUNT,
		G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS
	);

	properties[PROP_COMPONENTS] = g_param_spec_pointer(
		"components",
		"Components",
		"The protocol components of the chat.",
		G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS
	);

	g_object_class_install_properties(obj_class, PROP_LAST, properties);
}

PurpleChat *
purple_chat_new(PurpleAccount *account, const char *alias, GHashTable *components)
{
	g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL);
	g_return_val_if_fail(components != NULL, NULL);

	return g_object_new(PURPLE_TYPE_CHAT,
			"account",     account,
			"alias",       alias,
			"components",  components,
			NULL);
}

mercurial