GnuCash  5.6-150-g038405b370+
table-model.c
1 /********************************************************************\
2  * table-model.c -- 2D grid table object model *
3  * Copyright (c) 2001 Free Software Foundation *
4  * Author: Dave Peticolas <dave@krondo.com> *
5  * *
6  * This program is free software; you can redistribute it and/or *
7  * modify it under the terms of the GNU General Public License as *
8  * published by the Free Software Foundation; either version 2 of *
9  * the License, or (at your option) any later version. *
10  * *
11  * This program is distributed in the hope that it will be useful, *
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14  * GNU General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU General Public License*
17  * along with this program; if not, contact: *
18  * *
19  * Free Software Foundation Voice: +1-617-542-5942 *
20  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 *
21  * Boston, MA 02110-1301, USA gnu@gnu.org *
22  * *
23 \********************************************************************/
24 
25 #include <config.h>
26 
27 #include <glib.h>
28 
29 #include "table-model.h"
30 
31 
32 #define DEFAULT_HANDLER ""
33 
34 typedef struct
35 {
36  char *cell_name;
37  gpointer handler;
38 } HandlerNode;
39 
40 
41 static GHashTable *
42 gnc_table_model_handler_hash_new (void)
43 {
44  return g_hash_table_new (g_str_hash, g_str_equal);
45 }
46 
47 static void
48 hash_destroy_helper (gpointer key, gpointer value, gpointer user_data)
49 {
50  HandlerNode *node = value;
51 
52  g_free (node->cell_name);
53  node->cell_name = NULL;
54 
55  g_free (node);
56 }
57 
58 static void
59 gnc_table_model_handler_hash_destroy (GHashTable *hash)
60 {
61  if (!hash) return;
62 
63  g_hash_table_foreach (hash, hash_destroy_helper, NULL);
64  g_hash_table_destroy (hash);
65 }
66 
67 static void
68 gnc_table_model_handler_hash_remove (GHashTable *hash, const char *cell_name)
69 {
70  HandlerNode *node;
71 
72  if (!hash) return;
73 
74  node = g_hash_table_lookup (hash, cell_name);
75  if (!node) return;
76 
77  g_hash_table_remove (hash, cell_name);
78 
79  g_free (node->cell_name);
80  node->cell_name = NULL;
81 
82  g_free (node);
83 }
84 
85 static void
86 gnc_table_model_handler_hash_insert (GHashTable *hash,
87  const char *cell_name,
88  gpointer handler)
89 {
90  HandlerNode *node;
91 
92  g_return_if_fail (hash != NULL);
93  g_return_if_fail (cell_name != NULL);
94 
95  gnc_table_model_handler_hash_remove (hash, cell_name);
96  if (!handler) return;
97 
98  node = g_new0 (HandlerNode, 1);
99 
100  node->cell_name = g_strdup (cell_name);
101  node->handler = handler;
102 
103  g_hash_table_insert (hash, node->cell_name, node);
104 }
105 
106 static gpointer
107 gnc_table_model_handler_hash_lookup (GHashTable *hash, const char *cell_name)
108 {
109  HandlerNode *node;
110 
111  if (!hash) return NULL;
112 
113  if (cell_name)
114  {
115  node = g_hash_table_lookup (hash, cell_name);
116  if (node) return node->handler;
117  }
118 
119  cell_name = DEFAULT_HANDLER;
120  node = g_hash_table_lookup (hash, cell_name);
121  if (node) return node->handler;
122 
123  return NULL;
124 }
125 
126 TableModel *
127 gnc_table_model_new (void)
128 {
129  TableModel *model;
130 
131  model = g_new0 (TableModel, 1);
132 
133  model->entry_handlers = gnc_table_model_handler_hash_new ();
134  model->label_handlers = gnc_table_model_handler_hash_new ();
135  model->help_handlers = gnc_table_model_handler_hash_new ();
136  model->tooltip_handlers = gnc_table_model_handler_hash_new ();
137  model->io_flags_handlers = gnc_table_model_handler_hash_new ();
138  model->cell_color_handlers = gnc_table_model_handler_hash_new ();
139  model->cell_border_handlers = gnc_table_model_handler_hash_new ();
140  model->confirm_handlers = gnc_table_model_handler_hash_new ();
141  model->save_handlers = gnc_table_model_handler_hash_new ();
142 
143  model->read_only = FALSE;
144  model->dividing_row_upper = -1;
145  model->dividing_row = -1;
146  model->dividing_row_lower = -1;
147 
148  model->blank_trans_row = -1;
149 
150  return model;
151 }
152 
153 void
154 gnc_table_model_destroy (TableModel *model)
155 {
156  if (!model) return;
157 
158  gnc_table_model_handler_hash_destroy (model->entry_handlers);
159  model->entry_handlers = NULL;
160 
161  gnc_table_model_handler_hash_destroy (model->label_handlers);
162  model->label_handlers = NULL;
163 
164  gnc_table_model_handler_hash_destroy (model->tooltip_handlers);
165  model->tooltip_handlers = NULL;
166 
167  gnc_table_model_handler_hash_destroy (model->help_handlers);
168  model->help_handlers = NULL;
169 
170  gnc_table_model_handler_hash_destroy (model->io_flags_handlers);
171  model->io_flags_handlers = NULL;
172 
173  gnc_table_model_handler_hash_destroy (model->cell_color_handlers);
174  model->cell_color_handlers = NULL;
175 
176  gnc_table_model_handler_hash_destroy (model->cell_border_handlers);
177  model->cell_border_handlers = NULL;
178 
179  gnc_table_model_handler_hash_destroy (model->confirm_handlers);
180  model->confirm_handlers = NULL;
181 
182  gnc_table_model_handler_hash_destroy (model->save_handlers);
183  model->save_handlers = NULL;
184 
185  g_free (model);
186 }
187 
188 void
189 gnc_table_model_set_read_only (TableModel *model, gboolean read_only)
190 {
191  g_return_if_fail (model);
192 
193  model->read_only = read_only;
194 }
195 
196 gboolean
197 gnc_table_model_read_only (TableModel *model)
198 {
199  g_return_val_if_fail (model, FALSE);
200 
201  return model->read_only;
202 }
203 
204 void
205 gnc_table_model_set_reverse_sort (TableModel *model,
206  gboolean reverse_sort)
207 {
208  g_return_if_fail (model);
209  model->reverse_sort = reverse_sort;
210 }
211 
212 void
213 gnc_table_model_set_entry_handler (TableModel *model,
214  TableGetEntryHandler entry_handler,
215  const char * cell_name)
216 {
217  g_return_if_fail (model != NULL);
218  g_return_if_fail (cell_name != NULL);
219 
220  gnc_table_model_handler_hash_insert (model->entry_handlers,
221  cell_name,
222  entry_handler);
223 }
224 
225 void
226 gnc_table_model_set_default_entry_handler
227 (TableModel *model, TableGetEntryHandler entry_handler)
228 {
229  g_return_if_fail (model != NULL);
230 
231  gnc_table_model_handler_hash_insert (model->entry_handlers,
232  DEFAULT_HANDLER,
233  entry_handler);
234 }
235 
236 TableGetEntryHandler
237 gnc_table_model_get_entry_handler (TableModel *model, const char * cell_name)
238 {
239  g_return_val_if_fail (model != NULL, NULL);
240 
241  return gnc_table_model_handler_hash_lookup (model->entry_handlers,
242  cell_name);
243 }
244 
245 void
246 gnc_table_model_set_label_handler (TableModel *model,
247  TableGetLabelHandler label_handler,
248  const char * cell_name)
249 {
250  g_return_if_fail (model != NULL);
251  g_return_if_fail (cell_name != NULL);
252 
253  gnc_table_model_handler_hash_insert (model->label_handlers,
254  cell_name,
255  label_handler);
256 }
257 
258 void
259 gnc_table_model_set_default_label_handler
260 (TableModel *model, TableGetLabelHandler label_handler)
261 {
262  g_return_if_fail (model != NULL);
263 
264  gnc_table_model_handler_hash_insert (model->label_handlers,
265  DEFAULT_HANDLER,
266  label_handler);
267 }
268 
269 TableGetLabelHandler
270 gnc_table_model_get_label_handler (TableModel *model, const char * cell_name)
271 {
272  g_return_val_if_fail (model != NULL, NULL);
273 
274  return gnc_table_model_handler_hash_lookup (model->label_handlers,
275  cell_name);
276 }
277 
278 void
279 gnc_table_model_set_tooltip_handler (TableModel *model,
280  TableGetTooltipHandler tooltip_handler,
281  const char * cell_name)
282 {
283  g_return_if_fail (model != NULL);
284  g_return_if_fail (cell_name != NULL);
285 
286  gnc_table_model_handler_hash_insert (model->tooltip_handlers,
287  cell_name,
288  tooltip_handler);
289 }
290 
291 void
292 gnc_table_model_set_default_tooltip_handler
293 (TableModel *model, TableGetTooltipHandler tooltip_handler)
294 {
295  g_return_if_fail (model != NULL);
296 
297  gnc_table_model_handler_hash_insert (model->tooltip_handlers,
298  DEFAULT_HANDLER,
299  tooltip_handler);
300 }
301 
302 TableGetTooltipHandler
303 gnc_table_model_get_tooltip_handler (TableModel *model, const char * cell_name)
304 {
305  g_return_val_if_fail (model != NULL, NULL);
306 
307  return gnc_table_model_handler_hash_lookup (model->tooltip_handlers,
308  cell_name);
309 }
310 
311 void
312 gnc_table_model_set_help_handler (TableModel *model,
313  TableGetHelpHandler help_handler,
314  const char * cell_name)
315 {
316  g_return_if_fail (model != NULL);
317  g_return_if_fail (cell_name != NULL);
318 
319  gnc_table_model_handler_hash_insert (model->help_handlers,
320  cell_name,
321  help_handler);
322 }
323 
324 void
325 gnc_table_model_set_default_help_handler (TableModel *model,
326  TableGetHelpHandler help_handler)
327 {
328  g_return_if_fail (model != NULL);
329 
330  gnc_table_model_handler_hash_insert (model->help_handlers,
331  DEFAULT_HANDLER,
332  help_handler);
333 }
334 
335 TableGetHelpHandler
336 gnc_table_model_get_help_handler (TableModel *model, const char * cell_name)
337 {
338  g_return_val_if_fail (model != NULL, NULL);
339 
340  return gnc_table_model_handler_hash_lookup (model->help_handlers, cell_name);
341 }
342 
343 void
344 gnc_table_model_set_io_flags_handler
345 (TableModel *model,
346  TableGetCellIOFlagsHandler io_flags_handler,
347  const char * cell_name)
348 {
349  g_return_if_fail (model != NULL);
350  g_return_if_fail (cell_name != NULL);
351 
352  gnc_table_model_handler_hash_insert (model->io_flags_handlers,
353  cell_name,
354  io_flags_handler);
355 }
356 
357 void
358 gnc_table_model_set_default_io_flags_handler
359 (TableModel *model,
360  TableGetCellIOFlagsHandler io_flags_handler)
361 {
362  g_return_if_fail (model != NULL);
363 
364  gnc_table_model_handler_hash_insert (model->io_flags_handlers,
365  DEFAULT_HANDLER,
366  io_flags_handler);
367 }
368 
369 TableGetCellIOFlagsHandler
370 gnc_table_model_get_io_flags_handler (TableModel *model,
371  const char * cell_name)
372 {
373  g_return_val_if_fail (model != NULL, NULL);
374 
375  return gnc_table_model_handler_hash_lookup (model->io_flags_handlers,
376  cell_name);
377 }
378 
379 void
380 gnc_table_model_set_cell_color_handler
381 (TableModel *model,
382  TableGetCellColorHandler color_handler,
383  const char * cell_name)
384 {
385  g_return_if_fail (model != NULL);
386  g_return_if_fail (cell_name != NULL);
387 
388  gnc_table_model_handler_hash_insert (model->cell_color_handlers,
389  cell_name,
390  color_handler);
391 }
392 
393 void
394 gnc_table_model_set_default_cell_color_handler
395 (TableModel *model,
396  TableGetCellColorHandler color_handler)
397 {
398  g_return_if_fail (model != NULL);
399 
400  gnc_table_model_handler_hash_insert (model->cell_color_handlers,
401  DEFAULT_HANDLER,
402  color_handler);
403 }
404 
405 TableGetCellColorHandler
406 gnc_table_model_get_cell_color_handler (TableModel *model,
407  const char * cell_name)
408 {
409  g_return_val_if_fail (model != NULL, NULL);
410 
411  return gnc_table_model_handler_hash_lookup (model->cell_color_handlers,
412  cell_name);
413 }
414 
415 void
416 gnc_table_model_set_cell_border_handler
417 (TableModel *model,
418  TableGetCellBorderHandler cell_border_handler,
419  const char * cell_name)
420 {
421  g_return_if_fail (model != NULL);
422  g_return_if_fail (cell_name != NULL);
423 
424  gnc_table_model_handler_hash_insert (model->cell_border_handlers,
425  cell_name,
426  cell_border_handler);
427 }
428 
429 void
430 gnc_table_model_set_default_cell_border_handler
431 (TableModel *model,
432  TableGetCellBorderHandler cell_border_handler)
433 {
434  g_return_if_fail (model != NULL);
435 
436  gnc_table_model_handler_hash_insert (model->cell_border_handlers,
437  DEFAULT_HANDLER,
438  cell_border_handler);
439 }
440 
441 TableGetCellBorderHandler
442 gnc_table_model_get_cell_border_handler (TableModel *model,
443  const char * cell_name)
444 {
445  g_return_val_if_fail (model != NULL, NULL);
446 
447  return gnc_table_model_handler_hash_lookup (model->cell_border_handlers,
448  cell_name);
449 }
450 
451 void
452 gnc_table_model_set_confirm_handler
453 (TableModel *model,
454  TableConfirmHandler confirm_handler,
455  const char * cell_name)
456 {
457  g_return_if_fail (model != NULL);
458  g_return_if_fail (cell_name != NULL);
459 
460  gnc_table_model_handler_hash_insert (model->confirm_handlers,
461  cell_name,
462  confirm_handler);
463 }
464 
465 void
466 gnc_table_model_set_default_confirm_handler
467 (TableModel *model,
468  TableConfirmHandler confirm_handler)
469 {
470  g_return_if_fail (model != NULL);
471 
472  gnc_table_model_handler_hash_insert (model->confirm_handlers,
473  DEFAULT_HANDLER,
474  confirm_handler);
475 }
476 
477 TableConfirmHandler
478 gnc_table_model_get_confirm_handler (TableModel *model,
479  const char * cell_name)
480 {
481  g_return_val_if_fail (model != NULL, NULL);
482 
483  return gnc_table_model_handler_hash_lookup (model->confirm_handlers,
484  cell_name);
485 }
486 
487 void
488 gnc_table_model_set_save_handler
489 (TableModel *model,
490  TableSaveCellHandler save_handler,
491  const char * cell_name)
492 {
493  g_return_if_fail (model != NULL);
494  g_return_if_fail (cell_name != NULL);
495 
496  gnc_table_model_handler_hash_insert (model->save_handlers,
497  cell_name,
498  save_handler);
499 }
500 
501 void
502 gnc_table_model_set_pre_save_handler
503 (TableModel *model,
504  TableSaveHandler save_handler)
505 {
506  g_return_if_fail (model != NULL);
507 
508  model->pre_save_handler = save_handler;
509 }
510 
511 void
512 gnc_table_model_set_post_save_handler
513 (TableModel *model,
514  TableSaveHandler save_handler)
515 {
516  g_return_if_fail (model != NULL);
517 
518  model->post_save_handler = save_handler;
519 }
520 
521 TableSaveCellHandler
522 gnc_table_model_get_save_handler
523 (TableModel *model,
524  const char * cell_name)
525 {
526  g_return_val_if_fail (model != NULL, NULL);
527 
528  return gnc_table_model_handler_hash_lookup (model->save_handlers, cell_name);
529 }
530 
531 TableSaveHandler
532 gnc_table_model_get_pre_save_handler
533 (TableModel *model)
534 {
535  g_return_val_if_fail (model != NULL, NULL);
536 
537  return model->pre_save_handler;
538 }
539 
540 TableSaveHandler
541 gnc_table_model_get_post_save_handler
542 (TableModel *model)
543 {
544  g_return_val_if_fail (model != NULL, NULL);
545 
546  return model->post_save_handler;
547 }