GnuCash c935c2f+
Loading...
Searching...
No Matches
gnc-tree-model-commodity.c
1/*
2 * gnc-tree-model-commodity.c -- GtkTreeModel implementation to
3 * display commodities in a GtkTreeView.
4 *
5 * Copyright (C) 2003 Jan Arne Petersen <jpetersen@uni-bonn.de>
6 * Copyright (C) 2003 David Hampton <hampton@employees.org>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
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.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, contact:
20 *
21 * Free Software Foundation Voice: +1-617-542-5942
22 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
23 * Boston, MA 02110-1301, USA gnu@gnu.org
24 */
25
26/*
27 * In this model, valid paths take the form "X" or "X:Y", where:
28 * X is an index into the namespaces list held by the commodity db
29 * Y is an index into the commodity list for the namespace
30 *
31 * Iterators are populated with the following private data:
32 * iter->user_data Type NAMESPACE | COMMODITY
33 * iter->user_data2 A pointer to the namespace/commodity
34 * iter->user_data3 The index of the namespace/commodity within its parent list
35 */
36
37#include <config.h>
38
39#include <glib/gi18n.h>
40#include <gtk/gtk.h>
41#include <string.h>
42
44#include "gnc-component-manager.h"
45#include "gnc-engine.h"
46#include "gnc-gobject-utils.h"
47#include "gnc-ui-util.h"
48
49#define ITER_IS_NAMESPACE GINT_TO_POINTER(1)
50#define ITER_IS_COMMODITY GINT_TO_POINTER(2)
51
53static QofLogModule log_module = GNC_MOD_GUI;
54
56static void gnc_tree_model_commodity_finalize (GObject *object);
57static void gnc_tree_model_commodity_dispose (GObject *object);
58
59static void gnc_tree_model_commodity_tree_model_init (GtkTreeModelIface *iface);
60static GtkTreeModelFlags gnc_tree_model_commodity_get_flags (GtkTreeModel *tree_model);
61static int gnc_tree_model_commodity_get_n_columns (GtkTreeModel *tree_model);
62static GType gnc_tree_model_commodity_get_column_type (GtkTreeModel *tree_model,
63 int index);
64static gboolean gnc_tree_model_commodity_get_iter (GtkTreeModel *tree_model,
65 GtkTreeIter *iter,
66 GtkTreePath *path);
67static GtkTreePath *gnc_tree_model_commodity_get_path (GtkTreeModel *tree_model,
68 GtkTreeIter *iter);
69static void gnc_tree_model_commodity_get_value (GtkTreeModel *tree_model,
70 GtkTreeIter *iter,
71 int column,
72 GValue *value);
73static gboolean gnc_tree_model_commodity_iter_next (GtkTreeModel *tree_model,
74 GtkTreeIter *iter);
75static gboolean gnc_tree_model_commodity_iter_children (GtkTreeModel *tree_model,
76 GtkTreeIter *iter,
77 GtkTreeIter *parent);
78static gboolean gnc_tree_model_commodity_iter_has_child (GtkTreeModel *tree_model,
79 GtkTreeIter *iter);
80static int gnc_tree_model_commodity_iter_n_children (GtkTreeModel *tree_model,
81 GtkTreeIter *iter);
82static gboolean gnc_tree_model_commodity_iter_nth_child (GtkTreeModel *tree_model,
83 GtkTreeIter *iter,
84 GtkTreeIter *parent,
85 int n);
86static gboolean gnc_tree_model_commodity_iter_parent (GtkTreeModel *tree_model,
87 GtkTreeIter *iter,
88 GtkTreeIter *child);
89static void gnc_tree_model_commodity_event_handler (QofInstance *entity,
90 QofEventId event_type,
91 gpointer user_data,
92 gpointer event_data);
93
96{
97 GncTreeModel gnc_tree_model;
98 int stamp;
101 QofBook *book;
102 gnc_commodity_table *commodity_table;
103 gint event_handler_id;
104};
105
106G_DEFINE_TYPE_WITH_CODE(GncTreeModelCommodity, gnc_tree_model_commodity, GNC_TYPE_TREE_MODEL,
107 G_IMPLEMENT_INTERFACE(GTK_TYPE_TREE_MODEL,
108 gnc_tree_model_commodity_tree_model_init))
109
110static void
111gnc_tree_model_commodity_class_init (GncTreeModelCommodityClass *klass)
112{
113 GObjectClass *o_class = G_OBJECT_CLASS (klass);
114
115 o_class->finalize = gnc_tree_model_commodity_finalize;
116 o_class->dispose = gnc_tree_model_commodity_dispose;
117}
118
119static void
120gnc_tree_model_commodity_init (GncTreeModelCommodity *model)
121{
122 while (model->stamp == 0)
123 {
124 model->stamp = g_random_int ();
125 }
126}
127
128static void
129gnc_tree_model_commodity_finalize (GObject *object)
130{
131 GncTreeModelCommodity *model;
132
133 g_return_if_fail (object != NULL);
134 g_return_if_fail (GNC_IS_TREE_MODEL_COMMODITY (object));
135
136 ENTER("model %p", object);
137
138 model = GNC_TREE_MODEL_COMMODITY (object);
139 model->book = NULL;
140 model->commodity_table = NULL;
141
142 G_OBJECT_CLASS (gnc_tree_model_commodity_parent_class)->finalize (object);
143 LEAVE(" ");
144}
145
146static void
147gnc_tree_model_commodity_dispose (GObject *object)
148{
149 GncTreeModelCommodity *model;
150
151 g_return_if_fail (object != NULL);
152 g_return_if_fail (GNC_IS_TREE_MODEL_COMMODITY (object));
153
154 ENTER("model %p", object);
155 model = GNC_TREE_MODEL_COMMODITY (object);
156
157 if (model->event_handler_id)
158 {
159 qof_event_unregister_handler (model->event_handler_id);
160 model->event_handler_id = 0;
161 }
162
163 G_OBJECT_CLASS (gnc_tree_model_commodity_parent_class)->dispose (object);
164 LEAVE(" ");
165}
166
167GtkTreeModel *
168gnc_tree_model_commodity_new (QofBook *book, gnc_commodity_table *ct)
169{
170 GncTreeModelCommodity *model;
171 const GList *item;
172
173 ENTER("");
174
175 item = gnc_gobject_tracking_get_list(GNC_TREE_MODEL_COMMODITY_NAME);
176 for ( ; item; item = g_list_next(item))
177 {
178 model = (GncTreeModelCommodity *)item->data;
179 if (model->commodity_table == ct)
180 {
181 g_object_ref(G_OBJECT(model));
182 LEAVE("returning existing model %p", model);
183 return GTK_TREE_MODEL(model);
184 }
185 }
186
187 model = g_object_new (GNC_TYPE_TREE_MODEL_COMMODITY, NULL);
188 model->book = book;
189 model->commodity_table = ct;
190
191 model->event_handler_id =
192 qof_event_register_handler (gnc_tree_model_commodity_event_handler, model);
193
194 LEAVE("");
195 return GTK_TREE_MODEL (model);
196}
197
198gboolean
199gnc_tree_model_commodity_iter_is_namespace (GncTreeModelCommodity *model,
200 GtkTreeIter *iter)
201{
202 g_return_val_if_fail (GNC_IS_TREE_MODEL_COMMODITY (model), FALSE);
203 g_return_val_if_fail (iter != NULL, FALSE);
204 g_return_val_if_fail (iter->user_data != NULL, FALSE);
205 g_return_val_if_fail (iter->stamp == model->stamp, FALSE);
206
207 return (iter->user_data == ITER_IS_NAMESPACE);
208}
209
210gboolean
211gnc_tree_model_commodity_iter_is_commodity (GncTreeModelCommodity *model,
212 GtkTreeIter *iter)
213{
214 g_return_val_if_fail (GNC_IS_TREE_MODEL_COMMODITY (model), FALSE);
215 g_return_val_if_fail (iter != NULL, FALSE);
216 g_return_val_if_fail (iter->user_data != NULL, FALSE);
217 g_return_val_if_fail (iter->stamp == model->stamp, FALSE);
218
219 return (iter->user_data == ITER_IS_COMMODITY);
220}
221
222gnc_commodity_namespace *
223gnc_tree_model_commodity_get_namespace (GncTreeModelCommodity *model,
224 GtkTreeIter *iter)
225{
226 g_return_val_if_fail (GNC_IS_TREE_MODEL_COMMODITY (model), NULL);
227 g_return_val_if_fail (iter != NULL, NULL);
228 g_return_val_if_fail (iter->user_data != NULL, NULL);
229 g_return_val_if_fail (iter->stamp == model->stamp, NULL);
230
231 if (iter->user_data != ITER_IS_NAMESPACE)
232 return NULL;
233 return (gnc_commodity_namespace *)iter->user_data2;
234}
235
236gnc_commodity *
237gnc_tree_model_commodity_get_commodity (GncTreeModelCommodity *model,
238 GtkTreeIter *iter)
239{
240 g_return_val_if_fail (GNC_IS_TREE_MODEL_COMMODITY (model), NULL);
241 g_return_val_if_fail (iter != NULL, NULL);
242 g_return_val_if_fail (iter->user_data != NULL, NULL);
243 g_return_val_if_fail (iter->stamp == model->stamp, NULL);
244
245 if (iter->user_data != ITER_IS_COMMODITY)
246 return NULL;
247 return (gnc_commodity *)iter->user_data2;
248}
249
250/************************************************************/
251/* Gnc Tree Model Debugging Utility Function */
252/************************************************************/
253
254#define debug_path(fn, path) { \
255 gchar *path_string = gtk_tree_path_to_string(path); \
256 fn("tree path %s", path_string? path_string : "NULL"); \
257 g_free(path_string); \
258 }
259
260#define ITER_STRING_LEN 128
261
262static const gchar *
263iter_to_string (GtkTreeIter *iter)
264{
265 gnc_commodity_namespace *name_space;
266 gnc_commodity *commodity = NULL;
267#ifdef G_THREADS_ENABLED
268 static GPrivate gtmits_buffer_key = G_PRIVATE_INIT(g_free);
269 gchar *string;
270
271 string = g_private_get (&gtmits_buffer_key);
272 if (string == NULL)
273 {
274 string = g_malloc(ITER_STRING_LEN + 1);
275 g_private_set (&gtmits_buffer_key, string);
276 }
277#else
278 static char string[ITER_STRING_LEN + 1];
279#endif
280 if (iter)
281 {
282 switch (GPOINTER_TO_INT(iter->user_data))
283 {
284 case GPOINTER_TO_INT(ITER_IS_NAMESPACE):
285 name_space = (gnc_commodity_namespace *) iter->user_data2;
286 snprintf(string, ITER_STRING_LEN,
287 "[stamp:%x data:%d (NAMESPACE), %p (%s), %d]",
288 iter->stamp, GPOINTER_TO_INT(iter->user_data),
289 iter->user_data2, gnc_commodity_namespace_get_name (name_space),
290 GPOINTER_TO_INT(iter->user_data3));
291 break;
292
293 case GPOINTER_TO_INT(ITER_IS_COMMODITY):
294 commodity = (gnc_commodity *) iter->user_data2;
295 snprintf(string, ITER_STRING_LEN,
296 "[stamp:%x data:%d (COMMODITY), %p (%s), %d]",
297 iter->stamp, GPOINTER_TO_INT(iter->user_data),
298 iter->user_data2, gnc_commodity_get_mnemonic (commodity),
299 GPOINTER_TO_INT(iter->user_data3));
300 break;
301
302 default:
303 snprintf(string, ITER_STRING_LEN,
304 "[stamp:%x data:%d (UNKNOWN), %p, %d]",
305 iter->stamp,
306 GPOINTER_TO_INT(iter->user_data),
307 iter->user_data2,
308 GPOINTER_TO_INT(iter->user_data3));
309 break;
310 }
311 }
312 return string;
313}
314
315
316/************************************************************/
317/* Gtk Tree Model Required Interface Functions */
318/************************************************************/
319
320static void
321gnc_tree_model_commodity_tree_model_init (GtkTreeModelIface *iface)
322{
323 iface->get_flags = gnc_tree_model_commodity_get_flags;
324 iface->get_n_columns = gnc_tree_model_commodity_get_n_columns;
325 iface->get_column_type = gnc_tree_model_commodity_get_column_type;
326 iface->get_iter = gnc_tree_model_commodity_get_iter;
327 iface->get_path = gnc_tree_model_commodity_get_path;
328 iface->get_value = gnc_tree_model_commodity_get_value;
329 iface->iter_next = gnc_tree_model_commodity_iter_next;
330 iface->iter_children = gnc_tree_model_commodity_iter_children;
331 iface->iter_has_child = gnc_tree_model_commodity_iter_has_child;
332 iface->iter_n_children = gnc_tree_model_commodity_iter_n_children;
333 iface->iter_nth_child = gnc_tree_model_commodity_iter_nth_child;
334 iface->iter_parent = gnc_tree_model_commodity_iter_parent;
335}
336
337static GtkTreeModelFlags
338gnc_tree_model_commodity_get_flags (GtkTreeModel *tree_model)
339{
340 return 0;
341}
342
343static int
344gnc_tree_model_commodity_get_n_columns (GtkTreeModel *tree_model)
345{
346 return GNC_TREE_MODEL_COMMODITY_NUM_COLUMNS;
347}
348
349static GType
350gnc_tree_model_commodity_get_column_type (GtkTreeModel *tree_model,
351 int index)
352{
353 g_return_val_if_fail (GNC_IS_TREE_MODEL_COMMODITY (tree_model), G_TYPE_INVALID);
354 g_return_val_if_fail ((index < GNC_TREE_MODEL_COMMODITY_NUM_COLUMNS) && (index >= 0), G_TYPE_INVALID);
355
356 switch (index)
357 {
358 case GNC_TREE_MODEL_COMMODITY_COL_MNEMONIC:
359 case GNC_TREE_MODEL_COMMODITY_COL_NAMESPACE:
360 case GNC_TREE_MODEL_COMMODITY_COL_FULLNAME:
361 case GNC_TREE_MODEL_COMMODITY_COL_PRINTNAME:
362 case GNC_TREE_MODEL_COMMODITY_COL_CUSIP:
363 case GNC_TREE_MODEL_COMMODITY_COL_UNIQUE_NAME:
364 case GNC_TREE_MODEL_COMMODITY_COL_QUOTE_SOURCE:
365 case GNC_TREE_MODEL_COMMODITY_COL_QUOTE_TZ:
366 case GNC_TREE_MODEL_COMMODITY_COL_USER_SYMBOL:
367 return G_TYPE_STRING;
368 case GNC_TREE_MODEL_COMMODITY_COL_FRACTION:
369 return G_TYPE_INT;
370 case GNC_TREE_MODEL_COMMODITY_COL_QUOTE_FLAG:
371 case GNC_TREE_MODEL_COMMODITY_COL_VISIBILITY:
372 return G_TYPE_BOOLEAN;
373 default:
374 g_assert_not_reached ();
375 return G_TYPE_INVALID;
376 }
377}
378
379static gboolean
380gnc_tree_model_commodity_get_iter (GtkTreeModel *tree_model,
381 GtkTreeIter *iter,
382 GtkTreePath *path)
383{
384 GncTreeModelCommodity *model;
385 gnc_commodity_table *ct;
386 gnc_commodity_namespace *name_space;
387 gnc_commodity *commodity = NULL;
388 GList *list;
389 guint i, depth;
390
391 iter->stamp = 0;
392 g_return_val_if_fail (GNC_IS_TREE_MODEL_COMMODITY (tree_model), FALSE);
393 g_return_val_if_fail (iter != NULL, FALSE);
394 g_return_val_if_fail (path != NULL, FALSE);
395
396 depth = gtk_tree_path_get_depth (path);
397 ENTER("model %p, iter %p, path %p (depth %d)", tree_model, iter, path, depth);
398 debug_path(DEBUG, path);
399
400 /* Check the path depth. */
401 if (depth == 0)
402 {
403 LEAVE("depth too small");
404 return FALSE;
405 }
406 if (depth > 2)
407 {
408 LEAVE("depth too big");
409 return FALSE;
410 }
411
412 /* Make sure the model has a commodity db. */
413 model = GNC_TREE_MODEL_COMMODITY (tree_model);
414 ct = model->commodity_table;
415 if (ct == NULL)
416 {
417 LEAVE("no commodity table");
418 return FALSE;
419 }
420
421 /* Verify the first part of the path: the namespace. */
423 i = gtk_tree_path_get_indices (path)[0];
424 name_space = g_list_nth_data (list, i);
425 g_list_free (list);
426 if (!name_space)
427 {
428 LEAVE("invalid path at namespace");
429 return FALSE;
430 }
431
432 if (depth == 1)
433 {
434 /* Return an iterator for the namespace. */
435 iter->stamp = model->stamp;
436 iter->user_data = ITER_IS_NAMESPACE;
437 iter->user_data2 = name_space;
438 iter->user_data3 = GINT_TO_POINTER(i);
439 LEAVE("iter (ns) %s", iter_to_string(iter));
440 return TRUE;
441 }
442
443 /* Verify the second part of the path: the commodity. */
445 i = gtk_tree_path_get_indices (path)[1];
446 commodity = g_list_nth_data (list, i);
447 g_list_free (list);
448 if (!commodity)
449 {
450 LEAVE("invalid path at commodity");
451 return FALSE;
452 }
453
454 /* Return an iterator for the commodity. */
455 iter->stamp = model->stamp;
456 iter->user_data = ITER_IS_COMMODITY;
457 iter->user_data2 = commodity;
458 iter->user_data3 = GINT_TO_POINTER(i);
459 LEAVE("iter (cm) %s", iter_to_string(iter));
460 return TRUE;
461}
462
463static GtkTreePath *
464gnc_tree_model_commodity_get_path (GtkTreeModel *tree_model,
465 GtkTreeIter *iter)
466{
467 GncTreeModelCommodity *model;
468 GtkTreePath *path;
469 gnc_commodity_table *ct;
470 gnc_commodity_namespace *name_space;
471 GList *ns_list;
472
473 g_return_val_if_fail (GNC_IS_TREE_MODEL_COMMODITY (tree_model), NULL);
474 model = GNC_TREE_MODEL_COMMODITY (tree_model);
475 g_return_val_if_fail (iter != NULL, NULL);
476 g_return_val_if_fail (iter->user_data != NULL, NULL);
477 g_return_val_if_fail (iter->user_data2 != NULL, NULL);
478 g_return_val_if_fail (iter->stamp == model->stamp, NULL);
479 ENTER("model %p, iter %p (%s)", tree_model, iter, iter_to_string(iter));
480
481 /* Make sure this model has a commodity db. */
482 ct = model->commodity_table;
483 if (ct == NULL)
484 {
485 LEAVE("no commodity table");
486 return FALSE;
487 }
488
489 if (iter->user_data == ITER_IS_NAMESPACE)
490 {
491 /* Create a path to the namespace. This is just the index into
492 * the namespace list, which we already stored in user_data3. */
493 path = gtk_tree_path_new ();
494 gtk_tree_path_append_index (path, GPOINTER_TO_INT(iter->user_data3));
495 debug_path(LEAVE, path);
496 return path;
497 }
498
499 /* Get the namespaces list. */
501 name_space = gnc_commodity_get_namespace_ds((gnc_commodity*)iter->user_data2);
502
503 /* Create a path to the commodity. */
504 path = gtk_tree_path_new ();
505 gtk_tree_path_append_index (path, g_list_index (ns_list, name_space));
506 gtk_tree_path_append_index (path, GPOINTER_TO_INT(iter->user_data3));
507 debug_path(LEAVE, path);
508 g_list_free (ns_list);
509 return path;
510}
511
512static void
513gnc_tree_model_commodity_get_value (GtkTreeModel *tree_model,
514 GtkTreeIter *iter,
515 int column,
516 GValue *value)
517{
518 GncTreeModelCommodity *model = GNC_TREE_MODEL_COMMODITY (tree_model);
519 gnc_commodity_namespace *name_space;
520 gnc_commodity *commodity;
521 gnc_quote_source *source;
522
523 g_return_if_fail (GNC_IS_TREE_MODEL_COMMODITY (tree_model));
524 g_return_if_fail (iter != NULL);
525 g_return_if_fail (iter->user_data != NULL);
526 g_return_if_fail (iter->user_data2 != NULL);
527 g_return_if_fail (iter->stamp == model->stamp);
528
529 if (iter->user_data == ITER_IS_NAMESPACE)
530 {
531 name_space = (gnc_commodity_namespace *)iter->user_data2;
532 switch (column)
533 {
534 case GNC_TREE_MODEL_COMMODITY_COL_NAMESPACE:
535 g_value_init (value, G_TYPE_STRING);
536 g_value_set_string (value, _(gnc_commodity_namespace_get_gui_name (name_space)));
537 break;
538 default:
539 g_value_init (value, G_TYPE_STRING);
540 g_value_set_string (value, "");
541 break;
542 case GNC_TREE_MODEL_COMMODITY_COL_FRACTION:
543 g_value_init (value, G_TYPE_INT);
544 g_value_set_int (value, 0);
545 break;
546 case GNC_TREE_MODEL_COMMODITY_COL_QUOTE_FLAG:
547 g_value_init (value, G_TYPE_BOOLEAN);
548 g_value_set_boolean (value, FALSE);
549 break;
550 case GNC_TREE_MODEL_COMMODITY_COL_VISIBILITY:
551 g_value_init (value, G_TYPE_BOOLEAN);
552 g_value_set_boolean (value, FALSE);
553 break;
554 }
555 return;
556 }
557
558 commodity = (gnc_commodity *)iter->user_data2;
559 switch (column)
560 {
561 case GNC_TREE_MODEL_COMMODITY_COL_MNEMONIC:
562 g_value_init (value, G_TYPE_STRING);
563
564 g_value_set_string (value, gnc_commodity_get_mnemonic (commodity));
565 break;
566 case GNC_TREE_MODEL_COMMODITY_COL_NAMESPACE:
567 g_value_init (value, G_TYPE_STRING);
568
569// g_value_set_string (value, gnc_commodity_get_namespace (commodity));
570 g_value_set_string (value, NULL);
571 break;
572 case GNC_TREE_MODEL_COMMODITY_COL_FULLNAME:
573 g_value_init (value, G_TYPE_STRING);
574
575 g_value_set_string (value, gnc_commodity_get_fullname (commodity));
576 break;
577 case GNC_TREE_MODEL_COMMODITY_COL_PRINTNAME:
578 g_value_init (value, G_TYPE_STRING);
579
580 g_value_set_string (value, gnc_commodity_get_printname (commodity));
581 break;
582 case GNC_TREE_MODEL_COMMODITY_COL_CUSIP:
583 g_value_init (value, G_TYPE_STRING);
584
585 g_value_set_string (value, gnc_commodity_get_cusip (commodity));
586 break;
587 case GNC_TREE_MODEL_COMMODITY_COL_UNIQUE_NAME:
588 g_value_init (value, G_TYPE_STRING);
589
590 g_value_set_string (value, gnc_commodity_get_unique_name (commodity));
591 break;
592 case GNC_TREE_MODEL_COMMODITY_COL_FRACTION:
593 g_value_init (value, G_TYPE_INT);
594
595 g_value_set_int (value, gnc_commodity_get_fraction (commodity));
596 break;
597 case GNC_TREE_MODEL_COMMODITY_COL_QUOTE_FLAG:
598 g_value_init (value, G_TYPE_BOOLEAN);
599
600 g_value_set_boolean (value, gnc_commodity_get_quote_flag (commodity));
601 break;
602 case GNC_TREE_MODEL_COMMODITY_COL_QUOTE_SOURCE:
603 g_value_init (value, G_TYPE_STRING);
604
605 if (gnc_commodity_get_quote_flag (commodity))
606 {
607 source = gnc_commodity_get_quote_source (commodity);
608 g_value_set_string (value, gnc_quote_source_get_internal_name(source));
609 }
610 else
611 {
612 g_value_set_static_string (value, "");
613 }
614 break;
615 case GNC_TREE_MODEL_COMMODITY_COL_QUOTE_TZ:
616 g_value_init (value, G_TYPE_STRING);
617
618 if (gnc_commodity_get_quote_flag (commodity))
619 {
620 g_value_set_string (value, gnc_commodity_get_quote_tz (commodity));
621 }
622 else
623 {
624 g_value_set_static_string (value, "");
625 }
626 break;
627 case GNC_TREE_MODEL_COMMODITY_COL_USER_SYMBOL:
628 g_value_init (value, G_TYPE_STRING);
629
630 g_value_set_string (value, gnc_commodity_get_nice_symbol (commodity));
631 break;
632 case GNC_TREE_MODEL_COMMODITY_COL_VISIBILITY:
633 g_value_init (value, G_TYPE_BOOLEAN);
634 g_value_set_boolean (value, TRUE);
635 break;
636 default:
637 g_assert_not_reached ();
638 }
639}
640
641static gboolean
642gnc_tree_model_commodity_iter_next (GtkTreeModel *tree_model,
643 GtkTreeIter *iter)
644{
645 GncTreeModelCommodity *model;
646 gnc_commodity_table *ct;
647 gnc_commodity_namespace *name_space;
648 GList *list;
649 int n;
650
651 g_return_val_if_fail (GNC_IS_TREE_MODEL_COMMODITY (tree_model), FALSE);
652 model = GNC_TREE_MODEL_COMMODITY (tree_model);
653 g_return_val_if_fail (iter != NULL, FALSE);
654 g_return_val_if_fail (iter->user_data != NULL, FALSE);
655 g_return_val_if_fail (iter->user_data2 != NULL, FALSE);
656 g_return_val_if_fail (iter->stamp == model->stamp, FALSE);
657
658 ENTER("model %p, iter %p(%s)", tree_model, iter, iter_to_string(iter));
659 if (iter->user_data == ITER_IS_NAMESPACE)
660 {
661 ct = model->commodity_table;
663 }
664 else if (iter->user_data == ITER_IS_COMMODITY)
665 {
666 name_space = gnc_commodity_get_namespace_ds((gnc_commodity *)iter->user_data2);
668 }
669 else
670 {
671 LEAVE("unknown iter type");
672 return FALSE;
673 }
674
675 n = GPOINTER_TO_INT(iter->user_data3) + 1;
676 iter->user_data2 = g_list_nth_data(list, n);
677 g_list_free (list);
678 if (iter->user_data2 == NULL)
679 {
680 LEAVE("no next iter");
681 return FALSE;
682 }
683 iter->user_data3 = GINT_TO_POINTER(n);
684 LEAVE("iter %p(%s)", iter, iter_to_string(iter));
685 return TRUE;
686}
687
688
689static gboolean
690gnc_tree_model_commodity_iter_children (GtkTreeModel *tree_model,
691 GtkTreeIter *iter,
692 GtkTreeIter *parent)
693{
694 GncTreeModelCommodity *model;
695 gnc_commodity_table *ct;
696 gnc_commodity_namespace *name_space;
697 GList *list;
698
699 g_return_val_if_fail (GNC_IS_TREE_MODEL_COMMODITY (tree_model), FALSE);
700
701 ENTER("model %p, iter %p, parent %p (%s)",
702 tree_model, iter, parent, iter_to_string(parent));
703 model = GNC_TREE_MODEL_COMMODITY (tree_model);
704
705 if (parent == NULL)
706 {
707 ct = model->commodity_table;
709 if (list == NULL)
710 {
711 LEAVE("no namespaces");
712 return FALSE;
713 }
714
715 iter->stamp = model->stamp;
716 iter->user_data = ITER_IS_NAMESPACE;
717 iter->user_data2 = g_list_nth_data(list, 0);
718 iter->user_data3 = GINT_TO_POINTER(0);
719 LEAVE("ns iter %p (%s)", iter, iter_to_string(iter));
720 g_list_free (list);
721 return TRUE;
722 }
723
724 if (parent->user_data == ITER_IS_NAMESPACE)
725 {
726 name_space = (gnc_commodity_namespace *)parent->user_data2;
728 if (list == NULL)
729 {
730 LEAVE("no commodities");
731 return FALSE;
732 }
733
734 iter->stamp = model->stamp;
735 iter->user_data = ITER_IS_COMMODITY;
736 iter->user_data2 = g_list_nth_data(list, 0);
737 iter->user_data3 = GINT_TO_POINTER(0);
738 LEAVE("cm iter %p (%s)", iter, iter_to_string(iter));
739 g_list_free (list);
740 return TRUE;
741 }
742
743 LEAVE("FALSE");
744 return FALSE;
745}
746
747static gboolean
748gnc_tree_model_commodity_iter_has_child (GtkTreeModel *tree_model,
749 GtkTreeIter *iter)
750{
751 gnc_commodity_namespace *name_space;
752 GList *list;
753
754 g_return_val_if_fail (iter != NULL, FALSE);
755 ENTER("model %p, iter %p (%s)", tree_model,
756 iter, iter_to_string(iter));
757
758 if (iter->user_data != ITER_IS_NAMESPACE)
759 {
760 LEAVE("no children (not ns)");
761 return FALSE;
762 }
763
764 name_space = (gnc_commodity_namespace *)iter->user_data2;
766 LEAVE("%s children", list ? "has" : "no");
767 gboolean rv = (list != NULL);
768 g_list_free (list);
769 return rv;
770}
771
772static int
773gnc_tree_model_commodity_iter_n_children (GtkTreeModel *tree_model,
774 GtkTreeIter *iter)
775{
776 GncTreeModelCommodity *model;
777 gnc_commodity_table *ct;
778 gnc_commodity_namespace *name_space;
779 GList *list;
780
781 g_return_val_if_fail (GNC_IS_TREE_MODEL_COMMODITY (tree_model), -1);
782
783 ENTER("model %p, iter %p (%s)", tree_model, iter, iter_to_string(iter));
784 model = GNC_TREE_MODEL_COMMODITY (tree_model);
785
786 if (iter == NULL)
787 {
788 ct = model->commodity_table;
790 LEAVE("ns list length %d", g_list_length(list));
791 guint rv = g_list_length (list);
792 g_list_free (list);
793 return rv;
794 }
795
796 if (iter->user_data == ITER_IS_NAMESPACE)
797 {
798 name_space = (gnc_commodity_namespace *)iter->user_data2;
800 LEAVE("cm list length %d", g_list_length(list));
801 guint rv = g_list_length (list);
802 g_list_free (list);
803 return rv;
804 }
805
806 LEAVE("0");
807 return 0;
808}
809
810static gboolean
811gnc_tree_model_commodity_iter_nth_child (GtkTreeModel *tree_model,
812 GtkTreeIter *iter,
813 GtkTreeIter *parent,
814 int n)
815{
816 GncTreeModelCommodity *model;
817 gnc_commodity_table *ct;
818 gnc_commodity_namespace *name_space;
819 GList *list;
820
821 g_return_val_if_fail (GNC_IS_TREE_MODEL_COMMODITY (tree_model), FALSE);
822 g_return_val_if_fail (iter != NULL, FALSE);
823
824 ENTER("model %p, iter %p, parent %p (%s)",
825 tree_model, iter, parent, iter_to_string(parent));
826 model = GNC_TREE_MODEL_COMMODITY (tree_model);
827
828 if (parent == NULL)
829 {
830 ct = model->commodity_table;
832
833 iter->stamp = model->stamp;
834 iter->user_data = ITER_IS_NAMESPACE;
835 iter->user_data2 = g_list_nth_data(list, n);
836 iter->user_data3 = GINT_TO_POINTER(n);
837 LEAVE("ns iter %p (%s)", iter, iter_to_string(iter));
838 g_list_free (list);
839 return iter->user_data2 != NULL;
840 }
841
842 if (parent->user_data == ITER_IS_NAMESPACE)
843 {
844 name_space = (gnc_commodity_namespace *)parent->user_data2;
846
847 iter->stamp = model->stamp;
848 iter->user_data = ITER_IS_COMMODITY;
849 iter->user_data2 = g_list_nth_data(list, n);
850 iter->user_data3 = GINT_TO_POINTER(n);
851 LEAVE("cm iter %p (%s)", iter, iter_to_string(iter));
852 g_list_free (list);
853 return iter->user_data2 != NULL;
854 }
855
856 iter->stamp = 0;
857 LEAVE("FALSE");
858 return FALSE;
859}
860
861static gboolean
862gnc_tree_model_commodity_iter_parent (GtkTreeModel *tree_model,
863 GtkTreeIter *iter,
864 GtkTreeIter *child)
865{
866 GncTreeModelCommodity *model;
867 gnc_commodity_table *ct;
868 gnc_commodity_namespace *name_space;
869 GList *list;
870
871 g_return_val_if_fail (GNC_IS_TREE_MODEL_COMMODITY (tree_model), FALSE);
872 g_return_val_if_fail (iter != NULL, FALSE);
873 g_return_val_if_fail (child != NULL, FALSE);
874
875 ENTER("model %p, iter %p, child %p (%s)",
876 tree_model, iter, child, iter_to_string(child));
877 model = GNC_TREE_MODEL_COMMODITY (tree_model);
878
879 if (child->user_data == ITER_IS_NAMESPACE)
880 {
881 LEAVE("ns has no parent");
882 return FALSE;
883 }
884
885 ct = model->commodity_table;
887 name_space = gnc_commodity_get_namespace_ds((gnc_commodity*)child->user_data2);
888
889 iter->stamp = model->stamp;
890 iter->user_data = ITER_IS_NAMESPACE;
891 iter->user_data2 = name_space;
892 iter->user_data3 = GINT_TO_POINTER(g_list_index(list, name_space));
893 LEAVE("ns iter %p (%s)", iter, iter_to_string(iter));
894 g_list_free (list);
895 return TRUE;
896}
897
898/************************************************************/
899/* Commodity Tree View Functions */
900/************************************************************/
901
902/*
903 * Convert a model/commodity pair into a gtk_tree_model_iter. This
904 * routine should only be called from the file
905 * gnc-tree-view-commodity.c.
906 */
907gboolean
909 gnc_commodity *commodity,
910 GtkTreeIter *iter)
911{
912 gnc_commodity_namespace *name_space;
913 GList *list;
914 gint n;
915
916 g_return_val_if_fail (GNC_IS_TREE_MODEL_COMMODITY (model), FALSE);
917 g_return_val_if_fail ((commodity != NULL), FALSE);
918 g_return_val_if_fail ((iter != NULL), FALSE);
919
920 ENTER("model %p, commodity %p, iter %p", model, commodity, iter);
921
922 name_space = gnc_commodity_get_namespace_ds(commodity);
923 if (name_space == NULL)
924 {
925 LEAVE("no namespace");
926 return FALSE;
927 }
928
930 if (list == NULL)
931 {
932 LEAVE("empty list");
933 return FALSE;
934 }
935
936 n = g_list_index(list, commodity);
937 g_list_free (list);
938 if (n == -1)
939 {
940 LEAVE("not in list");
941 return FALSE;
942 }
943
944 iter->stamp = model->stamp;
945 iter->user_data = ITER_IS_COMMODITY;
946 iter->user_data2 = commodity;
947 iter->user_data3 = GINT_TO_POINTER(n);
948 LEAVE("iter %s", iter_to_string(iter));
949 return TRUE;
950}
951
952/*
953 * Convert a model/commodity pair into a gtk_tree_model_path. This
954 * routine should only be called from the file
955 * gnc-tree-view-commodity.c.
956 */
957GtkTreePath *
959 gnc_commodity *commodity)
960{
961 GtkTreeIter tree_iter;
962 GtkTreePath *tree_path;
963
964 g_return_val_if_fail (GNC_IS_TREE_MODEL_COMMODITY (model), NULL);
965 g_return_val_if_fail (commodity != NULL, NULL);
966 ENTER("model %p, commodity %p", model, commodity);
967
968 if (!gnc_tree_model_commodity_get_iter_from_commodity (model, commodity, &tree_iter))
969 {
970 LEAVE("no iter");
971 return NULL;
972 }
973
974 tree_path = gtk_tree_model_get_path (GTK_TREE_MODEL(model), &tree_iter);
975 if (tree_path)
976 {
977 gchar *path_string = gtk_tree_path_to_string(tree_path);
978 LEAVE("path (2) %s", path_string);
979 g_free(path_string);
980 }
981 else
982 {
983 LEAVE("no path");
984 }
985 return tree_path;
986}
987
988/*
989 * Convert a model/namespace pair into a gtk_tree_model_iter. This
990 * routine should only be called from the file
991 * gnc-tree-view-commodity.c.
992 */
993gboolean
995 gnc_commodity_namespace *name_space,
996 GtkTreeIter *iter)
997{
998 GList *list;
999 gint n;
1000
1001 g_return_val_if_fail (GNC_IS_TREE_MODEL_COMMODITY (model), FALSE);
1002 g_return_val_if_fail ((name_space != NULL), FALSE);
1003 g_return_val_if_fail ((iter != NULL), FALSE);
1004
1005 ENTER("model %p, namespace %p, iter %p", model, name_space, iter);
1006
1007 list = gnc_commodity_table_get_namespaces_list(model->commodity_table);
1008 if (list == NULL)
1009 {
1010 LEAVE("");
1011 return FALSE;
1012 }
1013
1014 n = g_list_index(list, name_space);
1015 g_list_free (list);
1016 if (n == -1)
1017 {
1018 LEAVE("");
1019 return FALSE;
1020 }
1021
1022 iter->stamp = model->stamp;
1023 iter->user_data = ITER_IS_NAMESPACE;
1024 iter->user_data2 = name_space;
1025 iter->user_data3 = GINT_TO_POINTER(n);
1026 LEAVE("iter %s", iter_to_string(iter));
1027 return TRUE;
1028}
1029
1030
1031/************************************************************/
1032/* Commodity Tree Model - Engine Event Handling Functions */
1033/************************************************************/
1034
1035typedef struct _remove_data
1036{
1037 GncTreeModelCommodity *model;
1038 GtkTreePath *path;
1039} remove_data;
1040
1041static GSList *pending_removals = NULL;
1042
1054static void
1055gnc_tree_model_commodity_row_add (GncTreeModelCommodity *model,
1056 GtkTreeIter *iter)
1057{
1058 GtkTreePath *path;
1059 GtkTreeModel *tree_model;
1060 GtkTreeIter tmp_iter;
1061
1062 ENTER("model %p, iter (%p)%s", model, iter, iter_to_string(iter));
1063
1064 /* We're adding a row, so the lists on which this model is based have
1065 * changed. Since existing iterators (except the one just passed in)
1066 * are all based on old indexes into those lists, we need to invalidate
1067 * them, which we can do by changing the model's stamp. */
1068 do
1069 {
1070 model->stamp++;
1071 }
1072 while (model->stamp == 0);
1073 iter->stamp = model->stamp;
1074
1075 /* Tag the new row as inserted. */
1076 tree_model = GTK_TREE_MODEL(model);
1077 path = gnc_tree_model_commodity_get_path(tree_model, iter);
1078 gtk_tree_model_row_inserted(tree_model, path, iter);
1079
1080 /* Inform all ancestors. */
1081 /*
1082 * Charles Day: I don't think calls to gtk_tree_model_row_changed() should
1083 * be necessary. It is just a workaround for bug #540201.
1084 */
1085 if (gtk_tree_path_up(path) &&
1086 gtk_tree_path_get_depth(path) > 0 &&
1087 gtk_tree_model_get_iter(tree_model, &tmp_iter, path))
1088 {
1089 /* Signal the change to the parent. */
1090 gtk_tree_model_row_changed(tree_model, path, &tmp_iter);
1091
1092 /* Is this the parent's first child? */
1093 if (gtk_tree_model_iter_n_children(tree_model, &tmp_iter) == 1)
1094 gtk_tree_model_row_has_child_toggled(tree_model, path, &tmp_iter);
1095
1096 /* Signal any other ancestors. */
1097 while (gtk_tree_path_up(path) &&
1098 gtk_tree_path_get_depth(path) > 0 &&
1099 gtk_tree_model_get_iter(tree_model, &tmp_iter, path))
1100 {
1101 gtk_tree_model_row_changed(tree_model, path, &tmp_iter);
1102 }
1103 }
1104 gtk_tree_path_free(path);
1105
1106 /* If the new row already has children, signal that so the expander
1107 * can be shown. This can happen, for example, if a namespace is
1108 * changed in another place and gets removed and then re-added to
1109 * the commodity db. */
1110 if (gnc_tree_model_commodity_iter_has_child(tree_model, iter))
1111 {
1112 path = gnc_tree_model_commodity_get_path(tree_model, iter);
1113 gtk_tree_model_row_has_child_toggled(tree_model, path, iter);
1114 gtk_tree_path_free(path);
1115 }
1116
1117 LEAVE(" ");
1118}
1119
1131static void
1132gnc_tree_model_commodity_row_delete (GncTreeModelCommodity *model,
1133 GtkTreePath *path)
1134{
1135 GtkTreeModel *tree_model;
1136 GtkTreeIter iter;
1137
1138 g_return_if_fail(GNC_IS_TREE_MODEL_COMMODITY(model));
1139 g_return_if_fail(path);
1140
1141 debug_path(ENTER, path);
1142
1143 tree_model = GTK_TREE_MODEL(model);
1144
1145 /* We're removing a row, so the lists on which this model is based have
1146 * changed. Since existing iterators are all based on old indexes into
1147 * those lists, we need to invalidate them, which we can do by changing
1148 * the model's stamp. */
1149 do
1150 {
1151 model->stamp++;
1152 }
1153 while (model->stamp == 0);
1154
1155 /* Signal that the path has been deleted. */
1156 gtk_tree_model_row_deleted(tree_model, path);
1157
1158 /* Issue any appropriate signals to ancestors. */
1159 if (gtk_tree_path_up(path) &&
1160 gtk_tree_path_get_depth(path) > 0 &&
1161 gtk_tree_model_get_iter(tree_model, &iter, path) &&
1162 !gtk_tree_model_iter_has_child(tree_model, &iter))
1163 {
1164 DEBUG("parent toggled, iter %s", iter_to_string(&iter));
1165 gtk_tree_model_row_has_child_toggled(tree_model, path, &iter);
1166 }
1167
1168 LEAVE(" ");
1169}
1170
1171
1188static gboolean
1189gnc_tree_model_commodity_do_deletions (gpointer unused)
1190{
1191 ENTER(" ");
1192
1193 /* Go through the list of paths needing removal. */
1194 while (pending_removals)
1195 {
1196 remove_data *data = pending_removals->data;
1197 pending_removals = g_slist_delete_link(pending_removals, pending_removals);
1198
1199 if (data)
1200 {
1201 debug_path(DEBUG, data->path);
1202
1203 /* Remove the path. */
1204 gnc_tree_model_commodity_row_delete(data->model, data->path);
1205
1206 gtk_tree_path_free(data->path);
1207 g_free(data);
1208 }
1209 }
1210
1211 LEAVE(" ");
1212 /* Don't call me again. */
1213 return FALSE;
1214}
1215
1216
1248static void
1249gnc_tree_model_commodity_event_handler (QofInstance *entity,
1250 QofEventId event_type,
1251 gpointer user_data,
1252 gpointer event_data)
1253{
1254 GncTreeModelCommodity *model;
1255 GtkTreePath *path;
1256 GtkTreeIter iter;
1257 remove_data *data;
1258 const gchar *name;
1259
1260 model = (GncTreeModelCommodity *)user_data;
1261
1262 /* hard failures */
1263 g_return_if_fail(GNC_IS_TREE_MODEL_COMMODITY(model));
1264
1265 ENTER("entity %p, event %d, model %p, event data %p",
1266 entity, event_type, user_data, event_data);
1267
1268 /* Do deletions if any are pending. */
1269 if (pending_removals)
1270 gnc_tree_model_commodity_do_deletions(NULL);
1271
1272 /* get type specific data */
1273 if (GNC_IS_COMMODITY(entity))
1274 {
1275 gnc_commodity *commodity;
1276
1277 commodity = GNC_COMMODITY(entity);
1278 name = gnc_commodity_get_mnemonic(commodity);
1279 if (event_type != QOF_EVENT_DESTROY)
1280 {
1281 if (!gnc_tree_model_commodity_get_iter_from_commodity (model, commodity, &iter))
1282 {
1283 LEAVE("no iter");
1284 return;
1285 }
1286 }
1287 }
1288 else if (GNC_IS_COMMODITY_NAMESPACE(entity))
1289 {
1290 gnc_commodity_namespace *name_space;
1291
1292 name_space = GNC_COMMODITY_NAMESPACE(entity);
1293 name = gnc_commodity_namespace_get_name(name_space);
1294 if (event_type != QOF_EVENT_DESTROY)
1295 {
1296 if (!gnc_tree_model_commodity_get_iter_from_namespace (model, name_space, &iter))
1297 {
1298 LEAVE("no iter");
1299 return;
1300 }
1301 }
1302 }
1303 else
1304 {
1305 LEAVE("");
1306 return;
1307 }
1308
1309 switch (event_type)
1310 {
1311 case QOF_EVENT_ADD:
1312 /* Tell the filters/views where the new account was added. */
1313 DEBUG("add %s", name);
1314 gnc_tree_model_commodity_row_add (model, &iter);
1315 break;
1316
1317 case QOF_EVENT_REMOVE:
1318 /* Record the path of this account for later use in destruction */
1319 DEBUG("remove %s", name);
1320 path = gtk_tree_model_get_path (GTK_TREE_MODEL(model), &iter);
1321 if (path == NULL)
1322 {
1323 LEAVE("not in model");
1324 return;
1325 }
1326
1327 data = g_new0 (remove_data, 1);
1328 data->model = model;
1329 data->path = path;
1330 pending_removals = g_slist_append (pending_removals, data);
1331 g_idle_add_full(G_PRIORITY_HIGH_IDLE,
1332 gnc_tree_model_commodity_do_deletions, NULL, NULL);
1333
1334 LEAVE(" ");
1335 return;
1336
1337 case QOF_EVENT_MODIFY:
1338 DEBUG("change %s", name);
1339 path = gtk_tree_model_get_path (GTK_TREE_MODEL(model), &iter);
1340 if (path == NULL)
1341 {
1342 LEAVE("not in model");
1343 return;
1344 }
1345 gtk_tree_model_row_changed(GTK_TREE_MODEL(model), path, &iter);
1346 gtk_tree_path_free(path);
1347 LEAVE(" ");
1348 return;
1349
1350 default:
1351 LEAVE("ignored event for %s", name);
1352 return;
1353 }
1354 LEAVE(" new stamp %u", model->stamp);
1355}
All type declarations for the whole Gnucash engine.
Gobject helper routines.
GtkTreeModel implementation for gnucash commodities.
utility functions for the GnuCash UI
const char * gnc_commodity_get_fullname(const gnc_commodity *cm)
Retrieve the full name for the specified commodity.
const char * gnc_quote_source_get_internal_name(const gnc_quote_source *source)
Given a gnc_quote_source data structure, return the internal name of this quote source.
int gnc_commodity_get_fraction(const gnc_commodity *cm)
Retrieve the fraction for the specified commodity.
GList * gnc_commodity_namespace_get_commodity_list(const gnc_commodity_namespace *name_space)
Return a list of all commodity data structures in the specified namespace.
const char * gnc_commodity_get_quote_tz(const gnc_commodity *cm)
Retrieve the automatic price quote timezone for the specified commodity.
const char * gnc_commodity_get_nice_symbol(const gnc_commodity *cm)
Retrieve a symbol for the specified commodity, suitable for display to the user.
gnc_quote_source * gnc_commodity_get_quote_source(const gnc_commodity *cm)
Retrieve the automatic price quote source for the specified commodity.
const char * gnc_commodity_get_cusip(const gnc_commodity *cm)
Retrieve the 'exchange code' for the specified commodity.
const char * gnc_commodity_get_printname(const gnc_commodity *cm)
Retrieve the 'print' name for the specified commodity.
GList * gnc_commodity_table_get_namespaces_list(const gnc_commodity_table *table)
Return a list of all namespace data structures in the commodity table.
gnc_commodity_namespace * gnc_commodity_get_namespace_ds(const gnc_commodity *cm)
Retrieve the namespace data structure for the specified commodity.
const char * gnc_commodity_namespace_get_name(const gnc_commodity_namespace *ns)
Return the textual name of a namespace data structure.
const char * gnc_commodity_get_mnemonic(const gnc_commodity *cm)
Retrieve the mnemonic for the specified commodity.
gboolean gnc_commodity_get_quote_flag(const gnc_commodity *cm)
Retrieve the automatic price quote flag for the specified commodity.
const char * gnc_commodity_namespace_get_gui_name(const gnc_commodity_namespace *ns)
Return the textual name of a namespace data structure in a form suitable to present to the user.
const char * gnc_commodity_get_unique_name(const gnc_commodity *cm)
Retrieve the 'unique' name for the specified commodity.
void qof_event_unregister_handler(gint handler_id)
Unregister an event handler.
Definition qofevent.cpp:103
gint qof_event_register_handler(QofEventHandler handler, gpointer user_data)
Register a handler for events.
Definition qofevent.cpp:73
gint QofEventId
Define the type of events allowed.
Definition qofevent.h:45
const GList * gnc_gobject_tracking_get_list(const gchar *name)
Get a list of all known objects of a specified type.
gnc_commodity * gnc_tree_model_commodity_get_commodity(GncTreeModelCommodity *model, GtkTreeIter *iter)
Convert a model/iter pair to a gnucash commodity.
gboolean gnc_tree_model_commodity_iter_is_namespace(GncTreeModelCommodity *model, GtkTreeIter *iter)
Determine whether or not the specified GtkTreeIter points to a commodity namespace.
gboolean gnc_tree_model_commodity_get_iter_from_commodity(GncTreeModelCommodity *model, gnc_commodity *commodity, GtkTreeIter *iter)
Convert a commodity pointer into a GtkTreeIter.
GtkTreeModel * gnc_tree_model_commodity_new(QofBook *book, gnc_commodity_table *ct)
Create a new GtkTreeModel for manipulating gnucash commodities.
gboolean gnc_tree_model_commodity_iter_is_commodity(GncTreeModelCommodity *model, GtkTreeIter *iter)
Determine whether or not the specified GtkTreeIter points to a commodity.
gboolean gnc_tree_model_commodity_get_iter_from_namespace(GncTreeModelCommodity *model, gnc_commodity_namespace *name_space, GtkTreeIter *iter)
Convert a commodity namespace pointer into a GtkTreeIter.
gnc_commodity_namespace * gnc_tree_model_commodity_get_namespace(GncTreeModelCommodity *model, GtkTreeIter *iter)
Convert a model/iter pair to a gnucash commodity namespace.
GtkTreePath * gnc_tree_model_commodity_get_path_from_commodity(GncTreeModelCommodity *model, gnc_commodity *commodity)
Convert a commodity pointer into a GtkTreePath.
#define DEBUG(format, args...)
Print a debugging message.
Definition qoflog.h:264
#define LEAVE(format, args...)
Print a function exit debugging message.
Definition qoflog.h:282
#define ENTER(format, args...)
Print a function entry debugging message.
Definition qoflog.h:272
QofBook reference.
Definition qofbook-p.hpp:47
The instance data structure for a commodity tree model.
int stamp
The state of the model.
GncTreeModel gnc_tree_model
The parent object data.