summaryrefslogtreecommitdiff
path: root/libpurple
diff options
context:
space:
mode:
authorGary Kramlich <grim@reaperworld.com>2023-02-23 01:33:50 -0600
committerGary Kramlich <grim@reaperworld.com>2023-02-23 01:33:50 -0600
commitd029f072265c068cb35d563dacdf7911e3edd840 (patch)
tree9d3b81bb407e61a094827e6e785cb000d9c46873 /libpurple
parente22ab2383cdf2498f6b084ee7156c16dd90d5821 (diff)
downloadpidgin-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.build2
-rw-r--r--libpurple/purpleconversationmember.c182
-rw-r--r--libpurple/purpleconversationmember.h94
-rw-r--r--libpurple/tests/meson.build1
-rw-r--r--libpurple/tests/test_conversation_member.c90
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();
+}