libpurple/blistnodes.c

branch
soc.2013.gobjectification
changeset 34852
0e01a98b2ef7
parent 34851
8dd17abe4901
child 34853
cd81f6c8f83d
equal deleted inserted replaced
34851:8dd17abe4901 34852:0e01a98b2ef7
1 /*
2 * purple
3 *
4 * Purple is the legal property of its developers, whose names are too numerous
5 * to list here. Please refer to the COPYRIGHT file distributed with this
6 * source distribution.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
21 *
22 */
23 #include "blistnodetypes.h"
24 #include "internal.h"
25
26 #define PURPLE_BLIST_NODE_GET_PRIVATE(obj) \
27 (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_BLIST_NODE, PurpleBListNodePrivate))
28
29 /** @copydoc _PurpleBListNodePrivate */
30 typedef struct _PurpleBListNodePrivate PurpleBListNodePrivate;
31
32 #define PURPLE_COUNTING_NODE_GET_PRIVATE(obj) \
33 (G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_COUNTING_NODE, PurpleCountingNodePrivate))
34
35 /** @copydoc _PurpleCountingNodePrivate */
36 typedef struct _PurpleCountingNodePrivate PurpleCountingNodePrivate;
37
38 /** Private data of a buddy list node */
39 struct _PurpleBListNodePrivate {
40 GHashTable *settings; /**< per-node settings */
41 gboolean dont_save; /**< node should not be saved with the buddy list */
42 };
43
44 /* BList node property enums */
45 enum
46 {
47 BLNODE_PROP_0,
48 BLNODE_PROP_DONT_SAVE,
49 BLNODE_PROP_LAST
50 };
51
52 /** Private data of a counting node */
53 struct _PurpleCountingNodePrivate {
54 int totalsize; /**< The number of children under this node */
55 int currentsize; /**< The number of children under this node
56 corresponding to online accounts */
57 int onlinecount; /**< The number of children under this contact who are
58 currently online */
59 };
60
61 /* Counting node property enums */
62 enum
63 {
64 CNODE_PROP_0,
65 CNODE_PROP_TOTAL_SIZE,
66 CNODE_PROP_CURRENT_SIZE,
67 CNODE_PROP_ONLINE_COUNT,
68 CNODE_PROP_LAST
69 };
70
71 static GObjectClass *parent_class;
72
73 /**************************************************************************/
74 /* Buddy list node API */
75 /**************************************************************************/
76
77 static PurpleBListNode *get_next_node(PurpleBListNode *node, gboolean godeep)
78 {
79 if (node == NULL)
80 return NULL;
81
82 if (godeep && node->child)
83 return node->child;
84
85 if (node->next)
86 return node->next;
87
88 return get_next_node(node->parent, FALSE);
89 }
90
91 PurpleBListNode *purple_blist_node_next(PurpleBListNode *node, gboolean offline)
92 {
93 PurpleBListNode *ret = node;
94
95 if (offline)
96 return get_next_node(ret, TRUE);
97 do
98 {
99 ret = get_next_node(ret, TRUE);
100 } while (ret && PURPLE_IS_BUDDY(ret) &&
101 !purple_account_is_connected(purple_buddy_get_account((PurpleBuddy *)ret)));
102
103 return ret;
104 }
105
106 PurpleBListNode *purple_blist_node_get_parent(PurpleBListNode *node)
107 {
108 return node ? node->parent : NULL;
109 }
110
111 PurpleBListNode *purple_blist_node_get_first_child(PurpleBListNode *node)
112 {
113 return node ? node->child : NULL;
114 }
115
116 PurpleBListNode *purple_blist_node_get_sibling_next(PurpleBListNode *node)
117 {
118 return node? node->next : NULL;
119 }
120
121 PurpleBListNode *purple_blist_node_get_sibling_prev(PurpleBListNode *node)
122 {
123 return node? node->prev : NULL;
124 }
125
126 void *
127 purple_blist_node_get_ui_data(const PurpleBListNode *node)
128 {
129 g_return_val_if_fail(node, NULL);
130
131 return node->ui_data;
132 }
133
134 void
135 purple_blist_node_set_ui_data(PurpleBListNode *node, void *ui_data) {
136 g_return_if_fail(node);
137
138 node->ui_data = ui_data;
139 }
140
141 void purple_blist_node_remove_setting(PurpleBListNode *node, const char *key)
142 {
143 PurpleBListUiOps *ops;
144 PurpleBListNodePrivate *priv = PURPLE_BLIST_NODE_GET_PRIVATE(node);
145
146 g_return_if_fail(priv != NULL);
147 g_return_if_fail(priv->settings != NULL);
148 g_return_if_fail(key != NULL);
149
150 g_hash_table_remove(priv->settings, key);
151
152 ops = purple_blist_get_ui_ops();
153 if (ops && ops->save_node)
154 ops->save_node(node);
155 }
156
157 void
158 purple_blist_node_set_dont_save(PurpleBListNode *node, gboolean dont_save)
159 {
160 PurpleBListNodePrivate *priv = PURPLE_BLIST_NODE_GET_PRIVATE(node);
161
162 g_return_if_fail(priv != NULL);
163
164 priv->dont_save = dont_save;
165 }
166
167 gboolean
168 purple_blist_node_get_dont_save(PurpleBListNode *node)
169 {
170 PurpleBListNodePrivate *priv = PURPLE_BLIST_NODE_GET_PRIVATE(node);
171
172 g_return_val_if_fail(priv != NULL, 0);
173
174 return priv->dont_save;
175 }
176
177 GHashTable *
178 purple_blist_node_get_settings(PurpleBListNode *node)
179 {
180 PurpleBListNodePrivate *priv = PURPLE_BLIST_NODE_GET_PRIVATE(node);
181
182 g_return_val_if_fail(priv != NULL, NULL);
183
184 return priv->settings;
185 }
186
187 gboolean
188 purple_blist_node_has_setting(PurpleBListNode* node, const char *key)
189 {
190 PurpleBListNodePrivate *priv = PURPLE_BLIST_NODE_GET_PRIVATE(node);
191
192 g_return_val_if_fail(priv != NULL, FALSE);
193 g_return_val_if_fail(priv->settings != NULL, FALSE);
194 g_return_val_if_fail(key != NULL, FALSE);
195
196 /* Boxed type, so it won't ever be NULL, so no need for _extended */
197 return (g_hash_table_lookup(priv->settings, key) != NULL);
198 }
199
200 void
201 purple_blist_node_set_bool(PurpleBListNode* node, const char *key, gboolean data)
202 {
203 GValue *value;
204 PurpleBListUiOps *ops;
205 PurpleBListNodePrivate *priv = PURPLE_BLIST_NODE_GET_PRIVATE(node);
206
207 g_return_if_fail(priv != NULL);
208 g_return_if_fail(priv->settings != NULL);
209 g_return_if_fail(key != NULL);
210
211 value = purple_g_value_new(G_TYPE_BOOLEAN);
212 g_value_set_boolean(value, data);
213
214 g_hash_table_replace(priv->settings, g_strdup(key), value);
215
216 ops = purple_blist_get_ui_ops();
217 if (ops && ops->save_node)
218 ops->save_node(node);
219 }
220
221 gboolean
222 purple_blist_node_get_bool(PurpleBListNode* node, const char *key)
223 {
224 GValue *value;
225 PurpleBListNodePrivate *priv = PURPLE_BLIST_NODE_GET_PRIVATE(node);
226
227 g_return_val_if_fail(priv != NULL, FALSE);
228 g_return_val_if_fail(priv->settings != NULL, FALSE);
229 g_return_val_if_fail(key != NULL, FALSE);
230
231 value = g_hash_table_lookup(priv->settings, key);
232
233 if (value == NULL)
234 return FALSE;
235
236 g_return_val_if_fail(G_VALUE_HOLDS_BOOLEAN(value), FALSE);
237
238 return g_value_get_boolean(value);
239 }
240
241 void
242 purple_blist_node_set_int(PurpleBListNode* node, const char *key, int data)
243 {
244 GValue *value;
245 PurpleBListUiOps *ops;
246 PurpleBListNodePrivate *priv = PURPLE_BLIST_NODE_GET_PRIVATE(node);
247
248 g_return_if_fail(priv != NULL);
249 g_return_if_fail(priv->settings != NULL);
250 g_return_if_fail(key != NULL);
251
252 value = purple_g_value_new(G_TYPE_INT);
253 g_value_set_int(value, data);
254
255 g_hash_table_replace(priv->settings, g_strdup(key), value);
256
257 ops = purple_blist_get_ui_ops();
258 if (ops && ops->save_node)
259 ops->save_node(node);
260 }
261
262 int
263 purple_blist_node_get_int(PurpleBListNode* node, const char *key)
264 {
265 GValue *value;
266 PurpleBListNodePrivate *priv = PURPLE_BLIST_NODE_GET_PRIVATE(node);
267
268 g_return_val_if_fail(priv != NULL, 0);
269 g_return_val_if_fail(priv->settings != NULL, 0);
270 g_return_val_if_fail(key != NULL, 0);
271
272 value = g_hash_table_lookup(priv->settings, key);
273
274 if (value == NULL)
275 return 0;
276
277 g_return_val_if_fail(G_VALUE_HOLDS_INT(value), 0);
278
279 return g_value_get_int(value);
280 }
281
282 void
283 purple_blist_node_set_string(PurpleBListNode* node, const char *key, const char *data)
284 {
285 GValue *value;
286 PurpleBListUiOps *ops;
287 PurpleBListNodePrivate *priv = PURPLE_BLIST_NODE_GET_PRIVATE(node);
288
289 g_return_if_fail(priv != NULL);
290 g_return_if_fail(priv->settings != NULL);
291 g_return_if_fail(key != NULL);
292
293 value = purple_g_value_new(G_TYPE_STRING);
294 g_value_set_string(value, data);
295
296 g_hash_table_replace(priv->settings, g_strdup(key), value);
297
298 ops = purple_blist_get_ui_ops();
299 if (ops && ops->save_node)
300 ops->save_node(node);
301 }
302
303 const char *
304 purple_blist_node_get_string(PurpleBListNode* node, const char *key)
305 {
306 GValue *value;
307 PurpleBListNodePrivate *priv = PURPLE_BLIST_NODE_GET_PRIVATE(node);
308
309 g_return_val_if_fail(priv != NULL, NULL);
310 g_return_val_if_fail(priv->settings != NULL, NULL);
311 g_return_val_if_fail(key != NULL, NULL);
312
313 value = g_hash_table_lookup(priv->settings, key);
314
315 if (value == NULL)
316 return NULL;
317
318 g_return_val_if_fail(G_VALUE_HOLDS_STRING(value), NULL);
319
320 return g_value_get_string(value);
321 }
322
323 GList *
324 purple_blist_node_get_extended_menu(PurpleBListNode *n)
325 {
326 GList *menu = NULL;
327
328 g_return_val_if_fail(n != NULL, NULL);
329
330 purple_signal_emit(purple_blist_get_handle(), "blist-node-extended-menu",
331 n, &menu);
332 return menu;
333 }
334
335 /**************************************************************************
336 * GObject code for PurpleBListNode
337 **************************************************************************/
338
339 /* GObject Property names */
340 #define BLNODE_PROP_DONT_SAVE_S "dont-save"
341
342 /* Set method for GObject properties */
343 static void
344 purple_blist_node_set_property(GObject *obj, guint param_id, const GValue *value,
345 GParamSpec *pspec)
346 {
347 PurpleBListNode *node = PURPLE_BLIST_NODE(obj);
348
349 switch (param_id) {
350 case BLNODE_PROP_DONT_SAVE:
351 purple_blist_node_set_dont_save(node, g_value_get_boolean(value));
352 break;
353 default:
354 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
355 break;
356 }
357 }
358
359 /* Get method for GObject properties */
360 static void
361 purple_blist_node_get_property(GObject *obj, guint param_id, GValue *value,
362 GParamSpec *pspec)
363 {
364 PurpleBListNode *node = PURPLE_BLIST_NODE(obj);
365
366 switch (param_id) {
367 case BLNODE_PROP_DONT_SAVE:
368 g_value_set_boolean(value, purple_blist_node_get_dont_save(node));
369 break;
370 default:
371 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
372 break;
373 }
374 }
375
376 /* GObject initialization function */
377 static void
378 purple_blist_node_init(GTypeInstance *instance, gpointer klass)
379 {
380 PurpleBListNodePrivate *priv = PURPLE_BLIST_NODE_GET_PRIVATE(instance);
381
382 priv->settings = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
383 (GDestroyNotify)purple_g_value_free);
384 }
385
386 /* GObject finalize function */
387 static void
388 purple_blist_node_finalize(GObject *object)
389 {
390 PurpleBListNodePrivate *priv = PURPLE_BLIST_NODE_GET_PRIVATE(object);
391
392 g_hash_table_destroy(priv->settings);
393
394 parent_class->finalize(object);
395 }
396
397 /* Class initializer function */
398 static void
399 purple_blist_node_class_init(PurpleBListNodeClass *klass)
400 {
401 GObjectClass *obj_class = G_OBJECT_CLASS(klass);
402
403 parent_class = g_type_class_peek_parent(klass);
404
405 obj_class->finalize = purple_blist_node_finalize;
406
407 /* Setup properties */
408 obj_class->get_property = purple_blist_node_get_property;
409 obj_class->set_property = purple_blist_node_set_property;
410
411 g_object_class_install_property(obj_class, BLNODE_PROP_DONT_SAVE,
412 g_param_spec_boolean(BLNODE_PROP_DONT_SAVE_S, _("Do not save"),
413 _("Whether node should not be saved with the buddy list."),
414 FALSE, G_PARAM_READWRITE)
415 );
416
417 g_type_class_add_private(klass, sizeof(PurpleBListNodePrivate));
418 }
419
420 GType
421 purple_blist_node_get_type(void)
422 {
423 static GType type = 0;
424
425 if(type == 0) {
426 static const GTypeInfo info = {
427 sizeof(PurpleBListNodeClass),
428 NULL,
429 NULL,
430 (GClassInitFunc)purple_blist_node_class_init,
431 NULL,
432 NULL,
433 sizeof(PurpleBListNode),
434 0,
435 (GInstanceInitFunc)purple_blist_node_init,
436 NULL,
437 };
438
439 type = g_type_register_static(G_TYPE_OBJECT, "PurpleBListNode",
440 &info, G_TYPE_FLAG_ABSTRACT);
441 }
442
443 return type;
444 }
445
446 /**************************************************************************/
447 /* Counting node API */
448 /**************************************************************************/
449
450 int
451 purple_counting_node_get_total_size(PurpleCountingNode *counter)
452 {
453 PurpleCountingNodePrivate *priv = PURPLE_COUNTING_NODE_GET_PRIVATE(counter);
454
455 g_return_val_if_fail(priv != NULL, -1);
456
457 return priv->totalsize;
458 }
459
460 int
461 purple_counting_node_get_current_size(PurpleCountingNode *counter)
462 {
463 PurpleCountingNodePrivate *priv = PURPLE_COUNTING_NODE_GET_PRIVATE(counter);
464
465 g_return_val_if_fail(priv != NULL, -1);
466
467 return priv->currentsize;
468 }
469
470 int
471 purple_counting_node_get_online_count(PurpleCountingNode *counter)
472 {
473 PurpleCountingNodePrivate *priv = PURPLE_COUNTING_NODE_GET_PRIVATE(counter);
474
475 g_return_val_if_fail(priv != NULL, -1);
476
477 return priv->onlinecount;
478 }
479
480 void
481 purple_counting_node_change_total_size(PurpleCountingNode *counter, int delta)
482 {
483 PurpleCountingNodePrivate *priv = PURPLE_COUNTING_NODE_GET_PRIVATE(counter);
484
485 g_return_if_fail(priv != NULL);
486
487 priv->totalsize += delta;
488 }
489
490 void
491 purple_counting_node_change_current_size(PurpleCountingNode *counter, int delta)
492 {
493 PurpleCountingNodePrivate *priv = PURPLE_COUNTING_NODE_GET_PRIVATE(counter);
494
495 g_return_if_fail(priv != NULL);
496
497 priv->currentsize += delta;
498 }
499
500 void
501 purple_counting_node_change_online_count(PurpleCountingNode *counter, int delta)
502 {
503 PurpleCountingNodePrivate *priv = PURPLE_COUNTING_NODE_GET_PRIVATE(counter);
504
505 g_return_if_fail(priv != NULL);
506
507 priv->onlinecount += delta;
508 }
509
510 void
511 purple_counting_node_set_total_size(PurpleCountingNode *counter, int totalsize)
512 {
513 PurpleCountingNodePrivate *priv = PURPLE_COUNTING_NODE_GET_PRIVATE(counter);
514
515 g_return_if_fail(priv != NULL);
516
517 priv->totalsize = totalsize;
518 }
519
520 void
521 purple_counting_node_set_current_size(PurpleCountingNode *counter, int currentsize)
522 {
523 PurpleCountingNodePrivate *priv = PURPLE_COUNTING_NODE_GET_PRIVATE(counter);
524
525 g_return_if_fail(priv != NULL);
526
527 priv->currentsize = currentsize;
528 }
529
530 void
531 purple_counting_node_set_online_count(PurpleCountingNode *counter, int onlinecount)
532 {
533 PurpleCountingNodePrivate *priv = PURPLE_COUNTING_NODE_GET_PRIVATE(counter);
534
535 g_return_if_fail(priv != NULL);
536
537 priv->onlinecount = onlinecount;
538 }
539
540 /**************************************************************************
541 * GObject code for PurpleCountingNode
542 **************************************************************************/
543
544 /* GObject Property names */
545 #define CNODE_PROP_TOTAL_SIZE_S "total-size"
546 #define CNODE_PROP_CURRENT_SIZE_S "current-size"
547 #define CNODE_PROP_ONLINE_COUNT_S "online-count"
548
549 /* Set method for GObject properties */
550 static void
551 purple_counting_node_set_property(GObject *obj, guint param_id, const GValue *value,
552 GParamSpec *pspec)
553 {
554 PurpleCountingNode *node = PURPLE_COUNTING_NODE(obj);
555
556 switch (param_id) {
557 case CNODE_PROP_TOTAL_SIZE:
558 purple_counting_node_set_total_size(node, g_value_get_int(value));
559 break;
560 case CNODE_PROP_CURRENT_SIZE:
561 purple_counting_node_set_current_size(node, g_value_get_int(value));
562 break;
563 case CNODE_PROP_ONLINE_COUNT:
564 purple_counting_node_set_online_count(node, g_value_get_int(value));
565 break;
566 default:
567 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
568 break;
569 }
570 }
571
572 /* Get method for GObject properties */
573 static void
574 purple_counting_node_get_property(GObject *obj, guint param_id, GValue *value,
575 GParamSpec *pspec)
576 {
577 PurpleCountingNode *node = PURPLE_COUNTING_NODE(obj);
578
579 switch (param_id) {
580 case CNODE_PROP_TOTAL_SIZE:
581 g_value_set_int(value, purple_counting_node_get_total_size(node));
582 break;
583 case CNODE_PROP_CURRENT_SIZE:
584 g_value_set_int(value, purple_counting_node_get_current_size(node));
585 break;
586 case CNODE_PROP_ONLINE_COUNT:
587 g_value_set_int(value, purple_counting_node_get_online_count(node));
588 break;
589 default:
590 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
591 break;
592 }
593 }
594
595 /* GObject initialization function */
596 static void
597 purple_counting_node_init(GTypeInstance *instance, gpointer klass)
598 {
599 PurpleCountingNodePrivate *priv = PURPLE_COUNTING_NODE_GET_PRIVATE(instance);
600
601 priv->totalsize = 0;
602 priv->currentsize = 0;
603 priv->onlinecount = 0;
604 }
605
606 /* Class initializer function */
607 static void
608 purple_counting_node_class_init(PurpleCountingNodeClass *klass)
609 {
610 GObjectClass *obj_class = G_OBJECT_CLASS(klass);
611
612 /* Setup properties */
613 obj_class->get_property = purple_counting_node_get_property;
614 obj_class->set_property = purple_counting_node_set_property;
615
616 g_object_class_install_property(obj_class, CNODE_PROP_TOTAL_SIZE,
617 g_param_spec_int(CNODE_PROP_TOTAL_SIZE_S, _("Total size"),
618 _("The number of children under this node."),
619 G_MININT, G_MAXINT, 0, G_PARAM_READWRITE)
620 );
621
622 g_object_class_install_property(obj_class, CNODE_PROP_CURRENT_SIZE,
623 g_param_spec_int(CNODE_PROP_CURRENT_SIZE_S, _("Current size"),
624 _("The number of children with online accounts."),
625 G_MININT, G_MAXINT, 0, G_PARAM_READWRITE)
626 );
627
628 g_object_class_install_property(obj_class, CNODE_PROP_ONLINE_COUNT,
629 g_param_spec_int(CNODE_PROP_ONLINE_COUNT_S, _("Online count"),
630 _("The number of children that are online."),
631 G_MININT, G_MAXINT, 0, G_PARAM_READWRITE)
632 );
633
634 g_type_class_add_private(klass, sizeof(PurpleCountingNodePrivate));
635 }
636
637 GType
638 purple_counting_node_get_type(void)
639 {
640 static GType type = 0;
641
642 if(type == 0) {
643 static const GTypeInfo info = {
644 sizeof(PurpleCountingNodeClass),
645 NULL,
646 NULL,
647 (GClassInitFunc)purple_counting_node_class_init,
648 NULL,
649 NULL,
650 sizeof(PurpleCountingNode),
651 0,
652 (GInstanceInitFunc)purple_counting_node_init,
653 NULL,
654 };
655
656 type = g_type_register_static(PURPLE_TYPE_BLIST_NODE,
657 "PurpleCountingNode",
658 &info, G_TYPE_FLAG_ABSTRACT);
659 }
660
661 return type;
662 }

mercurial