Change pidgin_convert_buddy_icon() to be more accommodating when attempting
[pidgin-git.git] / libpurple / roomlist.c
blob8a415ebe00aacd1621db6a9b1c76cbe4d6e36537
1 /**
2 * @file roomlist.c Room List API
3 * @ingroup core
4 */
6 /* purple
8 * Purple is the legal property of its developers, whose names are too numerous
9 * to list here. Please refer to the COPYRIGHT file distributed with this
10 * source distribution.
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
27 #include "internal.h"
29 #include "account.h"
30 #include "connection.h"
31 #include "debug.h"
32 #include "roomlist.h"
33 #include "server.h"
36 static PurpleRoomlistUiOps *ops = NULL;
38 /**************************************************************************/
39 /** @name Room List API */
40 /**************************************************************************/
41 /*@{*/
43 void purple_roomlist_show_with_account(PurpleAccount *account)
45 if (ops && ops->show_with_account)
46 ops->show_with_account(account);
49 PurpleRoomlist *purple_roomlist_new(PurpleAccount *account)
51 PurpleRoomlist *list;
53 g_return_val_if_fail(account != NULL, NULL);
55 list = g_new0(PurpleRoomlist, 1);
56 list->account = account;
57 list->rooms = NULL;
58 list->fields = NULL;
59 list->ref = 1;
61 if (ops && ops->create)
62 ops->create(list);
64 return list;
67 void purple_roomlist_ref(PurpleRoomlist *list)
69 g_return_if_fail(list != NULL);
71 list->ref++;
72 purple_debug_misc("roomlist", "reffing list, ref count now %d\n", list->ref);
75 static void purple_roomlist_room_destroy(PurpleRoomlist *list, PurpleRoomlistRoom *r)
77 GList *l, *j;
79 for (l = list->fields, j = r->fields; l && j; l = l->next, j = j->next) {
80 PurpleRoomlistField *f = l->data;
81 if (f->type == PURPLE_ROOMLIST_FIELD_STRING)
82 g_free(j->data);
85 g_list_free(r->fields);
86 g_free(r->name);
87 g_free(r);
90 static void purple_roomlist_field_destroy(PurpleRoomlistField *f)
92 g_free(f->label);
93 g_free(f->name);
94 g_free(f);
97 static void purple_roomlist_destroy(PurpleRoomlist *list)
99 GList *l;
101 purple_debug_misc("roomlist", "destroying list %p\n", list);
103 if (ops && ops->destroy)
104 ops->destroy(list);
106 for (l = list->rooms; l; l = l->next) {
107 PurpleRoomlistRoom *r = l->data;
108 purple_roomlist_room_destroy(list, r);
110 g_list_free(list->rooms);
112 g_list_foreach(list->fields, (GFunc)purple_roomlist_field_destroy, NULL);
113 g_list_free(list->fields);
115 g_free(list);
118 void purple_roomlist_unref(PurpleRoomlist *list)
120 g_return_if_fail(list != NULL);
121 g_return_if_fail(list->ref > 0);
123 list->ref--;
125 purple_debug_misc("roomlist", "unreffing list, ref count now %d\n", list->ref);
126 if (list->ref == 0)
127 purple_roomlist_destroy(list);
130 void purple_roomlist_set_fields(PurpleRoomlist *list, GList *fields)
132 g_return_if_fail(list != NULL);
134 list->fields = fields;
136 if (ops && ops->set_fields)
137 ops->set_fields(list, fields);
140 void purple_roomlist_set_in_progress(PurpleRoomlist *list, gboolean in_progress)
142 g_return_if_fail(list != NULL);
144 list->in_progress = in_progress;
146 if (ops && ops->in_progress)
147 ops->in_progress(list, in_progress);
150 gboolean purple_roomlist_get_in_progress(PurpleRoomlist *list)
152 g_return_val_if_fail(list != NULL, FALSE);
154 return list->in_progress;
157 void purple_roomlist_room_add(PurpleRoomlist *list, PurpleRoomlistRoom *room)
159 g_return_if_fail(list != NULL);
160 g_return_if_fail(room != NULL);
162 list->rooms = g_list_append(list->rooms, room);
164 if (ops && ops->add_room)
165 ops->add_room(list, room);
168 PurpleRoomlist *purple_roomlist_get_list(PurpleConnection *gc)
170 PurplePlugin *prpl = NULL;
171 PurplePluginProtocolInfo *prpl_info = NULL;
173 g_return_val_if_fail(gc != NULL, NULL);
174 g_return_val_if_fail(PURPLE_CONNECTION_IS_CONNECTED(gc), NULL);
176 prpl = purple_connection_get_prpl(gc);
178 if(prpl != NULL)
179 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
181 if(prpl_info && prpl_info->roomlist_get_list)
182 return prpl_info->roomlist_get_list(gc);
184 return NULL;
187 void purple_roomlist_cancel_get_list(PurpleRoomlist *list)
189 PurplePlugin *prpl = NULL;
190 PurplePluginProtocolInfo *prpl_info = NULL;
191 PurpleConnection *gc;
193 g_return_if_fail(list != NULL);
195 gc = purple_account_get_connection(list->account);
197 g_return_if_fail(gc != NULL);
199 if(gc)
200 prpl = purple_connection_get_prpl(gc);
202 if(prpl)
203 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
205 if(prpl_info && prpl_info->roomlist_cancel)
206 prpl_info->roomlist_cancel(list);
209 void purple_roomlist_expand_category(PurpleRoomlist *list, PurpleRoomlistRoom *category)
211 PurplePlugin *prpl = NULL;
212 PurplePluginProtocolInfo *prpl_info = NULL;
213 PurpleConnection *gc;
215 g_return_if_fail(list != NULL);
216 g_return_if_fail(category != NULL);
217 g_return_if_fail(category->type & PURPLE_ROOMLIST_ROOMTYPE_CATEGORY);
219 gc = purple_account_get_connection(list->account);
220 g_return_if_fail(gc != NULL);
222 if(gc)
223 prpl = purple_connection_get_prpl(gc);
225 if(prpl)
226 prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl);
228 if(prpl_info && prpl_info->roomlist_expand_category)
229 prpl_info->roomlist_expand_category(list, category);
232 GList * purple_roomlist_get_fields(PurpleRoomlist *list)
234 return list->fields;
237 /*@}*/
239 /**************************************************************************/
240 /** @name Room API */
241 /**************************************************************************/
242 /*@{*/
244 PurpleRoomlistRoom *purple_roomlist_room_new(PurpleRoomlistRoomType type, const gchar *name,
245 PurpleRoomlistRoom *parent)
247 PurpleRoomlistRoom *room;
249 g_return_val_if_fail(name != NULL, NULL);
251 room = g_new0(PurpleRoomlistRoom, 1);
252 room->type = type;
253 room->name = g_strdup(name);
254 room->parent = parent;
256 return room;
259 void purple_roomlist_room_add_field(PurpleRoomlist *list, PurpleRoomlistRoom *room, gconstpointer field)
261 PurpleRoomlistField *f;
263 g_return_if_fail(list != NULL);
264 g_return_if_fail(room != NULL);
265 g_return_if_fail(list->fields != NULL);
267 /* If this is the first call for this room, grab the first field in
268 * the Roomlist's fields. Otherwise, grab the field that is one
269 * more than the number of fields already present for the room.
270 * (This works because g_list_nth_data() is zero-indexed and
271 * g_list_length() is one-indexed.) */
272 if (!room->fields)
273 f = list->fields->data;
274 else
275 f = g_list_nth_data(list->fields, g_list_length(room->fields));
277 g_return_if_fail(f != NULL);
279 switch(f->type) {
280 case PURPLE_ROOMLIST_FIELD_STRING:
281 room->fields = g_list_append(room->fields, g_strdup(field));
282 break;
283 case PURPLE_ROOMLIST_FIELD_BOOL:
284 case PURPLE_ROOMLIST_FIELD_INT:
285 room->fields = g_list_append(room->fields, GINT_TO_POINTER(field));
286 break;
290 void purple_roomlist_room_join(PurpleRoomlist *list, PurpleRoomlistRoom *room)
292 GHashTable *components;
293 GList *l, *j;
294 PurpleConnection *gc;
296 g_return_if_fail(list != NULL);
297 g_return_if_fail(room != NULL);
299 gc = purple_account_get_connection(list->account);
300 if (!gc)
301 return;
303 components = g_hash_table_new(g_str_hash, g_str_equal);
305 g_hash_table_replace(components, "name", room->name);
306 for (l = list->fields, j = room->fields; l && j; l = l->next, j = j->next) {
307 PurpleRoomlistField *f = l->data;
309 g_hash_table_replace(components, f->name, j->data);
312 serv_join_chat(gc, components);
314 g_hash_table_destroy(components);
317 PurpleRoomlistRoomType purple_roomlist_room_get_type(PurpleRoomlistRoom *room)
319 return room->type;
322 const char * purple_roomlist_room_get_name(PurpleRoomlistRoom *room)
324 return room->name;
327 PurpleRoomlistRoom * purple_roomlist_room_get_parent(PurpleRoomlistRoom *room)
329 return room->parent;
332 GList * purple_roomlist_room_get_fields(PurpleRoomlistRoom *room)
334 return room->fields;
337 /*@}*/
339 /**************************************************************************/
340 /** @name Room Field API */
341 /**************************************************************************/
342 /*@{*/
344 PurpleRoomlistField *purple_roomlist_field_new(PurpleRoomlistFieldType type,
345 const gchar *label, const gchar *name,
346 gboolean hidden)
348 PurpleRoomlistField *f;
350 g_return_val_if_fail(label != NULL, NULL);
351 g_return_val_if_fail(name != NULL, NULL);
353 f = g_new0(PurpleRoomlistField, 1);
355 f->type = type;
356 f->label = g_strdup(label);
357 f->name = g_strdup(name);
358 f->hidden = hidden;
360 return f;
363 PurpleRoomlistFieldType purple_roomlist_field_get_type(PurpleRoomlistField *field)
365 return field->type;
368 const char * purple_roomlist_field_get_label(PurpleRoomlistField *field)
370 return field->label;
373 gboolean purple_roomlist_field_get_hidden(PurpleRoomlistField *field)
375 return field->hidden;
378 /*@}*/
380 /**************************************************************************/
381 /** @name UI Registration Functions */
382 /**************************************************************************/
383 /*@{*/
386 void purple_roomlist_set_ui_ops(PurpleRoomlistUiOps *ui_ops)
388 ops = ui_ops;
391 PurpleRoomlistUiOps *purple_roomlist_get_ui_ops(void)
393 return ops;
396 /*@}*/