Tue, 07 Jan 2025 04:49:09 -0600
Make sure we notify on the n-items property for all objects that have it
Testing Done:
Called in the turtles.
Reviewed at https://reviews.imfreedom.org/r/3736/
| 42918 | 1 | /* |
| 2 | * Purple - Internet Messaging Library | |
| 3 | * Copyright (C) Pidgin Developers <devel@pidgin.im> | |
| 4 | * | |
| 5 | * Purple is the legal property of its developers, whose names are too numerous | |
| 6 | * to list here. Please refer to the COPYRIGHT file distributed with this | |
| 7 | * source distribution. | |
| 8 | * | |
| 9 | * This library is free software; you can redistribute it and/or modify it | |
| 10 | * under the terms of the GNU General Public License as published by the Free | |
| 11 | * Software Foundation; either version 2 of the License, or (at your option) | |
| 12 | * any later version. | |
| 13 | * | |
| 14 | * This library is distributed in the hope that it will be useful, but WITHOUT | |
| 15 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
| 16 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
| 17 | * more details. | |
| 18 | * | |
| 19 | * You should have received a copy of the GNU General Public License along with | |
| 20 | * this library; if not, see <https://www.gnu.org/licenses/>. | |
| 21 | */ | |
| 22 | ||
| 23 | #include <gio/gio.h> | |
| 24 | ||
| 25 | #include "purplebadges.h" | |
| 26 | ||
| 27 | #include "util.h" | |
| 28 | ||
| 29 | struct _PurpleBadges { | |
| 30 | GObject parent; | |
| 31 | ||
| 32 | GPtrArray *badges; | |
| 33 | }; | |
| 34 | ||
| 35 | enum { | |
| 36 | PROP_0, | |
| 37 | PROP_ITEM_TYPE, | |
| 38 | PROP_N_ITEMS, | |
| 39 | N_PROPERTIES, | |
| 40 | }; | |
| 41 | static GParamSpec *properties[N_PROPERTIES] = {NULL, }; | |
| 42 | ||
| 43 | /****************************************************************************** | |
| 44 | * Helpers | |
| 45 | *****************************************************************************/ | |
| 46 | static gboolean | |
| 47 | purple_badges_equal(gconstpointer a, gconstpointer b) { | |
| 48 | PurpleBadge *badge1 = (gpointer)a; | |
| 49 | PurpleBadge *badge2 = (gpointer)b; | |
| 50 | ||
| 51 | return purple_badge_equal(badge1, badge2); | |
| 52 | } | |
| 53 | ||
| 54 | static int | |
| 55 | purple_badges_compare(gconstpointer a, gconstpointer b) { | |
| 56 | PurpleBadge *badge1 = (gpointer)a; | |
| 57 | PurpleBadge *badge2 = (gpointer)b; | |
| 58 | ||
| 59 | return purple_badge_compare(badge1, badge2); | |
| 60 | } | |
| 61 | ||
| 62 | /****************************************************************************** | |
| 63 | * GListModel Implementation | |
| 64 | *****************************************************************************/ | |
| 65 | static GType | |
| 66 | purple_badges_get_item_type(G_GNUC_UNUSED GListModel *model) { | |
| 67 | return PURPLE_TYPE_BADGE; | |
| 68 | } | |
| 69 | ||
| 70 | static guint | |
| 71 | purple_badges_get_n_items(GListModel *model) { | |
| 72 | PurpleBadges *badges = PURPLE_BADGES(model); | |
| 73 | ||
| 74 | return badges->badges->len; | |
| 75 | } | |
| 76 | ||
| 77 | static gpointer | |
| 78 | purple_badges_get_item(GListModel *model, guint position) { | |
| 79 | PurpleBadges *badges = PURPLE_BADGES(model); | |
| 80 | PurpleBadge *badge = NULL; | |
| 81 | ||
| 82 | if(position < badges->badges->len) { | |
| 83 | badge = g_ptr_array_index(badges->badges, position); | |
| 84 | ||
| 85 | if(PURPLE_IS_BADGE(badge)) { | |
| 86 | g_object_ref(badge); | |
| 87 | } | |
| 88 | } | |
| 89 | ||
| 90 | return badge; | |
| 91 | } | |
| 92 | ||
| 93 | static void | |
| 94 | purple_badges_list_model_init(GListModelInterface *iface) { | |
| 95 | iface->get_item_type = purple_badges_get_item_type; | |
| 96 | iface->get_n_items = purple_badges_get_n_items; | |
| 97 | iface->get_item = purple_badges_get_item; | |
| 98 | } | |
| 99 | ||
| 100 | /****************************************************************************** | |
| 101 | * GObject Implementation | |
| 102 | *****************************************************************************/ | |
| 103 | G_DEFINE_FINAL_TYPE_WITH_CODE(PurpleBadges, purple_badges, G_TYPE_OBJECT, | |
| 104 | G_IMPLEMENT_INTERFACE(G_TYPE_LIST_MODEL, | |
| 105 | purple_badges_list_model_init)) | |
| 106 | ||
| 107 | static void | |
| 108 | purple_badges_finalize(GObject *obj) { | |
| 109 | PurpleBadges *badges = PURPLE_BADGES(obj); | |
| 110 | ||
| 111 | g_clear_pointer(&badges->badges, g_ptr_array_unref); | |
| 112 | ||
| 113 | G_OBJECT_CLASS(purple_badges_parent_class)->finalize(obj); | |
| 114 | } | |
| 115 | ||
| 116 | static void | |
| 117 | purple_badges_get_property(GObject *obj, guint param_id, GValue *value, | |
| 118 | GParamSpec *pspec) | |
| 119 | { | |
| 120 | GListModel *model = G_LIST_MODEL(obj); | |
| 121 | ||
| 122 | switch(param_id) { | |
| 123 | case PROP_ITEM_TYPE: | |
| 124 | g_value_set_gtype(value, g_list_model_get_item_type(model)); | |
| 125 | break; | |
| 126 | case PROP_N_ITEMS: | |
| 127 | g_value_set_uint(value, g_list_model_get_n_items(model)); | |
| 128 | break; | |
| 129 | default: | |
| 130 | G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec); | |
| 131 | break; | |
| 132 | } | |
| 133 | } | |
| 134 | ||
| 135 | static void | |
| 136 | purple_badges_init(PurpleBadges *badges) { | |
| 137 | badges->badges = g_ptr_array_new_full(0, g_object_unref); | |
| 138 | } | |
| 139 | ||
| 140 | static void | |
| 141 | purple_badges_class_init(PurpleBadgesClass *klass) { | |
| 142 | GObjectClass *obj_class = G_OBJECT_CLASS(klass); | |
| 143 | ||
| 144 | obj_class->finalize = purple_badges_finalize; | |
| 145 | obj_class->get_property = purple_badges_get_property; | |
| 146 | ||
| 147 | /** | |
| 148 | * PurpleBadges:item-type: | |
| 149 | * | |
|
42984
818220289e67
Update the gi-docgen subproject and fix some new issues it found
Gary Kramlich <grim@reaperworld.com>
parents:
42918
diff
changeset
|
150 | * The type of items. See [vfunc@Gio.ListModel.get_item_type]. |
| 42918 | 151 | * |
| 152 | * Since: 3.0 | |
| 153 | */ | |
| 154 | properties[PROP_ITEM_TYPE] = g_param_spec_gtype( | |
| 155 | "item-type", NULL, NULL, | |
| 156 | PURPLE_TYPE_BADGE, | |
| 157 | G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); | |
| 158 | ||
| 159 | /** | |
| 160 | * PurpleBadges:n-items: | |
| 161 | * | |
|
42984
818220289e67
Update the gi-docgen subproject and fix some new issues it found
Gary Kramlich <grim@reaperworld.com>
parents:
42918
diff
changeset
|
162 | * The number of items. See [vfunc@Gio.ListModel.get_n_items]. |
| 42918 | 163 | * |
| 164 | * Since: 3.0 | |
| 165 | */ | |
| 166 | properties[PROP_N_ITEMS] = g_param_spec_uint( | |
| 167 | "n-items", NULL, NULL, | |
| 168 | 0, G_MAXUINT, 0, | |
| 169 | G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); | |
| 170 | ||
| 171 | g_object_class_install_properties(obj_class, N_PROPERTIES, properties); | |
| 172 | } | |
| 173 | ||
| 174 | /****************************************************************************** | |
| 175 | * Public API | |
| 176 | *****************************************************************************/ | |
| 177 | PurpleBadges * | |
| 178 | purple_badges_new(void) { | |
| 179 | return g_object_new(PURPLE_TYPE_BADGES, NULL); | |
| 180 | } | |
| 181 | ||
| 182 | gboolean | |
| 183 | purple_badges_add_badge(PurpleBadges *badges, PurpleBadge *badge) { | |
| 184 | gboolean found = FALSE; | |
| 185 | guint len = 0; | |
| 186 | ||
| 187 | g_return_val_if_fail(PURPLE_IS_BADGES(badges), FALSE); | |
| 188 | g_return_val_if_fail(PURPLE_IS_BADGE(badge), FALSE); | |
| 189 | ||
| 190 | found = g_ptr_array_find_with_equal_func(badges->badges, badge, | |
| 191 | purple_badges_equal, NULL); | |
| 192 | ||
| 193 | if(found) { | |
| 194 | return FALSE; | |
| 195 | } | |
| 196 | ||
| 197 | /* Store length before adding to make the math easier to understand. */ | |
| 198 | len = badges->badges->len; | |
| 199 | ||
| 200 | g_ptr_array_add(badges->badges, g_object_ref(badge)); | |
| 201 | g_ptr_array_sort_values(badges->badges, purple_badges_compare); | |
| 202 | ||
| 203 | g_list_model_items_changed(G_LIST_MODEL(badges), 0, len, len + 1); | |
|
43128
1ce3ad90614c
Make sure we notify on the n-items property for all objects that have it
Gary Kramlich <grim@reaperworld.com>
parents:
42984
diff
changeset
|
204 | g_object_notify_by_pspec(G_OBJECT(badges), properties[PROP_N_ITEMS]); |
| 42918 | 205 | |
| 206 | return TRUE; | |
| 207 | } | |
| 208 | ||
| 209 | gboolean | |
| 210 | purple_badges_remove_badge(PurpleBadges *badges, const char *id) { | |
| 211 | PurpleBadge *needle = NULL; | |
| 212 | gboolean found = FALSE; | |
| 213 | guint index = 0; | |
| 214 | ||
| 215 | g_return_val_if_fail(PURPLE_IS_BADGES(badges), FALSE); | |
| 216 | g_return_val_if_fail(!purple_strempty(id), FALSE); | |
| 217 | ||
| 218 | /* We only need the id, but the other values can't be null. */ | |
| 219 | needle = purple_badge_new(id, 0, "folder-saved-search-symbolic", "🔍"); | |
| 220 | ||
| 221 | found = g_ptr_array_find_with_equal_func(badges->badges, needle, | |
| 222 | purple_badges_equal, &index); | |
| 223 | g_clear_object(&needle); | |
| 224 | ||
| 225 | if(!found) { | |
| 226 | return FALSE; | |
| 227 | } | |
| 228 | ||
| 229 | g_ptr_array_remove_index(badges->badges, index); | |
| 230 | ||
| 231 | g_list_model_items_changed(G_LIST_MODEL(badges), index, 1, 0); | |
|
43128
1ce3ad90614c
Make sure we notify on the n-items property for all objects that have it
Gary Kramlich <grim@reaperworld.com>
parents:
42984
diff
changeset
|
232 | g_object_notify_by_pspec(G_OBJECT(badges), properties[PROP_N_ITEMS]); |
| 42918 | 233 | |
| 234 | return TRUE; | |
| 235 | } |