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
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"
25 #include "glibcompat.h"
28 struct _PurpleRequestDatasheet
36 GHashTable
*record_li_by_key
;
38 GHashTable
*marked_for_rem
;
41 struct _PurpleRequestDatasheetRecord
43 PurpleRequestDatasheet
*sheet
;
45 gchar
**data
; /* at this point, there is only string data possible */
48 struct _PurpleRequestDatasheetAction
52 PurpleRequestDatasheetActionCb cb
;
55 PurpleRequestDatasheetActionCheckCb sens_cb
;
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 *) */
91 purple_request_datasheet_free(PurpleRequestDatasheet
*sheet
)
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
);
120 purple_request_datasheet_add_column(PurpleRequestDatasheet
*sheet
,
121 PurpleRequestDatasheetColumnType type
, const gchar
*title
)
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");
133 title_clone
= g_strdup(title
);
135 g_array_append_val(sheet
->col_types
, type
);
136 g_array_append_val(sheet
->col_titles
, title_clone
);
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
,
152 g_return_val_if_fail(sheet
!= NULL
, 0);
154 return g_array_index(sheet
->col_types
,
155 PurpleRequestDatasheetColumnType
, col_no
);
159 purple_request_datasheet_get_column_title(PurpleRequestDatasheet
*sheet
,
162 g_return_val_if_fail(sheet
!= NULL
, 0);
164 return g_array_index(sheet
->col_titles
, gchar
*, col_no
);
168 purple_request_datasheet_get_records(PurpleRequestDatasheet
*sheet
)
170 g_return_val_if_fail(sheet
!= NULL
, NULL
);
172 return sheet
->record_list
;
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
);
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);
202 purple_request_datasheet_action_free(PurpleRequestDatasheetAction
*act
)
204 g_return_if_fail(act
!= NULL
);
210 purple_request_datasheet_action_set_label(PurpleRequestDatasheetAction
*act
,
215 g_return_if_fail(act
!= NULL
);
217 new_label
= g_strdup(label
);
219 act
->label
= new_label
;
223 purple_request_datasheet_action_get_label(PurpleRequestDatasheetAction
*act
)
225 g_return_val_if_fail(act
!= NULL
, NULL
);
231 purple_request_datasheet_action_set_cb(PurpleRequestDatasheetAction
*act
,
232 PurpleRequestDatasheetActionCb cb
, gpointer user_data
)
234 g_return_if_fail(act
!= NULL
);
237 act
->cb_data
= user_data
;
241 purple_request_datasheet_action_call(PurpleRequestDatasheetAction
*act
,
242 PurpleRequestDatasheetRecord
*rec
)
244 g_return_if_fail(act
!= NULL
);
249 if (!purple_request_datasheet_action_is_sensitive(act
, rec
)) {
250 purple_debug_warning("request-datasheet",
251 "Action is disabled for this record");
255 act
->cb(rec
, act
->cb_data
);
259 purple_request_datasheet_action_set_sens_cb(
260 PurpleRequestDatasheetAction
*act
,
261 PurpleRequestDatasheetActionCheckCb cb
, gpointer user_data
)
263 g_return_if_fail(act
!= NULL
);
266 act
->sens_data
= user_data
;
270 purple_request_datasheet_action_is_sensitive(PurpleRequestDatasheetAction
*act
,
271 PurpleRequestDatasheetRecord
*rec
)
273 g_return_val_if_fail(act
!= NULL
, FALSE
);
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);
290 purple_request_datasheet_record_free(PurpleRequestDatasheetRecord
*rec
)
292 g_strfreev(rec
->data
);
297 purple_request_datasheet_record_get_key(const PurpleRequestDatasheetRecord
*rec
)
299 g_return_val_if_fail(rec
!= NULL
, NULL
);
304 PurpleRequestDatasheet
*
305 purple_request_datasheet_record_get_datasheet(
306 PurpleRequestDatasheetRecord
*rec
)
308 g_return_val_if_fail(rec
!= NULL
, NULL
);
313 PurpleRequestDatasheetRecord
*
314 purple_request_datasheet_record_find(PurpleRequestDatasheet
*sheet
,
319 g_return_val_if_fail(sheet
!= NULL
, NULL
);
321 it
= g_hash_table_lookup(sheet
->record_li_by_key
, key
);
328 PurpleRequestDatasheetRecord
*
329 purple_request_datasheet_record_add(PurpleRequestDatasheet
*sheet
,
332 PurpleRequestDatasheetRecord
*rec
;
334 g_return_val_if_fail(sheet
!= NULL
, NULL
);
336 rec
= purple_request_datasheet_record_find(sheet
, key
);
338 if (sheet
->marked_for_rem
!= NULL
)
339 g_hash_table_remove(sheet
->marked_for_rem
, key
);
343 rec
= purple_request_datasheet_record_new();
347 /* we don't allow modifying collumn count when datasheet contains
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
);
362 purple_request_datasheet_record_remove(PurpleRequestDatasheet
*sheet
,
367 g_return_if_fail(sheet
!= NULL
);
369 it
= g_hash_table_lookup(sheet
->record_li_by_key
, key
);
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
);
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
);
394 purple_request_datasheet_record_mark_all_for_rem(PurpleRequestDatasheet
*sheet
)
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
);
412 purple_request_datasheet_record_remove_marked(PurpleRequestDatasheet
*sheet
)
418 if (sheet
->marked_for_rem
== NULL
)
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
);
431 purple_request_datasheet_record_set_common_data(
432 PurpleRequestDatasheetRecord
*rec
, guint col_no
, const gchar
*data
)
434 g_return_if_fail(rec
!= NULL
);
436 purple_request_datasheet_get_column_count(rec
->sheet
) > col_no
);
438 if (g_strcmp0(rec
->data
[col_no
], data
) == 0)
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
);
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
);
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
);
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
,
479 return rec
->data
[col_no
];
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
,
491 return purple_request_datasheet_record_get_common_data(rec
, col_no
);
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
,
503 return purple_request_datasheet_record_get_common_data(rec
, col_no
);