Use correct memory functions for GG oauth.
[pidgin-git.git] / libpurple / blistnode.c
blobb6556203452573b010a6cbafdb7a2cc570663023
1 /*
2 * purple
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.
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.
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.
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
23 #include "internal.h"
24 #include "glibcompat.h"
26 typedef struct _PurpleBlistNodePrivate PurpleBlistNodePrivate;
28 /* Private data of a buddy list node */
29 struct _PurpleBlistNodePrivate {
30 GHashTable *settings; /* per-node settings */
31 gboolean transient; /* node should not be saved with the buddy list */
34 /* Blist node property enums */
35 enum
37 BLNODE_PROP_0,
38 BLNODE_PROP_TRANSIENT,
39 BLNODE_PROP_LAST
42 static GParamSpec *bn_properties[BLNODE_PROP_LAST];
44 G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(PurpleBlistNode, purple_blist_node,
45 G_TYPE_OBJECT);
47 /**************************************************************************/
48 /* Buddy list node API */
49 /**************************************************************************/
51 static PurpleBlistNode *get_next_node(PurpleBlistNode *node, gboolean godeep)
53 if (node == NULL)
54 return NULL;
56 if (godeep && node->child)
57 return node->child;
59 if (node->next)
60 return node->next;
62 return get_next_node(node->parent, FALSE);
65 PurpleBlistNode *purple_blist_node_next(PurpleBlistNode *node, gboolean offline)
67 PurpleBlistNode *ret = node;
69 if (offline)
70 return get_next_node(ret, TRUE);
73 ret = get_next_node(ret, TRUE);
74 } while (ret && PURPLE_IS_BUDDY(ret) &&
75 !purple_account_is_connected(purple_buddy_get_account((PurpleBuddy *)ret)));
77 return ret;
80 PurpleBlistNode *purple_blist_node_get_parent(PurpleBlistNode *node)
82 return node ? node->parent : NULL;
85 PurpleBlistNode *purple_blist_node_get_first_child(PurpleBlistNode *node)
87 return node ? node->child : NULL;
90 PurpleBlistNode *purple_blist_node_get_sibling_next(PurpleBlistNode *node)
92 return node? node->next : NULL;
95 PurpleBlistNode *purple_blist_node_get_sibling_prev(PurpleBlistNode *node)
97 return node? node->prev : NULL;
100 void *
101 purple_blist_node_get_ui_data(const PurpleBlistNode *node)
103 g_return_val_if_fail(PURPLE_IS_BLIST_NODE(node), NULL);
105 return node->ui_data;
108 void
109 purple_blist_node_set_ui_data(PurpleBlistNode *node, void *ui_data) {
110 g_return_if_fail(PURPLE_IS_BLIST_NODE(node));
112 node->ui_data = ui_data;
115 void purple_blist_node_remove_setting(PurpleBlistNode *node, const char *key)
117 PurpleBlistNodePrivate *priv = NULL;
119 g_return_if_fail(PURPLE_IS_BLIST_NODE(node));
120 g_return_if_fail(key != NULL);
122 priv = purple_blist_node_get_instance_private(node);
123 g_return_if_fail(priv->settings != NULL);
125 g_hash_table_remove(priv->settings, key);
127 purple_blist_save_node(purple_blist_get_default(), node);
130 void
131 purple_blist_node_set_transient(PurpleBlistNode *node, gboolean transient)
133 PurpleBlistNodePrivate *priv = NULL;
135 g_return_if_fail(PURPLE_IS_BLIST_NODE(node));
137 priv = purple_blist_node_get_instance_private(node);
138 priv->transient = transient;
140 g_object_notify_by_pspec(G_OBJECT(node),
141 bn_properties[BLNODE_PROP_TRANSIENT]);
144 gboolean
145 purple_blist_node_is_transient(PurpleBlistNode *node)
147 PurpleBlistNodePrivate *priv = NULL;
149 g_return_val_if_fail(PURPLE_IS_BLIST_NODE(node), 0);
151 priv = purple_blist_node_get_instance_private(node);
152 return priv->transient;
155 GHashTable *
156 purple_blist_node_get_settings(PurpleBlistNode *node)
158 PurpleBlistNodePrivate *priv = NULL;
160 g_return_val_if_fail(PURPLE_IS_BLIST_NODE(node), NULL);
162 priv = purple_blist_node_get_instance_private(node);
163 return priv->settings;
166 gboolean
167 purple_blist_node_has_setting(PurpleBlistNode* node, const char *key)
169 PurpleBlistNodePrivate *priv = NULL;
171 g_return_val_if_fail(PURPLE_IS_BLIST_NODE(node), FALSE);
172 g_return_val_if_fail(key != NULL, FALSE);
174 priv = purple_blist_node_get_instance_private(node);
175 g_return_val_if_fail(priv->settings != NULL, FALSE);
177 /* Boxed type, so it won't ever be NULL, so no need for _extended */
178 return (g_hash_table_lookup(priv->settings, key) != NULL);
181 void
182 purple_blist_node_set_bool(PurpleBlistNode* node, const char *key, gboolean data)
184 PurpleBlistNodePrivate *priv = NULL;
185 GValue *value;
187 g_return_if_fail(PURPLE_IS_BLIST_NODE(node));
188 g_return_if_fail(key != NULL);
190 priv = purple_blist_node_get_instance_private(node);
191 g_return_if_fail(priv->settings != NULL);
193 value = purple_value_new(G_TYPE_BOOLEAN);
194 g_value_set_boolean(value, data);
196 g_hash_table_replace(priv->settings, g_strdup(key), value);
198 purple_blist_save_node(purple_blist_get_default(), node);
201 gboolean
202 purple_blist_node_get_bool(PurpleBlistNode* node, const char *key)
204 PurpleBlistNodePrivate *priv = NULL;
205 GValue *value;
207 g_return_val_if_fail(PURPLE_IS_BLIST_NODE(node), FALSE);
208 g_return_val_if_fail(key != NULL, FALSE);
210 priv = purple_blist_node_get_instance_private(node);
211 g_return_val_if_fail(priv->settings != NULL, FALSE);
213 value = g_hash_table_lookup(priv->settings, key);
215 if (value == NULL)
216 return FALSE;
218 g_return_val_if_fail(G_VALUE_HOLDS_BOOLEAN(value), FALSE);
220 return g_value_get_boolean(value);
223 void
224 purple_blist_node_set_int(PurpleBlistNode* node, const char *key, int data)
226 PurpleBlistNodePrivate *priv = NULL;
227 GValue *value;
229 g_return_if_fail(PURPLE_IS_BLIST_NODE(node));
230 g_return_if_fail(key != NULL);
232 priv = purple_blist_node_get_instance_private(node);
233 g_return_if_fail(priv->settings != NULL);
235 value = purple_value_new(G_TYPE_INT);
236 g_value_set_int(value, data);
238 g_hash_table_replace(priv->settings, g_strdup(key), value);
240 purple_blist_save_node(purple_blist_get_default(), node);
244 purple_blist_node_get_int(PurpleBlistNode* node, const char *key)
246 PurpleBlistNodePrivate *priv = NULL;
247 GValue *value;
249 g_return_val_if_fail(PURPLE_IS_BLIST_NODE(node), 0);
250 g_return_val_if_fail(key != NULL, 0);
252 priv = purple_blist_node_get_instance_private(node);
253 g_return_val_if_fail(priv->settings != NULL, 0);
255 value = g_hash_table_lookup(priv->settings, key);
257 if (value == NULL)
258 return 0;
260 g_return_val_if_fail(G_VALUE_HOLDS_INT(value), 0);
262 return g_value_get_int(value);
265 void
266 purple_blist_node_set_string(PurpleBlistNode* node, const char *key, const char *data)
268 PurpleBlistNodePrivate *priv = NULL;
269 GValue *value;
271 g_return_if_fail(PURPLE_IS_BLIST_NODE(node));
272 g_return_if_fail(key != NULL);
274 priv = purple_blist_node_get_instance_private(node);
275 g_return_if_fail(priv->settings != NULL);
277 value = purple_value_new(G_TYPE_STRING);
278 g_value_set_string(value, data);
280 g_hash_table_replace(priv->settings, g_strdup(key), value);
282 purple_blist_save_node(purple_blist_get_default(), node);
285 const char *
286 purple_blist_node_get_string(PurpleBlistNode* node, const char *key)
288 PurpleBlistNodePrivate *priv = NULL;
289 GValue *value;
291 g_return_val_if_fail(PURPLE_IS_BLIST_NODE(node), NULL);
292 g_return_val_if_fail(key != NULL, NULL);
294 priv = purple_blist_node_get_instance_private(node);
295 g_return_val_if_fail(priv->settings != NULL, NULL);
297 value = g_hash_table_lookup(priv->settings, key);
299 if (value == NULL)
300 return NULL;
302 g_return_val_if_fail(G_VALUE_HOLDS_STRING(value), NULL);
304 return g_value_get_string(value);
307 GList *
308 purple_blist_node_get_extended_menu(PurpleBlistNode *n)
310 GList *menu = NULL;
312 g_return_val_if_fail(n != NULL, NULL);
314 purple_signal_emit(purple_blist_get_handle(), "blist-node-extended-menu",
315 n, &menu);
316 return menu;
319 /**************************************************************************
320 * GObject code for PurpleBlistNode
321 **************************************************************************/
323 /* Set method for GObject properties */
324 static void
325 purple_blist_node_set_property(GObject *obj, guint param_id, const GValue *value,
326 GParamSpec *pspec)
328 PurpleBlistNode *node = PURPLE_BLIST_NODE(obj);
330 switch (param_id) {
331 case BLNODE_PROP_TRANSIENT:
332 purple_blist_node_set_transient(node, g_value_get_boolean(value));
333 break;
334 default:
335 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
336 break;
340 /* Get method for GObject properties */
341 static void
342 purple_blist_node_get_property(GObject *obj, guint param_id, GValue *value,
343 GParamSpec *pspec)
345 PurpleBlistNode *node = PURPLE_BLIST_NODE(obj);
347 switch (param_id) {
348 case BLNODE_PROP_TRANSIENT:
349 g_value_set_boolean(value, purple_blist_node_is_transient(node));
350 break;
351 default:
352 G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
353 break;
357 /* GObject initialization function */
358 static void
359 purple_blist_node_init(PurpleBlistNode *node)
361 PurpleBlistNodePrivate *priv =
362 purple_blist_node_get_instance_private(node);
364 priv->settings = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
365 (GDestroyNotify)purple_value_free);
368 /* GObject finalize function */
369 static void
370 purple_blist_node_finalize(GObject *object)
372 PurpleBlistNodePrivate *priv = purple_blist_node_get_instance_private(
373 PURPLE_BLIST_NODE(object));
375 g_hash_table_destroy(priv->settings);
377 G_OBJECT_CLASS(purple_blist_node_parent_class)->finalize(object);
380 /* Class initializer function */
381 static void
382 purple_blist_node_class_init(PurpleBlistNodeClass *klass)
384 GObjectClass *obj_class = G_OBJECT_CLASS(klass);
386 obj_class->finalize = purple_blist_node_finalize;
388 /* Setup properties */
389 obj_class->get_property = purple_blist_node_get_property;
390 obj_class->set_property = purple_blist_node_set_property;
392 bn_properties[BLNODE_PROP_TRANSIENT] = g_param_spec_boolean("transient",
393 "Transient",
394 "Whether node should not be saved with the buddy list.",
395 FALSE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
397 g_object_class_install_properties(obj_class, BLNODE_PROP_LAST,
398 bn_properties);