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-message"
5 : :
6 : : #include "config.h"
7 : :
8 : : #include <gio/gio.h>
9 : : #include <valent.h>
10 : :
11 : : #include "valent-message.h"
12 : :
13 : :
14 : : struct _ValentMessage
15 : : {
16 : : GObject parent_instance;
17 : :
18 : : ValentMessageBox box;
19 : : int64_t date;
20 : : int64_t id;
21 : : GVariant *metadata;
22 : : unsigned int read : 1;
23 : : char *sender;
24 : : char *text;
25 : : int64_t thread_id;
26 : : };
27 : :
28 [ + + + - ]: 389 : G_DEFINE_FINAL_TYPE (ValentMessage, valent_message, G_TYPE_OBJECT)
29 : :
30 : : enum {
31 : : PROP_0,
32 : : PROP_BOX,
33 : : PROP_DATE,
34 : : PROP_ID,
35 : : PROP_METADATA,
36 : : PROP_READ,
37 : : PROP_SENDER,
38 : : PROP_TEXT,
39 : : PROP_THREAD_ID,
40 : : N_PROPERTIES
41 : : };
42 : :
43 : : static GParamSpec *properties[N_PROPERTIES] = { NULL, };
44 : :
45 : :
46 : : /*
47 : : * GObject
48 : : */
49 : : static void
50 : 42 : valent_message_finalize (GObject *object)
51 : : {
52 : 42 : ValentMessage *self = VALENT_MESSAGE (object);
53 : :
54 [ + + ]: 42 : g_clear_pointer (&self->sender, g_free);
55 [ + + ]: 42 : g_clear_pointer (&self->text, g_free);
56 [ + + ]: 42 : g_clear_pointer (&self->metadata, g_variant_unref);
57 : :
58 : 42 : G_OBJECT_CLASS (valent_message_parent_class)->finalize (object);
59 : 42 : }
60 : :
61 : : static void
62 : 8 : valent_message_get_property (GObject *object,
63 : : guint prop_id,
64 : : GValue *value,
65 : : GParamSpec *pspec)
66 : : {
67 : 8 : ValentMessage *self = VALENT_MESSAGE (object);
68 : :
69 [ + + + + : 8 : switch (prop_id)
+ + + +
- ]
70 : : {
71 : 1 : case PROP_BOX:
72 : 1 : g_value_set_uint (value, self->box);
73 : 1 : break;
74 : :
75 : 1 : case PROP_DATE:
76 : 1 : g_value_set_int64 (value, self->date);
77 : 1 : break;
78 : :
79 : 1 : case PROP_ID:
80 : 1 : g_value_set_int64 (value, self->id);
81 : 1 : break;
82 : :
83 : 1 : case PROP_METADATA:
84 : 1 : g_value_set_variant (value, valent_message_get_metadata (self));
85 : 1 : break;
86 : :
87 : 1 : case PROP_READ:
88 : 1 : g_value_set_boolean (value, self->read);
89 : 1 : break;
90 : :
91 : 1 : case PROP_SENDER:
92 : 1 : g_value_set_string (value, self->sender);
93 : 1 : break;
94 : :
95 : 1 : case PROP_TEXT:
96 : 1 : g_value_set_string (value, self->text);
97 : 1 : break;
98 : :
99 : 1 : case PROP_THREAD_ID:
100 : 1 : g_value_set_int64 (value, self->thread_id);
101 : 1 : break;
102 : :
103 : 0 : default:
104 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
105 : : }
106 : 8 : }
107 : :
108 : : static void
109 : 428 : valent_message_set_property (GObject *object,
110 : : guint prop_id,
111 : : const GValue *value,
112 : : GParamSpec *pspec)
113 : : {
114 : 428 : ValentMessage *self = VALENT_MESSAGE (object);
115 : :
116 [ + + + + : 428 : switch (prop_id)
+ + + +
- ]
117 : : {
118 : 55 : case PROP_BOX:
119 : 55 : self->box = g_value_get_uint (value);
120 : 55 : break;
121 : :
122 : 55 : case PROP_DATE:
123 : 55 : self->date = g_value_get_int64 (value);
124 : 55 : break;
125 : :
126 : 55 : case PROP_ID:
127 : 55 : self->id = g_value_get_int64 (value);
128 : 55 : break;
129 : :
130 : 55 : case PROP_METADATA:
131 : 55 : self->metadata = g_value_dup_variant (value);
132 : 55 : break;
133 : :
134 : 43 : case PROP_READ:
135 : 43 : valent_message_set_read (self, g_value_get_boolean (value));
136 : 43 : break;
137 : :
138 : 55 : case PROP_SENDER:
139 : 55 : self->sender = g_value_dup_string (value);
140 : 55 : break;
141 : :
142 : 55 : case PROP_TEXT:
143 : 55 : self->text = g_value_dup_string (value);
144 : 55 : break;
145 : :
146 : 55 : case PROP_THREAD_ID:
147 : 55 : self->thread_id = g_value_get_int64 (value);
148 : 55 : break;
149 : :
150 : 0 : default:
151 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
152 : : }
153 : 428 : }
154 : :
155 : : static void
156 : 8 : valent_message_class_init (ValentMessageClass *klass)
157 : : {
158 : 8 : GObjectClass *object_class = G_OBJECT_CLASS (klass);
159 : :
160 : 8 : object_class->finalize = valent_message_finalize;
161 : 8 : object_class->get_property = valent_message_get_property;
162 : 8 : object_class->set_property = valent_message_set_property;
163 : :
164 : : /**
165 : : * ValentMessage:box:
166 : : *
167 : : * The `ValentMessageBox` of the message.
168 : : */
169 : 16 : properties [PROP_BOX] =
170 : 8 : g_param_spec_uint ("box", NULL, NULL,
171 : : VALENT_MESSAGE_BOX_ALL, VALENT_MESSAGE_BOX_FAILED,
172 : : VALENT_MESSAGE_BOX_ALL,
173 : : (G_PARAM_READWRITE |
174 : : G_PARAM_CONSTRUCT_ONLY |
175 : : G_PARAM_EXPLICIT_NOTIFY |
176 : : G_PARAM_STATIC_STRINGS));
177 : :
178 : : /**
179 : : * ValentMessage:date:
180 : : *
181 : : * A UNIX epoch timestamp for the message.
182 : : */
183 : 16 : properties [PROP_DATE] =
184 : 8 : g_param_spec_int64 ("date", NULL, NULL,
185 : : G_MININT64, G_MAXINT64,
186 : : 0,
187 : : (G_PARAM_READWRITE |
188 : : G_PARAM_CONSTRUCT_ONLY |
189 : : G_PARAM_EXPLICIT_NOTIFY |
190 : : G_PARAM_STATIC_STRINGS));
191 : :
192 : : /**
193 : : * ValentMessage:id:
194 : : *
195 : : * The unique ID for this message.
196 : : */
197 : 16 : properties [PROP_ID] =
198 : 8 : g_param_spec_int64 ("id", NULL, NULL,
199 : : G_MININT64, G_MAXINT64,
200 : : 0,
201 : : (G_PARAM_READWRITE |
202 : : G_PARAM_CONSTRUCT_ONLY |
203 : : G_PARAM_EXPLICIT_NOTIFY |
204 : : G_PARAM_STATIC_STRINGS));
205 : :
206 : : /**
207 : : * ValentMessage:metadata:
208 : : *
209 : : * Ancillary data for the message, such as media.
210 : : */
211 : 16 : properties [PROP_METADATA] =
212 : 8 : g_param_spec_variant ("metadata", NULL, NULL,
213 : : G_VARIANT_TYPE_VARDICT,
214 : : NULL,
215 : : (G_PARAM_READWRITE |
216 : : G_PARAM_CONSTRUCT_ONLY |
217 : : G_PARAM_EXPLICIT_NOTIFY |
218 : : G_PARAM_STATIC_STRINGS));
219 : :
220 : : /**
221 : : * ValentMessage:read:
222 : : *
223 : : * Whether the message has been read.
224 : : */
225 : 16 : properties [PROP_READ] =
226 : 8 : g_param_spec_boolean ("read", NULL, NULL,
227 : : FALSE,
228 : : (G_PARAM_READWRITE |
229 : : G_PARAM_EXPLICIT_NOTIFY |
230 : : G_PARAM_STATIC_STRINGS));
231 : :
232 : : /**
233 : : * ValentMessage:sender:
234 : : *
235 : : * The sender of the message. This will usually be a phone number or other
236 : : * address form.
237 : : */
238 : 16 : properties [PROP_SENDER] =
239 : 8 : g_param_spec_string ("sender", NULL, NULL,
240 : : NULL,
241 : : (G_PARAM_READWRITE |
242 : : G_PARAM_CONSTRUCT_ONLY |
243 : : G_PARAM_EXPLICIT_NOTIFY |
244 : : G_PARAM_STATIC_STRINGS));
245 : :
246 : : /**
247 : : * ValentMessage:text:
248 : : *
249 : : * The text content of the message.
250 : : */
251 : 16 : properties [PROP_TEXT] =
252 : 8 : g_param_spec_string ("text", NULL, NULL,
253 : : NULL,
254 : : (G_PARAM_READWRITE |
255 : : G_PARAM_CONSTRUCT_ONLY |
256 : : G_PARAM_EXPLICIT_NOTIFY |
257 : : G_PARAM_STATIC_STRINGS));
258 : :
259 : : /**
260 : : * ValentMessage:thread-id:
261 : : *
262 : : * The thread this message belongs to.
263 : : */
264 : 16 : properties [PROP_THREAD_ID] =
265 : 8 : g_param_spec_int64 ("thread-id", NULL, NULL,
266 : : G_MININT64, G_MAXINT64,
267 : : 0,
268 : : (G_PARAM_READWRITE |
269 : : G_PARAM_CONSTRUCT_ONLY |
270 : : G_PARAM_EXPLICIT_NOTIFY |
271 : : G_PARAM_STATIC_STRINGS));
272 : :
273 : 8 : g_object_class_install_properties (object_class, N_PROPERTIES, properties);
274 : 8 : }
275 : :
276 : : static void
277 : 55 : valent_message_init (ValentMessage *message)
278 : : {
279 : 55 : }
280 : :
281 : : /**
282 : : * valent_message_get_box:
283 : : * @message: a `ValentMessage`
284 : : *
285 : : * Get the `ValentMessageBox` of @message.
286 : : *
287 : : * Returns: a `ValentMessageBox`
288 : : */
289 : : ValentMessageBox
290 : 39 : valent_message_get_box (ValentMessage *message)
291 : : {
292 [ + - ]: 39 : g_return_val_if_fail (VALENT_IS_MESSAGE (message), VALENT_MESSAGE_BOX_ALL);
293 : :
294 : 39 : return message->box;
295 : : }
296 : :
297 : : /**
298 : : * valent_message_get_date:
299 : : * @message: a `ValentMessage`
300 : : *
301 : : * Get the timestamp for @message.
302 : : *
303 : : * Returns: the message timestamp
304 : : */
305 : : int64_t
306 : 30 : valent_message_get_date (ValentMessage *message)
307 : : {
308 [ + - ]: 30 : g_return_val_if_fail (VALENT_IS_MESSAGE (message), 0);
309 : :
310 : 30 : return message->date;
311 : : }
312 : :
313 : : /**
314 : : * valent_message_get_id:
315 : : * @message: a `ValentMessage`
316 : : *
317 : : * Get the unique ID for @message.
318 : : *
319 : : * Returns: the message ID
320 : : */
321 : : int64_t
322 : 23 : valent_message_get_id (ValentMessage *message)
323 : : {
324 [ + - ]: 23 : g_return_val_if_fail (VALENT_IS_MESSAGE (message), 0);
325 : :
326 : 23 : return message->id;
327 : : }
328 : :
329 : : /**
330 : : * valent_message_get_metadata:
331 : : * @message: a `ValentMessage`
332 : : *
333 : : * Get the `GVariant` dictionary of metadata.
334 : : *
335 : : * Returns: (transfer none) (nullable): the metadata
336 : : */
337 : : GVariant *
338 : 18 : valent_message_get_metadata (ValentMessage *message)
339 : : {
340 [ + - ]: 18 : g_return_val_if_fail (VALENT_IS_MESSAGE (message), NULL);
341 : :
342 : 18 : return message->metadata;
343 : : }
344 : :
345 : : /**
346 : : * valent_message_get_read:
347 : : * @message: a `ValentMessage`
348 : : *
349 : : * Get the read status of @message.
350 : : *
351 : : * Returns: %TRUE if the message has been read
352 : : */
353 : : gboolean
354 : 20 : valent_message_get_read (ValentMessage *message)
355 : : {
356 [ + - ]: 20 : g_return_val_if_fail (VALENT_IS_MESSAGE (message), FALSE);
357 : :
358 : 20 : return message->read;
359 : : }
360 : :
361 : : /**
362 : : * valent_message_set_read:
363 : : * @message: a `ValentMessage`
364 : : * @read: whether the message is read
365 : : *
366 : : * Set the read status of @message to @read.
367 : : */
368 : : void
369 : 43 : valent_message_set_read (ValentMessage *message,
370 : : gboolean read)
371 : : {
372 [ + - ]: 43 : g_return_if_fail (VALENT_IS_MESSAGE (message));
373 : :
374 [ + + ]: 43 : if (message->read == read)
375 : : return;
376 : :
377 : 6 : message->read = read;
378 : 6 : g_object_notify_by_pspec (G_OBJECT (message), properties [PROP_READ]);
379 : : }
380 : :
381 : : /**
382 : : * valent_message_get_sender:
383 : : * @message: a `ValentMessage`
384 : : *
385 : : * Get the sender of @message.
386 : : *
387 : : * Returns: (transfer none) (nullable): the message sender
388 : : */
389 : : const char *
390 : 22 : valent_message_get_sender (ValentMessage *message)
391 : : {
392 [ + - ]: 22 : g_return_val_if_fail (VALENT_IS_MESSAGE (message), NULL);
393 : :
394 : 22 : return message->sender;
395 : : }
396 : :
397 : : /**
398 : : * valent_message_get_text:
399 : : * @message: a `ValentMessage`
400 : : *
401 : : * Get the text content of @message.
402 : : *
403 : : * Returns: (transfer none) (nullable): the message text
404 : : */
405 : : const char *
406 : 35 : valent_message_get_text (ValentMessage *message)
407 : : {
408 [ + - ]: 35 : g_return_val_if_fail (VALENT_IS_MESSAGE (message), NULL);
409 : :
410 : 35 : return message->text;
411 : : }
412 : :
413 : : /**
414 : : * valent_message_get_thread_id:
415 : : * @message: a `ValentMessage`
416 : : *
417 : : * Get the thread ID @message belongs to.
418 : : *
419 : : * Returns: the thread ID
420 : : */
421 : : int64_t
422 : 17 : valent_message_get_thread_id (ValentMessage *message)
423 : : {
424 [ + - ]: 17 : g_return_val_if_fail (VALENT_IS_MESSAGE (message), 0);
425 : :
426 : 17 : return message->thread_id;
427 : : }
428 : :
429 : : /**
430 : : * valent_message_update:
431 : : * @message: a `ValentMessage`
432 : : * @update: (transfer full): a `ValentMessage`
433 : : *
434 : : * Update @message with data from @update. The `ValentMessage`:id property
435 : : * must match on both objects.
436 : : *
437 : : * This function consumes @update and all its memory, so it should not be used
438 : : * after calling this.
439 : : */
440 : : void
441 : 5 : valent_message_update (ValentMessage *message,
442 : : ValentMessage *update)
443 : : {
444 [ + - ]: 5 : g_return_if_fail (VALENT_IS_MESSAGE (message));
445 [ - + ]: 5 : g_return_if_fail (VALENT_IS_MESSAGE (update));
446 [ - + ]: 5 : g_return_if_fail (message->id == update->id);
447 : :
448 : 5 : g_object_freeze_notify (G_OBJECT (message));
449 : :
450 [ + - ]: 5 : if (message->box != update->box)
451 : : {
452 : 5 : message->box = update->box;
453 : 5 : g_object_notify_by_pspec (G_OBJECT (message), properties [PROP_BOX]);
454 : : }
455 : :
456 [ - + ]: 5 : if (message->date != update->date)
457 : : {
458 : 0 : message->date = update->date;
459 : 0 : g_object_notify_by_pspec (G_OBJECT (message), properties [PROP_DATE]);
460 : : }
461 : :
462 [ + - ]: 5 : if (message->metadata != update->metadata)
463 : : {
464 [ - + ]: 5 : g_clear_pointer (&message->metadata, g_variant_unref);
465 : 5 : message->metadata = g_steal_pointer (&update->metadata);
466 : : }
467 : :
468 [ - + ]: 5 : if (message->read != update->read)
469 : : {
470 : 0 : message->read = update->read;
471 : 0 : g_object_notify_by_pspec (G_OBJECT (message), properties [PROP_READ]);
472 : : }
473 : :
474 [ - + ]: 5 : if (g_set_str (&message->sender, update->sender))
475 : 0 : g_object_notify_by_pspec (G_OBJECT (message), properties [PROP_SENDER]);
476 : :
477 [ + - ]: 5 : if (g_set_str (&message->text, update->text))
478 : 5 : g_object_notify_by_pspec (G_OBJECT (message), properties [PROP_TEXT]);
479 : :
480 : 5 : g_object_thaw_notify (G_OBJECT (message));
481 : 5 : g_object_unref (update);
482 : : }
483 : :
|