Fri, 10 Feb 2023 03:03:39 -0600
Add a property and accessor for getting the avatar to display for a PurplePerson
Testing Done:
Ran the unit tests and verified everything looks looks right in the contact list.
Bugs closed: PIDGIN-17735
Reviewed at https://reviews.imfreedom.org/r/2232/
--- a/libpurple/purpleperson.c Fri Feb 10 03:00:58 2023 -0600 +++ b/libpurple/purpleperson.c Fri Feb 10 03:03:39 2023 -0600 @@ -37,6 +37,7 @@ PROP_ID, PROP_ALIAS, PROP_AVATAR, + PROP_AVATAR_FOR_DISPLAY, PROP_TAGS, PROP_NAME_FOR_DISPLAY, PROP_PRIORITY_CONTACT_INFO, @@ -109,6 +110,14 @@ g_object_freeze_notify(obj); g_object_notify_by_pspec(obj, properties[PROP_NAME_FOR_DISPLAY]); g_object_notify_by_pspec(obj, properties[PROP_PRIORITY_CONTACT_INFO]); + + /* If the person doesn't have an avatar set, notify that the + * avatar-for-display has changed. + */ + if(!GDK_IS_PIXBUF(person->avatar)) { + g_object_notify_by_pspec(obj, properties[PROP_AVATAR_FOR_DISPLAY]); + } + g_object_thaw_notify(obj); } } @@ -182,6 +191,9 @@ case PROP_AVATAR: g_value_set_object(value, purple_person_get_avatar(person)); break; + case PROP_AVATAR_FOR_DISPLAY: + g_value_set_object(value, purple_person_get_avatar_for_display(person)); + break; case PROP_TAGS: g_value_set_object(value, purple_person_get_tags(person)); break; @@ -315,6 +327,22 @@ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); /** + * PurplePerson:avatar-for-display + * + * The avatar to show for the person. If [property@Purple.Person:avatar] is + * set, it will be returned. Otherwise the value of + * [property@Purple.ContactInfo:avatar] for + * [property@Purple.Person:priority-contact-info] will be returned. + * + * Since: 3.0.0 + */ + properties[PROP_AVATAR_FOR_DISPLAY] = g_param_spec_object( + "avatar-for-display", "avatar-for-display", + "The avatar to display for this person", + GDK_TYPE_PIXBUF, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + /** * PurplePerson:tags: * * The [class@Purple.Tags] for this person. @@ -405,6 +433,24 @@ } GdkPixbuf * +purple_person_get_avatar_for_display(PurplePerson *person) { + PurpleContactInfo *priority = NULL; + + g_return_val_if_fail(PURPLE_IS_PERSON(person), NULL); + + if(GDK_IS_PIXBUF(person->avatar)) { + return person->avatar; + } + + priority = purple_person_get_priority_contact_info(person); + if(PURPLE_IS_CONTACT_INFO(priority)) { + return purple_contact_info_get_avatar(priority); + } + + return NULL; +} + +GdkPixbuf * purple_person_get_avatar(PurplePerson *person) { g_return_val_if_fail(PURPLE_IS_PERSON(person), NULL); @@ -416,7 +462,12 @@ g_return_if_fail(PURPLE_IS_PERSON(person)); if(g_set_object(&person->avatar, avatar)) { - g_object_notify_by_pspec(G_OBJECT(person), properties[PROP_AVATAR]); + GObject *obj = G_OBJECT(person); + + g_object_freeze_notify(obj); + g_object_notify_by_pspec(obj, properties[PROP_AVATAR]); + g_object_notify_by_pspec(obj, properties[PROP_AVATAR_FOR_DISPLAY]); + g_object_thaw_notify(obj); } }
--- a/libpurple/purpleperson.h Fri Feb 10 03:00:58 2023 -0600 +++ b/libpurple/purpleperson.h Fri Feb 10 03:03:39 2023 -0600 @@ -101,6 +101,21 @@ void purple_person_set_alias(PurplePerson *person, const gchar *alias); /** + * purple_person_get_avatar_for_display: + * @person: The instance. + * + * Gets the avatar that should be displayed for @person. If @person has an + * avatar set, it will be returned, otherwise this will fallback to the value + * of [property@Purple.ContactInfo:avatar] for + * [property@Purple.Person:priority-contact-info]. + * + * Returns: (transfer none) (nullable): The avatar to display. + * + * Since: 3.0.0 + */ +GdkPixbuf *purple_person_get_avatar_for_display(PurplePerson *person); + +/** * purple_person_get_avatar: * @person: The instance. *
--- a/libpurple/tests/test_person.c Fri Feb 10 03:00:58 2023 -0600 +++ b/libpurple/tests/test_person.c Fri Feb 10 03:03:39 2023 -0600 @@ -67,6 +67,7 @@ PurpleTags *tags = NULL; GdkPixbuf *avatar = NULL; GdkPixbuf *avatar1 = NULL; + GdkPixbuf *avatar_for_display = NULL; char *id = NULL; char *alias = NULL; char *name_for_display = NULL; @@ -89,6 +90,7 @@ "id", &id, "alias", &alias, "avatar", &avatar1, + "avatar-for-display", &avatar_for_display, "name-for-display", &name_for_display, "tags", &tags, NULL); @@ -97,6 +99,7 @@ g_assert_nonnull(id); g_assert_cmpstr(alias, ==, "alias"); g_assert_true(avatar1 == avatar); + g_assert_true(avatar1 == avatar_for_display); g_assert_cmpstr(name_for_display, ==, "alias"); g_assert_nonnull(tags); @@ -104,6 +107,7 @@ g_clear_pointer(&id, g_free); g_clear_pointer(&alias, g_free); g_clear_object(&avatar1); + g_clear_object(&avatar_for_display); g_clear_pointer(&name_for_display, g_free); g_clear_object(&tags); @@ -112,6 +116,48 @@ } static void +test_purple_person_avatar_for_display_person(void) { + PurpleContactInfo *info = NULL; + PurplePerson *person = NULL; + GdkPixbuf *avatar = NULL; + + person = purple_person_new(); + avatar = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, 1, 1); + purple_person_set_avatar(person, avatar); + + info = purple_contact_info_new("id"); + purple_person_add_contact_info(person, info); + + /* Make sure the person's alias is overriding the contact info. */ + g_assert_true(purple_person_get_avatar_for_display(person) == avatar); + + g_clear_object(&info); + g_clear_object(&person); + g_clear_object(&avatar); +} + +static void +test_purple_person_avatar_for_display_contact(void) { + PurpleContactInfo *info = NULL; + PurplePerson *person = NULL; + GdkPixbuf *avatar = NULL; + + person = purple_person_new(); + + info = purple_contact_info_new("id"); + avatar = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, 1, 1); + purple_contact_info_set_avatar(info, avatar); + purple_person_add_contact_info(person, info); + + /* Make sure the person's alias is overriding the contact info. */ + g_assert_true(purple_person_get_avatar_for_display(person) == avatar); + + g_clear_object(&info); + g_clear_object(&person); + g_clear_object(&avatar); +} + +static void test_purple_person_name_for_display_person(void) { PurpleContactInfo *info = NULL; PurplePerson *person = NULL; @@ -410,6 +456,11 @@ g_test_add_func("/person/properties", test_purple_person_properties); + g_test_add_func("/person/avatar-for-display/person", + test_purple_person_avatar_for_display_person); + g_test_add_func("/person/avatar-for-display/contact", + test_purple_person_avatar_for_display_contact); + g_test_add_func("/person/name-for-display/person", test_purple_person_name_for_display_person); g_test_add_func("/person/name-for-display/contact",
--- a/pidgin/pidgincontactlist.c Fri Feb 10 03:00:58 2023 -0600 +++ b/pidgin/pidgincontactlist.c Fri Feb 10 03:03:39 2023 -0600 @@ -46,6 +46,12 @@ PurpleContact *contact = NULL; PurpleBuddyIcon *icon = NULL; GdkTexture *texture = NULL; + GdkPixbuf *pixbuf = NULL; + + pixbuf = purple_person_get_avatar_for_display(person); + if(GDK_IS_PIXBUF(pixbuf)) { + return gdk_texture_new_for_pixbuf(pixbuf); + } info = purple_person_get_priority_contact_info(person);