Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-3.0-or-later
2 : : // SPDX-FileCopyrightText: Andy Holmes <andrew.g.r.holmes@gmail.com>
3 : :
4 : : #define G_LOG_DOMAIN "valent-messages"
5 : :
6 : : #include "config.h"
7 : :
8 : : #include <gio/gio.h>
9 : : #include <libpeas.h>
10 : : #include <libvalent-core.h>
11 : :
12 : : #include "valent-messages-adapter.h"
13 : :
14 : : #include "valent-messages.h"
15 : :
16 : :
17 : : /**
18 : : * ValentMessages:
19 : : *
20 : : * A class for managing address books.
21 : : *
22 : : * `ValentMessages` is an address book manager, intended for use by
23 : : * [class@Valent.DevicePlugin] implementations.
24 : : *
25 : : * Plugins can implement [class@Valent.MessagesAdapter] to provide an interface
26 : : * to manage instances of [class@Valent.MessagesAdapter].
27 : : *
28 : : * Since: 1.0
29 : : */
30 : :
31 : : struct _ValentMessages
32 : : {
33 : : ValentComponent parent_instance;
34 : :
35 : : GPtrArray *adapters;
36 : : };
37 : :
38 : : static void g_list_model_iface_init (GListModelInterface *iface);
39 : :
40 [ + + + - ]: 154 : G_DEFINE_FINAL_TYPE_WITH_CODE (ValentMessages, valent_messages, VALENT_TYPE_COMPONENT,
41 : : G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, g_list_model_iface_init))
42 : :
43 : : static ValentMessages *default_messages = NULL;
44 : :
45 : : /*
46 : : * GListModel
47 : : */
48 : : static gpointer
49 : 2 : valent_messages_get_item (GListModel *list,
50 : : unsigned int position)
51 : : {
52 : 2 : ValentMessages *self = VALENT_MESSAGES (list);
53 : :
54 [ + - ]: 2 : g_assert (VALENT_IS_MESSAGES (self));
55 : :
56 [ - + ]: 2 : if G_UNLIKELY (position >= self->adapters->len)
57 : : return NULL;
58 : :
59 : 0 : return g_object_ref (g_ptr_array_index (self->adapters, position));
60 : : }
61 : :
62 : : static GType
63 : 0 : valent_messages_get_item_type (GListModel *list)
64 : : {
65 : 0 : return VALENT_TYPE_MESSAGES_ADAPTER;
66 : : }
67 : :
68 : : static unsigned int
69 : 16 : valent_messages_get_n_items (GListModel *list)
70 : : {
71 : 16 : ValentMessages *self = VALENT_MESSAGES (list);
72 : :
73 [ + - ]: 16 : g_assert (VALENT_IS_MESSAGES (self));
74 : :
75 : 16 : return self->adapters->len;
76 : : }
77 : :
78 : : static void
79 : 2 : g_list_model_iface_init (GListModelInterface *iface)
80 : : {
81 : 2 : iface->get_item = valent_messages_get_item;
82 : 2 : iface->get_item_type = valent_messages_get_item_type;
83 : 2 : iface->get_n_items = valent_messages_get_n_items;
84 : 2 : }
85 : :
86 : : /*
87 : : * ValentComponent
88 : : */
89 : : static void
90 : 0 : valent_messages_bind_extension (ValentComponent *component,
91 : : GObject *extension)
92 : : {
93 : 0 : ValentMessages *self = VALENT_MESSAGES (component);
94 : 0 : GListModel *list = G_LIST_MODEL (extension);
95 : :
96 : 0 : VALENT_ENTRY;
97 : :
98 [ # # ]: 0 : g_assert (VALENT_IS_MESSAGES (self));
99 [ # # ]: 0 : g_assert (VALENT_IS_MESSAGES_ADAPTER (extension));
100 : :
101 : 0 : g_ptr_array_add (self->adapters, g_object_ref (extension));
102 : 0 : g_list_model_items_changed (list, self->adapters->len, 0, 1);
103 : :
104 : 0 : VALENT_EXIT;
105 : : }
106 : :
107 : : static void
108 : 0 : valent_messages_unbind_extension (ValentComponent *component,
109 : : GObject *extension)
110 : : {
111 : 0 : ValentMessages *self = VALENT_MESSAGES (component);
112 : 0 : GListModel *list = G_LIST_MODEL (extension);
113 : 0 : unsigned int position = 0;
114 : :
115 : 0 : VALENT_ENTRY;
116 : :
117 [ # # ]: 0 : g_assert (VALENT_IS_MESSAGES (self));
118 [ # # ]: 0 : g_assert (VALENT_IS_MESSAGES_ADAPTER (extension));
119 : :
120 [ # # ]: 0 : if (!g_ptr_array_find (self->adapters, extension, &position))
121 : : {
122 : 0 : g_warning ("No such adapter \"%s\" found in \"%s\"",
123 : : G_OBJECT_TYPE_NAME (extension),
124 : : G_OBJECT_TYPE_NAME (component));
125 : 0 : return;
126 : : }
127 : :
128 : 0 : g_ptr_array_remove (self->adapters, extension);
129 : 0 : g_list_model_items_changed (list, position, 1, 0);
130 : :
131 : 0 : VALENT_EXIT;
132 : : }
133 : :
134 : : /*
135 : : * GObject
136 : : */
137 : : static void
138 : 0 : valent_messages_finalize (GObject *object)
139 : : {
140 : 0 : ValentMessages *self = VALENT_MESSAGES (object);
141 : :
142 [ # # ]: 0 : g_clear_pointer (&self->adapters, g_ptr_array_unref);
143 : :
144 : 0 : G_OBJECT_CLASS (valent_messages_parent_class)->finalize (object);
145 : 0 : }
146 : :
147 : : static void
148 : 2 : valent_messages_class_init (ValentMessagesClass *klass)
149 : : {
150 : 2 : GObjectClass *object_class = G_OBJECT_CLASS (klass);
151 : 2 : ValentComponentClass *component_class = VALENT_COMPONENT_CLASS (klass);
152 : :
153 : 2 : object_class->finalize = valent_messages_finalize;
154 : :
155 : 2 : component_class->bind_extension = valent_messages_bind_extension;
156 : 2 : component_class->unbind_extension = valent_messages_unbind_extension;
157 : : }
158 : :
159 : : static void
160 : 1 : valent_messages_init (ValentMessages *self)
161 : : {
162 : 1 : self->adapters = g_ptr_array_new_with_free_func (g_object_unref);
163 : 1 : }
164 : :
165 : : /**
166 : : * valent_messages_get_default:
167 : : *
168 : : * Get the default [class@Valent.Messages].
169 : : *
170 : : * Returns: (transfer none) (not nullable): a `ValentMessages`
171 : : *
172 : : * Since: 1.0
173 : : */
174 : : ValentMessages *
175 : 2 : valent_messages_get_default (void)
176 : : {
177 [ + + ]: 2 : if (default_messages == NULL)
178 : : {
179 : 1 : default_messages = g_object_new (VALENT_TYPE_MESSAGES,
180 : : "plugin-domain", "messages",
181 : : "plugin-type", VALENT_TYPE_MESSAGES_ADAPTER,
182 : : NULL);
183 : 1 : g_object_add_weak_pointer (G_OBJECT (default_messages),
184 : : (gpointer)&default_messages);
185 : : }
186 : :
187 : 2 : return default_messages;
188 : : }
189 : :
190 : : /**
191 : : * valent_messages_export_adapter:
192 : : * @messages: a `ValentMessages`
193 : : * @object: a `ValentMessagesAdapter`
194 : : *
195 : : * Export @object on all adapters that support it.
196 : : *
197 : : * Since: 1.0
198 : : */
199 : : void
200 : 0 : valent_messages_export_adapter (ValentMessages *messages,
201 : : ValentMessagesAdapter *object)
202 : : {
203 : 0 : unsigned int position = 0;
204 : :
205 : 0 : VALENT_ENTRY;
206 : :
207 [ # # ]: 0 : g_return_if_fail (VALENT_IS_MESSAGES (messages));
208 [ # # ]: 0 : g_return_if_fail (VALENT_IS_MESSAGES_ADAPTER (object));
209 : :
210 [ # # ]: 0 : if (g_ptr_array_find (messages->adapters, object, NULL))
211 : : {
212 : 0 : g_critical ("%s(): known export %s",
213 : : G_STRFUNC,
214 : : G_OBJECT_TYPE_NAME (object));
215 : 0 : VALENT_EXIT;
216 : : }
217 : :
218 : : // Starting at index `1` skips the exports GListModel
219 [ # # ]: 0 : for (unsigned int i = 1; i < messages->adapters->len; i++)
220 : : {
221 : 0 : ValentMessagesAdapter *adapter = NULL;
222 : :
223 : 0 : adapter = g_ptr_array_index (messages->adapters, i);
224 : 0 : valent_messages_adapter_export_adapter (adapter, object);
225 : : }
226 : :
227 : 0 : position = messages->adapters->len;
228 : 0 : g_ptr_array_add (messages->adapters, g_object_ref (object));
229 : 0 : g_list_model_items_changed (G_LIST_MODEL (messages), position, 0, 1);
230 : :
231 : 0 : VALENT_EXIT;
232 : : }
233 : :
234 : : /**
235 : : * valent_messages_unexport_adapter:
236 : : * @messages: a `ValentMessages`
237 : : * @object: a `ValentMessagesAdapter`
238 : : *
239 : : * Unexport @object from all adapters that support it.
240 : : *
241 : : * Since: 1.0
242 : : */
243 : : void
244 : 0 : valent_messages_unexport_adapter (ValentMessages *messages,
245 : : ValentMessagesAdapter *object)
246 : : {
247 : 0 : unsigned int position = 0;
248 : :
249 : 0 : VALENT_ENTRY;
250 : :
251 [ # # ]: 0 : g_return_if_fail (VALENT_IS_MESSAGES (messages));
252 [ # # ]: 0 : g_return_if_fail (VALENT_IS_MESSAGES_ADAPTER (object));
253 : :
254 [ # # ]: 0 : if (!g_ptr_array_find (messages->adapters, object, &position))
255 : : {
256 : 0 : g_critical ("%s(): unknown export %s",
257 : : G_STRFUNC,
258 : : G_OBJECT_TYPE_NAME (object));
259 : 0 : VALENT_EXIT;
260 : : }
261 : :
262 [ # # ]: 0 : for (unsigned int i = 0; i < messages->adapters->len; i++)
263 : : {
264 : 0 : ValentMessagesAdapter *adapter = NULL;
265 : :
266 : 0 : adapter = g_ptr_array_index (messages->adapters, i);
267 [ # # ]: 0 : if (adapter != object)
268 : 0 : valent_messages_adapter_unexport_adapter (adapter, object);
269 : : }
270 : :
271 : 0 : g_ptr_array_remove (messages->adapters, g_object_ref (object));
272 : 0 : g_list_model_items_changed (G_LIST_MODEL (messages), position, 1, 0);
273 : :
274 : 0 : VALENT_EXIT;
275 : : }
276 : :
|