libpurple/purpleattachments.c

changeset 43145
dff7cdade009
child 43147
835d74e5d22d
equal deleted inserted replaced
43144:627ee13c5dee 43145:dff7cdade009
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 "purpleattachments.h"
26
27 struct _PurpleAttachments {
28 GObject parent;
29
30 GPtrArray *attachments;
31 };
32
33 enum {
34 PROP_0,
35 PROP_ITEM_TYPE,
36 PROP_N_ITEMS,
37 N_PROPERTIES,
38 };
39 static GParamSpec *properties[N_PROPERTIES] = {NULL, };
40
41 /******************************************************************************
42 * Helpers
43 *****************************************************************************/
44 static gboolean
45 purple_attachments_equal(gconstpointer a, gconstpointer b) {
46 PurpleAttachment *attachment1 = (gpointer)a;
47 PurpleAttachment *attachment2 = (gpointer)b;
48
49 return purple_attachment_equal(attachment1, attachment2);
50 }
51
52 /******************************************************************************
53 * GListModel Implementation
54 *****************************************************************************/
55 static GType
56 purple_attachments_get_item_type(G_GNUC_UNUSED GListModel *model) {
57 return PURPLE_TYPE_ATTACHMENT;
58 }
59
60 static guint
61 purple_attachments_get_n_items(GListModel *model) {
62 PurpleAttachments *attachments = PURPLE_ATTACHMENTS(model);
63
64 return attachments->attachments->len;
65 }
66
67 static gpointer
68 purple_attachments_get_item(GListModel *model, guint position) {
69 PurpleAttachments *attachments = PURPLE_ATTACHMENTS(model);
70 PurpleAttachment *attachment = NULL;
71
72 if(position < attachments->attachments->len) {
73 attachment = g_ptr_array_index(attachments->attachments, position);
74
75 if(PURPLE_IS_ATTACHMENT(attachment)) {
76 g_object_ref(attachment);
77 }
78 }
79
80 return attachment;
81 }
82
83 static void
84 purple_attachments_list_model_iface_init(GListModelInterface *iface) {
85 iface->get_item_type = purple_attachments_get_item_type;
86 iface->get_n_items = purple_attachments_get_n_items;
87 iface->get_item = purple_attachments_get_item;
88 }
89
90 /******************************************************************************
91 * GObject Implementation
92 *****************************************************************************/
93 G_DEFINE_FINAL_TYPE_WITH_CODE(PurpleAttachments,
94 purple_attachments,
95 G_TYPE_OBJECT,
96 G_IMPLEMENT_INTERFACE(G_TYPE_LIST_MODEL,
97 purple_attachments_list_model_iface_init))
98
99 static void
100 purple_attachments_finalize(GObject *obj) {
101 PurpleAttachments *attachments = PURPLE_ATTACHMENTS(obj);
102
103 g_clear_pointer(&attachments->attachments, g_ptr_array_unref);
104
105 G_OBJECT_CLASS(purple_attachments_parent_class)->finalize(obj);
106 }
107
108 static void
109 purple_attachments_get_property(GObject *obj, guint param_id, GValue *value,
110 GParamSpec *pspec)
111 {
112 GListModel *model = G_LIST_MODEL(obj);
113
114 switch(param_id) {
115 case PROP_ITEM_TYPE:
116 g_value_set_gtype(value, g_list_model_get_item_type(model));
117 break;
118 case PROP_N_ITEMS:
119 g_value_set_uint(value, g_list_model_get_n_items(model));
120 break;
121 default:
122 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
123 break;
124 }
125 }
126
127 static void
128 purple_attachments_init(PurpleAttachments *attachments) {
129 attachments->attachments = g_ptr_array_new_full(0, g_object_unref);
130 }
131
132 static void
133 purple_attachments_class_init(PurpleAttachmentsClass *klass) {
134 GObjectClass *obj_class = G_OBJECT_CLASS(klass);
135
136 obj_class->finalize = purple_attachments_finalize;
137 obj_class->get_property = purple_attachments_get_property;
138
139 /**
140 * PurpleAttachments:item-type:
141 *
142 * The type of items. See [vfunc@Gio.ListModel.get_item_type].
143 *
144 * Since: 3.0
145 */
146 properties[PROP_ITEM_TYPE] = g_param_spec_gtype(
147 "item-type", NULL, NULL,
148 PURPLE_TYPE_ATTACHMENT,
149 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
150
151 /**
152 * PurpleAttachments:n-items:
153 *
154 * The number of items. See [vfunc@Gio.ListModel.get_n_items].
155 *
156 * Since: 3.0
157 */
158 properties[PROP_N_ITEMS] = g_param_spec_uint(
159 "n-items", NULL, NULL,
160 0, G_MAXUINT, 0,
161 G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
162
163 g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
164 }
165
166 /******************************************************************************
167 * Public API
168 *****************************************************************************/
169 gboolean
170 purple_attachments_add_attachment(PurpleAttachments *attachments,
171 PurpleAttachment *attachment)
172 {
173 GObject *obj = NULL;
174 gboolean found = FALSE;
175 guint len = 0;
176
177 g_return_val_if_fail(PURPLE_IS_ATTACHMENTS(attachments), FALSE);
178 g_return_val_if_fail(PURPLE_IS_ATTACHMENT(attachment), FALSE);
179
180 found = g_ptr_array_find_with_equal_func(attachments->attachments,
181 attachment,
182 purple_attachments_equal,
183 NULL);
184
185 if(found) {
186 return FALSE;
187 }
188
189 /* Store length before adding to make the math easier to understand. */
190 len = attachments->attachments->len;
191
192 g_ptr_array_add(attachments->attachments, g_object_ref(attachment));
193
194 obj = G_OBJECT(attachments);
195 g_object_freeze_notify(obj);
196 g_list_model_items_changed(G_LIST_MODEL(attachments), len, 0, 1);
197 g_object_notify_by_pspec(obj, properties[PROP_N_ITEMS]);
198 g_object_thaw_notify(obj);
199
200 return TRUE;
201 }
202
203 PurpleAttachment *
204 purple_attachments_find_with_id(PurpleAttachments *attachments, guint64 id) {
205 g_return_val_if_fail(PURPLE_IS_ATTACHMENTS(attachments), NULL);
206
207 for(guint i = 0; i < attachments->attachments->len; i++) {
208 PurpleAttachment *attachment = NULL;
209
210 attachment = g_ptr_array_index(attachments->attachments, i);
211
212 if(purple_attachment_get_id(attachment) == id) {
213 return attachment;
214 }
215 }
216
217 return NULL;
218 }
219
220 PurpleAttachments *
221 purple_attachments_new(void) {
222 return g_object_new(PURPLE_TYPE_ATTACHMENTS, NULL);
223 }
224
225 gboolean
226 purple_attachments_remove_attachment(PurpleAttachments *attachments,
227 PurpleAttachment *attachment)
228 {
229 GObject *obj = NULL;
230 gboolean found = FALSE;
231 guint index = 0;
232
233 g_return_val_if_fail(PURPLE_IS_ATTACHMENTS(attachments), FALSE);
234 g_return_val_if_fail(PURPLE_IS_ATTACHMENT(attachment), FALSE);
235
236 found = g_ptr_array_find_with_equal_func(attachments->attachments,
237 attachment,
238 purple_attachments_equal,
239 &index);
240 if(!found) {
241 return FALSE;
242 }
243
244 g_ptr_array_remove_index(attachments->attachments, index);
245
246 obj = G_OBJECT(attachments);
247 g_object_freeze_notify(obj);
248 g_list_model_items_changed(G_LIST_MODEL(attachments), index, 1, 0);
249 g_object_notify_by_pspec(obj, properties[PROP_N_ITEMS]);
250 g_object_thaw_notify(obj);
251
252 return TRUE;
253 }
254
255 void
256 purple_attachments_remove_all(PurpleAttachments *attachments) {
257 guint removed = 0;
258
259 g_return_if_fail(PURPLE_IS_ATTACHMENTS(attachments));
260
261 removed = attachments->attachments->len;
262 g_ptr_array_remove_range(attachments->attachments, 0, removed);
263
264 if(removed > 0) {
265 GObject *obj = G_OBJECT(attachments);
266 g_object_freeze_notify(obj);
267 g_list_model_items_changed(G_LIST_MODEL(attachments), 0, removed, 0);
268 g_object_notify_by_pspec(obj, properties[PROP_N_ITEMS]);
269 g_object_thaw_notify(obj);
270 }
271 }

mercurial