pidgin/pidgin

Create PurpleCreateConversationDetails

5 weeks ago, Gary Kramlich
3844b333df53
Parents efe66edc9676
Children b82b5609c044
Create PurpleCreateConversationDetails

This is the first step of letting protocols create the conversations for us.

Testing Done:
Ran the unit tests and the turtles.

Bugs closed: PIDGIN-17855

Reviewed at https://reviews.imfreedom.org/r/3014/
--- a/libpurple/meson.build Mon Mar 18 23:50:39 2024 -0500
+++ b/libpurple/meson.build Tue Mar 19 00:38:22 2024 -0500
@@ -52,6 +52,7 @@
'purpleconversationmanager.c',
'purpleconversationmember.c',
'purpleconversationuiops.c',
+ 'purplecreateconversationdetails.c',
'purplecredentialmanager.c',
'purplecredentialprovider.c',
'purpledebugui.c',
@@ -176,6 +177,7 @@
'purpleconversationmanager.h',
'purpleconversationmember.h',
'purpleconversationuiops.h',
+ 'purplecreateconversationdetails.h',
'purplecredentialmanager.h',
'purplecredentialprovider.h',
'purpledebugui.h',
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/purplecreateconversationdetails.c Tue Mar 19 00:38:22 2024 -0500
@@ -0,0 +1,213 @@
+/*
+ * 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 <gio/gio.h>
+
+#include "purplecreateconversationdetails.h"
+
+#include "purplecontact.h"
+
+enum {
+ PROP_0,
+ PROP_MAX_PARTICIPANTS,
+ PROP_PARTICIPANTS,
+ N_PROPERTIES,
+};
+static GParamSpec *properties[N_PROPERTIES] = {NULL, };
+
+struct _PurpleCreateConversationDetails {
+ GObject parent;
+
+ guint max_participants;
+ GListModel *participants;
+};
+
+/******************************************************************************
+ * Helpers
+ *****************************************************************************/
+static void
+purple_create_conversation_details_set_max_participants(PurpleCreateConversationDetails *details,
+ guint max_participants)
+{
+ g_return_if_fail(PURPLE_IS_CREATE_CONVERSATION_DETAILS(details));
+
+ if(details->max_participants != max_participants) {
+ details->max_participants = max_participants;
+
+ g_object_notify_by_pspec(G_OBJECT(details),
+ properties[PROP_MAX_PARTICIPANTS]);
+ }
+}
+
+/******************************************************************************
+ * GObject Implementation
+ *****************************************************************************/
+G_DEFINE_TYPE(PurpleCreateConversationDetails,
+ purple_create_conversation_details,
+ G_TYPE_OBJECT)
+
+static void
+purple_create_conversation_details_finalize(GObject *obj) {
+ PurpleCreateConversationDetails *details = NULL;
+
+ details = PURPLE_CREATE_CONVERSATION_DETAILS(obj);
+
+ g_clear_object(&details->participants);
+
+ G_OBJECT_CLASS(purple_create_conversation_details_parent_class)->finalize(obj);
+}
+
+static void
+purple_create_conversation_details_get_property(GObject *obj, guint param_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleCreateConversationDetails *details = NULL;
+
+ details = PURPLE_CREATE_CONVERSATION_DETAILS(obj);
+
+ switch(param_id) {
+ case PROP_MAX_PARTICIPANTS:
+ g_value_set_uint(value,
+ purple_create_conversation_details_get_max_participants(details));
+ break;
+ case PROP_PARTICIPANTS:
+ g_value_set_object(value,
+ purple_create_conversation_details_get_participants(details));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+purple_create_conversation_details_set_property(GObject *obj, guint param_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleCreateConversationDetails *details = NULL;
+
+ details = PURPLE_CREATE_CONVERSATION_DETAILS(obj);
+
+ switch(param_id) {
+ case PROP_MAX_PARTICIPANTS:
+ purple_create_conversation_details_set_max_participants(details,
+ g_value_get_uint(value));
+ break;
+ case PROP_PARTICIPANTS:
+ purple_create_conversation_details_set_participants(details,
+ g_value_get_object(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+purple_create_conversation_details_init(G_GNUC_UNUSED PurpleCreateConversationDetails *details)
+{
+}
+
+static void
+purple_create_conversation_details_class_init(PurpleCreateConversationDetailsClass *klass)
+{
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+
+ obj_class->finalize = purple_create_conversation_details_finalize;
+ obj_class->get_property = purple_create_conversation_details_get_property;
+ obj_class->set_property = purple_create_conversation_details_set_property;
+
+ /**
+ * PurpleCreateConversationDetails:max-participants:
+ *
+ * The maximum number of participants that can be supported by the
+ * protocol not including the libpurple user.
+ *
+ * Since: 3.0.0
+ */
+ properties[PROP_MAX_PARTICIPANTS] = g_param_spec_uint(
+ "max-participants", "max-participants",
+ "The maximum number of participants that the protocol supports.",
+ 0, G_MAXUINT, 0,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+
+ /**
+ * PurpleCreateConversationDetails:participants:
+ *
+ * A [iface@Gio.ListModel] of [class@Contact]s to add to the conversation
+ * not including the libpurple user.
+ *
+ * Since: 3.0.0
+ */
+ properties[PROP_PARTICIPANTS] = g_param_spec_object(
+ "participants", "participants",
+ "The list of contacts to add to the conversation.",
+ G_TYPE_LIST_MODEL,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
+}
+
+/******************************************************************************
+ * Public API
+ *****************************************************************************/
+PurpleCreateConversationDetails *
+purple_create_conversation_details_new(guint max_participants) {
+ return g_object_new(
+ PURPLE_TYPE_CREATE_CONVERSATION_DETAILS,
+ "max-participants", max_participants,
+ NULL);
+}
+
+guint
+purple_create_conversation_details_get_max_participants(PurpleCreateConversationDetails *details)
+{
+ g_return_val_if_fail(PURPLE_IS_CREATE_CONVERSATION_DETAILS(details), 0);
+
+ return details->max_participants;
+}
+
+GListModel *
+purple_create_conversation_details_get_participants(PurpleCreateConversationDetails *details)
+{
+ g_return_val_if_fail(PURPLE_IS_CREATE_CONVERSATION_DETAILS(details), NULL);
+
+ return details->participants;
+}
+
+void
+purple_create_conversation_details_set_participants(PurpleCreateConversationDetails *details,
+ GListModel *participants)
+{
+ g_return_if_fail(PURPLE_IS_CREATE_CONVERSATION_DETAILS(details));
+
+ if(G_IS_LIST_MODEL(participants)) {
+ g_return_if_fail(g_list_model_get_item_type(participants) == PURPLE_TYPE_CONTACT);
+ }
+
+ if(g_set_object(&details->participants, participants)) {
+ g_object_notify_by_pspec(G_OBJECT(details),
+ properties[PROP_PARTICIPANTS]);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/purplecreateconversationdetails.h Tue Mar 19 00:38:22 2024 -0500
@@ -0,0 +1,114 @@
+/*
+ * 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_CREATE_CONVERSATION_DETAILS_H
+#define PURPLE_CREATE_CONVERSATION_DETAILS_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include "purpleversion.h"
+
+G_BEGIN_DECLS
+
+#define PURPLE_TYPE_CREATE_CONVERSATION_DETAILS (purple_create_conversation_details_get_type())
+
+PURPLE_AVAILABLE_IN_3_0
+G_DECLARE_FINAL_TYPE(PurpleCreateConversationDetails, purple_create_conversation_details, PURPLE, CREATE_CONVERSATION_DETAILS, GObject)
+
+/**
+ * PurpleCreateConversationDetails:
+ *
+ * The details that are necessary for a [class@Protocol] to create a
+ * conversation.
+ *
+ * This is only used to create direct messages and group direct messages. The
+ * user interface will ask a protocol for a [class@CreateConversationDetails]
+ * and then fill it out and pass it back to the protocol to actually create a
+ * conversation.
+ *
+ * Since: 3.0
+ */
+
+/**
+ * purple_create_conversation_details_new:
+ * @max_participants: The maximum number of participants. %0 to say unlimited.
+ *
+ * Creates a new [class@CreateConversationDetails].
+ *
+ * Returns: (transfer full): The new instance.
+ *
+ * Since: 3.0
+ */
+PURPLE_AVAILABLE_IN_3_0
+PurpleCreateConversationDetails *purple_create_conversation_details_new(guint max_participants);
+
+/**
+ * purple_create_conversation_details_get_max_participants:
+ * @details: The instance.
+ *
+ * Gets the maximum number of participants that are supported not including the
+ * libpurple user.
+ *
+ * Returns: The maximum number of participants.
+ *
+ * Since: 3.0
+ */
+PURPLE_AVAILABLE_IN_3_0
+guint purple_create_conversation_details_get_max_participants(PurpleCreateConversationDetails *details);
+
+/**
+ * purple_create_conversation_details_get_participants:
+ * @details: The instance.
+ *
+ * Gets the participants to add to the conversation.
+ *
+ * Returns: (transfer none) (nullable): The participants.
+ *
+ * Since: 3.0
+ */
+PURPLE_AVAILABLE_IN_3_0
+GListModel *purple_create_conversation_details_get_participants(PurpleCreateConversationDetails *details);
+
+/**
+ * purple_create_conversation_details_set_participants:
+ * @details: The instance.
+ * @participants: (nullable) (transfer none): The new participants.
+ *
+ * Sets the participants to @participants.
+ *
+ * Participants must have an item type of [class@Contact] and the number of
+ * items must be less than or equal to
+ * [property@CreateConversationDetails:max-participants].
+ *
+ * Since: 3.0
+ */
+PURPLE_AVAILABLE_IN_3_0
+void purple_create_conversation_details_set_participants(PurpleCreateConversationDetails *details, GListModel *participants);
+
+G_END_DECLS
+
+#endif /* PURPLE_CREATE_CONVERSATION_DETAILS_H */
--- a/libpurple/tests/meson.build Mon Mar 18 23:50:39 2024 -0500
+++ b/libpurple/tests/meson.build Tue Mar 19 00:38:22 2024 -0500
@@ -4,6 +4,7 @@
'authorization_request',
'channel_join_details',
'circular_buffer',
+ 'create_conversation_details',
'contact',
'contact_info',
'contact_manager',
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/tests/test_create_conversation_details.c Tue Mar 19 00:38:22 2024 -0500
@@ -0,0 +1,86 @@
+/*
+ * 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.h>
+
+#include <purple.h>
+
+/******************************************************************************
+ * Tests
+ *****************************************************************************/
+static void
+test_purple_create_conversation_details_new(void) {
+ PurpleCreateConversationDetails *details = NULL;
+
+ details = purple_create_conversation_details_new(9);
+ g_assert_true(PURPLE_IS_CREATE_CONVERSATION_DETAILS(details));
+
+ g_assert_finalize_object(details);
+}
+
+static void
+test_purple_create_conversation_details_properties(void) {
+ PurpleCreateConversationDetails *details = NULL;
+ GListStore *store = NULL;
+ GListModel *model = NULL;
+ guint max_participants = 0;
+
+ store = g_list_store_new(PURPLE_TYPE_CONTACT);
+
+ details = g_object_new(
+ PURPLE_TYPE_CREATE_CONVERSATION_DETAILS,
+ "max-participants", 9,
+ "participants", store,
+ NULL);
+
+ g_assert_true(PURPLE_IS_CREATE_CONVERSATION_DETAILS(details));
+
+ g_object_get(
+ G_OBJECT(details),
+ "max-participants", &max_participants,
+ "participants", &model,
+ NULL);
+
+ g_assert_cmpuint(max_participants, ==, 9);
+
+ g_assert_true(G_IS_LIST_MODEL(model));
+ g_assert_true(model == G_LIST_MODEL(store));
+ g_clear_object(&model);
+
+ g_assert_finalize_object(details);
+ g_assert_finalize_object(store);
+}
+
+/******************************************************************************
+ * Main
+ *****************************************************************************/
+int
+main(int argc, char *argv[]) {
+ g_test_init(&argc, &argv, NULL);
+
+ g_test_add_func("/create-conversation-details/new",
+ test_purple_create_conversation_details_new);
+ g_test_add_func("/create-conversation-details/properties",
+ test_purple_create_conversation_details_properties);
+
+ return g_test_run();
+}