Merged default into xdg-dirs
[pidgin-git.git] / libpurple / request-datasheet.c
blob31713c4647106adadadd8b3f092bbba6b34448e5
1 /* purple
3 * Purple is the legal property of its developers, whose names are too numerous
4 * to list here. Please refer to the COPYRIGHT file distributed with this
5 * source distribution.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
22 #include "request-datasheet.h"
24 #include "debug.h"
25 #include "glibcompat.h"
26 #include "signals.h"
28 struct _PurpleRequestDatasheet
30 guint col_count;
31 GArray *col_types;
32 GArray *col_titles;
33 GList *actions;
35 GList *record_list;
36 GHashTable *record_li_by_key;
38 GHashTable *marked_for_rem;
41 struct _PurpleRequestDatasheetRecord
43 PurpleRequestDatasheet *sheet;
44 gpointer key;
45 gchar **data; /* at this point, there is only string data possible */
48 struct _PurpleRequestDatasheetAction
50 gchar *label;
52 PurpleRequestDatasheetActionCb cb;
53 gpointer cb_data;
55 PurpleRequestDatasheetActionCheckCb sens_cb;
56 gpointer sens_data;
59 static void
60 purple_request_datasheet_record_free(PurpleRequestDatasheetRecord *rec);
62 /***** Datasheet API **********************************************************/
64 PurpleRequestDatasheet *
65 purple_request_datasheet_new(void)
67 PurpleRequestDatasheet *sheet;
69 sheet = g_new0(PurpleRequestDatasheet, 1);
71 sheet->col_types = g_array_new(FALSE, FALSE,
72 sizeof(PurpleRequestDatasheetColumnType));
73 sheet->col_titles = g_array_new(FALSE, FALSE, sizeof(gchar *));
74 /* XXX: use g_array_set_clear_func when we depend on Glib 2.32 */
76 sheet->record_li_by_key = g_hash_table_new(g_direct_hash, g_direct_equal);
78 purple_signal_register(sheet, "record-changed",
79 purple_marshal_VOID__POINTER_POINTER, G_TYPE_NONE, 2,
80 G_TYPE_POINTER, /* (PurpleRequestDatasheet *) */
81 G_TYPE_POINTER); /* NULL for all */
83 purple_signal_register(sheet, "destroy",
84 purple_marshal_VOID__POINTER, G_TYPE_NONE, 1,
85 G_TYPE_POINTER); /* (PurpleRequestDatasheet *) */
87 return sheet;
90 void
91 purple_request_datasheet_free(PurpleRequestDatasheet *sheet)
93 guint i;
95 g_return_if_fail(sheet != NULL);
97 purple_signal_emit(sheet, "destroy", sheet);
98 purple_signals_unregister_by_instance(sheet);
100 for (i = 0; i < sheet->col_titles->len; i++)
101 g_free(g_array_index(sheet->col_titles, gchar *, i));
103 g_array_free(sheet->col_titles, TRUE);
104 g_array_free(sheet->col_types, TRUE);
106 g_list_free_full(sheet->actions,
107 (GDestroyNotify)purple_request_datasheet_action_free);
109 g_hash_table_destroy(sheet->record_li_by_key);
110 g_list_free_full(sheet->record_list,
111 (GDestroyNotify)purple_request_datasheet_record_free);
113 if (sheet->marked_for_rem != NULL)
114 g_hash_table_destroy(sheet->marked_for_rem);
116 g_free(sheet);
119 void
120 purple_request_datasheet_add_column(PurpleRequestDatasheet *sheet,
121 PurpleRequestDatasheetColumnType type, const gchar *title)
123 gchar *title_clone;
125 g_return_if_fail(sheet != NULL);
127 if (sheet->record_list != NULL) {
128 purple_debug_error("request-datasheet", "Cannot modify model "
129 "when there is already some data");
130 return;
133 title_clone = g_strdup(title);
134 sheet->col_count++;
135 g_array_append_val(sheet->col_types, type);
136 g_array_append_val(sheet->col_titles, title_clone);
139 guint
140 purple_request_datasheet_get_column_count(PurpleRequestDatasheet *sheet)
142 g_return_val_if_fail(sheet != NULL, 0);
144 return sheet->col_count;
145 /*return sheet->col_types->len;*/
148 PurpleRequestDatasheetColumnType
149 purple_request_datasheet_get_column_type(PurpleRequestDatasheet *sheet,
150 guint col_no)
152 g_return_val_if_fail(sheet != NULL, 0);
154 return g_array_index(sheet->col_types,
155 PurpleRequestDatasheetColumnType, col_no);
158 const gchar *
159 purple_request_datasheet_get_column_title(PurpleRequestDatasheet *sheet,
160 guint col_no)
162 g_return_val_if_fail(sheet != NULL, 0);
164 return g_array_index(sheet->col_titles, gchar *, col_no);
167 const GList *
168 purple_request_datasheet_get_records(PurpleRequestDatasheet *sheet)
170 g_return_val_if_fail(sheet != NULL, NULL);
172 return sheet->record_list;
175 void
176 purple_request_datasheet_add_action(PurpleRequestDatasheet *sheet,
177 PurpleRequestDatasheetAction *action)
179 g_return_if_fail(sheet != NULL);
180 g_return_if_fail(action != NULL);
182 sheet->actions = g_list_append(sheet->actions, action);
185 const GList *
186 purple_request_datasheet_get_actions(PurpleRequestDatasheet *sheet)
188 g_return_val_if_fail(sheet != NULL, NULL);
190 return sheet->actions;
193 /***** Datasheet actions API **************************************************/
195 PurpleRequestDatasheetAction *
196 purple_request_datasheet_action_new(void)
198 return g_new0(PurpleRequestDatasheetAction, 1);
201 void
202 purple_request_datasheet_action_free(PurpleRequestDatasheetAction *act)
204 g_return_if_fail(act != NULL);
205 g_free(act->label);
206 g_free(act);
209 void
210 purple_request_datasheet_action_set_label(PurpleRequestDatasheetAction *act,
211 const gchar *label)
213 gchar *new_label;
215 g_return_if_fail(act != NULL);
217 new_label = g_strdup(label);
218 g_free(act->label);
219 act->label = new_label;
222 const gchar*
223 purple_request_datasheet_action_get_label(PurpleRequestDatasheetAction *act)
225 g_return_val_if_fail(act != NULL, NULL);
227 return act->label;
230 void
231 purple_request_datasheet_action_set_cb(PurpleRequestDatasheetAction *act,
232 PurpleRequestDatasheetActionCb cb, gpointer user_data)
234 g_return_if_fail(act != NULL);
236 act->cb = cb;
237 act->cb_data = user_data;
240 void
241 purple_request_datasheet_action_call(PurpleRequestDatasheetAction *act,
242 PurpleRequestDatasheetRecord *rec)
244 g_return_if_fail(act != NULL);
246 if (!act->cb)
247 return;
249 if (!purple_request_datasheet_action_is_sensitive(act, rec)) {
250 purple_debug_warning("request-datasheet",
251 "Action is disabled for this record");
252 return;
255 act->cb(rec, act->cb_data);
258 void
259 purple_request_datasheet_action_set_sens_cb(
260 PurpleRequestDatasheetAction *act,
261 PurpleRequestDatasheetActionCheckCb cb, gpointer user_data)
263 g_return_if_fail(act != NULL);
265 act->sens_cb = cb;
266 act->sens_data = user_data;
269 gboolean
270 purple_request_datasheet_action_is_sensitive(PurpleRequestDatasheetAction *act,
271 PurpleRequestDatasheetRecord *rec)
273 g_return_val_if_fail(act != NULL, FALSE);
275 if (!act->sens_cb)
276 return (rec != NULL);
278 return act->sens_cb(rec, act->sens_data);
281 /***** Datasheet record API ***************************************************/
283 static PurpleRequestDatasheetRecord *
284 purple_request_datasheet_record_new(void)
286 return g_new0(PurpleRequestDatasheetRecord, 1);
289 static void
290 purple_request_datasheet_record_free(PurpleRequestDatasheetRecord *rec)
292 g_strfreev(rec->data);
293 g_free(rec);
296 gpointer
297 purple_request_datasheet_record_get_key(const PurpleRequestDatasheetRecord *rec)
299 g_return_val_if_fail(rec != NULL, NULL);
301 return rec->key;
304 PurpleRequestDatasheet *
305 purple_request_datasheet_record_get_datasheet(
306 PurpleRequestDatasheetRecord *rec)
308 g_return_val_if_fail(rec != NULL, NULL);
310 return rec->sheet;
313 PurpleRequestDatasheetRecord *
314 purple_request_datasheet_record_find(PurpleRequestDatasheet *sheet,
315 gpointer key)
317 GList *it;
319 g_return_val_if_fail(sheet != NULL, NULL);
321 it = g_hash_table_lookup(sheet->record_li_by_key, key);
322 if (!it)
323 return NULL;
325 return it->data;
328 PurpleRequestDatasheetRecord *
329 purple_request_datasheet_record_add(PurpleRequestDatasheet *sheet,
330 gpointer key)
332 PurpleRequestDatasheetRecord *rec;
334 g_return_val_if_fail(sheet != NULL, NULL);
336 rec = purple_request_datasheet_record_find(sheet, key);
337 if (rec != NULL) {
338 if (sheet->marked_for_rem != NULL)
339 g_hash_table_remove(sheet->marked_for_rem, key);
340 return rec;
343 rec = purple_request_datasheet_record_new();
344 rec->sheet = sheet;
345 rec->key = key;
347 /* we don't allow modifying collumn count when datasheet contains
348 * any records */
349 rec->data = g_new0(gchar*,
350 purple_request_datasheet_get_column_count(sheet) + 1);
352 sheet->record_list = g_list_append(sheet->record_list, rec);
353 g_hash_table_insert(sheet->record_li_by_key, key,
354 g_list_find(sheet->record_list, rec));
356 purple_signal_emit(sheet, "record-changed", sheet, key);
358 return rec;
361 void
362 purple_request_datasheet_record_remove(PurpleRequestDatasheet *sheet,
363 gpointer key)
365 GList *it;
367 g_return_if_fail(sheet != NULL);
369 it = g_hash_table_lookup(sheet->record_li_by_key, key);
370 if (it == NULL)
371 return;
373 purple_request_datasheet_record_free(it->data);
374 sheet->record_list = g_list_delete_link(sheet->record_list, it);
375 g_hash_table_remove(sheet->record_li_by_key, key);
377 purple_signal_emit(sheet, "record-changed", sheet, key);
380 void
381 purple_request_datasheet_record_remove_all(PurpleRequestDatasheet *sheet)
383 g_return_if_fail(sheet != NULL);
385 g_list_free_full(sheet->record_list,
386 (GDestroyNotify)purple_request_datasheet_record_free);
387 sheet->record_list = NULL;
388 g_hash_table_remove_all(sheet->record_li_by_key);
390 purple_signal_emit(sheet, "record-changed", sheet, NULL);
393 void
394 purple_request_datasheet_record_mark_all_for_rem(PurpleRequestDatasheet *sheet)
396 const GList *it;
398 if (sheet->marked_for_rem != NULL)
399 g_hash_table_destroy(sheet->marked_for_rem);
400 sheet->marked_for_rem = g_hash_table_new(g_direct_hash, g_direct_equal);
402 it = purple_request_datasheet_get_records(sheet);
403 for (; it != NULL; it = g_list_next(it)) {
404 PurpleRequestDatasheetRecord *rec = it->data;
405 gpointer key = purple_request_datasheet_record_get_key(rec);
407 g_hash_table_insert(sheet->marked_for_rem, key, key);
411 void
412 purple_request_datasheet_record_remove_marked(PurpleRequestDatasheet *sheet)
414 GHashTableIter it;
415 gpointer key;
416 GHashTable *rem;
418 if (sheet->marked_for_rem == NULL)
419 return;
420 rem = sheet->marked_for_rem;
421 sheet->marked_for_rem = NULL;
423 g_hash_table_iter_init(&it, rem);
424 while (g_hash_table_iter_next(&it, &key, NULL))
425 purple_request_datasheet_record_remove(sheet, key);
427 g_hash_table_destroy(rem);
430 static void
431 purple_request_datasheet_record_set_common_data(
432 PurpleRequestDatasheetRecord *rec, guint col_no, const gchar *data)
434 g_return_if_fail(rec != NULL);
435 g_return_if_fail(
436 purple_request_datasheet_get_column_count(rec->sheet) > col_no);
438 if (g_strcmp0(rec->data[col_no], data) == 0)
439 return;
441 /* we assume, model hasn't changed */
442 g_free(rec->data[col_no]);
443 rec->data[col_no] = g_strdup(data);
445 purple_signal_emit(rec->sheet, "record-changed", rec->sheet, rec->key);
448 void
449 purple_request_datasheet_record_set_string_data(
450 PurpleRequestDatasheetRecord *rec, guint col_no, const gchar *data)
452 g_return_if_fail(rec != NULL);
453 g_return_if_fail(purple_request_datasheet_get_column_type(rec->sheet,
454 col_no) == PURPLE_REQUEST_DATASHEET_COLUMN_STRING);
456 purple_request_datasheet_record_set_common_data(rec, col_no, data);
459 void
460 purple_request_datasheet_record_set_image_data(
461 PurpleRequestDatasheetRecord *rec, guint col_no, const gchar *stock_id)
463 g_return_if_fail(rec != NULL);
464 g_return_if_fail(purple_request_datasheet_get_column_type(rec->sheet,
465 col_no) == PURPLE_REQUEST_DATASHEET_COLUMN_IMAGE);
467 purple_request_datasheet_record_set_common_data(rec, col_no, stock_id);
470 static const gchar *
471 purple_request_datasheet_record_get_common_data(
472 const PurpleRequestDatasheetRecord *rec, guint col_no)
474 g_return_val_if_fail(rec != NULL, NULL);
475 g_return_val_if_fail(
476 purple_request_datasheet_get_column_count(rec->sheet) > col_no,
477 NULL);
479 return rec->data[col_no];
482 const gchar *
483 purple_request_datasheet_record_get_string_data(
484 const PurpleRequestDatasheetRecord *rec, guint col_no)
486 g_return_val_if_fail(rec != NULL, NULL);
487 g_return_val_if_fail(purple_request_datasheet_get_column_type(
488 rec->sheet, col_no) == PURPLE_REQUEST_DATASHEET_COLUMN_STRING,
489 NULL);
491 return purple_request_datasheet_record_get_common_data(rec, col_no);
494 const gchar *
495 purple_request_datasheet_record_get_image_data(
496 const PurpleRequestDatasheetRecord *rec, guint col_no)
498 g_return_val_if_fail(rec != NULL, NULL);
499 g_return_val_if_fail(purple_request_datasheet_get_column_type(
500 rec->sheet, col_no) == PURPLE_REQUEST_DATASHEET_COLUMN_IMAGE,
501 NULL);
503 return purple_request_datasheet_record_get_common_data(rec, col_no);