Sun, 14 Apr 2024 01:48:40 -0500
Remove the remaining BuddyList API
It's taken a long time to get here, but we made it!
Testing Done:
Called in the turtles.
Reviewed at https://reviews.imfreedom.org/r/3125/
--- a/ChangeLog.API Sun Apr 14 01:30:58 2024 -0500 +++ b/ChangeLog.API Sun Apr 14 01:48:40 2024 -0500 @@ -248,6 +248,8 @@ instead. * account-setting-info, account-set-info signals * account-status-changing signal. + * blist-node-aliased signal. + * blist-node-extended-menu signal. * blocked-img-msg signal. * buddy-caps-changed signal. * buddy-got-login-time signal. @@ -334,6 +336,7 @@ * purple_account_privacy_permit_remove * purple_account_remove_buddy * purple_account_remove_buddies + * purple_account_remove_group * purple_account_remove_setting * purple_account_request_add. Use purple_add_contact_request_new instead. @@ -380,20 +383,50 @@ * purple_attention_type_get_unlocalized_name * purple_base16_* * purple_base64_*. Use g_base64_* instead + * PurpleBuddyList * purple_blist_add_account * purple_blist_add_buddy * purple_blist_add_chat + * purple_blist_add_contact + * purple_blist_add_group * purple_blist_find_chat + * purple_blist_get_buddies + * purple_blist_get_handle + * purple_blist_get_root * purple_blist_get_ui_data + * purple_blist_init * purple_blist_load * purple_blist_new + * PurpleBlistNode + * purple_blist_node_get_bool + * purple_blist_node_get_extended_menu + * purple_blist_node_get_first_child + * purple_blist_node_get_int + * purple_blist_node_get_parent + * purple_blist_node_get_sibling_next + * purple_blist_node_get_sibling_prev + * purple_blist_node_get_string + * purple_blist_node_get_type * purple_blist_node_get_ui_data + * purple_blist_node_next + * purple_blist_node_remove_setting + * purple_blist_node_set_bool + * purple_blist_node_set_int + * purple_blist_node_set_string * purple_blist_node_set_ui_data * purple_blist_remove_account * purple_blist_remove_buddy * purple_blist_remove_chat + * purple_blist_remove_contact + * purple_blist_remove_group + * purple_blist_request_add_buddy * purple_blist_request_add_chat + * purple_blist_request_add_group + * purple_blist_schedule_save * purple_blist_set_ui_data + * purple_blist_set_visible + * purple_blist_show + * purple_blist_uninit * purple_set_blist * purple_blist_update_buddy_icon * purple_buddy_get_local_alias @@ -492,6 +525,11 @@ * purple_get_attention_type_from_code * purple_get_host_name. Use g_get_host_name, instead. * purple_get_tzoff_str(). Use g_date_time_format, instead. + * PurpleGroup + * purple_group_get_accounts + * purple_group_get_name + * purple_group_new + * purple_group_on_account * purple_home_dir * PurpleIdleUiOps * purple_idle_get_ui_ops @@ -960,6 +998,8 @@ * struct PurpleAccountOption * struct PurpleAccountUserSplit * struct PurpleNotifySearchColumn + * ui-caps-changed signal + * update-idle signal * wpurple_g_access * writing-chat-msg signal * writing-im-msg signal
--- a/doc/reference/libpurple/libpurple.toml.in Sun Apr 14 01:30:58 2024 -0500 +++ b/doc/reference/libpurple/libpurple.toml.in Sun Apr 14 01:48:40 2024 -0500 @@ -41,7 +41,6 @@ "plugin_i18n.md", "plugin_ids.md", "signals_account.md", - "signals_blist.md", "signals_cmd.md", "signals_connection.md", "signals_conversation.md",
--- a/doc/reference/libpurple/meson.build Sun Apr 14 01:30:58 2024 -0500 +++ b/doc/reference/libpurple/meson.build Sun Apr 14 01:48:40 2024 -0500 @@ -3,7 +3,6 @@ 'plugin_i18n.md', 'plugin_ids.md', 'signals_account.md', - 'signals_blist.md', 'signals_cmd.md', 'signals_connection.md', 'signals_conversation.md',
--- a/doc/reference/libpurple/signals_blist.md Sun Apr 14 01:30:58 2024 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,92 +0,0 @@ -Title: Buddy List Signals -Slug: buddy-list-signals - -## Buddy List Signals - -### Signal List - -* [update-idle](#update-idle) -* [blist-node-extended-menu](#blist-node-extended-menu) -* [blist-node-aliased](#blist-node-aliased) -* [ui-caps-changed](#ui-caps-changed) - -### Signal Details - -#### update-idle - -```c -void user_function(gpointer user_data); -``` - -Emitted when the buddy list is refreshed and the idle times are updated. - -**Parameters:** - -**user_data** -: user data set when the signal handler was connected. - ----- - -#### blist-node-extended-menu - -```c -void user_function(PurpleBlistNode *node, GList **menu, gpointer user_data); -``` - -Emitted when a buddylist menu is being constructed `menu` is a pointer to a -GList of PurpleMenuAction's allowing a plugin to add menu items. - ----- - -#### blist-node-added - -```c -void user_function(PurpleBlistNode *node, gpointer user_data); -``` - -Emitted when a new blist node is added to the buddy list. - ----- - -#### blist-node-removed - -```c -void user_function(PurpleBlistNode *node, gpointer user_data); -``` - -Emitted when a blist node is removed from the buddy list. - ----- - -#### blist-node-aliased - -```c -void user_function(PurpleBlistNode *node, - const gchar *old_alias, - gpointer user_data); -``` - -Emitted when a blist node (buddy, chat, or contact) is aliased. - ----- - -#### ui-caps-changed - -```c -void user_function(PurpleMediaCaps newcaps, - PurpleMediaCaps oldcaps, - gpointer user_data); -``` - -Emitted when updating the media capabilities of the UI. - -**Parameters:** - -**newcaps** -: . - -**oldcaps** -: . - -**user_data** -: user data set when the signal handler was connected.
--- a/libpurple/blistnode.c Sun Apr 14 01:30:58 2024 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,370 +0,0 @@ -/* - * Purple - Internet Messaging Library - * Copyright (C) Pidgin Developers <devel@pidgin.im> - * - * 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 library 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 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this library; if not, see <https://www.gnu.org/licenses/>. - */ - -#include "blistnode.h" - -#include "buddylist.h" -#include "signals.h" -#include "util.h" - -typedef struct _PurpleBlistNodePrivate PurpleBlistNodePrivate; - -/* Private data of a buddy list node */ -struct _PurpleBlistNodePrivate { - GHashTable *settings; /* per-node settings */ - gboolean transient; /* node should not be saved with the buddy list */ -}; - -/* Blist node property enums */ -enum -{ - PROP_0, - PROP_TRANSIENT, - N_PROPERTIES, -}; - -static GParamSpec *properties[N_PROPERTIES] = {NULL, }; - -G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(PurpleBlistNode, purple_blist_node, - G_TYPE_OBJECT); - -/**************************************************************************/ -/* Buddy list node API */ -/**************************************************************************/ - -PurpleBlistNode * -purple_blist_node_next(G_GNUC_UNUSED PurpleBlistNode *node, - G_GNUC_UNUSED gboolean offline) -{ - return NULL; -} - -PurpleBlistNode *purple_blist_node_get_parent(PurpleBlistNode *node) -{ - return node ? node->parent : NULL; -} - -PurpleBlistNode *purple_blist_node_get_first_child(PurpleBlistNode *node) -{ - return node ? node->child : NULL; -} - -PurpleBlistNode *purple_blist_node_get_sibling_next(PurpleBlistNode *node) -{ - return node? node->next : NULL; -} - -PurpleBlistNode *purple_blist_node_get_sibling_prev(PurpleBlistNode *node) -{ - return node? node->prev : NULL; -} - -void purple_blist_node_remove_setting(PurpleBlistNode *node, const char *key) -{ - PurpleBlistNodePrivate *priv = NULL; - - g_return_if_fail(PURPLE_IS_BLIST_NODE(node)); - g_return_if_fail(key != NULL); - - priv = purple_blist_node_get_instance_private(node); - g_return_if_fail(priv->settings != NULL); - - g_hash_table_remove(priv->settings, key); - - purple_blist_save_node(purple_blist_get_default(), node); -} - -void -purple_blist_node_set_transient(PurpleBlistNode *node, gboolean transient) -{ - PurpleBlistNodePrivate *priv = NULL; - - g_return_if_fail(PURPLE_IS_BLIST_NODE(node)); - - priv = purple_blist_node_get_instance_private(node); - priv->transient = transient; - - g_object_notify_by_pspec(G_OBJECT(node), properties[PROP_TRANSIENT]); -} - -gboolean -purple_blist_node_is_transient(PurpleBlistNode *node) -{ - PurpleBlistNodePrivate *priv = NULL; - - g_return_val_if_fail(PURPLE_IS_BLIST_NODE(node), 0); - - priv = purple_blist_node_get_instance_private(node); - return priv->transient; -} - -GHashTable * -purple_blist_node_get_settings(PurpleBlistNode *node) -{ - PurpleBlistNodePrivate *priv = NULL; - - g_return_val_if_fail(PURPLE_IS_BLIST_NODE(node), NULL); - - priv = purple_blist_node_get_instance_private(node); - return priv->settings; -} - -gboolean -purple_blist_node_has_setting(PurpleBlistNode* node, const char *key) -{ - PurpleBlistNodePrivate *priv = NULL; - - g_return_val_if_fail(PURPLE_IS_BLIST_NODE(node), FALSE); - g_return_val_if_fail(key != NULL, FALSE); - - priv = purple_blist_node_get_instance_private(node); - g_return_val_if_fail(priv->settings != NULL, FALSE); - - /* Boxed type, so it won't ever be NULL, so no need for _extended */ - return (g_hash_table_lookup(priv->settings, key) != NULL); -} - -void -purple_blist_node_set_bool(PurpleBlistNode* node, const char *key, gboolean data) -{ - PurpleBlistNodePrivate *priv = NULL; - GValue *value; - - g_return_if_fail(PURPLE_IS_BLIST_NODE(node)); - g_return_if_fail(key != NULL); - - priv = purple_blist_node_get_instance_private(node); - g_return_if_fail(priv->settings != NULL); - - value = purple_value_new(G_TYPE_BOOLEAN); - g_value_set_boolean(value, data); - - g_hash_table_replace(priv->settings, g_strdup(key), value); - - purple_blist_save_node(purple_blist_get_default(), node); -} - -gboolean -purple_blist_node_get_bool(PurpleBlistNode* node, const char *key) -{ - PurpleBlistNodePrivate *priv = NULL; - GValue *value; - - g_return_val_if_fail(PURPLE_IS_BLIST_NODE(node), FALSE); - g_return_val_if_fail(key != NULL, FALSE); - - priv = purple_blist_node_get_instance_private(node); - g_return_val_if_fail(priv->settings != NULL, FALSE); - - value = g_hash_table_lookup(priv->settings, key); - - if (value == NULL) - return FALSE; - - g_return_val_if_fail(G_VALUE_HOLDS_BOOLEAN(value), FALSE); - - return g_value_get_boolean(value); -} - -void -purple_blist_node_set_int(PurpleBlistNode* node, const char *key, int data) -{ - PurpleBlistNodePrivate *priv = NULL; - GValue *value; - - g_return_if_fail(PURPLE_IS_BLIST_NODE(node)); - g_return_if_fail(key != NULL); - - priv = purple_blist_node_get_instance_private(node); - g_return_if_fail(priv->settings != NULL); - - value = purple_value_new(G_TYPE_INT); - g_value_set_int(value, data); - - g_hash_table_replace(priv->settings, g_strdup(key), value); - - purple_blist_save_node(purple_blist_get_default(), node); -} - -int -purple_blist_node_get_int(PurpleBlistNode* node, const char *key) -{ - PurpleBlistNodePrivate *priv = NULL; - GValue *value; - - g_return_val_if_fail(PURPLE_IS_BLIST_NODE(node), 0); - g_return_val_if_fail(key != NULL, 0); - - priv = purple_blist_node_get_instance_private(node); - g_return_val_if_fail(priv->settings != NULL, 0); - - value = g_hash_table_lookup(priv->settings, key); - - if (value == NULL) - return 0; - - g_return_val_if_fail(G_VALUE_HOLDS_INT(value), 0); - - return g_value_get_int(value); -} - -void -purple_blist_node_set_string(PurpleBlistNode* node, const char *key, const char *data) -{ - PurpleBlistNodePrivate *priv = NULL; - GValue *value; - - g_return_if_fail(PURPLE_IS_BLIST_NODE(node)); - g_return_if_fail(key != NULL); - - priv = purple_blist_node_get_instance_private(node); - g_return_if_fail(priv->settings != NULL); - - value = purple_value_new(G_TYPE_STRING); - g_value_set_string(value, data); - - g_hash_table_replace(priv->settings, g_strdup(key), value); - - purple_blist_save_node(purple_blist_get_default(), node); -} - -const char * -purple_blist_node_get_string(PurpleBlistNode* node, const char *key) -{ - PurpleBlistNodePrivate *priv = NULL; - GValue *value; - - g_return_val_if_fail(PURPLE_IS_BLIST_NODE(node), NULL); - g_return_val_if_fail(key != NULL, NULL); - - priv = purple_blist_node_get_instance_private(node); - g_return_val_if_fail(priv->settings != NULL, NULL); - - value = g_hash_table_lookup(priv->settings, key); - - if (value == NULL) - return NULL; - - g_return_val_if_fail(G_VALUE_HOLDS_STRING(value), NULL); - - return g_value_get_string(value); -} - -GList * -purple_blist_node_get_extended_menu(PurpleBlistNode *n) -{ - GList *menu = NULL; - - g_return_val_if_fail(n != NULL, NULL); - - purple_signal_emit(purple_blist_get_handle(), "blist-node-extended-menu", - n, &menu); - return menu; -} - -/************************************************************************** - * GObject code for PurpleBlistNode - **************************************************************************/ - -/* Set method for GObject properties */ -static void -purple_blist_node_set_property(GObject *obj, guint param_id, const GValue *value, - GParamSpec *pspec) -{ - PurpleBlistNode *node = PURPLE_BLIST_NODE(obj); - - switch (param_id) { - case PROP_TRANSIENT: - purple_blist_node_set_transient(node, g_value_get_boolean(value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); - break; - } -} - -/* Get method for GObject properties */ -static void -purple_blist_node_get_property(GObject *obj, guint param_id, GValue *value, - GParamSpec *pspec) -{ - PurpleBlistNode *node = PURPLE_BLIST_NODE(obj); - - switch (param_id) { - case PROP_TRANSIENT: - g_value_set_boolean(value, purple_blist_node_is_transient(node)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); - break; - } -} - -/* GObject initialization function */ -static void -purple_blist_node_init(PurpleBlistNode *node) -{ - PurpleBlistNodePrivate *priv = - purple_blist_node_get_instance_private(node); - - priv->settings = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, - (GDestroyNotify)purple_value_free); -} - -/* GObject finalize function */ -static void -purple_blist_node_finalize(GObject *object) -{ - PurpleBlistNodePrivate *priv = purple_blist_node_get_instance_private( - PURPLE_BLIST_NODE(object)); - - g_hash_table_destroy(priv->settings); - - G_OBJECT_CLASS(purple_blist_node_parent_class)->finalize(object); -} - -/* Class initializer function */ -static void -purple_blist_node_class_init(PurpleBlistNodeClass *klass) -{ - GObjectClass *obj_class = G_OBJECT_CLASS(klass); - - obj_class->finalize = purple_blist_node_finalize; - - /* Setup properties */ - obj_class->get_property = purple_blist_node_get_property; - obj_class->set_property = purple_blist_node_set_property; - - /** - * PurpleBlistNode:transient: - * - * If %TRUE the node will not be saved to the contact list. - * - * Since: 3.0 - */ - properties[PROP_TRANSIENT] = g_param_spec_boolean("transient", - "Transient", - "Whether node should not be saved with the buddy list.", - FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties(obj_class, N_PROPERTIES, properties); -}
--- a/libpurple/blistnode.h Sun Apr 14 01:30:58 2024 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,336 +0,0 @@ -/* - * Purple - Internet Messaging Library - * Copyright (C) Pidgin Developers <devel@pidgin.im> - * - * 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 library 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 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this library; if not, see <https://www.gnu.org/licenses/>. - */ - -#if !defined(PURPLE_GLOBAL_HEADER_INSIDE) && !defined(PURPLE_COMPILATION) -# error "only <purple.h> may be included directly" -#endif - -#ifndef PURPLE_BLIST_NODE_H -#define PURPLE_BLIST_NODE_H - -#include <glib.h> -#include <glib-object.h> - -#include "purpleversion.h" - -#define PURPLE_TYPE_BLIST_NODE (purple_blist_node_get_type()) -#define PURPLE_BLIST_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_BLIST_NODE, PurpleBlistNode)) -#define PURPLE_BLIST_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_BLIST_NODE, PurpleBlistNodeClass)) -#define PURPLE_IS_BLIST_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_BLIST_NODE)) -#define PURPLE_IS_BLIST_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_BLIST_NODE)) -#define PURPLE_BLIST_NODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_BLIST_NODE, PurpleBlistNodeClass)) - -typedef struct _PurpleBlistNode PurpleBlistNode; -typedef struct _PurpleBlistNodeClass PurpleBlistNodeClass; - -/** - * PurpleBlistNode: - * @prev: The sibling before this buddy. - * @next: The sibling after this buddy. - * @parent: The parent of this node. - * @child: The child of this node. - * - * A Buddy list node. This can represent a group, a buddy, or anything else. - * This is a base class for PurpleBuddy, PurpleContact, PurpleGroup, and for - * anything else that wants to put itself in the buddy list. - * - * Since: 2.0 - */ -struct _PurpleBlistNode { - GObject gparent; - - /*< public >*/ - PurpleBlistNode *prev; - PurpleBlistNode *next; - PurpleBlistNode *parent; - PurpleBlistNode *child; -}; - -struct _PurpleBlistNodeClass { - GObjectClass gparent_class; - - /*< private >*/ - void (*_purple_reserved1)(void); - void (*_purple_reserved2)(void); - void (*_purple_reserved3)(void); - void (*_purple_reserved4)(void); -}; - -G_BEGIN_DECLS - -/** - * purple_blist_node_get_type: - * - * Returns: The #GType for the #PurpleBlistNode object. - * - * Since: 2.1 - */ -PURPLE_AVAILABLE_IN_2_1 -GType purple_blist_node_get_type(void); - -/** - * purple_blist_node_next: - * @node: A node. - * @offline: Whether to include nodes for offline accounts - * - * Returns the next node of a given node. This function is to be used to iterate - * over the tree returned by purple_blist_get_default. - * - * See purple_blist_node_get_parent(), purple_blist_node_get_first_child(), - * purple_blist_node_get_sibling_next(), purple_blist_node_get_sibling_prev(). - * - * Returns: (transfer none): The next node - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -PurpleBlistNode *purple_blist_node_next(PurpleBlistNode *node, gboolean offline); - -/** - * purple_blist_node_get_parent: - * @node: A node. - * - * Returns the parent node of a given node. - * - * See purple_blist_node_get_first_child(), purple_blist_node_get_sibling_next(), - * purple_blist_node_get_sibling_prev(), purple_blist_node_next(). - * - * Returns: (transfer none): The parent node. - * - * Since: 2.4 - */ -PURPLE_AVAILABLE_IN_2_4 -PurpleBlistNode *purple_blist_node_get_parent(PurpleBlistNode *node); - -/** - * purple_blist_node_get_first_child: - * @node: A node. - * - * Returns the the first child node of a given node. - * - * See purple_blist_node_get_parent(), purple_blist_node_get_sibling_next(), - * purple_blist_node_get_sibling_prev(), purple_blist_node_next(). - * - * Returns: (transfer none): The child node. - * - * Since: 2.4 - */ -PURPLE_AVAILABLE_IN_2_4 -PurpleBlistNode *purple_blist_node_get_first_child(PurpleBlistNode *node); - -/** - * purple_blist_node_get_sibling_next: - * @node: A node. - * - * Returns the sibling node of a given node. - * - * See purple_blist_node_get_parent(), purple_blist_node_get_first_child(), - * purple_blist_node_get_sibling_prev(), purple_blist_node_next(). - * - * Returns: (transfer none): The sibling node. - * - * Since: 2.4 - */ -PURPLE_AVAILABLE_IN_2_4 -PurpleBlistNode *purple_blist_node_get_sibling_next(PurpleBlistNode *node); - -/** - * purple_blist_node_get_sibling_prev: - * @node: A node. - * - * Returns the previous sibling node of a given node. - * - * See purple_blist_node_get_parent(), purple_blist_node_get_first_child(), - * purple_blist_node_get_sibling_next(), purple_blist_node_next(). - * - * Returns: (transfer none): The sibling node. - * - * Since: 2.4 - */ -PURPLE_AVAILABLE_IN_2_4 -PurpleBlistNode *purple_blist_node_get_sibling_prev(PurpleBlistNode *node); - -/** - * purple_blist_node_get_settings: - * @node: The node to from which to get settings - * - * Returns a node's settings - * - * Returns: (transfer none): The hash table with the node's settings. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -GHashTable *purple_blist_node_get_settings(PurpleBlistNode *node); - -/** - * purple_blist_node_has_setting: - * @node: The node to check from which to check settings - * @key: The identifier of the data - * - * Checks whether a named setting exists for a node in the buddy list - * - * Returns: TRUE if a value exists, or FALSE if there is no setting - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -gboolean purple_blist_node_has_setting(PurpleBlistNode *node, const char *key); - -/** - * purple_blist_node_set_bool: - * @node: The node to associate the data with - * @key: The identifier for the data - * @value: The value to set - * - * Associates a boolean with a node in the buddy list - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -void purple_blist_node_set_bool(PurpleBlistNode *node, const char *key, gboolean value); - -/** - * purple_blist_node_get_bool: - * @node: The node to retrieve the data from - * @key: The identifier of the data - * - * Retrieves a named boolean setting from a node in the buddy list - * - * Returns: The value, or FALSE if there is no setting - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -gboolean purple_blist_node_get_bool(PurpleBlistNode *node, const char *key); - -/** - * purple_blist_node_set_int: - * @node: The node to associate the data with - * @key: The identifier for the data - * @value: The value to set - * - * Associates an integer with a node in the buddy list - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -void purple_blist_node_set_int(PurpleBlistNode *node, const char *key, int value); - -/** - * purple_blist_node_get_int: - * @node: The node to retrieve the data from - * @key: The identifier of the data - * - * Retrieves a named integer setting from a node in the buddy list - * - * Returns: The value, or 0 if there is no setting - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -int purple_blist_node_get_int(PurpleBlistNode *node, const char *key); - -/** - * purple_blist_node_set_string: - * @node: The node to associate the data with - * @key: The identifier for the data - * @value: The value to set - * - * Associates a string with a node in the buddy list - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -void purple_blist_node_set_string(PurpleBlistNode *node, const char *key, const char *value); - -/** - * purple_blist_node_get_string: - * @node: The node to retrieve the data from - * @key: The identifier of the data - * - * Retrieves a named string setting from a node in the buddy list - * - * Returns: The value, or NULL if there is no setting - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -const char *purple_blist_node_get_string(PurpleBlistNode *node, const char *key); - -/** - * purple_blist_node_remove_setting: - * @node: The node from which to remove the setting - * @key: The name of the setting - * - * Removes a named setting from a blist node - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -void purple_blist_node_remove_setting(PurpleBlistNode *node, const char *key); - -/** - * purple_blist_node_set_transient: - * @node: The node - * @transient: TRUE if the node should NOT be saved, FALSE if node should - * be saved - * - * Sets whether the node should be saved with the buddy list or not - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -void purple_blist_node_set_transient(PurpleBlistNode *node, gboolean transient); - -/** - * purple_blist_node_is_transient: - * @node: The node - * - * Gets whether the node should be saved with the buddy list or not - * - * Returns: TRUE if the node should NOT be saved, FALSE if node should be saved - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -gboolean purple_blist_node_is_transient(PurpleBlistNode *node); - -/** - * purple_blist_node_get_extended_menu: - * @n: The blist node for which to obtain the extended menu items. - * - * Emits the blist-node-extended-menu signal and returns the results. - * - * Returns: (element-type PurpleActionMenu) (transfer full): The extended menu - * items for a buddy list node, as harvested by the - * blist-node-extended-menu signal. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -GList *purple_blist_node_get_extended_menu(PurpleBlistNode *n); - -G_END_DECLS - -#endif /* PURPLE_BLIST_NODE_H */ -
--- a/libpurple/buddylist.c Sun Apr 14 01:30:58 2024 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1171 +0,0 @@ -/* - * Purple - Internet Messaging Library - * Copyright (C) Pidgin Developers <devel@pidgin.im> - * - * 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 library 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 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this library; if not, see <https://www.gnu.org/licenses/>. - */ - -#include <glib/gi18n-lib.h> - -#include "buddylist.h" -#include "debug.h" -#include "notify.h" -#include "prefs.h" -#include "purpleaccount.h" -#include "purpleaccountmanager.h" -#include "purpleprivate.h" -#include "purpleprotocol.h" -#include "purpleprotocolclient.h" -#include "purpleconversation.h" -#include "signals.h" -#include "util.h" -#include "xmlnode.h" - -/* Private data for a buddy list. */ -typedef struct { - PurpleBlistNode *root; - GHashTable *buddies; /* Every buddy in this list */ -} PurpleBuddyListPrivate; - -static GType buddy_list_type = G_TYPE_INVALID; -static PurpleBuddyList *purplebuddylist = NULL; - -G_DEFINE_TYPE_WITH_PRIVATE(PurpleBuddyList, purple_buddy_list, G_TYPE_OBJECT); - -/* - * A hash table used for efficient lookups of buddies by name. - * PurpleAccount* => GHashTable*, with the inner hash table being - * struct _purple_hbuddy => PurpleBuddy* - */ -static GHashTable *buddies_cache = NULL; - -/* - * A hash table used for efficient lookups of groups by name. - * UTF-8 collate-key => PurpleGroup*. - */ -static GHashTable *groups_cache = NULL; - -static guint save_timer = 0; -static gboolean blist_loaded = FALSE; -static gchar *localized_default_group_name = NULL; - -/********************************************************************* - * Private utility functions * - *********************************************************************/ - -static gchar * -purple_blist_fold_name(const gchar *name) -{ - gchar *res, *tmp; - - if (name == NULL) - return NULL; - - tmp = g_utf8_casefold(name, -1); - res = g_utf8_collate_key(tmp, -1); - g_free(tmp); - - return res; -} - -static PurpleBlistNode *purple_blist_get_last_sibling(PurpleBlistNode *node) -{ - PurpleBlistNode *n = node; - if (!n) - return NULL; - while (n->next) - n = n->next; - return n; -} - -PurpleBlistNode *_purple_blist_get_last_child(PurpleBlistNode *node) -{ - if (!node) - return NULL; - return purple_blist_get_last_sibling(node->child); -} - -struct _list_account_buddies { - GSList *list; - PurpleAccount *account; -}; - -struct _purple_hbuddy { - char *name; - PurpleAccount *account; - PurpleBlistNode *group; -}; - -/* This function must not use purple_normalize */ -static guint _purple_blist_hbuddy_hash(struct _purple_hbuddy *hb) -{ - return g_str_hash(hb->name) ^ g_direct_hash(hb->group) ^ g_direct_hash(hb->account); -} - -/* This function must not use purple_normalize */ -static guint _purple_blist_hbuddy_equal(struct _purple_hbuddy *hb1, struct _purple_hbuddy *hb2) -{ - return (hb1->group == hb2->group && - hb1->account == hb2->account && - purple_strequal(hb1->name, hb2->name)); -} - -static void _purple_blist_hbuddy_free_key(struct _purple_hbuddy *hb) -{ - g_free(hb->name); - g_free(hb); -} - -static void -purple_blist_buddies_cache_add_account(PurpleAccount *account) -{ - GHashTable *account_buddies = g_hash_table_new_full((GHashFunc)_purple_blist_hbuddy_hash, - (GEqualFunc)_purple_blist_hbuddy_equal, - (GDestroyNotify)_purple_blist_hbuddy_free_key, NULL); - g_hash_table_insert(buddies_cache, account, account_buddies); -} - -static void -purple_buddy_list_account_added_cb(G_GNUC_UNUSED PurpleAccountManager *manager, - PurpleAccount *account, - G_GNUC_UNUSED gpointer data) -{ - purple_blist_buddies_cache_add_account(account); -} - -static void -purple_blist_buddies_cache_remove_account(const PurpleAccount *account) -{ - g_hash_table_remove(buddies_cache, account); -} - -static void -purple_buddy_list_account_removed_cb(G_GNUC_UNUSED PurpleAccountManager *manager, - PurpleAccount *account, - G_GNUC_UNUSED gpointer data) -{ - purple_blist_buddies_cache_remove_account(account); -} - -/********************************************************************* - * Writing to disk * - *********************************************************************/ - -static void -value_to_xmlnode(gpointer key, gpointer hvalue, gpointer user_data) -{ - const char *name; - GValue *value; - PurpleXmlNode *node, *child; - char buf[21]; - - name = (const char *)key; - value = (GValue *)hvalue; - node = (PurpleXmlNode *)user_data; - - g_return_if_fail(value != NULL); - - child = purple_xmlnode_new_child(node, "setting"); - purple_xmlnode_set_attrib(child, "name", name); - - if (G_VALUE_HOLDS_INT(value)) { - purple_xmlnode_set_attrib(child, "type", "int"); - g_snprintf(buf, sizeof(buf), "%d", g_value_get_int(value)); - purple_xmlnode_insert_data(child, buf, -1); - } - else if (G_VALUE_HOLDS_STRING(value)) { - purple_xmlnode_set_attrib(child, "type", "string"); - purple_xmlnode_insert_data(child, g_value_get_string(value), -1); - } - else if (G_VALUE_HOLDS_BOOLEAN(value)) { - purple_xmlnode_set_attrib(child, "type", "bool"); - g_snprintf(buf, sizeof(buf), "%d", g_value_get_boolean(value)); - purple_xmlnode_insert_data(child, buf, -1); - } -} - -static PurpleXmlNode * -contact_to_xmlnode(PurpleMetaContact *contact) -{ - PurpleXmlNode *node; - gchar *alias; - - node = purple_xmlnode_new("contact"); - g_object_get(contact, "alias", &alias, NULL); - - if (alias != NULL) - { - purple_xmlnode_set_attrib(node, "alias", alias); - } - - /* Write contact settings */ - g_hash_table_foreach(purple_blist_node_get_settings(PURPLE_BLIST_NODE(contact)), - value_to_xmlnode, node); - - g_free(alias); - return node; -} - -static PurpleXmlNode * -group_to_xmlnode(PurpleGroup *group) -{ - PurpleXmlNode *node, *child; - PurpleBlistNode *cnode; - - node = purple_xmlnode_new("group"); - if (group != purple_blist_get_default_group()) - purple_xmlnode_set_attrib(node, "name", purple_group_get_name(group)); - - /* Write settings */ - g_hash_table_foreach(purple_blist_node_get_settings(PURPLE_BLIST_NODE(group)), - value_to_xmlnode, node); - - /* Write contacts and chats */ - for (cnode = PURPLE_BLIST_NODE(group)->child; cnode != NULL; cnode = cnode->next) - { - if (purple_blist_node_is_transient(cnode)) - continue; - if (PURPLE_IS_META_CONTACT(cnode)) - { - child = contact_to_xmlnode(PURPLE_META_CONTACT(cnode)); - purple_xmlnode_insert_child(node, child); - } - } - - return node; -} - -static PurpleXmlNode * -blist_to_xmlnode(void) { - PurpleXmlNode *node, *child, *grandchild; - PurpleBlistNode *gnode; - const gchar *localized_default; - - node = purple_xmlnode_new("purple"); - purple_xmlnode_set_attrib(node, "version", "1.0"); - - /* Write groups */ - child = purple_xmlnode_new_child(node, "blist"); - - localized_default = localized_default_group_name; - if (!purple_strequal(_("Buddies"), "Buddies")) - localized_default = _("Buddies"); - if (localized_default != NULL) { - purple_xmlnode_set_attrib(child, - "localized-default-group", localized_default); - } - - for (gnode = purple_blist_get_default_root(); gnode != NULL; - gnode = gnode->next) { - if (purple_blist_node_is_transient(gnode)) - continue; - if (PURPLE_IS_GROUP(gnode)) - { - grandchild = group_to_xmlnode(PURPLE_GROUP(gnode)); - purple_xmlnode_insert_child(child, grandchild); - } - } - - return node; -} - -static void -purple_blist_sync(void) -{ - PurpleXmlNode *node; - char *data; - - if (!blist_loaded) - { - purple_debug_error("buddylist", "Attempted to save buddy list before it " - "was read!\n"); - return; - } - - node = blist_to_xmlnode(); - data = purple_xmlnode_to_formatted_str(node, NULL); - purple_util_write_data_to_config_file("blist.xml", data, -1); - g_free(data); - purple_xmlnode_free(node); -} - -static gboolean -save_cb(G_GNUC_UNUSED gpointer data) -{ - purple_blist_sync(); - save_timer = 0; - return FALSE; -} - -static void -purple_blist_real_schedule_save(void) -{ - if (save_timer == 0) - save_timer = g_timeout_add_seconds(5, save_cb, NULL); -} - -static void -purple_blist_real_save_account(G_GNUC_UNUSED PurpleBuddyList *list, - G_GNUC_UNUSED PurpleAccount *account) -{ -#if 1 - purple_blist_real_schedule_save(); -#else - if (account != NULL) { - /* Save the buddies and privacy data for this account */ - } else { - /* Save all buddies and privacy data */ - } -#endif -} - -static void -purple_blist_real_save_node(G_GNUC_UNUSED PurpleBuddyList *list, - G_GNUC_UNUSED PurpleBlistNode *node) -{ - purple_blist_real_schedule_save(); -} - -void -purple_blist_schedule_save(void) -{ - PurpleBuddyListClass *klass = NULL; - - g_return_if_fail(PURPLE_IS_BUDDY_LIST(purplebuddylist)); - - klass = PURPLE_BUDDY_LIST_GET_CLASS(purplebuddylist); - - /* Save everything */ - if (klass && klass->save_account) { - klass->save_account(purplebuddylist, NULL); - } -} - -/********************************************************************* - * Reading from disk * - *********************************************************************/ - -static void -parse_setting(PurpleBlistNode *node, PurpleXmlNode *setting) -{ - const char *name = purple_xmlnode_get_attrib(setting, "name"); - const char *type = purple_xmlnode_get_attrib(setting, "type"); - char *value = purple_xmlnode_get_data(setting); - - if (!value) - return; - - if (!type || purple_strequal(type, "string")) - purple_blist_node_set_string(node, name, value); - else if (purple_strequal(type, "bool")) - purple_blist_node_set_bool(node, name, atoi(value)); - else if (purple_strequal(type, "int")) - purple_blist_node_set_int(node, name, atoi(value)); - - g_free(value); -} - -static void -parse_contact(PurpleGroup *group, PurpleXmlNode *cnode) -{ - PurpleMetaContact *contact = purple_meta_contact_new(); - PurpleXmlNode *x; - const char *alias; - - purple_blist_add_contact(contact, group, - _purple_blist_get_last_child((PurpleBlistNode*)group)); - - if ((alias = purple_xmlnode_get_attrib(cnode, "alias"))) { - purple_meta_contact_set_alias(contact, alias); - } - - for (x = cnode->child; x; x = x->next) { - if (x->type != PURPLE_XMLNODE_TYPE_TAG) - continue; - if (purple_strequal(x->name, "setting")) - parse_setting(PURPLE_BLIST_NODE(contact), x); - } - - /* if the contact is empty, don't keep it around. it causes problems */ - if (!PURPLE_BLIST_NODE(contact)->child) - purple_blist_remove_contact(contact); -} - -static void -parse_group(PurpleXmlNode *groupnode) -{ - const char *name = purple_xmlnode_get_attrib(groupnode, "name"); - PurpleGroup *group; - PurpleXmlNode *cnode; - - group = purple_group_new(name); - purple_blist_add_group(group, purple_blist_get_last_sibling( - purple_blist_get_default_root())); - - for (cnode = groupnode->child; cnode; cnode = cnode->next) { - if (cnode->type != PURPLE_XMLNODE_TYPE_TAG) - continue; - if (purple_strequal(cnode->name, "setting")) - parse_setting((PurpleBlistNode*)group, cnode); - else if (purple_strequal(cnode->name, "contact") || - purple_strequal(cnode->name, "person")) - parse_contact(group, cnode); - } -} - -static void -load_blist(void) -{ - PurpleXmlNode *purple, *blist; - - blist_loaded = TRUE; - - purple = purple_util_read_xml_from_config_file("blist.xml", _("buddy list")); - - if(purple == NULL) { - return; - } - - blist = purple_xmlnode_get_child(purple, "blist"); - if(blist) { - PurpleXmlNode *groupnode; - - localized_default_group_name = g_strdup( - purple_xmlnode_get_attrib(blist, - "localized-default-group")); - - for(groupnode = purple_xmlnode_get_child(blist, "group"); groupnode != NULL; - groupnode = purple_xmlnode_get_next_twin(groupnode)) { - parse_group(groupnode); - } - } else { - g_free(localized_default_group_name); - localized_default_group_name = NULL; - } - - purple_xmlnode_free(purple); -} - -/***************************************************************************** - * Public API functions * - *****************************************************************************/ - -void -purple_blist_set_ui(GType type) -{ - g_return_if_fail(g_type_is_a(type, PURPLE_TYPE_BUDDY_LIST) || - type == G_TYPE_INVALID); - buddy_list_type = type; -} - -void -purple_blist_boot(void) -{ - GListModel *manager_model = NULL; - PurpleBuddyList *gbl = g_object_new(buddy_list_type, NULL); - guint n_items = 0; - - buddies_cache = g_hash_table_new_full(g_direct_hash, g_direct_equal, - NULL, (GDestroyNotify)g_hash_table_destroy); - - groups_cache = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); - - manager_model = purple_account_manager_get_default_as_model(); - n_items = g_list_model_get_n_items(manager_model); - for(guint index = 0; index < n_items; index++) { - PurpleAccount *account = g_list_model_get_item(manager_model, index); - purple_blist_buddies_cache_add_account(account); - g_object_unref(account); - } - - purplebuddylist = gbl; - - load_blist(); -} - -PurpleBuddyList * -purple_blist_get_default(void) -{ - return purplebuddylist; -} - -PurpleBlistNode * -purple_blist_get_default_root(void) -{ - if (purplebuddylist) { - PurpleBuddyListPrivate *priv = - purple_buddy_list_get_instance_private(purplebuddylist); - return priv->root; - } - return NULL; -} - -PurpleBlistNode * -purple_blist_get_root(PurpleBuddyList *list) -{ - PurpleBuddyListPrivate *priv = NULL; - - g_return_val_if_fail(PURPLE_IS_BUDDY_LIST(list), NULL); - priv = purple_buddy_list_get_instance_private(list); - - return priv->root; -} - -static void -append_buddy(G_GNUC_UNUSED gpointer key, gpointer value, gpointer user_data) -{ - GSList **list = user_data; - *list = g_slist_prepend(*list, value); -} - -GSList * -purple_blist_get_buddies(void) -{ - PurpleBuddyListPrivate *priv; - GSList *buddies = NULL; - - if (!purplebuddylist) - return NULL; - - priv = purple_buddy_list_get_instance_private(purplebuddylist); - g_hash_table_foreach(priv->buddies, append_buddy, &buddies); - return buddies; -} - -void -purple_blist_show(void) -{ - PurpleBuddyListClass *klass = NULL; - - g_return_if_fail(PURPLE_IS_BUDDY_LIST(purplebuddylist)); - klass = PURPLE_BUDDY_LIST_GET_CLASS(purplebuddylist); - - if (klass && klass->show) { - klass->show(purplebuddylist); - } -} - -void purple_blist_set_visible(gboolean show) -{ - PurpleBuddyListClass *klass = NULL; - - g_return_if_fail(PURPLE_IS_BUDDY_LIST(purplebuddylist)); - klass = PURPLE_BUDDY_LIST_GET_CLASS(purplebuddylist); - - if (klass && klass->set_visible) { - klass->set_visible(purplebuddylist, show); - } -} - -void purple_blist_update_groups_cache(PurpleGroup *group, const char *new_name) -{ - gchar* key; - - key = purple_blist_fold_name(purple_group_get_name(group)); - g_hash_table_remove(groups_cache, key); - g_free(key); - - g_hash_table_insert(groups_cache, - purple_blist_fold_name(new_name), group); -} - -void purple_blist_add_contact(PurpleMetaContact *contact, PurpleGroup *group, PurpleBlistNode *node) -{ - PurpleBuddyListClass *klass = NULL; - PurpleGroup *g; - PurpleBlistNode *gnode, *cnode, *bnode; - PurpleCountingNode *contact_counter, *group_counter; - - g_return_if_fail(PURPLE_IS_META_CONTACT(contact)); - g_return_if_fail(PURPLE_IS_BUDDY_LIST(purplebuddylist)); - - if (PURPLE_BLIST_NODE(contact) == node) - return; - - klass = PURPLE_BUDDY_LIST_GET_CLASS(purplebuddylist); - - if (node && (PURPLE_IS_META_CONTACT(node))) - g = PURPLE_GROUP(node->parent); - else if (group) - g = group; - else - g = purple_blist_get_default_group(); - - gnode = (PurpleBlistNode*)g; - cnode = (PurpleBlistNode*)contact; - - if (cnode->parent) { - if (cnode->parent->child == cnode) - cnode->parent->child = cnode->next; - if (cnode->prev) - cnode->prev->next = cnode->next; - if (cnode->next) - cnode->next->prev = cnode->prev; - - contact_counter = PURPLE_COUNTING_NODE(contact); - group_counter = PURPLE_COUNTING_NODE(cnode->parent); - - if (purple_counting_node_get_online_count(contact_counter) > 0) - purple_counting_node_change_online_count(group_counter, -1); - if (purple_counting_node_get_current_size(contact_counter) > 0) - purple_counting_node_change_current_size(group_counter, -1); - purple_counting_node_change_total_size(group_counter, -1); - - if (klass && klass->remove) { - klass->remove(purplebuddylist, cnode); - } - - if (klass && klass->remove_node) { - klass->remove_node(purplebuddylist, cnode); - } - } - - if (node && (PURPLE_IS_META_CONTACT(node))) { - if (node->next) - node->next->prev = cnode; - cnode->next = node->next; - cnode->prev = node; - cnode->parent = node->parent; - node->next = cnode; - } else { - if (gnode->child) - gnode->child->prev = cnode; - cnode->prev = NULL; - cnode->next = gnode->child; - gnode->child = cnode; - cnode->parent = gnode; - } - - contact_counter = PURPLE_COUNTING_NODE(contact); - group_counter = PURPLE_COUNTING_NODE(g); - - if (purple_counting_node_get_online_count(contact_counter) > 0) - purple_counting_node_change_online_count(group_counter, +1); - if (purple_counting_node_get_current_size(contact_counter) > 0) - purple_counting_node_change_current_size(group_counter, +1); - purple_counting_node_change_total_size(group_counter, +1); - - if (klass && klass->save_node) { - if (cnode->child) { - klass->save_node(purplebuddylist, cnode); - } - for (bnode = cnode->child; bnode; bnode = bnode->next) { - klass->save_node(purplebuddylist, bnode); - } - } - - if (klass && klass->update) { - if (cnode->child) { - klass->update(purplebuddylist, cnode); - } - - for (bnode = cnode->child; bnode; bnode = bnode->next) { - klass->update(purplebuddylist, bnode); - } - } -} - -void purple_blist_add_group(PurpleGroup *group, PurpleBlistNode *node) -{ - PurpleBuddyListClass *klass = NULL; - PurpleBuddyListPrivate *priv = NULL; - PurpleBlistNode *gnode = (PurpleBlistNode*)group; - gchar* key; - - g_return_if_fail(PURPLE_IS_BUDDY_LIST(purplebuddylist)); - g_return_if_fail(PURPLE_IS_GROUP(group)); - - klass = PURPLE_BUDDY_LIST_GET_CLASS(purplebuddylist); - priv = purple_buddy_list_get_instance_private(purplebuddylist); - - /* if we're moving to overtop of ourselves, do nothing */ - if (gnode == node) { - if (!priv->root) { - node = NULL; - } else { - return; - } - } - - if (purple_blist_find_group(purple_group_get_name(group))) { - /* This is just being moved */ - - if (klass && klass->remove) { - klass->remove(purplebuddylist, - (PurpleBlistNode *)group); - } - - if (gnode == priv->root) { - priv->root = gnode->next; - } - if (gnode->prev) - gnode->prev->next = gnode->next; - if (gnode->next) - gnode->next->prev = gnode->prev; - } else { - key = purple_blist_fold_name(purple_group_get_name(group)); - g_hash_table_insert(groups_cache, key, group); - } - - if (node && PURPLE_IS_GROUP(node)) { - gnode->next = node->next; - gnode->prev = node; - if (node->next) - node->next->prev = gnode; - node->next = gnode; - } else { - if (priv->root) { - priv->root->prev = gnode; - } - gnode->next = priv->root; - gnode->prev = NULL; - priv->root = gnode; - } - - if (klass && klass->save_node) { - klass->save_node(purplebuddylist, gnode); - for (node = gnode->child; node; node = node->next) { - klass->save_node(purplebuddylist, node); - } - } - - if (klass && klass->update) { - klass->update(purplebuddylist, gnode); - for (node = gnode->child; node; node = node->next) { - klass->update(purplebuddylist, node); - } - } - - purple_signal_emit(purple_blist_get_handle(), "blist-node-added", - gnode); -} - -void purple_blist_remove_contact(PurpleMetaContact *contact) -{ - PurpleBuddyListClass *klass = NULL; - PurpleBlistNode *node, *gnode; - PurpleGroup *group; - - g_return_if_fail(PURPLE_IS_BUDDY_LIST(purplebuddylist)); - g_return_if_fail(PURPLE_IS_META_CONTACT(contact)); - - klass = PURPLE_BUDDY_LIST_GET_CLASS(purplebuddylist); - node = (PurpleBlistNode *)contact; - gnode = node->parent; - group = PURPLE_GROUP(gnode); - - /* Remove the node from its parent */ - if (gnode->child == node) - gnode->child = node->next; - if (node->prev) - node->prev->next = node->next; - if (node->next) - node->next->prev = node->prev; - purple_counting_node_change_total_size(PURPLE_COUNTING_NODE(group), -1); - - /* Update the UI */ - if (klass && klass->remove) { - klass->remove(purplebuddylist, node); - } - - if (klass && klass->remove_node) { - klass->remove_node(purplebuddylist, node); - } - - purple_signal_emit(purple_blist_get_handle(), "blist-node-removed", - PURPLE_BLIST_NODE(contact)); - - /* Delete the node */ - g_object_unref(contact); -} - -void purple_blist_remove_group(PurpleGroup *group) -{ - PurpleAccountManager *manager = NULL; - PurpleBuddyListClass *klass = NULL; - PurpleBuddyListPrivate *priv = NULL; - PurpleBlistNode *node; - GList *accounts = NULL; - gchar* key; - - g_return_if_fail(PURPLE_IS_BUDDY_LIST(purplebuddylist)); - g_return_if_fail(PURPLE_IS_GROUP(group)); - - if (group == purple_blist_get_default_group()) - purple_debug_warning("buddylist", "cannot remove default group"); - - klass = PURPLE_BUDDY_LIST_GET_CLASS(purplebuddylist); - priv = purple_buddy_list_get_instance_private(purplebuddylist); - node = (PurpleBlistNode *)group; - - /* Make sure the group is empty */ - if (node->child) - return; - - /* Remove the node from its parent */ - if (priv->root == node) { - priv->root = node->next; - } - if (node->prev) - node->prev->next = node->next; - if (node->next) - node->next->prev = node->prev; - - key = purple_blist_fold_name(purple_group_get_name(group)); - g_hash_table_remove(groups_cache, key); - g_free(key); - - /* Update the UI */ - if (klass && klass->remove) { - klass->remove(purplebuddylist, node); - } - - if (klass && klass->remove_node) { - klass->remove_node(purplebuddylist, node); - } - - purple_signal_emit(purple_blist_get_handle(), "blist-node-removed", - PURPLE_BLIST_NODE(group)); - - /* Remove the group from all accounts that are online */ - manager = purple_account_manager_get_default(); - accounts = purple_account_manager_get_connected(manager); - while(accounts != NULL) { - purple_account_remove_group(accounts->data, group); - - accounts = g_list_delete_link(accounts, accounts); - } - - /* Delete the node */ - g_object_unref(group); -} - -PurpleGroup *purple_blist_find_group(const char *name) -{ - gchar* key; - PurpleGroup *group; - - g_return_val_if_fail(PURPLE_IS_BUDDY_LIST(purplebuddylist), NULL); - - if (name == NULL || name[0] == '\0') - name = PURPLE_BLIST_DEFAULT_GROUP_NAME; - if (purple_strequal(name, "Buddies")) - name = PURPLE_BLIST_DEFAULT_GROUP_NAME; - if (purple_strequal(name, localized_default_group_name)) - name = PURPLE_BLIST_DEFAULT_GROUP_NAME; - - key = purple_blist_fold_name(name); - group = g_hash_table_lookup(groups_cache, key); - g_free(key); - - return group; -} - -PurpleGroup * -purple_blist_get_default_group(void) -{ - PurpleGroup *group; - - group = purple_blist_find_group(PURPLE_BLIST_DEFAULT_GROUP_NAME); - if (!group) { - group = purple_group_new(PURPLE_BLIST_DEFAULT_GROUP_NAME); - purple_blist_add_group(group, NULL); - } - - return group; -} - -void -purple_blist_walk(PurpleBlistWalkFunc group_func, - PurpleBlistWalkFunc meta_contact_func, - PurpleBlistWalkFunc contact_func, - gpointer data) -{ - PurpleBlistNode *group = NULL, *meta_contact = NULL, *contact = NULL; - - for (group = purple_blist_get_default_root(); group != NULL; - group = group->next) { - if(group_func != NULL) { - group_func(group, data); - } - - for(meta_contact = group->child; meta_contact != NULL; meta_contact = meta_contact->next) { - if(PURPLE_IS_META_CONTACT(meta_contact)) { - if(meta_contact_func != NULL) { - meta_contact_func(meta_contact, data); - } - - if(contact_func != NULL) { - for(contact = meta_contact->child; contact != NULL; contact = contact->next) { - contact_func(contact, data); - } - } - } - } - } -} - -const gchar * -purple_blist_get_default_group_name(void) { - return _("Buddies"); -} - - -void -purple_blist_request_add_buddy(PurpleAccount *account, const char *username, - const char *group, const char *alias) -{ - PurpleBuddyListClass *klass = NULL; - - g_return_if_fail(PURPLE_IS_BUDDY_LIST(purplebuddylist)); - - klass = PURPLE_BUDDY_LIST_GET_CLASS(purplebuddylist); - if (klass != NULL && klass->request_add_buddy != NULL) { - klass->request_add_buddy(purplebuddylist, account, username, - group, alias); - } -} - -void -purple_blist_request_add_group(void) -{ - PurpleBuddyListClass *klass = NULL; - - g_return_if_fail(PURPLE_IS_BUDDY_LIST(purplebuddylist)); - - klass = PURPLE_BUDDY_LIST_GET_CLASS(purplebuddylist); - if (klass != NULL && klass->request_add_group != NULL) { - klass->request_add_group(purplebuddylist); - } -} - -void -purple_blist_new_node(PurpleBuddyList *list, PurpleBlistNode *node) -{ - PurpleBuddyListClass *klass = NULL; - - g_return_if_fail(PURPLE_IS_BUDDY_LIST(list)); - - klass = PURPLE_BUDDY_LIST_GET_CLASS(list); - if (klass && klass->new_node) { - klass->new_node(list, node); - } -} - -void -purple_blist_update_node(PurpleBuddyList *list, PurpleBlistNode *node) -{ - PurpleBuddyListClass *klass = NULL; - - g_return_if_fail(PURPLE_IS_BUDDY_LIST(list)); - - klass = PURPLE_BUDDY_LIST_GET_CLASS(list); - if (klass && klass->update) { - klass->update(list, node); - } -} - -void -purple_blist_save_node(PurpleBuddyList *list, PurpleBlistNode *node) -{ - PurpleBuddyListClass *klass = NULL; - - g_return_if_fail(PURPLE_IS_BUDDY_LIST(list)); - - klass = PURPLE_BUDDY_LIST_GET_CLASS(list); - if (klass && klass->save_node) { - klass->save_node(list, node); - } -} - -void -purple_blist_save_account(PurpleBuddyList *list, PurpleAccount *account) -{ - PurpleBuddyListClass *klass = NULL; - - /* XXX: There's a chicken and egg problem with the accounts api, where - * it'll call this function before purple_blist_init is called, this will - * cause the following g_return_if_fail to fail, and muck up the logs. We - * need to find a better fix for this, but this gets rid of it for now. - */ - if(G_UNLIKELY(list == NULL && purplebuddylist == NULL)) { - return; - } - - g_return_if_fail(PURPLE_IS_BUDDY_LIST(list)); - - klass = PURPLE_BUDDY_LIST_GET_CLASS(list); - if (klass && klass->save_account) { - klass->save_account(list, account); - } -} - -const gchar * -_purple_blist_get_localized_default_group_name(void) -{ - return localized_default_group_name; -} - -void * -purple_blist_get_handle(void) -{ - static int handle; - - return &handle; -} - -void -purple_blist_init(void) -{ - void *handle = purple_blist_get_handle(); - - /* Set a default, which can't be done as a static initializer. */ - buddy_list_type = PURPLE_TYPE_BUDDY_LIST; - - purple_signal_register(handle, "blist-node-added", - purple_marshal_VOID__POINTER, G_TYPE_NONE, 1, - PURPLE_TYPE_BLIST_NODE); - - purple_signal_register(handle, "blist-node-removed", - purple_marshal_VOID__POINTER, G_TYPE_NONE, 1, - PURPLE_TYPE_BLIST_NODE); - - purple_signal_register(handle, "update-idle", purple_marshal_VOID, - G_TYPE_NONE, 0); - - purple_signal_register(handle, "blist-node-extended-menu", - purple_marshal_VOID__POINTER_POINTER, G_TYPE_NONE, 2, - PURPLE_TYPE_BLIST_NODE, - G_TYPE_POINTER); /* (GList **) */ - - purple_signal_register(handle, "blist-node-aliased", - purple_marshal_VOID__POINTER_POINTER, G_TYPE_NONE, 2, - PURPLE_TYPE_BLIST_NODE, G_TYPE_STRING); -} - -static void -blist_node_destroy(PurpleBuddyListClass *klass, PurpleBuddyList *list, - PurpleBlistNode *node) -{ - PurpleBlistNode *child, *next_child; - - child = node->child; - while (child) { - next_child = child->next; - blist_node_destroy(klass, list, child); - child = next_child; - } - - /* Allow the UI to free data */ - node->parent = NULL; - node->child = NULL; - node->next = NULL; - node->prev = NULL; - if (klass && klass->remove) { - klass->remove(list, node); - } - - g_object_unref(node); -} - -void -purple_blist_uninit(void) -{ - /* This happens if we quit before purple_set_blist is called. */ - if (purplebuddylist == NULL) - return; - - if(save_timer != 0) { - g_clear_handle_id(&save_timer, g_source_remove); - purple_blist_sync(); - } - - purple_debug_info("buddylist", "Destroying"); - - g_clear_pointer(&buddies_cache, g_hash_table_destroy); - g_clear_pointer(&groups_cache, g_hash_table_destroy); - - g_clear_object(&purplebuddylist); - - g_clear_pointer(&localized_default_group_name, g_free); - - purple_signals_disconnect_by_handle(purple_blist_get_handle()); - purple_signals_unregister_by_instance(purple_blist_get_handle()); -} - -/************************************************************************** - * GObject code - **************************************************************************/ - -/* GObject initialization function */ -static void -purple_buddy_list_init(PurpleBuddyList *blist) -{ - PurpleBuddyListPrivate *priv = NULL; - PurpleAccountManager *manager = NULL; - - priv = purple_buddy_list_get_instance_private(blist); - - priv->buddies = g_hash_table_new_full( - (GHashFunc)_purple_blist_hbuddy_hash, - (GEqualFunc)_purple_blist_hbuddy_equal, - (GDestroyNotify)_purple_blist_hbuddy_free_key, NULL); - - manager = purple_account_manager_get_default(); - g_signal_connect_object(manager, "added", - G_CALLBACK(purple_buddy_list_account_added_cb), - blist, 0); - g_signal_connect_object(manager, "removed", - G_CALLBACK(purple_buddy_list_account_removed_cb), - blist, 0); -} - -/* GObject finalize function */ -static void -purple_buddy_list_finalize(GObject *object) -{ - PurpleBuddyList *list = PURPLE_BUDDY_LIST(object); - PurpleBuddyListClass *klass = PURPLE_BUDDY_LIST_GET_CLASS(list); - PurpleBuddyListPrivate *priv = - purple_buddy_list_get_instance_private(list); - PurpleBlistNode *node, *next_node; - - g_hash_table_destroy(priv->buddies); - - node = priv->root; - while (node) { - next_node = node->next; - blist_node_destroy(klass, list, node); - node = next_node; - } - priv->root = NULL; - - G_OBJECT_CLASS(purple_buddy_list_parent_class)->finalize(object); -} - -/* Class initializer function */ -static void purple_buddy_list_class_init(PurpleBuddyListClass *klass) -{ - GObjectClass *obj_class = G_OBJECT_CLASS(klass); - - obj_class->finalize = purple_buddy_list_finalize; - - klass->save_node = purple_blist_real_save_node; - klass->remove_node = purple_blist_real_save_node; - klass->save_account = purple_blist_real_save_account; -}
--- a/libpurple/buddylist.h Sun Apr 14 01:30:58 2024 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,543 +0,0 @@ -/* - * Purple - Internet Messaging Library - * Copyright (C) Pidgin Developers <devel@pidgin.im> - * - * 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 library 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 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this library; if not, see <https://www.gnu.org/licenses/>. - */ - -#if !defined(PURPLE_GLOBAL_HEADER_INSIDE) && !defined(PURPLE_COMPILATION) -# error "only <purple.h> may be included directly" -#endif - -#ifndef PURPLE_BUDDY_LIST_H -#define PURPLE_BUDDY_LIST_H - -/* I can't believe I let ChipX86 inspire me to write good code. -Sean */ - -#include "purpleaccount.h" -#include "purpleversion.h" - -#define PURPLE_TYPE_BUDDY_LIST (purple_buddy_list_get_type()) -typedef struct _PurpleBuddyList PurpleBuddyList; - -/** - * PURPLE_BLIST_DEFAULT_GROUP_NAME: - * - * A helper to get the default group name for the buddy list. - */ -#define PURPLE_BLIST_DEFAULT_GROUP_NAME (purple_blist_get_default_group_name()) - -#include "contact.h" - -/** - * _purple_blist_get_localized_default_group_name: - * - * Returns the name of default group for previously used non-English - * localization. It's used for merging default group, in cases when roster - * contains localized name. - * - * Please note, prpls shouldn't save default group name depending on current - * locale. So, this function is mostly for libpurple2 compatibility. And for - * improperly written prpls. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -const gchar * -_purple_blist_get_localized_default_group_name(void); - -/** - * PurpleBlistWalkFunc: - * @node: The node that's being iterated - * @data: User supplied data. - * - * A callback function for purple_blist_walk. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_TYPE_IN_3_0 -typedef void (*PurpleBlistWalkFunc)(PurpleBlistNode *node, gpointer data); - -/**************************************************************************/ -/* Data Structures */ -/**************************************************************************/ -/** - * PurpleBuddyList: - * - * The Buddy List - * - * Since: 2.0 - */ -/** - * PurpleBuddyListClass: - * @new_node: Sets UI-specific data on a node. - * @show: The core will call this when it's finished doing its core - * stuff. - * @update: This will update a node in the buddy list. - * @remove: This removes a node from the list - * @set_visible: Hides or unhides the buddy list. - * @request_add_buddy: Called when information is needed to add a buddy to the - * buddy list. See purple_blist_request_add_buddy(). - * @request_add_group: Called when information is needed to add a group to the - * buddy list. See purple_blist_request_add_group(). - * @save_node: This is called when a node has been modified and should be - * saved. - * <sbr/>Implementation of this method is - * <emphasis>OPTIONAL</emphasis>. If not implemented, it will be - * set to a fallback function that saves data to - * <filename>blist.xml</filename> like in previous libpurple - * versions. - * <sbr/>@node: The node which has been modified. - * @remove_node: Called when a node is about to be removed from the buddy list. - * The method should update the relevant data structures to - * remove this node (for example, removing a buddy from the - * group this node is in). - * <sbr/>Implementation of this method is - * <emphasis>OPTIONAL</emphasis>. If not implemented, it will be - * set to a fallback function that saves data to - * <filename>blist.xml</filename> like in previous libpurple - * versions. - * <sbr/>@node: The node which has been modified. - * @save_account: Called to save all the data for an account. If the UI sets - * this, the callback must save the privacy and buddy list data - * for an account. If the account is %NULL, save the data for all - * accounts. - * <sbr/>Implementation of this method is - * <emphasis>OPTIONAL</emphasis>. If not implemented, it will be - * set to a fallback function that saves data to - * <filename>blist.xml</filename> like in previous - * libpurple versions. - * <sbr/>@account: The account whose data to save. If %NULL, - * save all data for all accounts. - * - * Buddy list operations. - * - * Any UI representing a buddy list must derive a filled-out - * @PurpleBuddyListClass and set the GType using purple_blist_set_ui() before a - * buddy list is created. - */ -struct _PurpleBuddyListClass { - /*< private >*/ - GObjectClass gparent_class; - - /*< public >*/ - void (*new_node)(PurpleBuddyList *list, PurpleBlistNode *node); - void (*show)(PurpleBuddyList *list); - void (*update)(PurpleBuddyList *list, PurpleBlistNode *node); - void (*remove)(PurpleBuddyList *list, PurpleBlistNode *node); - void (*set_visible)(PurpleBuddyList *list, gboolean show); - - void (*request_add_buddy)(PurpleBuddyList *list, PurpleAccount *account, - const char *username, const char *group, - const char *alias); - - void (*request_add_group)(PurpleBuddyList *list); - - void (*save_node)(PurpleBuddyList *list, PurpleBlistNode *node); - void (*remove_node)(PurpleBuddyList *list, PurpleBlistNode *node); - - void (*save_account)(PurpleBuddyList *list, PurpleAccount *account); - - /*< private >*/ - gpointer reserved[4]; -}; - -G_BEGIN_DECLS - -/**************************************************************************/ -/* Buddy List API */ -/**************************************************************************/ - -/** - * purple_buddy_list_get_type: - * - * Returns: The #GType for the #PurpleBuddyList object. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -G_DECLARE_DERIVABLE_TYPE(PurpleBuddyList, purple_buddy_list, PURPLE, BUDDY_LIST, - GObject) - -/** - * purple_blist_get_default: - * - * Returns the default buddy list. - * - * Returns: (transfer none): The default buddy list. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -PurpleBuddyList *purple_blist_get_default(void); - -/** - * purple_blist_get_default_root: - * - * Returns the root node of the default buddy list. - * - * Returns: (transfer none): The root node. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -PurpleBlistNode *purple_blist_get_default_root(void); - -/** - * purple_blist_get_root: - * @list: The buddy list to query. - * - * Returns the root node of the specified buddy list. - * - * Returns: (transfer none): The root node. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -PurpleBlistNode *purple_blist_get_root(PurpleBuddyList *list); - -/** - * purple_blist_get_buddies: - * - * Returns a list of every buddy in the list. Use of this function is - * discouraged if you do not actually need every buddy in the list. Use - * purple_blist_find_buddies instead. - * - * See purple_blist_find_buddies(). - * - * Returns: (element-type PurpleBlistNode) (transfer container): A list of every - * buddy in the list. - * - * Since: 2.6 - */ -PURPLE_AVAILABLE_IN_2_6 -GSList *purple_blist_get_buddies(void); - -/** - * purple_blist_show: - * - * Shows the buddy list, creating a new one if necessary. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -void purple_blist_show(void); - -/** - * purple_blist_set_visible: - * @show: Whether or not to show the buddy list - * - * Hides or unhides the buddy list. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -void purple_blist_set_visible(gboolean show); - -/** - * purple_blist_update_groups_cache: - * @group: The group whose name will be changed. - * @new_name: The new name of the group. - * - * Updates the groups hash table when a group has been renamed. This only - * updates the cache, the caller is responsible for the actual renaming of - * the group after updating the cache. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -void purple_blist_update_groups_cache(PurpleGroup *group, const char *new_name); - -/** - * purple_blist_add_group: - * @group: The group - * @node: The insertion point - * - * Adds a new group to the buddy list. - * - * The new group will be inserted after insert or prepended to the list if - * node is NULL. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -void purple_blist_add_group(PurpleGroup *group, PurpleBlistNode *node); - -/** - * purple_blist_add_contact: - * @contact: The contact - * @group: The group to add the contact to - * @node: The insertion point - * - * Adds a new contact to the buddy list. - * - * The new contact will be inserted after insert or prepended to the list if - * node is NULL. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -void purple_blist_add_contact(PurpleMetaContact *contact, PurpleGroup *group, PurpleBlistNode *node); - -/** - * purple_blist_remove_contact: - * @contact: The contact to be removed - * - * Removes a contact, and any buddies it contains, and frees the memory - * allocated to it. This calls purple_blist_remove_buddy and therefore - * doesn't remove the buddies from the server list. - * - * See purple_blist_remove_buddy(). - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -void purple_blist_remove_contact(PurpleMetaContact *contact); - -/** - * purple_blist_remove_group: - * @group: The group to be removed - * - * Removes a group from the buddy list and frees the memory allocated to it and to - * its children - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -void purple_blist_remove_group(PurpleGroup *group); - -/** - * purple_blist_find_group: - * @name: The group's name - * - * Finds a group by name - * - * Returns: (transfer none): The group or %NULL if the group does not exist. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -PurpleGroup *purple_blist_find_group(const char *name); - -/** - * purple_blist_get_default_group: - * - * Finds or creates default group. - * - * Returns: (transfer none): The default group. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -PurpleGroup *purple_blist_get_default_group(void); - -/** - * purple_blist_walk: - * @group_func: (scope call): The callback for groups - * @meta_contact_func: (scope call): The callback for meta-contacts - * @contact_func: (scope call): The callback for contacts - * @data: User supplied data. - * - * Walks the buddy list and calls the appropriate function for each node. If - * a callback function is omitted iteration will continue without it. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -void purple_blist_walk(PurpleBlistWalkFunc group_func, PurpleBlistWalkFunc meta_contact_func, PurpleBlistWalkFunc contact_func, gpointer data); - -/** - * purple_blist_get_default_group_name: - * - * Gets the default group name for the buddy list. - * - * Returns: The name of the default group. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -const gchar *purple_blist_get_default_group_name(void); - -/****************************************************************************************/ -/* Buddy list file management API */ -/****************************************************************************************/ - -/** - * purple_blist_schedule_save: - * - * Schedule a save of the <filename>blist.xml</filename> file. This is used by - * the account API whenever the privacy settings are changed. If you make a - * change to <filename>blist.xml</filename> using one of the functions in the - * buddy list API, then the buddy list is saved automatically, so you should not - * need to call this. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -void purple_blist_schedule_save(void); - -/** - * purple_blist_request_add_buddy: - * @account: The account the buddy is added to. - * @username: The username of the buddy. - * @group: The name of the group to place the buddy in. - * @alias: The optional alias for the buddy. - * - * Requests from the user information needed to add a buddy to the - * buddy list. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -void purple_blist_request_add_buddy(PurpleAccount *account, const char *username, - const char *group, const char *alias); - -/** - * purple_blist_request_add_group: - * - * Requests from the user information needed to add a group to the - * buddy list. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -void purple_blist_request_add_group(void); - -/** - * purple_blist_new_node: - * @list: The list that contains the node. - * @node: The node to initialize. - * - * Sets UI-specific data on a node. - * - * This should usually only be run when initializing a @PurpleBlistNode - * instance. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -void purple_blist_new_node(PurpleBuddyList *list, PurpleBlistNode *node); - -/** - * purple_blist_update_node: - * @list: The buddy list to modify. - * @node: The node to update. - * - * Update a node in the buddy list in the UI. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -void purple_blist_update_node(PurpleBuddyList *list, PurpleBlistNode *node); - -/** - * purple_blist_save_node: - * @list: The list that contains the node. - * @node: The node which has been modified. - * - * This is called when a node has been modified and should be saved by the UI. - * - * If the UI does not implement a more specific method, it will be set to save - * data to <filename>blist.xml</filename> like in previous libpurple versions. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -void purple_blist_save_node(PurpleBuddyList *list, PurpleBlistNode *node); - -/** - * purple_blist_save_account: - * @list: The list that contains the account. - * @account: The account whose data to save. If %NULL, save all data for all - * accounts. - * - * Save all the data for an account. - * - * If the UI does not set a more specific method, it will be set to save data - * to <filename>blist.xml</filename> like in previous libpurple versions. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -void purple_blist_save_account(PurpleBuddyList *list, PurpleAccount *account); - -/**************************************************************************/ -/* Buddy List Subsystem */ -/**************************************************************************/ - -/** - * purple_blist_set_ui: - * @type: The @GType of a derived UI implementation of @PurpleBuddyList. - * - * Set the UI implementation of the buddy list. - * - * This must be called before the buddy list is created or you will get the - * default libpurple implementation. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -void purple_blist_set_ui(GType type); - -/** - * purple_blist_get_handle: - * - * Returns the handle for the buddy list subsystem. - * - * Returns: The buddy list subsystem handle. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -void *purple_blist_get_handle(void); - -/** - * purple_blist_init: - * - * Initializes the buddy list subsystem. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -void purple_blist_init(void); - -/** - * purple_blist_boot: - * - * Loads the buddy list. - * - * You shouldn't call this. purple_core_init() will do it for you. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -void purple_blist_boot(void); - -/** - * purple_blist_uninit: - * - * Uninitializes the buddy list subsystem. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -void purple_blist_uninit(void); - -G_END_DECLS - -#endif /* PURPLE_BUDDY_LIST_H */
--- a/libpurple/connection.c Sun Apr 14 01:30:58 2024 -0500 +++ b/libpurple/connection.c Sun Apr 14 01:48:40 2024 -0500 @@ -22,7 +22,6 @@ #include <glib/gi18n-lib.h> -#include "buddylist.h" #include "connection.h" #include "debug.h" #include "notify.h"
--- a/libpurple/contact.c Sun Apr 14 01:30:58 2024 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,201 +0,0 @@ -/* - * Purple - Internet Messaging Library - * Copyright (C) Pidgin Developers <devel@pidgin.im> - * - * 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 library 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 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this library; if not, see <https://www.gnu.org/licenses/>. - */ - -#include "contact.h" - -#include "buddylist.h" -#include "prefs.h" -#include "purpleconversationmanager.h" -#include "purpleprivate.h" -#include "signals.h" -#include "util.h" - -typedef struct _PurpleMetaContactPrivate PurpleMetaContactPrivate; - -struct _PurpleMetaContactPrivate { - char *alias; /* The user-set alias of the contact */ -}; - -enum -{ - PROP_0, - PROP_ALIAS, - N_PROPERTIES, -}; - -/****************************************************************************** - * Globals - *****************************************************************************/ -static GParamSpec *properties[N_PROPERTIES] = {NULL, }; - -G_DEFINE_TYPE_WITH_PRIVATE(PurpleMetaContact, purple_meta_contact, - PURPLE_TYPE_COUNTING_NODE); - -/****************************************************************************** - * API - *****************************************************************************/ -void -purple_meta_contact_set_alias(PurpleMetaContact *contact, const char *alias) -{ - PurpleMetaContactPrivate *priv = NULL; - char *old_alias; - char *new_alias = NULL; - - g_return_if_fail(PURPLE_IS_META_CONTACT(contact)); - priv = purple_meta_contact_get_instance_private(contact); - - 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(contact), properties[PROP_ALIAS]); - - purple_blist_save_node(purple_blist_get_default(), - PURPLE_BLIST_NODE(contact)); - purple_blist_update_node(purple_blist_get_default(), - PURPLE_BLIST_NODE(contact)); - - purple_signal_emit(purple_blist_get_handle(), "blist-node-aliased", - contact, old_alias); - g_free(old_alias); -} - -const char *purple_meta_contact_get_alias(PurpleMetaContact* contact) -{ - PurpleMetaContactPrivate *priv = NULL; - - g_return_val_if_fail(PURPLE_IS_META_CONTACT(contact), NULL); - - priv = purple_meta_contact_get_instance_private(contact); - if (priv->alias) - return priv->alias; - - return NULL; -} - -/************************************************************************** - * GObject Stuff - **************************************************************************/ -/* Set method for GObject properties */ -static void -purple_meta_contact_set_property(GObject *obj, guint param_id, const GValue *value, - GParamSpec *pspec) -{ - PurpleMetaContact *contact = PURPLE_META_CONTACT(obj); - - switch (param_id) { - case PROP_ALIAS: - purple_meta_contact_set_alias(contact, g_value_get_string(value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); - break; - } -} - -/* Get method for GObject properties */ -static void -purple_meta_contact_get_property(GObject *obj, guint param_id, GValue *value, - GParamSpec *pspec) -{ - PurpleMetaContact *contact = PURPLE_META_CONTACT(obj); - PurpleMetaContactPrivate *priv = - purple_meta_contact_get_instance_private(contact); - - switch (param_id) { - case PROP_ALIAS: - g_value_set_string(value, priv->alias); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); - break; - } -} - -/* GObject initialization function */ -static void -purple_meta_contact_init(PurpleMetaContact *contact) -{ - purple_blist_new_node(purple_blist_get_default(), - PURPLE_BLIST_NODE(contact)); -} - -/* GObject finalize function */ -static void -purple_meta_contact_finalize(GObject *object) -{ - PurpleMetaContactPrivate *priv = purple_meta_contact_get_instance_private( - PURPLE_META_CONTACT(object)); - - g_free(priv->alias); - - G_OBJECT_CLASS(purple_meta_contact_parent_class)->finalize(object); -} - -/* Class initializer function */ -static void purple_meta_contact_class_init(PurpleMetaContactClass *klass) -{ - GObjectClass *obj_class = G_OBJECT_CLASS(klass); - - obj_class->finalize = purple_meta_contact_finalize; - - /* Setup properties */ - obj_class->get_property = purple_meta_contact_get_property; - obj_class->set_property = purple_meta_contact_set_property; - - /** - * PurpleMetaContact:alias: - * - * The alias for the contact. - * - * Since: 3.0 - */ - properties[PROP_ALIAS] = g_param_spec_string( - "alias", - "Alias", - "The alias for the contact.", - NULL, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS - ); - - g_object_class_install_properties(obj_class, N_PROPERTIES, properties); -} - -PurpleMetaContact * -purple_meta_contact_new(void) -{ - return g_object_new(PURPLE_TYPE_META_CONTACT, NULL); -} -
--- a/libpurple/contact.h Sun Apr 14 01:30:58 2024 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,123 +0,0 @@ -/* - * Purple - Internet Messaging Library - * Copyright (C) Pidgin Developers <devel@pidgin.im> - * - * 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 library 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 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this library; if not, see <https://www.gnu.org/licenses/>. - */ - -#if !defined(PURPLE_GLOBAL_HEADER_INSIDE) && !defined(PURPLE_COMPILATION) -# error "only <purple.h> may be included directly" -#endif - -#ifndef PURPLE_META_CONTACT_H -#define PURPLE_META_CONTACT_H - -#define PURPLE_TYPE_META_CONTACT (purple_meta_contact_get_type()) -#define PURPLE_META_CONTACT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_META_CONTACT, PurpleMetaContact)) -#define PURPLE_META_CONTACT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_META_CONTACT, PurpleMetaContactClass)) -#define PURPLE_IS_META_CONTACT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_META_CONTACT)) -#define PURPLE_IS_META_CONTACT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_META_CONTACT)) -#define PURPLE_META_CONTACT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_META_CONTACT, PurpleMetaContactClass)) - -typedef struct _PurpleMetaContact PurpleMetaContact; -typedef struct _PurpleMetaContactClass PurpleMetaContactClass; - -#include "countingnode.h" -#include "group.h" -#include "purpleaccount.h" -#include "purpleversion.h" - -/** - * PurpleMetaContact: - * - * A contact on the buddy list. - * - * A contact is a counting node, which means it keeps track of the counts of - * the buddies under this contact. - */ -struct _PurpleMetaContact { - PurpleCountingNode counting; -}; - -struct _PurpleMetaContactClass { - PurpleCountingNodeClass counting_class; - - /*< private >*/ - void (*_purple_reserved1)(void); - void (*_purple_reserved2)(void); - void (*_purple_reserved3)(void); - void (*_purple_reserved4)(void); -}; - -G_BEGIN_DECLS - -/**************************************************************************/ -/* Contact API */ -/**************************************************************************/ - -/** - * purple_meta_contact_get_type: - * - * Returns: The #GType for the #PurpleMetaContact object. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -GType purple_meta_contact_get_type(void); - -/** - * purple_meta_contact_new: - * - * Creates a new contact - * - * Returns: A new contact struct - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -PurpleMetaContact *purple_meta_contact_new(void); - -/** - * purple_meta_contact_set_alias: - * @contact: The contact - * @alias: The alias - * - * Sets the alias for a contact. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -void purple_meta_contact_set_alias(PurpleMetaContact *contact, const char *alias); - -/** - * purple_meta_contact_get_alias: - * @contact: The contact - * - * Gets the alias for a contact. - * - * Returns: The alias, or NULL if it is not set. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -const char *purple_meta_contact_get_alias(PurpleMetaContact *contact); - -G_END_DECLS - -#endif /* PURPLE_META_CONTACT_H */ -
--- a/libpurple/core.c Sun Apr 14 01:30:58 2024 -0500 +++ b/libpurple/core.c Sun Apr 14 01:48:40 2024 -0500 @@ -26,7 +26,6 @@ #define G_SETTINGS_ENABLE_BACKEND #include <gio/gsettingsbackend.h> -#include "buddylist.h" #include "cmds.h" #include "connection.h" #include "conversations.h" @@ -158,7 +157,6 @@ purple_conversations_init(); purple_conversation_manager_startup(); purple_whiteboard_manager_startup(); - purple_blist_init(); /* Setup the history adapter. */ adapter = purple_ui_get_history_adapter(ui); @@ -196,9 +194,6 @@ return FALSE; } - /* Load the buddy list after UI init */ - purple_blist_boot(); - purple_signal_emit(purple_get_core(), "core-initialized"); return TRUE; @@ -229,7 +224,6 @@ purple_whiteboard_manager_shutdown(); purple_conversation_manager_shutdown(); purple_conversations_uninit(); - purple_blist_uninit(); purple_notify_uninit(); purple_connections_uninit(); purple_presence_manager_shutdown();
--- a/libpurple/countingnode.c Sun Apr 14 01:30:58 2024 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,270 +0,0 @@ -/* - * Purple - Internet Messaging Library - * Copyright (C) Pidgin Developers <devel@pidgin.im> - * - * 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 library 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 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this library; if not, see <https://www.gnu.org/licenses/>. - */ - -#include "countingnode.h" - -typedef struct _PurpleCountingNodePrivate PurpleCountingNodePrivate; - -/* Private data of a counting node */ -struct _PurpleCountingNodePrivate { - int totalsize; /* The number of children under this node */ - int currentsize; /* The number of children under this node - corresponding to online accounts */ - int onlinecount; /* The number of children under this contact who are - currently online */ -}; - -/* Counting node property enums */ -enum -{ - PROP_0, - PROP_TOTAL_SIZE, - PROP_CURRENT_SIZE, - PROP_ONLINE_COUNT, - N_PROPERTIES, -}; - -static GParamSpec *properties[N_PROPERTIES] = {NULL, }; - -G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(PurpleCountingNode, purple_counting_node, - PURPLE_TYPE_BLIST_NODE); - -/****************************************************************************** - * API - *****************************************************************************/ -int -purple_counting_node_get_total_size(PurpleCountingNode *counter) -{ - PurpleCountingNodePrivate *priv = NULL; - - g_return_val_if_fail(PURPLE_IS_COUNTING_NODE(counter), -1); - - priv = purple_counting_node_get_instance_private(counter); - return priv->totalsize; -} - -int -purple_counting_node_get_current_size(PurpleCountingNode *counter) -{ - PurpleCountingNodePrivate *priv = NULL; - - g_return_val_if_fail(PURPLE_IS_COUNTING_NODE(counter), -1); - - priv = purple_counting_node_get_instance_private(counter); - return priv->currentsize; -} - -int -purple_counting_node_get_online_count(PurpleCountingNode *counter) -{ - PurpleCountingNodePrivate *priv = NULL; - - g_return_val_if_fail(PURPLE_IS_COUNTING_NODE(counter), -1); - - priv = purple_counting_node_get_instance_private(counter); - return priv->onlinecount; -} - -void -purple_counting_node_change_total_size(PurpleCountingNode *counter, int delta) -{ - PurpleCountingNodePrivate *priv = NULL; - - g_return_if_fail(PURPLE_IS_COUNTING_NODE(counter)); - - priv = purple_counting_node_get_instance_private(counter); - purple_counting_node_set_total_size(counter, priv->totalsize + delta); -} - -void -purple_counting_node_change_current_size(PurpleCountingNode *counter, int delta) -{ - PurpleCountingNodePrivate *priv = NULL; - - g_return_if_fail(PURPLE_IS_COUNTING_NODE(counter)); - - priv = purple_counting_node_get_instance_private(counter); - purple_counting_node_set_current_size(counter, priv->currentsize + delta); -} - -void -purple_counting_node_change_online_count(PurpleCountingNode *counter, int delta) -{ - PurpleCountingNodePrivate *priv = NULL; - - g_return_if_fail(PURPLE_IS_COUNTING_NODE(counter)); - - priv = purple_counting_node_get_instance_private(counter); - purple_counting_node_set_online_count(counter, priv->onlinecount + delta); -} - -void -purple_counting_node_set_total_size(PurpleCountingNode *counter, int totalsize) -{ - PurpleCountingNodePrivate *priv = NULL; - - g_return_if_fail(PURPLE_IS_COUNTING_NODE(counter)); - - priv = purple_counting_node_get_instance_private(counter); - priv->totalsize = totalsize; - - g_object_notify_by_pspec(G_OBJECT(counter), properties[PROP_TOTAL_SIZE]); -} - -void -purple_counting_node_set_current_size(PurpleCountingNode *counter, int currentsize) -{ - PurpleCountingNodePrivate *priv = NULL; - - g_return_if_fail(PURPLE_IS_COUNTING_NODE(counter)); - - priv = purple_counting_node_get_instance_private(counter); - priv->currentsize = currentsize; - - g_object_notify_by_pspec(G_OBJECT(counter), properties[PROP_CURRENT_SIZE]); -} - -void -purple_counting_node_set_online_count(PurpleCountingNode *counter, int onlinecount) -{ - PurpleCountingNodePrivate *priv = NULL; - - g_return_if_fail(PURPLE_IS_COUNTING_NODE(counter)); - - priv = purple_counting_node_get_instance_private(counter); - priv->onlinecount = onlinecount; - - g_object_notify_by_pspec(G_OBJECT(counter), properties[PROP_ONLINE_COUNT]); -} - -/************************************************************************** - * GObject Stuff - **************************************************************************/ -/* Set method for GObject properties */ -static void -purple_counting_node_set_property(GObject *obj, guint param_id, const GValue *value, - GParamSpec *pspec) -{ - PurpleCountingNode *node = PURPLE_COUNTING_NODE(obj); - - switch (param_id) { - case PROP_TOTAL_SIZE: - purple_counting_node_set_total_size(node, g_value_get_int(value)); - break; - case PROP_CURRENT_SIZE: - purple_counting_node_set_current_size(node, g_value_get_int(value)); - break; - case PROP_ONLINE_COUNT: - purple_counting_node_set_online_count(node, g_value_get_int(value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); - break; - } -} - -/* Get method for GObject properties */ -static void -purple_counting_node_get_property(GObject *obj, guint param_id, GValue *value, - GParamSpec *pspec) -{ - PurpleCountingNode *node = PURPLE_COUNTING_NODE(obj); - - switch (param_id) { - case PROP_TOTAL_SIZE: - g_value_set_int(value, purple_counting_node_get_total_size(node)); - break; - case PROP_CURRENT_SIZE: - g_value_set_int(value, purple_counting_node_get_current_size(node)); - break; - case PROP_ONLINE_COUNT: - g_value_set_int(value, purple_counting_node_get_online_count(node)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); - break; - } -} - -static void -purple_counting_node_init(G_GNUC_UNUSED PurpleCountingNode *counter) -{ -} - -/* Class initializer function */ -static void -purple_counting_node_class_init(PurpleCountingNodeClass *klass) -{ - GObjectClass *obj_class = G_OBJECT_CLASS(klass); - - /* Setup properties */ - obj_class->get_property = purple_counting_node_get_property; - obj_class->set_property = purple_counting_node_set_property; - - /** - * PurpleCountingNode:total-size: - * - * The number of children under this node. - * - * Since: 3.0 - */ - properties[PROP_TOTAL_SIZE] = g_param_spec_int( - "total-size", - "Total size", - "The number of children under this node.", - G_MININT, G_MAXINT, 0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS - ); - - /** - * PurpleCountingNode:current-size: - * - * The number of children with online accounts. - * - * Since: 3.0 - */ - properties[PROP_CURRENT_SIZE] = g_param_spec_int( - "current-size", - "Current size", - "The number of children with online accounts.", - G_MININT, G_MAXINT, 0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS - ); - - /** - * PurpleCountingNode:online-count: - * - * The number of children that are online. - * - * Since: 3.0 - */ - properties[PROP_ONLINE_COUNT] = g_param_spec_int( - "online-count", - "Online count", - "The number of children that are online.", - G_MININT, G_MAXINT, 0, - G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS - ); - - g_object_class_install_properties(obj_class, N_PROPERTIES, properties); -} -
--- a/libpurple/countingnode.h Sun Apr 14 01:30:58 2024 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,212 +0,0 @@ -/* - * Purple - Internet Messaging Library - * Copyright (C) Pidgin Developers <devel@pidgin.im> - * - * 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 library 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 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this library; if not, see <https://www.gnu.org/licenses/>. - */ - -#if !defined(PURPLE_GLOBAL_HEADER_INSIDE) && !defined(PURPLE_COMPILATION) -# error "only <purple.h> may be included directly" -#endif - -#ifndef PURPLE_COUNTING_NODE_H -#define PURPLE_COUNTING_NODE_H - -#include <glib.h> -#include <glib-object.h> - -#include "blistnode.h" -#include "purpleversion.h" - -#define PURPLE_TYPE_COUNTING_NODE (purple_counting_node_get_type()) -#define PURPLE_COUNTING_NODE(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_COUNTING_NODE, PurpleCountingNode)) -#define PURPLE_COUNTING_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_COUNTING_NODE, PurpleCountingNodeClass)) -#define PURPLE_IS_COUNTING_NODE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_COUNTING_NODE)) -#define PURPLE_IS_COUNTING_NODE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_COUNTING_NODE)) -#define PURPLE_COUNTING_NODE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_COUNTING_NODE, PurpleCountingNodeClass)) - -PURPLE_AVAILABLE_TYPE_IN_3_0 -typedef struct _PurpleCountingNode PurpleCountingNode; -typedef struct _PurpleCountingNodeClass PurpleCountingNodeClass; - -/** - * PurpleCountingNode: - * - * A node that keeps count of the number of children that it has. It tracks the - * total number of children, the number of children corresponding to online - * accounts, and the number of online children. - * - * The two types of counting nodes are: - * <orderedlist> - * <listitem>Contact: Keeps track of the number of buddies under it.</listitem> - * <listitem>Group: Keeps track of the number of chats and contacts under it. - * </listitem> - * </orderedlist> - * - * See #PurpleContact, #PurpleGroup - * - * Since: 3.0 - */ -struct _PurpleCountingNode { - PurpleBlistNode node; -}; - -struct _PurpleCountingNodeClass { - PurpleBlistNodeClass node_class; - - /*< private >*/ - void (*_purple_reserved1)(void); - void (*_purple_reserved2)(void); - void (*_purple_reserved3)(void); - void (*_purple_reserved4)(void); -}; - -G_BEGIN_DECLS - -/** - * purple_counting_node_get_type: - * - * Returns: The #GType for the #PurpleCountingNode object. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -GType purple_counting_node_get_type(void); - -/** - * purple_counting_node_get_total_size: - * @counter: The node - * - * Returns the total number of children of the counting node. - * - * Returns: The total number of children of the node - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -int purple_counting_node_get_total_size(PurpleCountingNode *counter); - -/** - * purple_counting_node_get_current_size: - * @counter: The node - * - * Returns the number of children of the counting node corresponding to online - * accounts. - * - * Returns: The number of children with online accounts - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -int purple_counting_node_get_current_size(PurpleCountingNode *counter); - -/** - * purple_counting_node_get_online_count: - * @counter: The node - * - * Returns the number of children of the counting node that are online. - * - * Returns: The total number of online children - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -int purple_counting_node_get_online_count(PurpleCountingNode *counter); - -/** - * purple_counting_node_change_total_size: - * @counter: The node - * @delta: The value to change the total size by - * - * Changes the total number of children of the counting node. The provided - * delta value is added to the count, or if it's negative, the count is - * decreased. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -void purple_counting_node_change_total_size(PurpleCountingNode *counter, int delta); - -/** - * purple_counting_node_change_current_size: - * @counter: The node - * @delta: The value to change the current size by - * - * Changes the number of children of the counting node corresponding to online - * accounts. The provided delta value is added to the count, or if it's - * negative, the count is decreased. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -void purple_counting_node_change_current_size(PurpleCountingNode *counter, int delta); - -/** - * purple_counting_node_change_online_count: - * @counter: The node - * @delta: The value to change the online count by - * - * Changes the number of children of the counting node that are online. The - * provided delta value is added to the count, or if it's negative, the count is - * decreased. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -void purple_counting_node_change_online_count(PurpleCountingNode *counter, int delta); - -/** - * purple_counting_node_set_total_size: - * @counter: The node - * @totalsize: The total number of children of the node - * - * Sets the total number of children of the counting node. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -void purple_counting_node_set_total_size(PurpleCountingNode *counter, int totalsize); - -/** - * purple_counting_node_set_current_size: - * @counter: The node - * @currentsize: The number of children with online accounts - * - * Sets the number of children of the counting node corresponding to online - * accounts. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -void purple_counting_node_set_current_size(PurpleCountingNode *counter, int currentsize); - -/** - * purple_counting_node_set_online_count: - * @counter: The node - * @onlinecount: The total number of online children - * - * Sets the number of children of the counting node that are online. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -void purple_counting_node_set_online_count(PurpleCountingNode *counter, int onlinecount); - -G_END_DECLS - -#endif /* PURPLE_COUNTING_NODE_H */
--- a/libpurple/group.c Sun Apr 14 01:30:58 2024 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,325 +0,0 @@ -/* - * Purple - Internet Messaging Library - * Copyright (C) Pidgin Developers <devel@pidgin.im> - * - * 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 library 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 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this library; if not, see <https://www.gnu.org/licenses/>. - */ - -#include "group.h" - -#include "buddylist.h" -#include "contact.h" -#include "debug.h" -#include "purpleprivate.h" -#include "purpleprotocolserver.h" -#include "util.h" - -typedef struct _PurpleGroupPrivate PurpleGroupPrivate; - -/****************************************************************************** - * Private Data - *****************************************************************************/ -struct _PurpleGroupPrivate { - char *name; /* The name of this group. */ - gboolean is_constructed; /* Indicates if the group has finished being - constructed. */ -}; - -/* Group property enums */ -enum -{ - PROP_0, - PROP_NAME, - N_PROPERTIES, -}; - -/****************************************************************************** - * Globals - *****************************************************************************/ -static GParamSpec *properties[N_PROPERTIES] = {NULL, }; - -G_DEFINE_TYPE_WITH_PRIVATE(PurpleGroup, purple_group, - PURPLE_TYPE_COUNTING_NODE); - -/****************************************************************************** - * Group API - *****************************************************************************/ -GSList * -purple_group_get_accounts(G_GNUC_UNUSED PurpleGroup *group) { - return NULL; -} - -gboolean -purple_group_on_account(G_GNUC_UNUSED PurpleGroup *g, - G_GNUC_UNUSED PurpleAccount *account) -{ - return FALSE; -} - -/* - * TODO: If merging, prompt the user if they want to merge. - */ -void purple_group_set_name(PurpleGroup *source, const char *name) { - PurpleGroupPrivate *priv = NULL; - PurpleGroup *dest; - gchar *old_name; - gchar *new_name; - GList *moved_buddies = NULL; - GSList *accts; - - g_return_if_fail(PURPLE_IS_GROUP(source)); - g_return_if_fail(name != NULL); - - priv = purple_group_get_instance_private(source); - - new_name = purple_utf8_strip_unprintables(name); - - if (*new_name == '\0' || purple_strequal(new_name, priv->name)) { - g_free(new_name); - return; - } - - dest = purple_blist_find_group(new_name); - if (dest != NULL && purple_utf8_strcasecmp(priv->name, - purple_group_get_name(dest)) != 0) { - /* We're merging two groups */ - PurpleBlistNode *prev, *child, *next; - - prev = _purple_blist_get_last_child((PurpleBlistNode*)dest); - child = PURPLE_BLIST_NODE(source)->child; - - /* - * TODO: This seems like a dumb way to do this... why not just - * append all children from the old group to the end of the new - * one? Protocols might be expecting to receive an add_buddy() for - * each moved buddy... - */ - while (child) - { - next = child->next; - if (PURPLE_IS_META_CONTACT(child)) { - purple_blist_add_contact((PurpleMetaContact *)child, dest, prev); - prev = child; - } else { - purple_debug_error("blistnodetypes", "Unknown child type in group %s", priv->name); - } - child = next; - } - - /* Make a copy of the old group name and then delete the old group */ - old_name = g_strdup(priv->name); - purple_blist_remove_group(source); - source = dest; - g_free(new_name); - } else { - /* A simple rename */ - PurpleBlistNode *cnode, *bnode; - - /* Build a GList of all buddies in this group */ - for (cnode = PURPLE_BLIST_NODE(source)->child; cnode != NULL; cnode = cnode->next) { - if (PURPLE_IS_META_CONTACT(cnode)) - for (bnode = cnode->child; bnode != NULL; bnode = bnode->next) - moved_buddies = g_list_append(moved_buddies, bnode); - } - - purple_blist_update_groups_cache(source, new_name); - - old_name = priv->name; - priv->name = new_name; - - g_object_notify_by_pspec(G_OBJECT(source), properties[PROP_NAME]); - } - - /* Save our changes */ - purple_blist_save_node(purple_blist_get_default(), - PURPLE_BLIST_NODE(source)); - - /* Update the UI */ - purple_blist_update_node(purple_blist_get_default(), - PURPLE_BLIST_NODE(source)); - - /* Notify all protocols */ - /* TODO: Is this condition needed? Seems like it would always be TRUE */ - if(old_name && !purple_strequal(priv->name, old_name)) { - for (accts = purple_group_get_accounts(source); accts; - accts = g_slist_delete_link(accts, accts)) { - PurpleAccount *account = accts->data; - PurpleConnection *gc = NULL; - PurpleProtocol *protocol = NULL; - GList *buddies = NULL; - - gc = purple_account_get_connection(account); - - if(gc) - protocol = purple_connection_get_protocol(gc); - - if(!protocol) - continue; - - if(PURPLE_PROTOCOL_IMPLEMENTS(protocol, SERVER, rename_group)) { - purple_protocol_server_rename_group(PURPLE_PROTOCOL_SERVER(protocol), - gc, old_name, source, - buddies); - } else { - GList *cur, *groups = NULL; - - /* Make a list of what the groups each buddy is in */ - for(cur = buddies; cur; cur = cur->next) { - PurpleBlistNode *node = (PurpleBlistNode *)cur->data; - groups = g_list_prepend(groups, node->parent->parent); - } - - g_list_free(groups); - } - - g_list_free(buddies); - } - } - g_list_free(moved_buddies); - g_free(old_name); - - g_object_notify_by_pspec(G_OBJECT(source), properties[PROP_NAME]); -} - -const char *purple_group_get_name(PurpleGroup *group) { - PurpleGroupPrivate *priv = NULL; - - g_return_val_if_fail(PURPLE_IS_GROUP(group), NULL); - - priv = purple_group_get_instance_private(group); - return priv->name; -} - -/****************************************************************************** - * GObject Stuff - *****************************************************************************/ -/* Set method for GObject properties */ -static void -purple_group_set_property(GObject *obj, guint param_id, const GValue *value, - GParamSpec *pspec) -{ - PurpleGroup *group = PURPLE_GROUP(obj); - PurpleGroupPrivate *priv = purple_group_get_instance_private(group); - - switch (param_id) { - case PROP_NAME: - if (priv->is_constructed) - purple_group_set_name(group, g_value_get_string(value)); - else - priv->name = - purple_utf8_strip_unprintables(g_value_get_string(value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); - break; - } -} - -/* Get method for GObject properties */ -static void -purple_group_get_property(GObject *obj, guint param_id, GValue *value, - GParamSpec *pspec) -{ - PurpleGroup *group = PURPLE_GROUP(obj); - - switch (param_id) { - case PROP_NAME: - g_value_set_string(value, purple_group_get_name(group)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); - break; - } -} - -/* GObject initialization function */ -static void -purple_group_init(G_GNUC_UNUSED PurpleGroup *group) { -} - -/* Called when done constructing */ -static void -purple_group_constructed(GObject *object) { - PurpleGroup *group = PURPLE_GROUP(object); - PurpleGroupPrivate *priv = purple_group_get_instance_private(group); - - G_OBJECT_CLASS(purple_group_parent_class)->constructed(object); - - purple_blist_new_node(purple_blist_get_default(), - PURPLE_BLIST_NODE(group)); - - priv->is_constructed = TRUE; -} - -/* GObject finalize function */ -static void -purple_group_finalize(GObject *object) { - PurpleGroupPrivate *priv = purple_group_get_instance_private( - PURPLE_GROUP(object)); - - g_free(priv->name); - - G_OBJECT_CLASS(purple_group_parent_class)->finalize(object); -} - -/* Class initializer function */ -static void -purple_group_class_init(PurpleGroupClass *klass) { - GObjectClass *obj_class = G_OBJECT_CLASS(klass); - - obj_class->finalize = purple_group_finalize; - obj_class->constructed = purple_group_constructed; - - /* Setup properties */ - obj_class->get_property = purple_group_get_property; - obj_class->set_property = purple_group_set_property; - - /** - * PurpleGroup:name: - * - * The name of the group. - * - * Since: 3.0 - */ - properties[PROP_NAME] = g_param_spec_string( - "name", - "Name", - "Name of the group.", - NULL, - G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS - ); - - g_object_class_install_properties(obj_class, N_PROPERTIES, properties); -} - -PurpleGroup * -purple_group_new(const char *name) { - PurpleGroup *group; - - if (name == NULL || name[0] == '\0') - name = PURPLE_BLIST_DEFAULT_GROUP_NAME; - if (g_strcmp0(name, "Buddies") == 0) - name = PURPLE_BLIST_DEFAULT_GROUP_NAME; - - group = purple_blist_find_group(name); - if (group != NULL) - return group; - - return g_object_new(PURPLE_TYPE_GROUP, "name", name, NULL); -} -
--- a/libpurple/group.h Sun Apr 14 01:30:58 2024 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,161 +0,0 @@ -/* - * Purple - Internet Messaging Library - * Copyright (C) Pidgin Developers <devel@pidgin.im> - * - * 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 library 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 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 General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this library; if not, see <https://www.gnu.org/licenses/>. - */ - -#if !defined(PURPLE_GLOBAL_HEADER_INSIDE) && !defined(PURPLE_COMPILATION) -# error "only <purple.h> may be included directly" -#endif - -#ifndef PURPLE_GROUP_H -#define PURPLE_GROUP_H - -#include "countingnode.h" - -#define PURPLE_TYPE_GROUP (purple_group_get_type()) -#define PURPLE_GROUP(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_GROUP, PurpleGroup)) -#define PURPLE_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_GROUP, PurpleGroupClass)) -#define PURPLE_IS_GROUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_GROUP)) -#define PURPLE_IS_GROUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_GROUP)) -#define PURPLE_GROUP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_GROUP, PurpleGroupClass)) - -typedef struct _PurpleGroup PurpleGroup; -typedef struct _PurpleGroupClass PurpleGroupClass; - -#include "purpleaccount.h" -#include "purpleversion.h" - -/**************************************************************************/ -/* Data Structures */ -/**************************************************************************/ - -/** - * PurpleGroup: - * - * A group on the buddy list. - * - * A group is a counting node, which means it keeps track of the counts of the - * chats and contacts under this group. - * - * Since: 2.0 - */ -struct _PurpleGroup { - PurpleCountingNode counting; -}; - -struct _PurpleGroupClass { - PurpleCountingNodeClass counting_class; - - /*< private >*/ - void (*_purple_reserved1)(void); - void (*_purple_reserved2)(void); - void (*_purple_reserved3)(void); - void (*_purple_reserved4)(void); -}; - -G_BEGIN_DECLS - -/**************************************************************************/ -/* Group API */ -/**************************************************************************/ - -/** - * purple_group_get_type: - * - * Returns: The #GType for the #PurpleGroup object. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -GType purple_group_get_type(void); - -/** - * purple_group_new: - * @name: The name of the new group - * - * Creates a new group - * - * You can't have more than one group with the same name. Sorry. If you pass - * this the name of a group that already exists, it will return that group. - * - * Returns: A new group struct - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -PurpleGroup *purple_group_new(const char *name); - -/** - * purple_group_get_accounts: - * @g: The group - * - * Returns a list of accounts that have buddies in this group - * - * Returns: (element-type PurpleAccount) (transfer container): A list of - * accounts, or %NULL if the group has no accounts. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -GSList *purple_group_get_accounts(PurpleGroup *g); - -/** - * purple_group_on_account: - * @g: The group to search through. - * @account: The account. - * - * Determines whether an account owns any buddies in a given group - * - * Returns: TRUE if there are any buddies in the group, or FALSE otherwise. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -gboolean purple_group_on_account(PurpleGroup *g, PurpleAccount *account); - -/** - * purple_group_set_name: - * @group: The group. - * @name: The name of the group. - * - * Sets the name of a group. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -void purple_group_set_name(PurpleGroup *group, const char *name); - -/** - * purple_group_get_name: - * @group: The group. - * - * Returns the name of a group. - * - * Returns: The name of the group. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -const char *purple_group_get_name(PurpleGroup *group); - -G_END_DECLS - -#endif /* PURPLE_GROUP_H */ -
--- a/libpurple/meson.build Sun Apr 14 01:30:58 2024 -0500 +++ b/libpurple/meson.build Sun Apr 14 01:48:40 2024 -0500 @@ -1,17 +1,12 @@ purple_coresources = [ 'accounts.c', 'action.c', - 'blistnode.c', - 'buddylist.c', 'circularbuffer.c', 'cmds.c', 'connection.c', - 'contact.c', 'conversations.c', 'core.c', - 'countingnode.c', 'debug.c', - 'group.c', 'image.c', 'media/backend-iface.c', 'media/candidate.c', @@ -108,17 +103,12 @@ purple_coreheaders = [ 'accounts.h', 'action.h', - 'blistnode.h', - 'buddylist.h', 'circularbuffer.h', 'cmds.h', 'connection.h', - 'contact.h', 'conversations.h', 'core.h', - 'countingnode.h', 'debug.h', - 'group.h', 'image.h', 'media.h', 'media-gst.h',
--- a/libpurple/purpleaccount.c Sun Apr 14 01:30:58 2024 -0500 +++ b/libpurple/purpleaccount.c Sun Apr 14 01:48:40 2024 -0500 @@ -1613,21 +1613,6 @@ } void -purple_account_remove_group(PurpleAccount *account, PurpleGroup *group) { - PurpleProtocol *protocol = NULL; - PurpleConnection *gc = purple_account_get_connection(account); - - if(gc != NULL) { - protocol = purple_connection_get_protocol(gc); - } - - if(PURPLE_IS_PROTOCOL_SERVER(protocol)) { - purple_protocol_server_remove_group(PURPLE_PROTOCOL_SERVER(protocol), - gc, group); - } -} - -void purple_account_change_password(PurpleAccount *account, const char *orig_pw, const char *new_pw) {
--- a/libpurple/purpleaccount.h Sun Apr 14 01:30:58 2024 -0500 +++ b/libpurple/purpleaccount.h Sun Apr 14 01:48:40 2024 -0500 @@ -35,7 +35,6 @@ typedef struct _PurpleAccount PurpleAccount; #include "connection.h" -#include "group.h" #include "purpleconnectionerrorinfo.h" #include "purplecontactinfo.h" #include "purpleprotocol.h" @@ -506,18 +505,6 @@ gboolean purple_account_get_bool(PurpleAccount *account, const char *name, gboolean default_value); /** - * purple_account_remove_group: - * @account: The account. - * @group: The group to remove. - * - * Removes a group from the server-side buddy list. - * - * Since: 2.0 - */ -PURPLE_AVAILABLE_IN_ALL -void purple_account_remove_group(PurpleAccount *account, PurpleGroup *group); - -/** * purple_account_change_password: * @account: The account. * @orig_pw: The old password.
--- a/libpurple/purpleprivate.h Sun Apr 14 01:30:58 2024 -0500 +++ b/libpurple/purpleprivate.h Sun Apr 14 01:48:40 2024 -0500 @@ -51,17 +51,6 @@ PurpleXmlNode *_purple_account_to_xmlnode(PurpleAccount *account); /** - * _purple_blist_get_last_child: - * @node: The node whose last child is to be retrieved. - * - * Returns the last child of a particular node. - * - * Returns: The last child of the node. - */ -G_GNUC_INTERNAL -PurpleBlistNode *_purple_blist_get_last_child(PurpleBlistNode *node); - -/** * _purple_connection_wants_to_die: * @gc: The connection to check *
--- a/libpurple/purpleprotocolserver.c Sun Apr 14 01:30:58 2024 -0500 +++ b/libpurple/purpleprotocolserver.c Sun Apr 14 01:48:40 2024 -0500 @@ -102,42 +102,6 @@ } } -void -purple_protocol_server_rename_group(PurpleProtocolServer *protocol_server, - PurpleConnection *connection, - const gchar *old_name, PurpleGroup *group, - GList *moved_buddies) -{ - PurpleProtocolServerInterface *iface = NULL; - - g_return_if_fail(PURPLE_IS_PROTOCOL_SERVER(protocol_server)); - g_return_if_fail(PURPLE_IS_CONNECTION(connection)); - g_return_if_fail(PURPLE_IS_GROUP(group)); - - iface = PURPLE_PROTOCOL_SERVER_GET_IFACE(protocol_server); - if(iface != NULL && iface->rename_group != NULL) { - iface->rename_group(protocol_server, connection, old_name, group, - moved_buddies); - } -} - -void -purple_protocol_server_remove_group(PurpleProtocolServer *protocol_server, - PurpleConnection *connection, - PurpleGroup *group) -{ - PurpleProtocolServerInterface *iface = NULL; - - g_return_if_fail(PURPLE_IS_PROTOCOL_SERVER(protocol_server)); - g_return_if_fail(PURPLE_IS_CONNECTION(connection)); - g_return_if_fail(PURPLE_IS_GROUP(group)); - - iface = PURPLE_PROTOCOL_SERVER_GET_IFACE(protocol_server); - if(iface != NULL && iface->remove_group != NULL) { - iface->remove_group(protocol_server, connection, group); - } -} - gint purple_protocol_server_send_raw(PurpleProtocolServer *protocol_server, PurpleConnection *connection,
--- a/libpurple/purpleprotocolserver.h Sun Apr 14 01:30:58 2024 -0500 +++ b/libpurple/purpleprotocolserver.h Sun Apr 14 01:48:40 2024 -0500 @@ -31,7 +31,6 @@ #include <glib-object.h> #include "connection.h" -#include "group.h" #include "purpleaccount.h" #include "purplemessage.h" #include "purpleprotocol.h" @@ -66,10 +65,6 @@ void (*change_passwd)(PurpleProtocolServer *protocol_server, PurpleConnection *connection, const gchar *old_pass, const gchar *new_pass); - void (*rename_group)(PurpleProtocolServer *protocol_server, PurpleConnection *connection, const gchar *old_name, PurpleGroup *group, GList *moved_buddies); - - void (*remove_group)(PurpleProtocolServer *protocol_server, PurpleConnection *connection, PurpleGroup *group); - gint (*send_raw)(PurpleProtocolServer *protocol_server, PurpleConnection *connection, const gchar *buf, gint len); /*< private >*/ @@ -131,35 +126,6 @@ void purple_protocol_server_change_passwd(PurpleProtocolServer *protocol_server, PurpleConnection *connection, const gchar *old_pass, const gchar *new_pass); /** - * purple_protocol_server_rename_group: - * @protocol_server: The #PurpleProtocolServer instance. - * @connection: The #PurpleConnection instance. - * @old_name: The old name of the group. - * @group: The new #PurpleGroup instance. - * @moved_buddies: (element-type GObject): A list of #PurpleBuddy's being - * moved as part of this rename. - * - * Renames the group named @old_name to the new @group. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -void purple_protocol_server_rename_group(PurpleProtocolServer *protocol_server, PurpleConnection *connection, const gchar *old_name, PurpleGroup *group, GList *moved_buddies); - -/** - * purple_protocol_server_remove_group: - * @protocol_server: The #PurpleProtocolServer instance. - * @connection: The #PurpleConnection instance. - * @group: The #PurpleGroup instance. - * - * Removes @group from the server side contact list. - * - * Since: 3.0 - */ -PURPLE_AVAILABLE_IN_3_0 -void purple_protocol_server_remove_group(PurpleProtocolServer *protocol_server, PurpleConnection *connection, PurpleGroup *group); - -/** * purple_protocol_server_send_raw: * @protocol_server: The #PurpleProtocolServer instance. * @connection: The #PurpleConnection instance.
--- a/po/POTFILES.in Sun Apr 14 01:30:58 2024 -0500 +++ b/po/POTFILES.in Sun Apr 14 01:48:40 2024 -0500 @@ -1,16 +1,11 @@ libpurple/accounts.c libpurple/action.c -libpurple/blistnode.c -libpurple/buddylist.c libpurple/circularbuffer.c libpurple/cmds.c libpurple/connection.c -libpurple/contact.c libpurple/conversations.c libpurple/core.c -libpurple/countingnode.c libpurple/debug.c -libpurple/group.c libpurple/image.c libpurple/media/backend-iface.c libpurple/media.c