pidgin/pidgin

0da91f053305
Parents c8a4853205e3
Children f802660eaef2
Make PurpleAccount subclass PurpleContactInfo

This allows accounts to be treated as PurpleContactInfo without duplication.

The existing api was left with deprecation flags so we can knock them out file by file.

Buddy Icons will replaced once /r/2092/ is merged.

Presence is a little goofy for now, because it still depends on PurpleAccountPresence which I want to remove in a simplification of the status api. I considered overriding the propert, but since `purple_contact_info_get_presence` returns its instance, this won't work.

Testing Done:
Ran the unit tests and connected the demo protocol and an XMPP account that had contacts in the list.

Reviewed at https://reviews.imfreedom.org/r/2113/
--- a/libpurple/account.c Sun Dec 11 22:56:34 2022 -0600
+++ b/libpurple/account.c Mon Dec 12 00:47:54 2022 -0600
@@ -52,13 +52,9 @@
struct _PurpleAccount
{
- GObject gparent;
-
- gchar *id;
+ PurpleContactInfo parent;
- char *username; /* The username. */
gboolean require_password;
- char *alias; /* How you appear to yourself. */
char *user_info; /* User information. */
char *buddy_icon_path; /* The buddy icon's non-cached path. */
@@ -88,8 +84,6 @@
PurpleConnectionErrorInfo *current_error; /* Errors */
PurpleNotification *error_notification;
-
- PurpleContact *contact;
} PurpleAccountPrivate;
typedef struct
@@ -101,10 +95,7 @@
enum {
PROP_0,
- PROP_ID,
- PROP_USERNAME,
PROP_REQUIRE_PASSWORD,
- PROP_PRIVATE_ALIAS,
PROP_ENABLED,
PROP_CONNECTION,
PROP_PROTOCOL_ID,
@@ -113,7 +104,6 @@
PROP_REMEMBER_PASSWORD,
PROP_PROXY_INFO,
PROP_ERROR,
- PROP_CONTACT,
PROP_LAST
};
static GParamSpec *properties[PROP_LAST];
@@ -124,7 +114,7 @@
};
static guint signals[N_SIGNALS] = {0, };
-G_DEFINE_TYPE(PurpleAccount, purple_account, G_TYPE_OBJECT);
+G_DEFINE_TYPE(PurpleAccount, purple_account, PURPLE_TYPE_CONTACT_INFO);
/******************************************************************************
* Helpers
@@ -133,10 +123,12 @@
purple_account_free_notify_settings(PurpleAccount *account) {
g_return_if_fail(PURPLE_IS_ACCOUNT(account));
- g_slist_free_full(account->freeze_queue->names, g_free);
+ if(account->freeze_queue != NULL) {
+ g_slist_free_full(account->freeze_queue->names, g_free);
- g_slice_free(PurpleAccountSettingFreezeQueue, account->freeze_queue);
- account->freeze_queue = NULL;
+ g_slice_free(PurpleAccountSettingFreezeQueue, account->freeze_queue);
+ account->freeze_queue = NULL;
+ }
}
static void
@@ -570,9 +562,10 @@
node = purple_xmlnode_new("account");
- if(account->id != NULL) {
+ tmp = purple_contact_info_get_id(PURPLE_CONTACT_INFO(account));
+ if(tmp != NULL) {
child = purple_xmlnode_new_child(node, "id");
- purple_xmlnode_insert_data(child, account->id, -1);
+ purple_xmlnode_insert_data(child, tmp, -1);
}
child = purple_xmlnode_new_child(node, "protocol");
@@ -591,8 +584,8 @@
purple_xmlnode_insert_data(child, data, -1);
g_clear_pointer(&data, g_free);
- if ((tmp = purple_account_get_private_alias(account)) != NULL)
- {
+ tmp = purple_contact_info_get_alias(PURPLE_CONTACT_INFO(account));
+ if(tmp != NULL) {
child = purple_xmlnode_new_child(node, "alias");
purple_xmlnode_insert_data(child, tmp, -1);
}
@@ -623,17 +616,6 @@
}
/******************************************************************************
- * Helpers
- *****************************************************************************/
-static void
-purple_account_set_id(PurpleAccount *account, const gchar *id) {
- g_free(account->id);
- account->id = g_strdup(id);
-
- g_object_notify_by_pspec(G_OBJECT(account), properties[PROP_ID]);
-}
-
-/******************************************************************************
* GObject Implementation
*****************************************************************************/
static void
@@ -643,19 +625,10 @@
PurpleAccount *account = PURPLE_ACCOUNT(obj);
switch (param_id) {
- case PROP_ID:
- purple_account_set_id(account, g_value_get_string(value));
- break;
- case PROP_USERNAME:
- purple_account_set_username(account, g_value_get_string(value));
- break;
case PROP_REQUIRE_PASSWORD:
purple_account_set_require_password(account,
g_value_get_boolean(value));
break;
- case PROP_PRIVATE_ALIAS:
- purple_account_set_private_alias(account, g_value_get_string(value));
- break;
case PROP_ENABLED:
purple_account_set_enabled(account, g_value_get_boolean(value));
break;
@@ -692,19 +665,10 @@
PurpleAccount *account = PURPLE_ACCOUNT(obj);
switch (param_id) {
- case PROP_ID:
- g_value_set_string(value, purple_account_get_id(account));
- break;
- case PROP_USERNAME:
- g_value_set_string(value, purple_account_get_username(account));
- break;
case PROP_REQUIRE_PASSWORD:
g_value_set_boolean(value,
purple_account_get_require_password(account));
break;
- case PROP_PRIVATE_ALIAS:
- g_value_set_string(value, purple_account_get_private_alias(account));
- break;
case PROP_ENABLED:
g_value_set_boolean(value, purple_account_get_enabled(account));
break;
@@ -746,6 +710,7 @@
{
PurpleAccount *account = PURPLE_ACCOUNT(object);
gchar *username, *protocol_id;
+ const char *id = NULL;
PurpleProtocol *protocol = NULL;
PurpleProtocolManager *manager = NULL;
PurpleStatusType *status_type;
@@ -753,32 +718,23 @@
G_OBJECT_CLASS(purple_account_parent_class)->constructed(object);
/* If we didn't get an id, checksum the protocol id and the username. */
- if(account->id == NULL) {
- GChecksum *checksum = g_checksum_new(G_CHECKSUM_SHA256);
+ id = purple_contact_info_get_id(PURPLE_CONTACT_INFO(object));
+ if(id == NULL) {
+ PurpleContactInfo *info = PURPLE_CONTACT_INFO(account);
+ GChecksum *checksum = NULL;
+ const char *username = NULL;
+
+ checksum = g_checksum_new(G_CHECKSUM_SHA256);
+ username = purple_contact_info_get_username(info);
g_checksum_update(checksum, (const guchar *)account->protocol_id, -1);
- g_checksum_update(checksum, (const guchar *)account->username, -1);
+ g_checksum_update(checksum, (const guchar *)username, -1);
- purple_account_set_id(account, g_checksum_get_string(checksum));
+ purple_contact_info_set_id(info, g_checksum_get_string(checksum));
g_checksum_free(checksum);
}
- /* Create the contact for the account and bind our properties to it. */
- account->contact = purple_contact_new(account, NULL);
- /* Skip id for now as it's construct only and exposing it is more work than
- * it's worth right now.
- */
-#if 0
- g_object_bind_property(account, "id", account->contact, "id",
- G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
-#endif
- g_object_bind_property(account, "username", account->contact, "username",
- G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
- g_object_bind_property(account, "private-alias",
- account->contact, "display-name",
- G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
-
g_object_get(object,
"username", &username,
"protocol-id", &protocol_id,
@@ -823,7 +779,6 @@
g_clear_object(&account->gc);
g_clear_object(&account->presence);
- g_clear_object(&account->contact);
G_OBJECT_CLASS(purple_account_parent_class)->dispose(object);
}
@@ -858,9 +813,6 @@
g_clear_pointer(&account->current_error, purple_connection_error_info_free);
g_clear_object(&account->error_notification);
- g_free(account->id);
- g_free(account->username);
- g_free(account->alias);
g_free(account->user_info);
g_free(account->buddy_icon_path);
g_free(account->protocol_id);
@@ -881,23 +833,6 @@
obj_class->set_property = purple_account_set_property;
/**
- * PurpleAccount::id
- *
- * An identifier for the account.
- *
- * Since: 3.0.0
- */
- properties[PROP_ID] = g_param_spec_string(
- "id", "id",
- "The identifier of the account",
- NULL,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
-
- properties[PROP_USERNAME] = g_param_spec_string("username", "Username",
- "The username for the account.", NULL,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
-
- /**
* PurpleAccount:require-password:
*
* Whether or not this account should require a password. This is only used
@@ -912,11 +847,6 @@
FALSE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- properties[PROP_PRIVATE_ALIAS] = g_param_spec_string("private-alias",
- "Private Alias",
- "The private alias for the account.", NULL,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
-
properties[PROP_USER_INFO] = g_param_spec_string("user-info",
"User information",
"Detailed user information for the account.", NULL,
@@ -967,19 +897,6 @@
PURPLE_TYPE_CONNECTION_ERROR_INFO,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- /**
- * PurpleAccount:contact:
- *
- * The [class@Purple.Contact] that represents this account.
- *
- * Since: 3.0.0
- */
- properties[PROP_CONTACT] = g_param_spec_object(
- "contact", "contact",
- "The contact for this account",
- PURPLE_TYPE_CONTACT,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
-
g_object_class_install_properties(obj_class, PROP_LAST, properties);
/**
@@ -1055,7 +972,7 @@
purple_account_get_id(PurpleAccount *account) {
g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL);
- return account->id;
+ return purple_contact_info_get_id(PURPLE_CONTACT_INFO(account));
}
void
@@ -1279,10 +1196,7 @@
{
g_return_if_fail(PURPLE_IS_ACCOUNT(account));
- g_free(account->username);
- account->username = g_strdup(username);
-
- g_object_notify_by_pspec(G_OBJECT(account), properties[PROP_USERNAME]);
+ purple_contact_info_set_username(PURPLE_CONTACT_INFO(account), username);
purple_accounts_schedule_save();
@@ -1294,26 +1208,17 @@
void
purple_account_set_private_alias(PurpleAccount *account, const char *alias)
{
+ const char *old_alias = NULL;
+
g_return_if_fail(PURPLE_IS_ACCOUNT(account));
- /*
- * Do nothing if alias and account->alias are both NULL. Or if
- * they're the exact same string.
- */
- if (alias == account->alias)
+ old_alias = purple_contact_info_get_alias(PURPLE_CONTACT_INFO(account));
+ if(purple_strequal(old_alias, alias)) {
return;
+ }
- if ((!alias && account->alias) || (alias && !account->alias) ||
- g_utf8_collate(account->alias, alias))
- {
- g_free(account->alias);
- account->alias = g_strdup(alias);
-
- g_object_notify_by_pspec(G_OBJECT(account),
- properties[PROP_PRIVATE_ALIAS]);
-
- purple_accounts_schedule_save();
- }
+ purple_contact_info_set_alias(PURPLE_CONTACT_INFO(account), alias);
+ purple_accounts_schedule_save();
}
void
@@ -1569,7 +1474,7 @@
{
g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL);
- return account->username;
+ return purple_contact_info_get_username(PURPLE_CONTACT_INFO(account));
}
const char *
@@ -1577,7 +1482,7 @@
{
g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL);
- return account->alias;
+ return purple_contact_info_get_alias(PURPLE_CONTACT_INFO(account));
}
const char *
@@ -1637,39 +1542,10 @@
}
const gchar *
-purple_account_get_name_for_display(PurpleAccount *account)
-{
- PurpleBuddy *self = NULL;
- PurpleConnection *gc = NULL;
- const gchar *name = NULL, *username = NULL, *displayname = NULL;
-
- name = purple_account_get_private_alias(account);
-
- if (name) {
- return name;
- }
-
- username = purple_account_get_username(account);
- self = purple_blist_find_buddy((PurpleAccount *)account, username);
+purple_account_get_name_for_display(PurpleAccount *account) {
+ g_return_val_if_fail(PURPLE_IS_CONTACT_INFO(account), NULL);
- if (self) {
- const gchar *calias= purple_buddy_get_contact_alias(self);
-
- /* We don't want to return the buddy name if the buddy/contact
- * doesn't have an alias set. */
- if (!purple_strequal(username, calias)) {
- return calias;
- }
- }
-
- gc = purple_account_get_connection(account);
- displayname = purple_connection_get_display_name(gc);
-
- if (displayname) {
- return displayname;
- }
-
- return username;
+ return purple_contact_info_get_name_for_display(PURPLE_CONTACT_INFO(account));
}
gboolean
@@ -2008,13 +1884,6 @@
return account->require_password;
}
-PurpleContact *
-purple_account_get_contact(PurpleAccount *account) {
- g_return_val_if_fail(PURPLE_IS_ACCOUNT(account), NULL);
-
- return account->contact;
-}
-
void
purple_account_freeze_notify_settings(PurpleAccount *account) {
g_return_if_fail(PURPLE_IS_ACCOUNT(account));
--- a/libpurple/account.h Sun Dec 11 22:56:34 2022 -0600
+++ b/libpurple/account.h Mon Dec 12 00:47:54 2022 -0600
@@ -39,7 +39,7 @@
#include "connection.h"
#include "group.h"
#include "purpleconnectionerrorinfo.h"
-#include "purplecontact.h"
+#include "purplecontactinfo.h"
#include "purpleprotocol.h"
#include "purpleproxyinfo.h"
#include "status.h"
@@ -82,7 +82,8 @@
*
* Returns: The #GType for the Account object.
*/
-G_DECLARE_FINAL_TYPE(PurpleAccount, purple_account, PURPLE, ACCOUNT, GObject)
+G_DECLARE_FINAL_TYPE(PurpleAccount, purple_account, PURPLE, ACCOUNT,
+ PurpleContactInfo)
/**
* purple_account_new:
@@ -105,6 +106,7 @@
*
* Since: 3.0.0
*/
+G_DEPRECATED_FOR(purple_contact_info_get_id)
const gchar *purple_account_get_id(PurpleAccount *account);
/**
@@ -188,6 +190,7 @@
*
* Sets the account's username.
*/
+G_DEPRECATED_FOR(purple_contact_info_set_username)
void purple_account_set_username(PurpleAccount *account, const char *username);
/**
@@ -401,6 +404,7 @@
*
* Returns: The username.
*/
+G_DEPRECATED_FOR(purple_contact_info_get_username)
const char *purple_account_get_username(PurpleAccount *account);
/**
@@ -487,6 +491,7 @@
*
* Returns: The name to display.
*/
+G_DEPRECATED_FOR(purple_contact_info_get_name_for_display)
const gchar *purple_account_get_name_for_display(PurpleAccount *account);
/**
@@ -767,22 +772,6 @@
gboolean purple_account_get_require_password(PurpleAccount *account);
/**
- * purple_account_get_contact:
- * @account: The instance.
- *
- * Gets the [class@Purple.Contact] for @account that represents the user of
- * @account.
- *
- * This can be used by protocol plugins to store additional information about
- * the account.
- *
- * Returns: (transfer none): The contact that represents @account.
- *
- * Since: 3.0.0
- */
-PurpleContact *purple_account_get_contact(PurpleAccount *account);
-
-/**
* purple_account_freeze_notify_settings:
* @account: The instance.
*
--- a/libpurple/purplecontactinfo.c Sun Dec 11 22:56:34 2022 -0600
+++ b/libpurple/purplecontactinfo.c Mon Dec 12 00:47:54 2022 -0600
@@ -226,7 +226,7 @@
"username", "username",
"The username of the contact",
NULL,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
/**
* PurpleContactInfo:display-name:
@@ -381,7 +381,6 @@
PurpleContactInfoPrivate *priv = NULL;
g_return_if_fail(PURPLE_IS_CONTACT_INFO(info));
- g_return_if_fail(username != NULL);
priv = purple_contact_info_get_instance_private(info);
--- a/libpurple/purplecontactinfo.h Sun Dec 11 22:56:34 2022 -0600
+++ b/libpurple/purplecontactinfo.h Mon Dec 12 00:47:54 2022 -0600
@@ -116,9 +116,8 @@
* @id: The new identifier.
*
* Sets the identifier of @info to @id. Note, this should be used rarely if
- * at all. The main intent of this, is for protocols to update the id of
- * [property@Purple.Account:contact] when an account is connected if it is
- * missing.
+ * at all. The main intent of this, is for protocols to update the id of an
+ * an account when it is connected if the id is missing.
*
* Since: 3.0.0
*/