libpurple/chat.c

changeset 37947
12ce09a23094
child 37951
c80bc6ef5d20
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/chat.c	Fri Aug 12 18:53:31 2016 -0500
@@ -0,0 +1,337 @@
+/*
+ * 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 "dbus-maybe.h"
+#include "utils.h"
+
+#define PURPLE_CHAT_GET_PRIVATE(obj) \
+	(G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_CHAT, PurpleChatPrivate))
+
+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 PurpleBlistNode *blistnode_parent_class;
+static GParamSpec *properties[PROP_LAST];
+
+/******************************************************************************
+ * API
+ *****************************************************************************/
+
+const char *purple_chat_get_name(PurpleChat *chat)
+{
+	PurpleChatPrivate *priv = PURPLE_CHAT_GET_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_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_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_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_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_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_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(GTypeInstance *instance, gpointer klass)
+{
+	PURPLE_DBUS_REGISTER_POINTER(PURPLE_CHAT(instance), PurpleChat);
+}
+
+/* Called when done constructing */
+static void
+purple_chat_constructed(GObject *object)
+{
+	PurpleChat *chat = PURPLE_CHAT(object);
+	PurpleChatPrivate *priv = PURPLE_CHAT_GET_PRIVATE(chat);
+	PurpleBlistUiOps *ops = purple_blist_get_ui_ops();
+
+	G_OBJECT_CLASS(blistnode_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_PRIVATE(object);
+
+	g_free(priv->alias);
+	g_hash_table_destroy(priv->components);
+
+	PURPLE_DBUS_UNREGISTER_POINTER(object);
+
+	G_OBJECT_CLASS(blistnode_parent_class)->finalize(object);
+}
+
+/* Class initializer function */
+static void purple_chat_class_init(PurpleChatClass *klass)
+{
+	GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+
+	blistnode_parent_class = g_type_class_peek_parent(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;
+
+	g_type_class_add_private(klass, sizeof(PurpleChatPrivate));
+
+	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);
+}
+
+GType
+purple_chat_get_type(void)
+{
+	static GType type = 0;
+
+	if(type == 0) {
+		static const GTypeInfo info = {
+			sizeof(PurpleChatClass),
+			NULL,
+			NULL,
+			(GClassInitFunc)purple_chat_class_init,
+			NULL,
+			NULL,
+			sizeof(PurpleChat),
+			0,
+			(GInstanceInitFunc)purple_chat_init,
+			NULL,
+		};
+
+		type = g_type_register_static(PURPLE_TYPE_BLIST_NODE,
+				"PurpleChat",
+				&info, 0);
+	}
+
+	return type;
+}
+
+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