diff options
author | Gary Kramlich <grim@reaperworld.com> | 2023-02-23 01:33:50 -0600 |
---|---|---|
committer | Gary Kramlich <grim@reaperworld.com> | 2023-02-23 01:33:50 -0600 |
commit | d029f072265c068cb35d563dacdf7911e3edd840 (patch) | |
tree | 9d3b81bb407e61a094827e6e785cb000d9c46873 /libpurple | |
parent | e22ab2383cdf2498f6b084ee7156c16dd90d5821 (diff) | |
download | pidgin-d029f072265c068cb35d563dacdf7911e3edd840.tar.gz |
Add PurpleConversationMember to link a PurpleContactInfo to a PurpleConversation
Testing Done:
Ran the unit tests.
Bugs closed: PIDGIN-17764
Reviewed at https://reviews.imfreedom.org/r/2258/
Diffstat (limited to 'libpurple')
-rw-r--r-- | libpurple/meson.build | 2 | ||||
-rw-r--r-- | libpurple/purpleconversationmember.c | 182 | ||||
-rw-r--r-- | libpurple/purpleconversationmember.h | 94 | ||||
-rw-r--r-- | libpurple/tests/meson.build | 1 | ||||
-rw-r--r-- | libpurple/tests/test_conversation_member.c | 90 |
5 files changed, 369 insertions, 0 deletions
diff --git a/libpurple/meson.build b/libpurple/meson.build index a6d290c063..449bc90ebb 100644 --- a/libpurple/meson.build +++ b/libpurple/meson.build @@ -50,6 +50,7 @@ purple_coresources = [ 'purplecontactmanager.c', 'purpleconversation.c', 'purpleconversationmanager.c', + 'purpleconversationmember.c', 'purpleconversationuiops.c', 'purplecredentialmanager.c', 'purplecredentialprovider.c', @@ -154,6 +155,7 @@ purple_coreheaders = [ 'purplecontactmanager.h', 'purpleconversation.h', 'purpleconversationmanager.h', + 'purpleconversationmember.h', 'purpleconversationuiops.h', 'purplecredentialmanager.h', 'purplecredentialprovider.h', diff --git a/libpurple/purpleconversationmember.c b/libpurple/purpleconversationmember.c new file mode 100644 index 0000000000..e4f101db7e --- /dev/null +++ b/libpurple/purpleconversationmember.c @@ -0,0 +1,182 @@ +/* + * Purple - Internet Messaging Library + * Copyright (C) Pidgin Developers <devel@pidgin.im> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that `it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses/>. + */ + +#include "purpleconversationmember.h" + +struct _PurpleConversationMember { + GObject parent; + + PurpleContactInfo *contact_info; + PurpleTags *tags; +}; + +enum { + PROP_0, + PROP_CONTACT_INFO, + PROP_TAGS, + N_PROPERTIES +}; +static GParamSpec *properties[N_PROPERTIES] = {NULL, }; + +G_DEFINE_TYPE(PurpleConversationMember, purple_conversation_member, + G_TYPE_OBJECT) + +/****************************************************************************** + * Helpers + *****************************************************************************/ +static void +purple_conversation_member_set_contact_info(PurpleConversationMember *member, + PurpleContactInfo *contact_info) +{ + g_return_if_fail(PURPLE_IS_CONVERSATION_MEMBER(member)); + g_return_if_fail(PURPLE_IS_CONTACT_INFO(contact_info)); + + if(g_set_object(&member->contact_info, contact_info)) { + g_object_notify_by_pspec(G_OBJECT(member), + properties[PROP_CONTACT_INFO]); + } +} + +/****************************************************************************** + * GObject Implementation + *****************************************************************************/ +static void +purple_conversation_member_get_property(GObject *obj, guint param_id, + GValue *value, GParamSpec *pspec) +{ + PurpleConversationMember *member = PURPLE_CONVERSATION_MEMBER(obj); + + switch(param_id) { + case PROP_CONTACT_INFO: + g_value_set_object(value, + purple_conversation_member_get_contact_info(member)); + break; + case PROP_TAGS: + g_value_set_object(value, + purple_conversation_member_get_tags(member)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); + break; + } +} + +static void +purple_conversation_member_set_property(GObject *obj, guint param_id, + const GValue *value, GParamSpec *pspec) +{ + PurpleConversationMember *member = PURPLE_CONVERSATION_MEMBER(obj); + + switch(param_id) { + case PROP_CONTACT_INFO: + purple_conversation_member_set_contact_info(member, + g_value_get_object(value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); + break; + } +} + +static void +purple_conversation_member_dispose(GObject *obj) { + PurpleConversationMember *member = PURPLE_CONVERSATION_MEMBER(obj); + + g_clear_object(&member->contact_info); + + G_OBJECT_CLASS(purple_conversation_member_parent_class)->dispose(obj); +} + +static void +purple_conversation_member_finalize(GObject *obj) { + PurpleConversationMember *member = PURPLE_CONVERSATION_MEMBER(obj); + + g_clear_object(&member->tags); + + G_OBJECT_CLASS(purple_conversation_member_parent_class)->finalize(obj); +} + +static void +purple_conversation_member_init(PurpleConversationMember *member) { + member->tags = purple_tags_new(); +} + +static void +purple_conversation_member_class_init(PurpleConversationMemberClass *klass) { + GObjectClass *obj_class = G_OBJECT_CLASS(klass); + + obj_class->dispose = purple_conversation_member_dispose; + obj_class->finalize = purple_conversation_member_finalize; + obj_class->get_property = purple_conversation_member_get_property; + obj_class->set_property = purple_conversation_member_set_property; + + /** + * PurpleConversationMember:contact-info: + * + * The contact info that this member is for. + * + * Since: 3.0.0 + */ + properties[PROP_CONTACT_INFO] = g_param_spec_object( + "contact-info", "contact-info", + "The contact-info this member is for", + PURPLE_TYPE_CONTACT_INFO, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + + /** + * PurpleConversationMember:tags: + * + * The [class@Purple.Tags] instance for this member. + * + * Since: 3.0.0 + */ + properties[PROP_TAGS] = g_param_spec_object( + "tags", "tags", + "The tags for this member", + PURPLE_TYPE_TAGS, + G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties(obj_class, N_PROPERTIES, properties); +} + +/****************************************************************************** + * Public API + *****************************************************************************/ +PurpleConversationMember * +purple_conversation_member_new(PurpleContactInfo *info) { + g_return_val_if_fail(PURPLE_IS_CONTACT_INFO(info), NULL); + + return g_object_new( + PURPLE_TYPE_CONVERSATION_MEMBER, + "contact-info", info, + NULL); +} + +PurpleContactInfo * +purple_conversation_member_get_contact_info(PurpleConversationMember *member) { + g_return_val_if_fail(PURPLE_IS_CONVERSATION_MEMBER(member), NULL); + + return member->contact_info; +} + +PurpleTags * +purple_conversation_member_get_tags(PurpleConversationMember *member) { + g_return_val_if_fail(PURPLE_IS_CONVERSATION_MEMBER(member), NULL); + + return member->tags; +} diff --git a/libpurple/purpleconversationmember.h b/libpurple/purpleconversationmember.h new file mode 100644 index 0000000000..82f200d6b2 --- /dev/null +++ b/libpurple/purpleconversationmember.h @@ -0,0 +1,94 @@ +/* + * Purple - Internet Messaging Library + * Copyright (C) Pidgin Developers <devel@pidgin.im> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses/>. + */ + +#if !defined(PURPLE_GLOBAL_HEADER_INSIDE) && !defined(PURPLE_COMPILATION) +# error "only <pidgin.h> may be included directly" +#endif + +#ifndef PURPLE_CONVERSATION_MEMBER_H +#define PURPLE_CONVERSATION_MEMBER_H + +#include <glib.h> +#include <glib-object.h> + +#include <libpurple/purplecontactinfo.h> +#include <libpurple/purpletags.h> + +G_BEGIN_DECLS + +#define PURPLE_TYPE_CONVERSATION_MEMBER (purple_conversation_member_get_type()) +G_DECLARE_FINAL_TYPE(PurpleConversationMember, purple_conversation_member, + PURPLE, CONVERSATION_MEMBER, GObject) + +/** + * PurpleConversationMember: + * + * A conversation member links a [class@Purple.ContactInfo] to a + * [class@Purple.Conversation] as well as any data that is unique to the link. + * + * Some examples of this are typing state, badges, tags, etc. + * + * This does not hold a reference to a [class@Purple.Conversation] as you + * should not need to hold onto these and will have the + * [class@Purple.Conversation] when you need to look it up. + * + * Since: 3.0.0 + */ + +/** + * purple_conversation_member_new: + * @info: The [class@Purple.ContactInfo] for the member. + * + * Creates a new [class@Purple.ConversationMember]. This does not track the + * [class@Purple.Conversation] as you already need to know the conversation to + * access the member. + * + * Returns: (transfer full): The new instance. + * + * Since: 3.0.0 + */ +PurpleConversationMember *purple_conversation_member_new(PurpleContactInfo *info); + +/** + * purple_conversation_member_get_contact_info: + * @conversation_member: The instance. + * + * Gets the [class@Purple.ContactInfo] for @conversation_member. + * + * Returns: (transfer none): The [class@Purple.ContactInfo] for + * @conversation_member. + * + * Since: 3.0.0 + */ +PurpleContactInfo *purple_conversation_member_get_contact_info(PurpleConversationMember *conversation_member); + +/** + * purple_conversation_member_get_tags: + * @conversation_member: The instance. + * + * Gets the [class@Purple.Tags] instance for @conversation_member. + * + * Returns: (transfer none): The [class@Purple.Tags] for @conversation_member. + * + * Since: 3.0.0 + */ +PurpleTags *purple_conversation_member_get_tags(PurpleConversationMember *conversation_member); + +G_END_DECLS + +#endif /* PURPLE_CONVERSATION_MEMBER_H */ diff --git a/libpurple/tests/meson.build b/libpurple/tests/meson.build index 697e818d59..ca07cd7b17 100644 --- a/libpurple/tests/meson.build +++ b/libpurple/tests/meson.build @@ -6,6 +6,7 @@ PROGS = [ 'contact', 'contact_info', 'contact_manager', + 'conversation_member', 'credential_manager', 'credential_provider', 'history_adapter', diff --git a/libpurple/tests/test_conversation_member.c b/libpurple/tests/test_conversation_member.c new file mode 100644 index 0000000000..73fafb846c --- /dev/null +++ b/libpurple/tests/test_conversation_member.c @@ -0,0 +1,90 @@ +/* + * Purple - Internet Messaging Library + * Copyright (C) Pidgin Developers <devel@pidgin.im> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see <https://www.gnu.org/licenses/>. + */ + +#include <glib.h> + +#include <purple.h> + +/****************************************************************************** + * Tests + *****************************************************************************/ +static void +test_purple_conversation_member_new(void) { + PurpleContactInfo *info = NULL; + PurpleConversationMember *member = NULL; + + info = purple_contact_info_new(NULL); + g_assert_true(PURPLE_IS_CONTACT_INFO(info)); + + member = purple_conversation_member_new(info); + g_assert_true(PURPLE_IS_CONVERSATION_MEMBER(member)); + + g_clear_object(&info); + g_clear_object(&member); +} + +static void +test_purple_conversation_member_properties(void) { + PurpleContactInfo *info = NULL; + PurpleContactInfo *info1 = NULL; + PurpleConversationMember *member = NULL; + PurpleTags *tags = NULL; + + info = purple_contact_info_new("abc123"); + + /* Use g_object_new so we can test setting properties by name. All of them + * call the setter methods, so by doing it this way we exercise more of the + * code. + */ + member = g_object_new( + PURPLE_TYPE_CONVERSATION_MEMBER, + "contact-info", info, + NULL); + + /* Now use g_object_get to read all of the properties. */ + g_object_get(member, + "contact-info", &info1, + "tags", &tags, + NULL); + + /* Compare all the things. */ + g_assert_true(info1 == info); + g_assert_true(PURPLE_IS_TAGS(tags)); + + /* Free/unref all the things. */ + g_clear_object(&info1); + g_clear_object(&tags); + + g_clear_object(&info); + g_clear_object(&member); +} + +/****************************************************************************** + * Main + *****************************************************************************/ +gint +main(gint argc, gchar *argv[]) { + g_test_init(&argc, &argv, NULL); + + g_test_add_func("/conversation-member/new", + test_purple_conversation_member_new); + g_test_add_func("/conversation-member/properties", + test_purple_conversation_member_properties); + + return g_test_run(); +} |