Tue, 19 Mar 2024 00:38:22 -0500
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(); +}