From b90b99f1bd2450d8f48597c4ea996af4d0157a94 Mon Sep 17 00:00:00 2001 From: mindonwarp Date: Fri, 23 Jan 2026 22:22:43 +0100 Subject: [PATCH] core: Use GListModel for attendees instead of GSList Part-of: --- src/core/gcal-event-attendee.c | 6 ++-- src/core/gcal-event.c | 31 +++++++++---------- src/core/gcal-event.h | 3 +- src/gui/event-editor/gcal-attendees-section.c | 24 ++++---------- .../event-editor/gcal-event-editor-dialog.c | 14 +++------ tests/test-event.c | 8 ++--- 6 files changed, 35 insertions(+), 51 deletions(-) diff --git a/src/core/gcal-event-attendee.c b/src/core/gcal-event-attendee.c index bf418dbd..27dfd684 100644 --- a/src/core/gcal-event-attendee.c +++ b/src/core/gcal-event-attendee.c @@ -200,11 +200,13 @@ gcal_event_attendee_get_property (GObject *object, } static void -gcal_event_attendee_dispose (GObject *instance) +gcal_event_attendee_dispose (GObject *object) { - GcalEventAttendee *self = GCAL_EVENT_ATTENDEE (instance); + GcalEventAttendee *self = GCAL_EVENT_ATTENDEE (object); g_clear_pointer (&self->ecal_attendee, e_cal_component_attendee_free); + + G_OBJECT_CLASS (gcal_event_attendee_parent_class)->dispose (object); } static void diff --git a/src/core/gcal-event.c b/src/core/gcal-event.c index 1f37329e..af7453df 100644 --- a/src/core/gcal-event.c +++ b/src/core/gcal-event.c @@ -27,6 +27,7 @@ #include "gcal-recurrence.h" #include "gcal-utils.h" +#include #include #define LIBICAL_TZID_PREFIX "/freeassociation.sourceforge.net/" @@ -99,7 +100,7 @@ struct _GcalEvent /* A map of GcalAlarmType */ GHashTable *alarms; - GSList *attendees; + GListStore *attendees; GcalEventOrganizer *organizer; ECalComponent *component; @@ -315,10 +316,9 @@ load_attendees (GcalEvent *self) for (c = ecal_attendees; c != NULL; c = c->next) { - GcalEventAttendee *attendee; + g_autoptr (GcalEventAttendee) attendee = NULL; attendee = gcal_event_attendee_new (c->data); - /* we don't care about the order so no need to reverse */ - self->attendees = g_slist_prepend (self->attendees, attendee); + g_list_store_append (self->attendees, attendee); } g_slist_free_full (ecal_attendees, e_cal_component_attendee_free); @@ -504,10 +504,10 @@ gcal_event_finalize (GObject *object) g_clear_pointer (&self->alarms, g_hash_table_unref); g_clear_pointer (&self->uid, g_free); g_clear_pointer (&self->color, gdk_rgba_free); + g_clear_pointer (&self->recurrence, gcal_recurrence_unref); g_clear_object (&self->component); g_clear_object (&self->calendar); - g_clear_pointer (&self->recurrence, gcal_recurrence_unref); - g_slist_free_full (self->attendees, g_object_unref); + g_clear_object (&self->attendees); g_clear_object (&self->organizer); G_OBJECT_CLASS (gcal_event_parent_class)->finalize (object); @@ -813,6 +813,9 @@ gcal_event_init (GcalEvent *self) /* Alarms */ self->alarms = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free); + + /* Attendees */ + self->attendees = g_list_store_new (GCAL_TYPE_EVENT_ATTENDEE); } /** @@ -1833,9 +1836,12 @@ gcal_event_overlaps (GcalEvent *self, * gcal_event_get_attendees: * @self: a #GcalEvent * - * Returns: (transfer full) (nullable): a copy list of attendees. + * Remember that g_list_model_get_item() increases the ref count on + * the returned object. + * + * Returns: (transfer none) (nullable): the attendees belonging to @self */ -GSList * +GListModel * gcal_event_get_attendees (GcalEvent *self) { g_return_val_if_fail (GCAL_IS_EVENT (self), NULL); @@ -1843,14 +1849,7 @@ gcal_event_get_attendees (GcalEvent *self) if (self->attendees == NULL) return NULL; - GSList *ret = NULL, *c = NULL; - for (c = self->attendees; c != NULL; c = c->next) - { - ret = g_slist_prepend (ret, g_object_ref (c->data)); - } - - /* reverse here so the returned list order matches the internal one */ - return g_slist_reverse (ret); + return G_LIST_MODEL (self->attendees); } /** diff --git a/src/core/gcal-event.h b/src/core/gcal-event.h index 47b0a076..ef3443d8 100644 --- a/src/core/gcal-event.h +++ b/src/core/gcal-event.h @@ -24,6 +24,7 @@ #include "gcal-range.h" #include "gcal-recurrence.h" +#include #include #include #include @@ -134,7 +135,7 @@ gchar* gcal_event_format_date (GcalEvent gboolean gcal_event_overlaps (GcalEvent *self, GcalRange *range); -GSList * gcal_event_get_attendees (GcalEvent *self); +GListModel * gcal_event_get_attendees (GcalEvent *self); GcalEventOrganizer * gcal_event_get_organizer (GcalEvent *self); diff --git a/src/gui/event-editor/gcal-attendees-section.c b/src/gui/event-editor/gcal-attendees-section.c index 7f63ccde..e50e01ce 100644 --- a/src/gui/event-editor/gcal-attendees-section.c +++ b/src/gui/event-editor/gcal-attendees-section.c @@ -41,7 +41,7 @@ struct _GcalAttendeesSection AdwActionRow *summary_row; - GListStore *attendees; + GListModel *attendees; }; static void gcal_event_editor_section_init_iface (GcalEventEditorSectionInterface *iface); @@ -60,27 +60,17 @@ enum static GParamSpec *properties[N_PROPS] = { NULL, }; -static void -reset_section (GcalAttendeesSection *self, - GcalEvent *event) -{ - g_set_object (&self->event, event); - - g_list_store_remove_all (self->attendees); -} - static void gcal_attendees_section_set_event (GcalEventEditorSection *section, GcalEvent *event, GcalEventEditorFlags flags) { GcalAttendeesSection *self = GCAL_ATTENDEES_SECTION (section); - g_autoptr (GSList) attendees = NULL; if (event == self->event) return; - reset_section (self, event); + g_set_object (&self->event, event); if (self->event == NULL) return; @@ -89,9 +79,7 @@ gcal_attendees_section_set_event (GcalEventEditorSection *section, self->organizer = gcal_event_get_organizer (self->event); /* set attendees and summarize attendance status */ - attendees = gcal_event_get_attendees (self->event); - for (GSList *l = attendees; l != NULL; l = l->next) - g_list_store_append (self->attendees, GCAL_EVENT_ATTENDEE (l->data)); + self->attendees = gcal_event_get_attendees (self->event); g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ATTENDEES]); g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ORGANIZER]); @@ -176,7 +164,8 @@ gcal_attendees_section_finalize (GObject *object) g_clear_object (&self->context); g_clear_object (&self->event); - g_clear_pointer (&self->attendees, g_list_store_remove_all); + + self->attendees = NULL; /* not owned */ G_OBJECT_CLASS (gcal_attendees_section_parent_class)->finalize (object); } @@ -184,7 +173,6 @@ gcal_attendees_section_finalize (GObject *object) static void gcal_attendees_section_init (GcalAttendeesSection *instance) { - instance->attendees = g_list_store_new (GCAL_TYPE_EVENT_ATTENDEE); gtk_widget_init_template (GTK_WIDGET (instance)); } @@ -219,7 +207,7 @@ gcal_attendees_section_class_init (GcalAttendeesSectionClass *klass) */ properties[PROP_ATTENDEES] = g_param_spec_object ("attendees", NULL, NULL, - G_TYPE_LIST_STORE, + G_TYPE_LIST_MODEL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); /** diff --git a/src/gui/event-editor/gcal-event-editor-dialog.c b/src/gui/event-editor/gcal-event-editor-dialog.c index feb35cd8..c6b06a16 100644 --- a/src/gui/event-editor/gcal-event-editor-dialog.c +++ b/src/gui/event-editor/gcal-event-editor-dialog.c @@ -81,7 +81,7 @@ struct _GcalEventEditorDialog GBinding *event_title_binding; GListStore *read_only_calendar_model; - GListStore *attendees_model; + GListModel *attendees_model; GSimpleActionGroup *action_group; /* flags */ @@ -205,7 +205,6 @@ setup_context (GcalEventEditorDialog *self) writable_calendars = gcal_create_writable_calendars_model (manager); self->read_only_calendar_model = g_list_store_new (GCAL_TYPE_CALENDAR); - self->attendees_model = g_list_store_new (GCAL_TYPE_EVENT_ATTENDEE); all_calendars = g_list_store_new (G_TYPE_LIST_MODEL); g_list_store_append (all_calendars, self->read_only_calendar_model); @@ -330,7 +329,7 @@ on_show_attendees_detail_page_action_activated_cb (GSimpleAction *action, GcalEventEditorDialog *self = GCAL_EVENT_EDITOR_DIALOG (user_data); gcal_attendee_details_page_set_attendees (GCAL_ATTENDEE_DETAILS_PAGE (self->attendee_details_page), - G_LIST_MODEL (self->attendees_model)); + self->attendees_model); gcal_attendee_details_page_set_type_filter (GCAL_ATTENDEE_DETAILS_PAGE (self->attendee_details_page), g_variant_get_uint32 (param)); @@ -479,7 +478,8 @@ gcal_event_editor_dialog_finalize (GObject *object) g_clear_object (&self->action_group); g_clear_object (&self->context); g_clear_object (&self->event); - g_clear_pointer (&self->attendees_model, g_list_store_remove_all); + + self->attendees_model = NULL; /* not owned */ G_OBJECT_CLASS (gcal_event_editor_dialog_parent_class)->finalize (object); @@ -677,7 +677,6 @@ gcal_event_editor_dialog_set_event (GcalEventEditorDialog *self, { g_autoptr (GdkPaintable) paintable = NULL; g_autoptr (GcalEvent) cloned_event = NULL; - g_autoptr (GSList) attendees = NULL; GcalEventEditorFlags flags; GcalCalendar *calendar; gint i; @@ -687,7 +686,6 @@ gcal_event_editor_dialog_set_event (GcalEventEditorDialog *self, g_return_if_fail (GCAL_IS_EVENT_EDITOR_DIALOG (self)); g_clear_object (&self->event); - g_list_store_remove_all (self->attendees_model); /* If we just set the event to NULL, simply send a property notify */ if (!event) @@ -732,9 +730,7 @@ gcal_event_editor_dialog_set_event (GcalEventEditorDialog *self, gtk_widget_grab_focus (self->done_button); /* fill attendees list */ - attendees = gcal_event_get_attendees (self->event); - for (GSList *it = attendees; it != NULL; it = it->next) - g_list_store_append (self->attendees_model, GCAL_EVENT_ATTENDEE (it->data)); + self->attendees_model = gcal_event_get_attendees (self->event); out: flags = GCAL_EVENT_EDITOR_FLAG_NONE; diff --git a/tests/test-event.c b/tests/test-event.c index 8e9307bc..3816465a 100644 --- a/tests/test-event.c +++ b/tests/test-event.c @@ -411,7 +411,7 @@ event_get_attendees (void) /* "ATTENDEE;CN=Carol Lee;RSVP=FALSE;ROLE=OPT-PARTICIPANT:mailto:carol@example.com\n" \ */ g_autoptr (GcalEvent) event = NULL; g_autoptr (GError) error = NULL; - GSList *attendees = NULL, *l = NULL; + GListModel *attendees = NULL; event = create_event_for_string (STUB_EVENT_WITH_ATTENDEES, &error); @@ -419,9 +419,9 @@ event_get_attendees (void) g_assert_nonnull (attendees); - for (l = attendees; l != NULL; l = l->next) + for (guint i = 0; i < g_list_model_get_n_items (attendees); ++i) { - GcalEventAttendee *at = (GcalEventAttendee *) l->data; + g_autoptr (GcalEventAttendee) at = (GcalEventAttendee *) g_list_model_get_item (attendees, i); g_assert_cmpstr (NULL, !=, gcal_event_attendee_get_name (at)); g_assert_cmpstr (NULL, !=, gcal_event_attendee_get_uri (at)); @@ -438,8 +438,6 @@ event_get_attendees (void) g_autofree const gchar *uri_trimmed = gcal_get_email_from_mailto_uri (gcal_event_organizer_get_uri (organizer)); g_assert_cmpstr ("alice@example.com", ==, uri_trimmed); - - g_slist_free_full (attendees, g_object_unref); } /*********************************************************************************************************************/