Move PurpleChatUser to it's own file and fix a few issues with the docs and translations

Sat, 22 Aug 2020 03:45:42 -0500

author
Gary Kramlich <grim@reaperworld.com>
date
Sat, 22 Aug 2020 03:45:42 -0500
changeset 40517
5211982886af
parent 40516
fefaa6596e74
child 40518
d587dad11411

Move PurpleChatUser to it's own file and fix a few issues with the docs and translations

Move PurpleChatUser to its own file. Also fixed po/POTFILES.in

Testing Done:
Compiled and ran. ChatUser flags are not displayed but they also are not displayed on default right now either.

Reviewed at https://reviews.imfreedom.org/r/78/

doc/reference/libpurple/libpurple-docs.xml file | annotate | diff | comparison | revisions
libpurple/conversationtypes.c file | annotate | diff | comparison | revisions
libpurple/conversationtypes.h file | annotate | diff | comparison | revisions
libpurple/meson.build file | annotate | diff | comparison | revisions
libpurple/purplechatuser.c file | annotate | diff | comparison | revisions
libpurple/purplechatuser.h file | annotate | diff | comparison | revisions
po/POTFILES.in file | annotate | diff | comparison | revisions
--- a/doc/reference/libpurple/libpurple-docs.xml	Sat Aug 22 02:58:07 2020 -0500
+++ b/doc/reference/libpurple/libpurple-docs.xml	Sat Aug 22 03:45:42 2020 -0500
@@ -66,6 +66,8 @@
       <xi:include href="xml/purple-gio.xml" />
       <xi:include href="xml/purpleaccountoption.xml" />
       <xi:include href="xml/purpleaccountusersplit.xml" />
+      <xi:include href="xml/purplechatuser.xml" />
+      <xi:include href="xml/purpleimconversation.xml" />
       <xi:include href="xml/purplekeyvaluepair.xml" />
       <xi:include href="xml/purpleprotocolfactory.xml" />
       <xi:include href="xml/purpleprotocolim.xml" />
--- a/libpurple/conversationtypes.c	Sat Aug 22 02:58:07 2020 -0500
+++ b/libpurple/conversationtypes.c	Sat Aug 22 03:45:42 2020 -0500
@@ -62,61 +62,6 @@
 G_DEFINE_TYPE_WITH_PRIVATE(PurpleChatConversation, purple_chat_conversation,
 		PURPLE_TYPE_CONVERSATION);
 
-/**************************************************************************/
-/* PurpleChatUser                                                         */
-/**************************************************************************/
-
-/**
- * PurpleChatUser:
- *
- * Structure representing a chat user instance.
- */
-struct _PurpleChatUser
-{
-	GObject gparent;
-
-	gpointer ui_data;
-};
-
-/*
- * Data for "Chat Buddies"
- */
-typedef struct
-{
-	PurpleChatConversation *chat;  /* The chat                              */
-	char *name;                    /* The chat participant's name in the
-	                                  chat.                                 */
-	char *alias;                   /* The chat participant's alias, if known;
-	                                  NULL otherwise.                       */
-	char *alias_key;               /* A string by which this user will be
-	                                  sorted, or @c NULL if the user should be
-	                                  sorted by its @name.
-	                                  (This is currently always NULL.       */
-	gboolean buddy;                /* TRUE if this chat participant is on
-	                                  the buddy list; FALSE otherwise.      */
-	PurpleChatUserFlags flags;     /* A bitwise OR of flags for this
-	                                  participant, such as whether they
-	                                  are a channel operator.               */
-} PurpleChatUserPrivate;
-
-/* Chat User Property enums */
-enum {
-	CU_PROP_0,
-	CU_PROP_CHAT,
-	CU_PROP_NAME,
-	CU_PROP_ALIAS,
-	CU_PROP_FLAGS,
-	CU_PROP_LAST
-};
-
-static GParamSpec *cu_properties[CU_PROP_LAST];
-
-G_DEFINE_TYPE_WITH_PRIVATE(PurpleChatUser, purple_chat_user,
-		G_TYPE_OBJECT);
-
-static int purple_chat_user_compare(PurpleChatUser *a,
-		PurpleChatUser *b);
-
 /**************************************************************************
  * Chat Conversation API
  **************************************************************************/
@@ -1125,314 +1070,3 @@
 
 	return chat;
 }
-
-/**************************************************************************
- * Chat Conversation User API
- **************************************************************************/
-static int
-purple_chat_user_compare(PurpleChatUser *a, PurpleChatUser *b)
-{
-	PurpleChatUserFlags f1 = 0, f2 = 0;
-	PurpleChatUserPrivate *priva, *privb;
-	char *user1 = NULL, *user2 = NULL;
-	gint ret = 0;
-
-	priva = purple_chat_user_get_instance_private(a);
-	privb = purple_chat_user_get_instance_private(b);
-
-	if (priva) {
-		f1 = priva->flags;
-		if (priva->alias_key)
-			user1 = priva->alias_key;
-		else if (priva->name)
-			user1 = priva->name;
-	}
-
-	if (privb) {
-		f2 = privb->flags;
-		if (privb->alias_key)
-			user2 = privb->alias_key;
-		else if (privb->name)
-			user2 = privb->name;
-	}
-
-	if (user1 == NULL || user2 == NULL) {
-		if (!(user1 == NULL && user2 == NULL))
-			ret = (user1 == NULL) ? -1: 1;
-	} else if (f1 != f2) {
-		/* sort more important users first */
-		ret = (f1 > f2) ? -1 : 1;
-	} else if (priva->buddy != privb->buddy) {
-		ret = priva->buddy ? -1 : 1;
-	} else {
-		ret = purple_utf8_strcasecmp(user1, user2);
-	}
-
-	return ret;
-}
-
-const char *
-purple_chat_user_get_alias(PurpleChatUser *cb)
-{
-	PurpleChatUserPrivate *priv;
-
-	g_return_val_if_fail(PURPLE_IS_CHAT_USER(cb), NULL);
-
-	priv = purple_chat_user_get_instance_private(cb);
-	return priv->alias;
-}
-
-const char *
-purple_chat_user_get_name(PurpleChatUser *cb)
-{
-	PurpleChatUserPrivate *priv;
-
-	g_return_val_if_fail(PURPLE_IS_CHAT_USER(cb), NULL);
-
-	priv = purple_chat_user_get_instance_private(cb);
-	return priv->name;
-}
-
-void
-purple_chat_user_set_flags(PurpleChatUser *cb,
-							  PurpleChatUserFlags flags)
-{
-	PurpleConversationUiOps *ops;
-	PurpleChatUserFlags oldflags;
-	PurpleChatUserPrivate *priv;
-
-	g_return_if_fail(PURPLE_IS_CHAT_USER(cb));
-
-	priv = purple_chat_user_get_instance_private(cb);
-
-	if (flags == priv->flags)
-		return;
-
-	oldflags = priv->flags;
-	priv->flags = flags;
-
-	g_object_notify_by_pspec(G_OBJECT(cb), cu_properties[CU_PROP_FLAGS]);
-
-	ops = purple_conversation_get_ui_ops(PURPLE_CONVERSATION(priv->chat));
-
-	if (ops != NULL && ops->chat_update_user != NULL)
-		ops->chat_update_user(cb);
-
-	purple_signal_emit(purple_conversations_get_handle(),
-					 "chat-user-flags", cb, oldflags, flags);
-}
-
-PurpleChatUserFlags
-purple_chat_user_get_flags(PurpleChatUser *cb)
-{
-	PurpleChatUserPrivate *priv;
-
-	g_return_val_if_fail(PURPLE_IS_CHAT_USER(cb), PURPLE_CHAT_USER_NONE);
-
-	priv = purple_chat_user_get_instance_private(cb);
-	return priv->flags;
-}
-
-void
-purple_chat_user_set_ui_data(PurpleChatUser *cb, gpointer ui_data)
-{
-	g_return_if_fail(PURPLE_IS_CHAT_USER(cb));
-
-	cb->ui_data = ui_data;
-}
-
-gpointer
-purple_chat_user_get_ui_data(PurpleChatUser *cb)
-{
-	g_return_val_if_fail(PURPLE_IS_CHAT_USER(cb), NULL);
-
-	return cb->ui_data;
-}
-
-void
-purple_chat_user_set_chat(PurpleChatUser *cb,
-		PurpleChatConversation *chat)
-{
-	PurpleChatUserPrivate *priv;
-
-	g_return_if_fail(PURPLE_IS_CHAT_USER(cb));
-
-	priv = purple_chat_user_get_instance_private(cb);
-	priv->chat = chat;
-
-	g_object_notify_by_pspec(G_OBJECT(cb), cu_properties[CU_PROP_CHAT]);
-}
-
-PurpleChatConversation *
-purple_chat_user_get_chat(PurpleChatUser *cb)
-{
-	PurpleChatUserPrivate *priv;
-
-	g_return_val_if_fail(PURPLE_IS_CHAT_USER(cb), NULL);
-
-	priv = purple_chat_user_get_instance_private(cb);
-	return priv->chat;
-}
-
-gboolean
-purple_chat_user_is_buddy(PurpleChatUser *cb)
-{
-	PurpleChatUserPrivate *priv;
-
-	g_return_val_if_fail(PURPLE_IS_CHAT_USER(cb), FALSE);
-
-	priv = purple_chat_user_get_instance_private(cb);
-	return priv->buddy;
-}
-
-/**************************************************************************
- * GObject code for chat user
- **************************************************************************/
-
-/* Set method for GObject properties */
-static void
-purple_chat_user_set_property(GObject *obj, guint param_id, const GValue *value,
-		GParamSpec *pspec)
-{
-	PurpleChatUser *cb = PURPLE_CHAT_USER(obj);
-	PurpleChatUserPrivate *priv =
-			purple_chat_user_get_instance_private(cb);
-
-	switch (param_id) {
-		case CU_PROP_CHAT:
-			priv->chat = g_value_get_object(value);
-			break;
-		case CU_PROP_NAME:
-			g_free(priv->name);
-			priv->name = g_value_dup_string(value);
-			break;
-		case CU_PROP_ALIAS:
-			g_free(priv->alias);
-			priv->alias = g_value_dup_string(value);
-			break;
-		case CU_PROP_FLAGS:
-			priv->flags = g_value_get_flags(value);
-			break;
-		default:
-			G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
-			break;
-	}
-}
-
-/* Get method for GObject properties */
-static void
-purple_chat_user_get_property(GObject *obj, guint param_id, GValue *value,
-		GParamSpec *pspec)
-{
-	PurpleChatUser *cb = PURPLE_CHAT_USER(obj);
-
-	switch (param_id) {
-		case CU_PROP_CHAT:
-			g_value_set_object(value, purple_chat_user_get_chat(cb));
-			break;
-		case CU_PROP_NAME:
-			g_value_set_string(value, purple_chat_user_get_name(cb));
-			break;
-		case CU_PROP_ALIAS:
-			g_value_set_string(value, purple_chat_user_get_alias(cb));
-			break;
-		case CU_PROP_FLAGS:
-			g_value_set_flags(value, purple_chat_user_get_flags(cb));
-			break;
-		default:
-			G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
-			break;
-	}
-}
-
-/* GObject initialization function */
-static void
-purple_chat_user_init(PurpleChatUser *user)
-{
-}
-
-/* Called when done constructing */
-static void
-purple_chat_user_constructed(GObject *object)
-{
-	PurpleChatUserPrivate *priv = purple_chat_user_get_instance_private(
-			PURPLE_CHAT_USER(object));
-	PurpleAccount *account;
-
-	G_OBJECT_CLASS(purple_chat_user_parent_class)->constructed(object);
-
-	account = purple_conversation_get_account(PURPLE_CONVERSATION(priv->chat));
-
-	if (purple_blist_find_buddy(account, priv->name) != NULL)
-		priv->buddy = TRUE;
-}
-
-/* GObject finalize function */
-static void
-purple_chat_user_finalize(GObject *object)
-{
-	PurpleChatUser *cb = PURPLE_CHAT_USER(object);
-	PurpleChatUserPrivate *priv =
-			purple_chat_user_get_instance_private(cb);
-
-	purple_signal_emit(purple_conversations_get_handle(),
-			"deleting-chat-user", cb);
-
-	g_free(priv->alias);
-	g_free(priv->alias_key);
-	g_free(priv->name);
-
-	G_OBJECT_CLASS(purple_chat_user_parent_class)->finalize(object);
-}
-
-/* Class initializer function */
-static void purple_chat_user_class_init(PurpleChatUserClass *klass)
-{
-	GObjectClass *obj_class = G_OBJECT_CLASS(klass);
-
-	obj_class->constructed = purple_chat_user_constructed;
-	obj_class->finalize = purple_chat_user_finalize;
-
-	/* Setup properties */
-	obj_class->get_property = purple_chat_user_get_property;
-	obj_class->set_property = purple_chat_user_set_property;
-
-	cu_properties[CU_PROP_CHAT] = g_param_spec_object("chat", "Chat",
-				"The chat the buddy belongs to.", PURPLE_TYPE_CHAT_CONVERSATION,
-				G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
-				G_PARAM_STATIC_STRINGS);
-
-	cu_properties[CU_PROP_NAME] = g_param_spec_string("name", "Name",
-				"Name of the chat user.", NULL,
-				G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
-
-	cu_properties[CU_PROP_ALIAS] = g_param_spec_string("alias", "Alias",
-				"Alias of the chat user.", NULL,
-				G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
-
-	cu_properties[CU_PROP_FLAGS] = g_param_spec_flags("flags", "Buddy flags",
-				"The flags for the chat user.",
-				PURPLE_TYPE_CHAT_USER_FLAGS, PURPLE_CHAT_USER_NONE,
-				G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
-
-	g_object_class_install_properties(obj_class, CU_PROP_LAST, cu_properties);
-}
-
-PurpleChatUser *
-purple_chat_user_new(PurpleChatConversation *chat, const char *name,
-		const char *alias, PurpleChatUserFlags flags)
-{
-	PurpleChatUser *cb;
-
-	g_return_val_if_fail(PURPLE_IS_CHAT_CONVERSATION(chat), NULL);
-	g_return_val_if_fail(name != NULL, NULL);
-
-	cb = g_object_new(PURPLE_TYPE_CHAT_USER,
-			"chat",  chat,
-			"name",  name,
-			"alias", alias,
-			"flags", flags,
-			NULL);
-
-	return cb;
-}
--- a/libpurple/conversationtypes.h	Sat Aug 22 02:58:07 2020 -0500
+++ b/libpurple/conversationtypes.h	Sat Aug 22 03:45:42 2020 -0500
@@ -47,32 +47,7 @@
 typedef struct _PurpleChatConversation       PurpleChatConversation;
 typedef struct _PurpleChatConversationClass  PurpleChatConversationClass;
 
-typedef struct _PurpleChatUser       PurpleChatUser;
-
-/**
- * PurpleChatUserFlags:
- * @PURPLE_CHAT_USER_NONE:    No flags
- * @PURPLE_CHAT_USER_VOICE:   Voiced user or "Participant"
- * @PURPLE_CHAT_USER_HALFOP:  Half-op
- * @PURPLE_CHAT_USER_OP:      Channel Op or Moderator
- * @PURPLE_CHAT_USER_FOUNDER: Channel Founder
- * @PURPLE_CHAT_USER_TYPING:  Currently typing
- * @PURPLE_CHAT_USER_AWAY:    Currently away.
- *
- * Flags applicable to users in Chats.
- */
-typedef enum /*< flags >*/
-{
-	PURPLE_CHAT_USER_NONE     = 0x0000,
-	PURPLE_CHAT_USER_VOICE    = 0x0001,
-	PURPLE_CHAT_USER_HALFOP   = 0x0002,
-	PURPLE_CHAT_USER_OP       = 0x0004,
-	PURPLE_CHAT_USER_FOUNDER  = 0x0008,
-	PURPLE_CHAT_USER_TYPING   = 0x0010,
-	PURPLE_CHAT_USER_AWAY     = 0x0020
-
-} PurpleChatUserFlags;
-
+#include "purplechatuser.h"
 #include "purpleimconversation.h"
 #include "conversation.h"
 
@@ -434,140 +409,6 @@
  */
 gboolean purple_chat_conversation_has_left(PurpleChatConversation *chat);
 
-/**************************************************************************/
-/* Chat Conversation User API                                             */
-/**************************************************************************/
-
-#define PURPLE_TYPE_CHAT_USER  purple_chat_user_get_type()
-
-/**
- * purple_chat_user_get_type:
- *
- * Returns: The #GType for the ChatConversationBuddy object.
- */
-G_DECLARE_FINAL_TYPE(PurpleChatUser, purple_chat_user, PURPLE, CHAT_USER,
-		GObject)
-
-/**
- * purple_chat_user_set_chat:
- * @cb:	The chat user
- * @chat:	The chat conversation that the buddy belongs to.
- *
- * Set the chat conversation associated with this chat user.
- *
- * Since: 3.0.0
- */
-void purple_chat_user_set_chat(PurpleChatUser *cb,
-		PurpleChatConversation *chat);
-
-/**
- * purple_chat_user_get_chat:
- * @cb:	The chat user.
- *
- * Get the chat conversation associated with this chat user.
- *
- * Returns: (transfer none):
- *          The chat conversation that the buddy belongs to.
- *
- * Since: 3.0.0
- */
-PurpleChatConversation *purple_chat_user_get_chat(PurpleChatUser *cb);
-
-/**
- * purple_chat_user_new:
- * @chat: The chat that the buddy belongs to.
- * @name: The name.
- * @alias: The alias.
- * @flags: The flags.
- *
- * Creates a new chat user
- *
- * Returns: The new chat user
- */
-PurpleChatUser *purple_chat_user_new(PurpleChatConversation *chat,
-		const char *name, const char *alias, PurpleChatUserFlags flags);
-
-/**
- * purple_chat_user_set_ui_data:
- * @cb:			The chat user
- * @ui_data:		A pointer to associate with this chat user.
- *
- * Set the UI data associated with this chat user.
- *
- * Since: 3.0.0
- */
-void purple_chat_user_set_ui_data(PurpleChatUser *cb, gpointer ui_data);
-
-/**
- * purple_chat_user_get_ui_data:
- * @cb:			The chat user.
- *
- * Get the UI data associated with this chat user.
- *
- * Returns: (transfer none):
- *         The UI data associated with this chat user.  This is a
- *         convenience field provided to the UIs--it is not
- *         used by the libpurple core.
- *
- * Since: 3.0.0
- */
-gpointer purple_chat_user_get_ui_data(PurpleChatUser *cb);
-
-/**
- * purple_chat_user_get_alias:
- * @cb:    The chat user.
- *
- * Get the alias of a chat user
- *
- * Returns: The alias of the chat user.
- *
- * Since: 3.0.0
- */
-const char *purple_chat_user_get_alias(PurpleChatUser *cb);
-
-/**
- * purple_chat_user_get_name:
- * @cb:    The chat user.
- *
- * Get the name of a chat user
- *
- * Returns: The name of the chat user.
- */
-const char *purple_chat_user_get_name(PurpleChatUser *cb);
-
-/**
- * purple_chat_user_set_flags:
- * @cb:     The chat user.
- * @flags:  The new flags.
- *
- * Set the flags of a chat user.
- */
-void purple_chat_user_set_flags(PurpleChatUser *cb, PurpleChatUserFlags flags);
-
-/**
- * purple_chat_user_get_flags:
- * @cb:	The chat user.
- *
- * Get the flags of a chat user.
- *
- * Returns: The flags of the chat user.
- *
- * Since: 3.0.0
- */
-PurpleChatUserFlags purple_chat_user_get_flags(PurpleChatUser *cb);
-
-/**
- * purple_chat_user_is_buddy:
- * @cb:	The chat user.
- *
- * Indicates if this chat user is on the buddy list.
- *
- * Returns: TRUE if the chat user is on the buddy list.
- *
- * Since: 3.0.0
- */
-gboolean purple_chat_user_is_buddy(PurpleChatUser *cb);
-
 G_END_DECLS
 
 #endif /* PURPLE_CONVERSATION_TYPES_H */
--- a/libpurple/meson.build	Sat Aug 22 02:58:07 2020 -0500
+++ b/libpurple/meson.build	Sat Aug 22 03:45:42 2020 -0500
@@ -49,6 +49,7 @@
 	'purple-gio.c',
 	'purpleaccountoption.c',
 	'purpleaccountusersplit.c',
+	'purplechatuser.c',
 	'purpleimconversation.c',
 	'purplekeyvaluepair.c',
 	'purpleprotocolfactory.c',
@@ -127,6 +128,7 @@
 	'purple-gio.h',
 	'purpleaccountoption.h',
 	'purpleaccountusersplit.h',
+	'purplechatuser.h',
 	'purpleimconversation.h',
 	'purplekeyvaluepair.h',
 	'purpleprotocolfactory.h',
@@ -200,13 +202,13 @@
 	'buddyicon.h',
 	'connection.h',
 	'conversation.h',
-	'conversationtypes.h',
 	'debug.h',
 	'eventloop.h',
 	'notify.h',
 	'plugins.h',
 	'protocol.h',
 	'protocols.h',
+	'purplechatuser.h',
 	'purpleimconversation.h',
 	'roomlist.h',
 	'status.h',
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/purplechatuser.c	Sat Aug 22 03:45:42 2020 -0500
@@ -0,0 +1,358 @@
+/*
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "purplechatuser.h"
+#include "enums.h"
+
+struct _PurpleChatUser {
+	GObject parent;
+
+	gpointer ui_data;
+
+	PurpleChatConversation *chat;  /* The chat                              */
+	gchar *name;                   /* The chat participant's name in the
+	                                  chat.                                 */
+	gchar *alias;                  /* The chat participant's alias, if known;
+	                                  NULL otherwise.                       */
+	gchar *alias_key;              /* A string by which this user will be
+	                                  sorted, or @c NULL if the user should be
+	                                  sorted by its @name.
+	                                  (This is currently always NULL.       */
+	gboolean buddy;                /* TRUE if this chat participant is on
+	                                  the buddy list; FALSE otherwise.      */
+	PurpleChatUserFlags flags;     /* A bitwise OR of flags for this
+	                                  participant, such as whether they
+	                                  are a channel operator.               */
+};
+
+enum {
+	PROP_0,
+	PROP_CHAT,
+	PROP_NAME,
+	PROP_ALIAS,
+	PROP_FLAGS,
+	N_PROPERTIES,
+};
+static GParamSpec *properties[N_PROPERTIES] = {NULL, };
+
+/**************************************************************************
+ * Private Setters
+ **************************************************************************/
+static void
+purple_chat_user_set_name(PurpleChatUser *chat_user, const gchar *name) {
+	g_return_if_fail(PURPLE_IS_CHAT_USER(chat_user));
+
+	g_free(chat_user->name);
+	chat_user->name = g_strdup(name);
+
+	g_object_notify_by_pspec(G_OBJECT(chat_user), properties[PROP_NAME]);
+}
+
+static void
+purple_chat_user_set_alias(PurpleChatUser *chat_user, const gchar *alias) {
+	g_return_if_fail(PURPLE_IS_CHAT_USER(chat_user));
+
+	g_free(chat_user->alias);
+	chat_user->alias = g_strdup(alias);
+
+	g_object_notify_by_pspec(G_OBJECT(chat_user), properties[PROP_ALIAS]);
+}
+
+/**************************************************************************
+ * GObject Implementation
+ **************************************************************************/
+G_DEFINE_TYPE(PurpleChatUser, purple_chat_user, G_TYPE_OBJECT);
+
+static void
+purple_chat_user_set_property(GObject *obj, guint param_id, const GValue *value,
+                              GParamSpec *pspec)
+{
+	PurpleChatUser *chat_user = PURPLE_CHAT_USER(obj);
+
+	switch (param_id) {
+		case PROP_CHAT:
+			purple_chat_user_set_chat(chat_user, g_value_get_object(value));
+			break;
+		case PROP_NAME:
+			purple_chat_user_set_name(chat_user, g_value_get_string(value));
+			break;
+		case PROP_ALIAS:
+			purple_chat_user_set_alias(chat_user, g_value_get_string(value));
+			break;
+		case PROP_FLAGS:
+			purple_chat_user_set_flags(chat_user, g_value_get_flags(value));
+			break;
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+			break;
+	}
+}
+
+static void
+purple_chat_user_get_property(GObject *obj, guint param_id, GValue *value,
+                              GParamSpec *pspec)
+{
+	PurpleChatUser *chat_user = PURPLE_CHAT_USER(obj);
+
+	switch (param_id) {
+		case PROP_CHAT:
+			g_value_set_object(value, purple_chat_user_get_chat(chat_user));
+			break;
+		case PROP_NAME:
+			g_value_set_string(value, purple_chat_user_get_name(chat_user));
+			break;
+		case PROP_ALIAS:
+			g_value_set_string(value, purple_chat_user_get_alias(chat_user));
+			break;
+		case PROP_FLAGS:
+			g_value_set_flags(value, purple_chat_user_get_flags(chat_user));
+			break;
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+			break;
+	}
+}
+
+static void
+purple_chat_user_init(PurpleChatUser *user) {
+}
+
+static void
+purple_chat_user_constructed(GObject *object) {
+	PurpleChatUser *chat_user = NULL;
+	PurpleAccount *account = NULL;
+
+	G_OBJECT_CLASS(purple_chat_user_parent_class)->constructed(object);
+
+	chat_user = PURPLE_CHAT_USER(object);
+	account = purple_conversation_get_account(PURPLE_CONVERSATION(chat_user->chat));
+
+	if(purple_blist_find_buddy(account, chat_user->name) != NULL) {
+		chat_user->buddy = TRUE;
+	}
+}
+
+static void
+purple_chat_user_finalize(GObject *object) {
+	PurpleChatUser *chat_user = PURPLE_CHAT_USER(object);
+
+	purple_signal_emit(purple_conversations_get_handle(),
+	                   "deleting-chat-user", chat_user);
+
+	g_free(chat_user->alias);
+	g_free(chat_user->alias_key);
+	g_free(chat_user->name);
+
+	G_OBJECT_CLASS(purple_chat_user_parent_class)->finalize(object);
+}
+
+static void
+purple_chat_user_class_init(PurpleChatUserClass *klass) {
+	GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+
+	obj_class->constructed = purple_chat_user_constructed;
+	obj_class->get_property = purple_chat_user_get_property;
+	obj_class->set_property = purple_chat_user_set_property;
+	obj_class->finalize = purple_chat_user_finalize;
+
+	properties[PROP_CHAT] = g_param_spec_object(
+		"chat", "Chat",
+		"The chat the buddy belongs to.",
+		PURPLE_TYPE_CHAT_CONVERSATION,
+		G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+
+	properties[PROP_NAME] = g_param_spec_string(
+		"name", "Name",
+		"Name of the chat user.",
+		NULL,
+		G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
+
+	properties[PROP_ALIAS] = g_param_spec_string(
+		"alias", "Alias",
+		"Alias of the chat user.",
+		NULL,
+		G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
+
+	properties[PROP_FLAGS] = g_param_spec_flags(
+		"flags", "Buddy flags",
+		"The flags for the chat user.",
+		PURPLE_TYPE_CHAT_USER_FLAGS,
+		PURPLE_CHAT_USER_NONE,
+		G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
+
+	g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
+}
+
+/******************************************************************************
+ * Public API
+ *****************************************************************************/
+PurpleChatUser *
+purple_chat_user_new(PurpleChatConversation *chat, const gchar *name,
+                     const gchar *alias, PurpleChatUserFlags flags)
+{
+	PurpleChatUser *chat_user = NULL;
+
+	g_return_val_if_fail(PURPLE_IS_CHAT_CONVERSATION(chat), NULL);
+	g_return_val_if_fail(name != NULL, NULL);
+
+	chat_user = g_object_new(
+		PURPLE_TYPE_CHAT_USER,
+		"chat", chat,
+		"name", name,
+		"alias", alias,
+		"flags", flags,
+		NULL);
+
+	return chat_user;
+}
+
+const gchar *
+purple_chat_user_get_alias(PurpleChatUser *chat_user) {
+	g_return_val_if_fail(PURPLE_IS_CHAT_USER(chat_user), NULL);
+
+	return chat_user->alias;
+}
+
+const gchar *
+purple_chat_user_get_name(PurpleChatUser *chat_user) {
+	g_return_val_if_fail(PURPLE_IS_CHAT_USER(chat_user), NULL);
+
+	return chat_user->name;
+}
+
+void
+purple_chat_user_set_flags(PurpleChatUser *chat_user,
+                           PurpleChatUserFlags flags)
+{
+	PurpleConversationUiOps *ops;
+	PurpleChatUserFlags oldflags;
+
+	g_return_if_fail(PURPLE_IS_CHAT_USER(chat_user));
+
+	if(flags == chat_user->flags) {
+		return;
+	}
+
+	oldflags = chat_user->flags;
+	chat_user->flags = flags;
+
+	g_object_notify_by_pspec(G_OBJECT(chat_user), properties[PROP_FLAGS]);
+
+	ops = purple_conversation_get_ui_ops(PURPLE_CONVERSATION(chat_user->chat));
+	if(ops != NULL && ops->chat_update_user != NULL) {
+		ops->chat_update_user(chat_user);
+	}
+
+	purple_signal_emit(purple_conversations_get_handle(),
+	                   "chat-user-flags", chat_user, oldflags, flags);
+}
+
+PurpleChatUserFlags
+purple_chat_user_get_flags(PurpleChatUser *chat_user) {
+	g_return_val_if_fail(PURPLE_IS_CHAT_USER(chat_user), PURPLE_CHAT_USER_NONE);
+
+	return chat_user->flags;
+}
+
+void
+purple_chat_user_set_ui_data(PurpleChatUser *chat_user, gpointer ui_data) {
+	g_return_if_fail(PURPLE_IS_CHAT_USER(chat_user));
+
+	chat_user->ui_data = ui_data;
+}
+
+gpointer
+purple_chat_user_get_ui_data(PurpleChatUser *chat_user) {
+	g_return_val_if_fail(PURPLE_IS_CHAT_USER(chat_user), NULL);
+
+	return chat_user->ui_data;
+}
+
+void
+purple_chat_user_set_chat(PurpleChatUser *chat_user,
+                          PurpleChatConversation *chat)
+{
+	g_return_if_fail(PURPLE_IS_CHAT_USER(chat_user));
+
+	if(g_set_object(&chat_user->chat, chat)) {
+		g_object_notify_by_pspec(G_OBJECT(chat_user), properties[PROP_CHAT]);
+	}
+}
+
+PurpleChatConversation *
+purple_chat_user_get_chat(PurpleChatUser *chat_user) {
+	g_return_val_if_fail(PURPLE_IS_CHAT_USER(chat_user), NULL);
+
+	return chat_user->chat;
+}
+
+gboolean
+purple_chat_user_is_buddy(PurpleChatUser *chat_user) {
+	g_return_val_if_fail(PURPLE_IS_CHAT_USER(chat_user), FALSE);
+
+	return chat_user->buddy;
+}
+
+gint
+purple_chat_user_compare(PurpleChatUser *a, PurpleChatUser *b) {
+	gchar *namea = NULL, *nameb = NULL;
+
+	/* NULL is equal to NULL */
+	if(a == NULL && b == NULL) {
+		return 0;
+	}
+
+	/* non-NULL sorts before NULL */
+	if(a == NULL && b != NULL) {
+		return 1;
+	} else if(a != NULL && b == NULL) {
+		return -1;
+	}
+
+	/* higher valued flags sort before lower values */
+	if(a->flags > b->flags) {
+		return -1;
+	} else if(a->flags < b->flags) {
+		return 1;
+	}
+
+	/* buddies sort before non-buddies */
+	if(a->buddy != b->buddy) {
+		return a->buddy ? -1 : 1;
+	}
+
+	/* figure out what name we need to check for user a */
+	if(a->alias_key) {
+		namea = a->alias_key;
+	} else if (a->name) {
+		namea = a->name;
+	}
+
+	/* figure out what name we need to check for user b */
+	if(b->alias_key) {
+		nameb = b->alias_key;
+	} else if(b->name) {
+		nameb = b->name;
+	}
+
+	/* finally we're just sorting names */
+	return purple_utf8_strcasecmp(namea, nameb);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/purplechatuser.h	Sat Aug 22 03:45:42 2020 -0500
@@ -0,0 +1,215 @@
+/*
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#if !defined(PURPLE_GLOBAL_HEADER_INSIDE) && !defined(PURPLE_COMPILATION)
+# error "only <purple.h> may be included directly"
+#endif
+
+#ifndef PURPLE_CHAT_USER_H
+#define PURPLE_CHAT_USER_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+/**
+ * SECTION:purplechatuser
+ * @section_id: libpurple-purplechatuser
+ * @short_description: <filename>purplechatuser.h</filename>
+ * @title: Chat User Objects
+ */
+
+/**
+ * PurpleChatUser:
+ *
+ * Structure representing a chat user instance.
+ */
+
+/**
+ * PurpleChatUserFlags:
+ * @PURPLE_CHAT_USER_NONE:    No flags
+ * @PURPLE_CHAT_USER_VOICE:   Voiced user or "Participant"
+ * @PURPLE_CHAT_USER_HALFOP:  Half-op
+ * @PURPLE_CHAT_USER_OP:      Channel Op or Moderator
+ * @PURPLE_CHAT_USER_FOUNDER: Channel Founder
+ * @PURPLE_CHAT_USER_TYPING:  Currently typing
+ * @PURPLE_CHAT_USER_AWAY:    Currently away.
+ *
+ * Flags applicable to users in Chats.
+ */
+typedef enum /*< flags >*/
+{
+	PURPLE_CHAT_USER_NONE     = 0x0000,
+	PURPLE_CHAT_USER_VOICE    = 0x0001,
+	PURPLE_CHAT_USER_HALFOP   = 0x0002,
+	PURPLE_CHAT_USER_OP       = 0x0004,
+	PURPLE_CHAT_USER_FOUNDER  = 0x0008,
+	PURPLE_CHAT_USER_TYPING   = 0x0010,
+	PURPLE_CHAT_USER_AWAY     = 0x0020
+
+} PurpleChatUserFlags;
+
+#define PURPLE_TYPE_CHAT_USER purple_chat_user_get_type()
+
+/**
+ * purple_chat_user_get_type:
+ *
+ * Returns: The #GType for the ChatConversationBuddy object.
+ */
+
+G_DECLARE_FINAL_TYPE(PurpleChatUser, purple_chat_user, PURPLE, CHAT_USER,
+                     GObject)
+
+#include <libpurple/conversationtypes.h>
+
+/**
+ * purple_chat_user_new:
+ * @chat: The chat that the buddy belongs to.
+ * @name: The name.
+ * @alias: The alias.
+ * @flags: The flags.
+ *
+ * Creates a new chat user
+ *
+ * Returns: The new chat user
+ */
+PurpleChatUser *purple_chat_user_new(PurpleChatConversation *chat,
+                                     const gchar *name,
+                                     const gchar *alias,
+                                     PurpleChatUserFlags flags);
+
+/**
+ * purple_chat_user_set_chat:
+ * @chat_user: The chat user
+ * @chat: The chat conversation that @chat_user belongs to.
+ *
+ * Set the chat conversation associated with this chat user.
+ *
+ * Since: 3.0.0
+ */
+void purple_chat_user_set_chat(PurpleChatUser *chat_user,
+                               PurpleChatConversation *chat);
+
+/**
+ * purple_chat_user_get_chat:
+ * @chat_user: The chat user.
+ *
+ * Get the chat conversation associated with this chat user.
+ *
+ * Returns: (transfer full): The chat conversation that the buddy belongs to.
+ *
+ * Since: 3.0.0
+ */
+PurpleChatConversation *purple_chat_user_get_chat(PurpleChatUser *chat_user);
+
+/**
+ * purple_chat_user_set_ui_data:
+ * @chat_user: The chat user
+ * @ui_data: A pointer to associate with this chat user.
+ *
+ * Set the UI data associated with this chat user.
+ *
+ * Since: 3.0.0
+ */
+void purple_chat_user_set_ui_data(PurpleChatUser *chat_user, gpointer ui_data);
+
+/**
+ * purple_chat_user_get_ui_data:
+ * @chat_user: The chat user.
+ *
+ * Get the UI data associated with this chat user.
+ *
+ * Returns: (transfer none): The UI data associated with this chat user.  This
+ *          is a convenience field provided to the UIs--it is not used by the
+ *          libpurple core.
+ *
+ * Since: 3.0.0
+ */
+gpointer purple_chat_user_get_ui_data(PurpleChatUser *chat_user);
+
+/**
+ * purple_chat_user_get_alias:
+ * @chat_user: The chat user.
+ *
+ * Get the alias of a chat user.
+ *
+ * Returns: The alias of the chat user.
+ *
+ * Since: 3.0.0
+ */
+const gchar *purple_chat_user_get_alias(PurpleChatUser *chat_user);
+
+/**
+ * purple_chat_user_get_name:
+ * @chat_user: The chat user.
+ *
+ * Get the name of a chat user.
+ *
+ * Returns: The name of the chat user.
+ */
+const gchar *purple_chat_user_get_name(PurpleChatUser *chat_user);
+
+/**
+ * purple_chat_user_set_flags:
+ * @chat_user: The chat user.
+ * @flags: The new flags.
+ *
+ * Set the flags of a chat user.
+ */
+void purple_chat_user_set_flags(PurpleChatUser *chat_user,
+                                PurpleChatUserFlags flags);
+
+/**
+ * purple_chat_user_get_flags:
+ * @chat_user: The chat user.
+ *
+ * Get the flags of a chat user.
+ *
+ * Returns: The flags of the chat user.
+ *
+ * Since: 3.0.0
+ */
+PurpleChatUserFlags purple_chat_user_get_flags(PurpleChatUser *chat_user);
+
+/**
+ * purple_chat_user_is_buddy:
+ * @chat_user: The chat user.
+ *
+ * Indicates if this chat user is on the buddy list.
+ *
+ * Returns: %TRUE if the chat user is on the buddy list.
+ *
+ * Since: 3.0.0
+ */
+gboolean purple_chat_user_is_buddy(PurpleChatUser *chat_user);
+
+/**
+ * purple_chat_user_compare:
+ * @a: The first #PurpleChatUser.
+ * @b: The second #PurpleChatUser.
+ *
+ * Compares #PurpleChatUser's @a and @b and returns -1 if @a should be sorted
+ * first, 0 if sorted equally, and 1 if @a should be sorted after @b.
+ *
+ * Returns: The sorting order of @a and @b.
+ */
+gint purple_chat_user_compare(PurpleChatUser *a, PurpleChatUser *b);
+
+#endif /* PURPLE_CHAT_USER_H */
--- a/po/POTFILES.in	Sat Aug 22 02:58:07 2020 -0500
+++ b/po/POTFILES.in	Sat Aug 22 03:45:42 2020 -0500
@@ -14,7 +14,6 @@
 finch/gntprefs.c
 finch/gntrequest.c
 finch/gntroomlist.c
-finch/gntsound.c
 finch/gntstatus.c
 finch/gntui.c
 finch/gntxfer.c
@@ -219,9 +218,6 @@
 libpurple/protocols/simple/ntlm.c
 libpurple/protocols/simple/simple.c
 libpurple/protocols/simple/sipmsg.c
-libpurple/protocols/zephyr/error_message.c
-libpurple/protocols/zephyr/et_name.c
-libpurple/protocols/zephyr/init_et.c
 libpurple/protocols/zephyr/ZAsyncLocate.c
 libpurple/protocols/zephyr/ZCkAuth.c
 libpurple/protocols/zephyr/ZCkIfNot.c
@@ -229,7 +225,6 @@
 libpurple/protocols/zephyr/ZCmpUID.c
 libpurple/protocols/zephyr/ZCmpUIDP.c
 libpurple/protocols/zephyr/zephyr.c
-libpurple/protocols/zephyr/zephyr_err.c
 libpurple/protocols/zephyr/ZFlsLocs.c
 libpurple/protocols/zephyr/ZFlsSubs.c
 libpurple/protocols/zephyr/ZFmtAuth.c
@@ -271,6 +266,8 @@
 libpurple/protocols/zephyr/ZWait4Not.c
 libpurple/proxy.c
 libpurple/purple-gio.c
+libpurple/purplechatuser.c
+libpurple/purpleimconversation.c
 libpurple/queuedoutputstream.c
 libpurple/request.c
 libpurple/request-datasheet.c
@@ -283,12 +280,7 @@
 libpurple/smiley-list.c
 libpurple/smiley-parser.c
 libpurple/smiley-theme.c
-libpurple/sound.c
-libpurple/sound-theme.c
-libpurple/sound-theme-loader.c
-libpurple/sslconn.c
 libpurple/status.c
-libpurple/stringref.c
 libpurple/stun.c
 libpurple/tests/test_attention_type.c
 libpurple/tests/test_image.c
@@ -328,7 +320,6 @@
 pidgin/gtkidle.c
 pidgin/gtkmedia.c
 pidgin/gtknotify.c
-pidgin/gtkplugin.c
 pidgin/gtkpluginpref.c
 pidgin/gtkpounce.c
 pidgin/gtkprefs.c
@@ -339,7 +330,6 @@
 pidgin/gtkscrollbook.c
 pidgin/gtksmiley-manager.c
 pidgin/gtksmiley-theme.c
-pidgin/gtksound.c
 pidgin/gtkstatusbox.c
 pidgin/gtkstatus-icon-theme.c
 pidgin/gtkstyle.c
@@ -352,7 +342,6 @@
 pidgin/pidgin.c
 pidgin/pidgincontactcompletion.c
 pidgin/pidgindebug.c
-pidgin/pidgindebugplugininfo.c
 pidgin/pidgingdkpixbuf.c
 pidgin/pidgininvitedialog.c
 pidgin/pidginlog.c
@@ -361,12 +350,10 @@
 pidgin/pidginstock.c
 pidgin/pidgintalkatu.c
 pidgin/pidgintooltip.c
-pidgin/plugins/cap/cap.c
 pidgin/plugins/contact_priority.c
 pidgin/plugins/disco/gtkdisco.c
 pidgin/plugins/disco/xmppdisco.c
 pidgin/plugins/disco/resources/disco.ui
-pidgin/plugins/extplacement.c
 pidgin/plugins/gestures/gestures.c
 pidgin/plugins/gestures/stroke.c
 pidgin/plugins/gestures/stroke-draw.c
@@ -385,7 +372,6 @@
 pidgin/plugins/musicmessaging/musicmessaging.c
 pidgin/plugins/notify.c
 pidgin/plugins/pidgininc.c
-pidgin/plugins/raw.c
 pidgin/plugins/relnot.c
 pidgin/plugins/screencap.c
 pidgin/plugins/spellchk.c
@@ -407,8 +393,6 @@
 pidgin/resources/Debug/debug.ui
 pidgin/resources/Debug/plugininfo.ui
 pidgin/resources/Conversations/invite_dialog.ui
-pidgin/win32/gtkdocklet-win32.c
 pidgin/win32/gtkwin32dep.c
-pidgin/win32/MinimizeToTray.c
 pidgin/win32/untar.c
 pidgin/win32/winpidgin.c

mercurial