GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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 <[email protected]>
6  * Copyright (C) 2003 David Hampton <[email protected]>
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 [email protected]
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 <gtk/gtk.h>
40 #include <string.h>
41 
43 #include "gnc-component-manager.h"
44 #include "gnc-engine.h"
45 #include "gnc-gobject-utils.h"
46 #include "gnc-ui-util.h"
47 
48 #define ITER_IS_NAMESPACE GINT_TO_POINTER(1)
49 #define ITER_IS_COMMODITY GINT_TO_POINTER(2)
50 
52 static QofLogModule log_module = GNC_MOD_GUI;
53 
55 static void gnc_tree_model_commodity_class_init (GncTreeModelCommodityClass *klass);
56 static void gnc_tree_model_commodity_init (GncTreeModelCommodity *model);
57 static void gnc_tree_model_commodity_finalize (GObject *object);
58 static void gnc_tree_model_commodity_dispose (GObject *object);
59 
60 static void gnc_tree_model_commodity_tree_model_init (GtkTreeModelIface *iface);
61 static GtkTreeModelFlags gnc_tree_model_commodity_get_flags (GtkTreeModel *tree_model);
62 static int gnc_tree_model_commodity_get_n_columns (GtkTreeModel *tree_model);
63 static GType gnc_tree_model_commodity_get_column_type (GtkTreeModel *tree_model,
64  int index);
65 static gboolean gnc_tree_model_commodity_get_iter (GtkTreeModel *tree_model,
66  GtkTreeIter *iter,
67  GtkTreePath *path);
68 static GtkTreePath *gnc_tree_model_commodity_get_path (GtkTreeModel *tree_model,
69  GtkTreeIter *iter);
70 static void gnc_tree_model_commodity_get_value (GtkTreeModel *tree_model,
71  GtkTreeIter *iter,
72  int column,
73  GValue *value);
74 static gboolean gnc_tree_model_commodity_iter_next (GtkTreeModel *tree_model,
75  GtkTreeIter *iter);
76 static gboolean gnc_tree_model_commodity_iter_children (GtkTreeModel *tree_model,
77  GtkTreeIter *iter,
78  GtkTreeIter *parent);
79 static gboolean gnc_tree_model_commodity_iter_has_child (GtkTreeModel *tree_model,
80  GtkTreeIter *iter);
81 static int gnc_tree_model_commodity_iter_n_children (GtkTreeModel *tree_model,
82  GtkTreeIter *iter);
83 static gboolean gnc_tree_model_commodity_iter_nth_child (GtkTreeModel *tree_model,
84  GtkTreeIter *iter,
85  GtkTreeIter *parent,
86  int n);
87 static gboolean gnc_tree_model_commodity_iter_parent (GtkTreeModel *tree_model,
88  GtkTreeIter *iter,
89  GtkTreeIter *child);
90 static void gnc_tree_model_commodity_event_handler (QofInstance *entity,
91  QofEventId event_type,
92  gpointer user_data,
93  gpointer event_data);
94 
97 {
98  QofBook *book;
99  gnc_commodity_table *commodity_table;
100  gint event_handler_id;
102 
103 #define GNC_TREE_MODEL_COMMODITY_GET_PRIVATE(o) \
104  (G_TYPE_INSTANCE_GET_PRIVATE ((o), GNC_TYPE_TREE_MODEL_COMMODITY, GncTreeModelCommodityPrivate))
105 
107 static GtkObjectClass *parent_class = NULL;
108 
109 GType
111 {
112  static GType gnc_tree_model_commodity_type = 0;
113 
114  if (gnc_tree_model_commodity_type == 0)
115  {
116  static const GTypeInfo our_info =
117  {
119  NULL,
120  NULL,
121  (GClassInitFunc) gnc_tree_model_commodity_class_init,
122  NULL,
123  NULL,
124  sizeof (GncTreeModelCommodity),
125  0,
126  (GInstanceInitFunc) gnc_tree_model_commodity_init
127  };
128 
129  static const GInterfaceInfo tree_model_info =
130  {
131  (GInterfaceInitFunc) gnc_tree_model_commodity_tree_model_init,
132  NULL,
133  NULL
134  };
135 
136  gnc_tree_model_commodity_type = g_type_register_static (GNC_TYPE_TREE_MODEL,
137  GNC_TREE_MODEL_COMMODITY_NAME,
138  &our_info, 0);
139 
140  g_type_add_interface_static (gnc_tree_model_commodity_type,
141  GTK_TYPE_TREE_MODEL,
142  &tree_model_info);
143  }
144 
145  return gnc_tree_model_commodity_type;
146 }
147 
148 static void
149 gnc_tree_model_commodity_class_init (GncTreeModelCommodityClass *klass)
150 {
151  GObjectClass *o_class = G_OBJECT_CLASS (klass);
152 
153  parent_class = g_type_class_peek_parent (klass);
154 
155  o_class->finalize = gnc_tree_model_commodity_finalize;
156  o_class->dispose = gnc_tree_model_commodity_dispose;
157 
158  g_type_class_add_private(klass, sizeof(GncTreeModelCommodityPrivate));
159 }
160 
161 static void
162 gnc_tree_model_commodity_init (GncTreeModelCommodity *model)
163 {
164  while (model->stamp == 0)
165  {
166  model->stamp = g_random_int ();
167  }
168 }
169 
170 static void
171 gnc_tree_model_commodity_finalize (GObject *object)
172 {
173  GncTreeModelCommodity *model;
175 
176  g_return_if_fail (object != NULL);
177  g_return_if_fail (GNC_IS_TREE_MODEL_COMMODITY (object));
178 
179  ENTER("model %p", object);
180 
181  model = GNC_TREE_MODEL_COMMODITY (object);
182  priv = GNC_TREE_MODEL_COMMODITY_GET_PRIVATE(model);
183  priv->book = NULL;
184  priv->commodity_table = NULL;
185 
186  G_OBJECT_CLASS (parent_class)->finalize (object);
187  LEAVE(" ");
188 }
189 
190 static void
191 gnc_tree_model_commodity_dispose (GObject *object)
192 {
193  GncTreeModelCommodity *model;
195 
196  g_return_if_fail (object != NULL);
197  g_return_if_fail (GNC_IS_TREE_MODEL_COMMODITY (object));
198 
199  ENTER("model %p", object);
200  model = GNC_TREE_MODEL_COMMODITY (object);
201  priv = GNC_TREE_MODEL_COMMODITY_GET_PRIVATE(model);
202 
203  if (priv->event_handler_id)
204  {
205  qof_event_unregister_handler (priv->event_handler_id);
206  priv->event_handler_id = 0;
207  }
208 
209  if (G_OBJECT_CLASS (parent_class)->dispose)
210  G_OBJECT_CLASS (parent_class)->dispose (object);
211  LEAVE(" ");
212 }
213 
214 GtkTreeModel *
216 {
217  GncTreeModelCommodity *model;
219  const GList *item;
220 
221  ENTER("");
222 
223  item = gnc_gobject_tracking_get_list(GNC_TREE_MODEL_COMMODITY_NAME);
224  for ( ; item; item = g_list_next(item))
225  {
226  model = (GncTreeModelCommodity *)item->data;
227  priv = GNC_TREE_MODEL_COMMODITY_GET_PRIVATE(model);
228  if (priv->commodity_table == ct)
229  {
230  g_object_ref(G_OBJECT(model));
231  LEAVE("returning existing model %p", model);
232  return GTK_TREE_MODEL(model);
233  }
234  }
235 
236  model = g_object_new (GNC_TYPE_TREE_MODEL_COMMODITY, NULL);
237  priv = GNC_TREE_MODEL_COMMODITY_GET_PRIVATE(model);
238  priv->book = book;
239  priv->commodity_table = ct;
240 
241  priv->event_handler_id =
242  qof_event_register_handler (gnc_tree_model_commodity_event_handler, model);
243 
244  LEAVE("");
245  return GTK_TREE_MODEL (model);
246 }
247 
248 gboolean
250  GtkTreeIter *iter)
251 {
252  g_return_val_if_fail (GNC_IS_TREE_MODEL_COMMODITY (model), FALSE);
253  g_return_val_if_fail (iter != NULL, FALSE);
254  g_return_val_if_fail (iter->user_data != NULL, FALSE);
255  g_return_val_if_fail (iter->stamp == model->stamp, FALSE);
256 
257  return (iter->user_data == ITER_IS_NAMESPACE);
258 }
259 
260 gboolean
262  GtkTreeIter *iter)
263 {
264  g_return_val_if_fail (GNC_IS_TREE_MODEL_COMMODITY (model), FALSE);
265  g_return_val_if_fail (iter != NULL, FALSE);
266  g_return_val_if_fail (iter->user_data != NULL, FALSE);
267  g_return_val_if_fail (iter->stamp == model->stamp, FALSE);
268 
269  return (iter->user_data == ITER_IS_COMMODITY);
270 }
271 
274  GtkTreeIter *iter)
275 {
276  g_return_val_if_fail (GNC_IS_TREE_MODEL_COMMODITY (model), NULL);
277  g_return_val_if_fail (iter != NULL, NULL);
278  g_return_val_if_fail (iter->user_data != NULL, NULL);
279  g_return_val_if_fail (iter->stamp == model->stamp, NULL);
280 
281  if (iter->user_data != ITER_IS_NAMESPACE)
282  return NULL;
283  return (gnc_commodity_namespace *)iter->user_data2;
284 }
285 
288  GtkTreeIter *iter)
289 {
290  g_return_val_if_fail (GNC_IS_TREE_MODEL_COMMODITY (model), NULL);
291  g_return_val_if_fail (iter != NULL, NULL);
292  g_return_val_if_fail (iter->user_data != NULL, NULL);
293  g_return_val_if_fail (iter->stamp == model->stamp, NULL);
294 
295  if (iter->user_data != ITER_IS_COMMODITY)
296  return NULL;
297  return (gnc_commodity *)iter->user_data2;
298 }
299 
300 /************************************************************/
301 /* Gnc Tree Model Debugging Utility Function */
302 /************************************************************/
303 
304 #define debug_path(fn, path) { \
305  gchar *path_string = gtk_tree_path_to_string(path); \
306  fn("tree path %s", path_string? path_string : "NULL"); \
307  g_free(path_string); \
308  }
309 
310 #define ITER_STRING_LEN 128
311 
312 static const gchar *
313 iter_to_string (GtkTreeIter *iter)
314 {
315  gnc_commodity_namespace *name_space;
316  gnc_commodity *commodity = NULL;
317 #ifdef G_THREADS_ENABLED
318 #ifndef HAVE_GLIB_2_32
319  static GStaticPrivate gtmits_buffer_key = G_STATIC_PRIVATE_INIT;
320  gchar *string;
321 
322  string = g_static_private_get (&gtmits_buffer_key);
323  if (string == NULL)
324  {
325  string = g_malloc(ITER_STRING_LEN + 1);
326  g_static_private_set (&gtmits_buffer_key, string, g_free);
327  }
328 #else
329  static GPrivate gtmits_buffer_key = G_PRIVATE_INIT(g_free);
330  gchar *string;
331 
332  string = g_private_get (&gtmits_buffer_key);
333  if (string == NULL)
334  {
335  string = g_malloc(ITER_STRING_LEN + 1);
336  g_private_set (&gtmits_buffer_key, string);
337  }
338 #endif
339 #else
340  static char string[ITER_STRING_LEN + 1];
341 #endif
342  if (iter)
343  {
344  switch (GPOINTER_TO_INT(iter->user_data))
345  {
346  case GPOINTER_TO_INT(ITER_IS_NAMESPACE):
347  name_space = (gnc_commodity_namespace *) iter->user_data2;
348  snprintf(string, ITER_STRING_LEN,
349  "[stamp:%x data:%d (NAMESPACE), %p (%s), %d]",
350  iter->stamp, GPOINTER_TO_INT(iter->user_data),
351  iter->user_data2, gnc_commodity_namespace_get_name (name_space),
352  GPOINTER_TO_INT(iter->user_data3));
353  break;
354 
355  case GPOINTER_TO_INT(ITER_IS_COMMODITY):
356  commodity = (gnc_commodity *) iter->user_data2;
357  snprintf(string, ITER_STRING_LEN,
358  "[stamp:%x data:%d (COMMODITY), %p (%s), %d]",
359  iter->stamp, GPOINTER_TO_INT(iter->user_data),
360  iter->user_data2, gnc_commodity_get_mnemonic (commodity),
361  GPOINTER_TO_INT(iter->user_data3));
362  break;
363 
364  default:
365  snprintf(string, ITER_STRING_LEN,
366  "[stamp:%x data:%d (UNKNOWN), %p, %d]",
367  iter->stamp,
368  GPOINTER_TO_INT(iter->user_data),
369  iter->user_data2,
370  GPOINTER_TO_INT(iter->user_data3));
371  break;
372  }
373  }
374  return string;
375 }
376 
377 
378 /************************************************************/
379 /* Gtk Tree Model Required Interface Functions */
380 /************************************************************/
381 
382 static void
383 gnc_tree_model_commodity_tree_model_init (GtkTreeModelIface *iface)
384 {
385  iface->get_flags = gnc_tree_model_commodity_get_flags;
386  iface->get_n_columns = gnc_tree_model_commodity_get_n_columns;
387  iface->get_column_type = gnc_tree_model_commodity_get_column_type;
388  iface->get_iter = gnc_tree_model_commodity_get_iter;
389  iface->get_path = gnc_tree_model_commodity_get_path;
390  iface->get_value = gnc_tree_model_commodity_get_value;
391  iface->iter_next = gnc_tree_model_commodity_iter_next;
392  iface->iter_children = gnc_tree_model_commodity_iter_children;
393  iface->iter_has_child = gnc_tree_model_commodity_iter_has_child;
394  iface->iter_n_children = gnc_tree_model_commodity_iter_n_children;
395  iface->iter_nth_child = gnc_tree_model_commodity_iter_nth_child;
396  iface->iter_parent = gnc_tree_model_commodity_iter_parent;
397 }
398 
399 static GtkTreeModelFlags
400 gnc_tree_model_commodity_get_flags (GtkTreeModel *tree_model)
401 {
402  return 0;
403 }
404 
405 static int
406 gnc_tree_model_commodity_get_n_columns (GtkTreeModel *tree_model)
407 {
408  return GNC_TREE_MODEL_COMMODITY_NUM_COLUMNS;
409 }
410 
411 static GType
412 gnc_tree_model_commodity_get_column_type (GtkTreeModel *tree_model,
413  int index)
414 {
415  g_return_val_if_fail (GNC_IS_TREE_MODEL_COMMODITY (tree_model), G_TYPE_INVALID);
416  g_return_val_if_fail ((index < GNC_TREE_MODEL_COMMODITY_NUM_COLUMNS) && (index >= 0), G_TYPE_INVALID);
417 
418  switch (index)
419  {
420  case GNC_TREE_MODEL_COMMODITY_COL_MNEMONIC:
421  case GNC_TREE_MODEL_COMMODITY_COL_NAMESPACE:
422  case GNC_TREE_MODEL_COMMODITY_COL_FULLNAME:
423  case GNC_TREE_MODEL_COMMODITY_COL_PRINTNAME:
424  case GNC_TREE_MODEL_COMMODITY_COL_CUSIP:
425  case GNC_TREE_MODEL_COMMODITY_COL_UNIQUE_NAME:
426  case GNC_TREE_MODEL_COMMODITY_COL_QUOTE_SOURCE:
427  case GNC_TREE_MODEL_COMMODITY_COL_QUOTE_TZ:
428  case GNC_TREE_MODEL_COMMODITY_COL_USER_SYMBOL:
429  return G_TYPE_STRING;
430  case GNC_TREE_MODEL_COMMODITY_COL_FRACTION:
431  return G_TYPE_INT;
432  case GNC_TREE_MODEL_COMMODITY_COL_QUOTE_FLAG:
433  case GNC_TREE_MODEL_COMMODITY_COL_VISIBILITY:
434  return G_TYPE_BOOLEAN;
435  default:
436  g_assert_not_reached ();
437  return G_TYPE_INVALID;
438  }
439 }
440 
441 static gboolean
442 gnc_tree_model_commodity_get_iter (GtkTreeModel *tree_model,
443  GtkTreeIter *iter,
444  GtkTreePath *path)
445 {
446  GncTreeModelCommodity *model;
449  gnc_commodity_namespace *name_space;
450  gnc_commodity *commodity = NULL;
451  GList *list;
452  guint i, depth;
453 
454  iter->stamp = 0;
455  g_return_val_if_fail (GNC_IS_TREE_MODEL_COMMODITY (tree_model), FALSE);
456  g_return_val_if_fail (iter != NULL, FALSE);
457  g_return_val_if_fail (path != NULL, FALSE);
458 
459  depth = gtk_tree_path_get_depth (path);
460  ENTER("model %p, iter %p, path %p (depth %d)", tree_model, iter, path, depth);
461  debug_path(DEBUG, path);
462 
463  /* Check the path depth. */
464  if (depth == 0)
465  {
466  LEAVE("depth too small");
467  return FALSE;
468  }
469  if (depth > 2)
470  {
471  LEAVE("depth too big");
472  return FALSE;
473  }
474 
475  /* Make sure the model has a commodity db. */
476  model = GNC_TREE_MODEL_COMMODITY (tree_model);
477  priv = GNC_TREE_MODEL_COMMODITY_GET_PRIVATE(model);
478  ct = priv->commodity_table;
479  if (ct == NULL)
480  {
481  LEAVE("no commodity table");
482  return FALSE;
483  }
484 
485  /* Verify the first part of the path: the namespace. */
487  i = gtk_tree_path_get_indices (path)[0];
488  name_space = g_list_nth_data (list, i);
489  if (!name_space)
490  {
491  LEAVE("invalid path at namespace");
492  return FALSE;
493  }
494 
495  if (depth == 1)
496  {
497  /* Return an iterator for the namespace. */
498  iter->stamp = model->stamp;
499  iter->user_data = ITER_IS_NAMESPACE;
500  iter->user_data2 = name_space;
501  iter->user_data3 = GINT_TO_POINTER(i);
502  LEAVE("iter (ns) %s", iter_to_string(iter));
503  return TRUE;
504  }
505 
506  /* Verify the second part of the path: the commodity. */
508  i = gtk_tree_path_get_indices (path)[1];
509  commodity = g_list_nth_data (list, i);
510  if (!commodity)
511  {
512  LEAVE("invalid path at commodity");
513  return FALSE;
514  }
515 
516  /* Return an iterator for the commodity. */
517  iter->stamp = model->stamp;
518  iter->user_data = ITER_IS_COMMODITY;
519  iter->user_data2 = commodity;
520  iter->user_data3 = GINT_TO_POINTER(i);
521  LEAVE("iter (cm) %s", iter_to_string(iter));
522  return TRUE;
523 }
524 
525 static GtkTreePath *
526 gnc_tree_model_commodity_get_path (GtkTreeModel *tree_model,
527  GtkTreeIter *iter)
528 {
529  GncTreeModelCommodity *model;
531  GtkTreePath *path;
533  gnc_commodity_namespace *name_space;
534  GList *ns_list;
535 
536  g_return_val_if_fail (GNC_IS_TREE_MODEL_COMMODITY (tree_model), NULL);
537  model = GNC_TREE_MODEL_COMMODITY (tree_model);
538  g_return_val_if_fail (iter != NULL, NULL);
539  g_return_val_if_fail (iter->user_data != NULL, NULL);
540  g_return_val_if_fail (iter->user_data2 != NULL, NULL);
541  g_return_val_if_fail (iter->stamp == model->stamp, NULL);
542  ENTER("model %p, iter %p (%s)", tree_model, iter, iter_to_string(iter));
543 
544  /* Make sure this model has a commodity db. */
545  priv = GNC_TREE_MODEL_COMMODITY_GET_PRIVATE(model);
546  ct = priv->commodity_table;
547  if (ct == NULL)
548  {
549  LEAVE("no commodity table");
550  return FALSE;
551  }
552 
553  if (iter->user_data == ITER_IS_NAMESPACE)
554  {
555  /* Create a path to the namespace. This is just the index into
556  * the namespace list, which we already stored in user_data3. */
557  path = gtk_tree_path_new ();
558  gtk_tree_path_append_index (path, GPOINTER_TO_INT(iter->user_data3));
559  debug_path(LEAVE, path);
560  return path;
561  }
562 
563  /* Get the namespaces list. */
565  name_space = gnc_commodity_get_namespace_ds((gnc_commodity*)iter->user_data2);
566 
567  /* Create a path to the commodity. */
568  path = gtk_tree_path_new ();
569  gtk_tree_path_append_index (path, g_list_index (ns_list, name_space));
570  gtk_tree_path_append_index (path, GPOINTER_TO_INT(iter->user_data3));
571  debug_path(LEAVE, path);
572  return path;
573 }
574 
575 static void
576 gnc_tree_model_commodity_get_value (GtkTreeModel *tree_model,
577  GtkTreeIter *iter,
578  int column,
579  GValue *value)
580 {
581  GncTreeModelCommodity *model = GNC_TREE_MODEL_COMMODITY (tree_model);
582  gnc_commodity_namespace *name_space;
583  gnc_commodity *commodity;
584  gnc_quote_source *source;
585 
586  g_return_if_fail (GNC_IS_TREE_MODEL_COMMODITY (tree_model));
587  g_return_if_fail (iter != NULL);
588  g_return_if_fail (iter->user_data != NULL);
589  g_return_if_fail (iter->user_data2 != NULL);
590  g_return_if_fail (iter->stamp == model->stamp);
591 
592  if (iter->user_data == ITER_IS_NAMESPACE)
593  {
594  name_space = (gnc_commodity_namespace *)iter->user_data2;
595  switch (column)
596  {
597  case GNC_TREE_MODEL_COMMODITY_COL_NAMESPACE:
598  g_value_init (value, G_TYPE_STRING);
599  g_value_set_string (value, gnc_commodity_namespace_get_name (name_space));
600  break;
601  default:
602  g_value_init (value, G_TYPE_STRING);
603  g_value_set_string (value, "");
604  break;
605  case GNC_TREE_MODEL_COMMODITY_COL_FRACTION:
606  g_value_init (value, G_TYPE_INT);
607  g_value_set_int (value, 0);
608  break;
609  case GNC_TREE_MODEL_COMMODITY_COL_QUOTE_FLAG:
610  g_value_init (value, G_TYPE_BOOLEAN);
611  g_value_set_boolean (value, FALSE);
612  break;
613  case GNC_TREE_MODEL_COMMODITY_COL_VISIBILITY:
614  g_value_init (value, G_TYPE_BOOLEAN);
615  g_value_set_boolean (value, FALSE);
616  break;
617  }
618  return;
619  }
620 
621  commodity = (gnc_commodity *)iter->user_data2;
622  switch (column)
623  {
624  case GNC_TREE_MODEL_COMMODITY_COL_MNEMONIC:
625  g_value_init (value, G_TYPE_STRING);
626 
627  g_value_set_string (value, gnc_commodity_get_mnemonic (commodity));
628  break;
629  case GNC_TREE_MODEL_COMMODITY_COL_NAMESPACE:
630  g_value_init (value, G_TYPE_STRING);
631 
632 // g_value_set_string (value, gnc_commodity_get_namespace (commodity));
633  g_value_set_string (value, NULL);
634  break;
635  case GNC_TREE_MODEL_COMMODITY_COL_FULLNAME:
636  g_value_init (value, G_TYPE_STRING);
637 
638  g_value_set_string (value, gnc_commodity_get_fullname (commodity));
639  break;
640  case GNC_TREE_MODEL_COMMODITY_COL_PRINTNAME:
641  g_value_init (value, G_TYPE_STRING);
642 
643  g_value_set_string (value, gnc_commodity_get_printname (commodity));
644  break;
645  case GNC_TREE_MODEL_COMMODITY_COL_CUSIP:
646  g_value_init (value, G_TYPE_STRING);
647 
648  g_value_set_string (value, gnc_commodity_get_cusip (commodity));
649  break;
650  case GNC_TREE_MODEL_COMMODITY_COL_UNIQUE_NAME:
651  g_value_init (value, G_TYPE_STRING);
652 
653  g_value_set_string (value, gnc_commodity_get_unique_name (commodity));
654  break;
655  case GNC_TREE_MODEL_COMMODITY_COL_FRACTION:
656  g_value_init (value, G_TYPE_INT);
657 
658  g_value_set_int (value, gnc_commodity_get_fraction (commodity));
659  break;
660  case GNC_TREE_MODEL_COMMODITY_COL_QUOTE_FLAG:
661  g_value_init (value, G_TYPE_BOOLEAN);
662 
663  g_value_set_boolean (value, gnc_commodity_get_quote_flag (commodity));
664  break;
665  case GNC_TREE_MODEL_COMMODITY_COL_QUOTE_SOURCE:
666  g_value_init (value, G_TYPE_STRING);
667 
668  if (gnc_commodity_get_quote_flag (commodity))
669  {
670  source = gnc_commodity_get_quote_source (commodity);
671  g_value_set_string (value, gnc_quote_source_get_internal_name(source));
672  }
673  else
674  {
675  g_value_set_static_string (value, "");
676  }
677  break;
678  case GNC_TREE_MODEL_COMMODITY_COL_QUOTE_TZ:
679  g_value_init (value, G_TYPE_STRING);
680 
681  if (gnc_commodity_get_quote_flag (commodity))
682  {
683  g_value_set_string (value, gnc_commodity_get_quote_tz (commodity));
684  }
685  else
686  {
687  g_value_set_static_string (value, "");
688  }
689  break;
690  case GNC_TREE_MODEL_COMMODITY_COL_USER_SYMBOL:
691  g_value_init (value, G_TYPE_STRING);
692 
693  g_value_set_string (value, gnc_commodity_get_nice_symbol (commodity));
694  break;
695  case GNC_TREE_MODEL_COMMODITY_COL_VISIBILITY:
696  g_value_init (value, G_TYPE_BOOLEAN);
697  g_value_set_boolean (value, TRUE);
698  break;
699  default:
700  g_assert_not_reached ();
701  }
702 }
703 
704 static gboolean
705 gnc_tree_model_commodity_iter_next (GtkTreeModel *tree_model,
706  GtkTreeIter *iter)
707 {
708  GncTreeModelCommodity *model;
711  gnc_commodity_namespace *name_space;
712  GList *list;
713  int n;
714 
715  g_return_val_if_fail (GNC_IS_TREE_MODEL_COMMODITY (tree_model), FALSE);
716  model = GNC_TREE_MODEL_COMMODITY (tree_model);
717  g_return_val_if_fail (iter != NULL, FALSE);
718  g_return_val_if_fail (iter->user_data != NULL, FALSE);
719  g_return_val_if_fail (iter->user_data2 != NULL, FALSE);
720  g_return_val_if_fail (iter->stamp == model->stamp, FALSE);
721 
722  ENTER("model %p, iter %p(%s)", tree_model, iter, iter_to_string(iter));
723  priv = GNC_TREE_MODEL_COMMODITY_GET_PRIVATE(model);
724  if (iter->user_data == ITER_IS_NAMESPACE)
725  {
726  ct = priv->commodity_table;
728  }
729  else if (iter->user_data == ITER_IS_COMMODITY)
730  {
731  name_space = gnc_commodity_get_namespace_ds((gnc_commodity *)iter->user_data2);
733  }
734  else
735  {
736  LEAVE("unknown iter type");
737  return FALSE;
738  }
739 
740  n = GPOINTER_TO_INT(iter->user_data3) + 1;
741  iter->user_data2 = g_list_nth_data(list, n);
742  if (iter->user_data2 == NULL)
743  {
744  LEAVE("no next iter");
745  return FALSE;
746  }
747  iter->user_data3 = GINT_TO_POINTER(n);
748  LEAVE("iter %p(%s)", iter, iter_to_string(iter));
749  return TRUE;
750 }
751 
752 
753 static gboolean
754 gnc_tree_model_commodity_iter_children (GtkTreeModel *tree_model,
755  GtkTreeIter *iter,
756  GtkTreeIter *parent)
757 {
758  GncTreeModelCommodity *model;
761  gnc_commodity_namespace *name_space;
762  GList *list;
763 
764  g_return_val_if_fail (GNC_IS_TREE_MODEL_COMMODITY (tree_model), FALSE);
765 
766  ENTER("model %p, iter %p, parent %p (%s)",
767  tree_model, iter, parent, iter_to_string(parent));
768  model = GNC_TREE_MODEL_COMMODITY (tree_model);
769  priv = GNC_TREE_MODEL_COMMODITY_GET_PRIVATE(model);
770 
771  if (parent == NULL)
772  {
773  ct = priv->commodity_table;
775  if (list == NULL)
776  {
777  LEAVE("no namespaces");
778  return FALSE;
779  }
780 
781  iter->stamp = model->stamp;
782  iter->user_data = ITER_IS_NAMESPACE;
783  iter->user_data2 = g_list_nth_data(list, 0);
784  iter->user_data3 = GINT_TO_POINTER(0);
785  LEAVE("ns iter %p (%s)", iter, iter_to_string(iter));
786  return TRUE;
787  }
788 
789  if (parent->user_data == ITER_IS_NAMESPACE)
790  {
791  name_space = (gnc_commodity_namespace *)parent->user_data2;
793  if (list == NULL)
794  {
795  LEAVE("no commodities");
796  return FALSE;
797  }
798 
799  iter->stamp = model->stamp;
800  iter->user_data = ITER_IS_COMMODITY;
801  iter->user_data2 = g_list_nth_data(list, 0);
802  iter->user_data3 = GINT_TO_POINTER(0);
803  LEAVE("cm iter %p (%s)", iter, iter_to_string(iter));
804  return TRUE;
805  }
806 
807  LEAVE("FALSE");
808  return FALSE;
809 }
810 
811 static gboolean
812 gnc_tree_model_commodity_iter_has_child (GtkTreeModel *tree_model,
813  GtkTreeIter *iter)
814 {
815  gnc_commodity_namespace *name_space;
816  GList *list;
817 
818  g_return_val_if_fail (iter != NULL, FALSE);
819  ENTER("model %p, iter %p (%s)", tree_model,
820  iter, iter_to_string(iter));
821 
822  if (iter->user_data != ITER_IS_NAMESPACE)
823  {
824  LEAVE("no children (not ns)");
825  return FALSE;
826  }
827 
828  name_space = (gnc_commodity_namespace *)iter->user_data2;
830  LEAVE("%s children", list ? "has" : "no");
831  return list != NULL;
832 }
833 
834 static int
835 gnc_tree_model_commodity_iter_n_children (GtkTreeModel *tree_model,
836  GtkTreeIter *iter)
837 {
838  GncTreeModelCommodity *model;
841  gnc_commodity_namespace *name_space;
842  GList *list;
843 
844  g_return_val_if_fail (GNC_IS_TREE_MODEL_COMMODITY (tree_model), -1);
845 
846  ENTER("model %p, iter %p (%s)", tree_model, iter, iter_to_string(iter));
847  model = GNC_TREE_MODEL_COMMODITY (tree_model);
848  priv = GNC_TREE_MODEL_COMMODITY_GET_PRIVATE(model);
849 
850  if (iter == NULL)
851  {
852  ct = priv->commodity_table;
854  LEAVE("ns list length %d", g_list_length(list));
855  return g_list_length (list);
856  }
857 
858  if (iter->user_data == ITER_IS_NAMESPACE)
859  {
860  name_space = (gnc_commodity_namespace *)iter->user_data2;
862  LEAVE("cm list length %d", g_list_length(list));
863  return g_list_length (list);
864  }
865 
866  LEAVE("0");
867  return 0;
868 }
869 
870 static gboolean
871 gnc_tree_model_commodity_iter_nth_child (GtkTreeModel *tree_model,
872  GtkTreeIter *iter,
873  GtkTreeIter *parent,
874  int n)
875 {
876  GncTreeModelCommodity *model;
879  gnc_commodity_namespace *name_space;
880  GList *list;
881 
882  g_return_val_if_fail (GNC_IS_TREE_MODEL_COMMODITY (tree_model), FALSE);
883  g_return_val_if_fail (iter != NULL, FALSE);
884 
885  ENTER("model %p, iter %p, parent %p (%s)",
886  tree_model, iter, parent, iter_to_string(parent));
887  model = GNC_TREE_MODEL_COMMODITY (tree_model);
888  priv = GNC_TREE_MODEL_COMMODITY_GET_PRIVATE(model);
889 
890  if (parent == NULL)
891  {
892  ct = priv->commodity_table;
894 
895  iter->stamp = model->stamp;
896  iter->user_data = ITER_IS_NAMESPACE;
897  iter->user_data2 = g_list_nth_data(list, n);
898  iter->user_data3 = GINT_TO_POINTER(n);
899  LEAVE("ns iter %p (%s)", iter, iter_to_string(iter));
900  return iter->user_data2 != NULL;
901  }
902 
903  if (parent->user_data == ITER_IS_NAMESPACE)
904  {
905  name_space = (gnc_commodity_namespace *)parent->user_data2;
907 
908  iter->stamp = model->stamp;
909  iter->user_data = ITER_IS_COMMODITY;
910  iter->user_data2 = g_list_nth_data(list, n);
911  iter->user_data3 = GINT_TO_POINTER(n);
912  LEAVE("cm iter %p (%s)", iter, iter_to_string(iter));
913  return iter->user_data2 != NULL;
914  }
915 
916  iter->stamp = 0;
917  LEAVE("FALSE");
918  return FALSE;
919 }
920 
921 static gboolean
922 gnc_tree_model_commodity_iter_parent (GtkTreeModel *tree_model,
923  GtkTreeIter *iter,
924  GtkTreeIter *child)
925 {
926  GncTreeModelCommodity *model;
929  gnc_commodity_namespace *name_space;
930  GList *list;
931 
932  g_return_val_if_fail (GNC_IS_TREE_MODEL_COMMODITY (tree_model), FALSE);
933  g_return_val_if_fail (iter != NULL, FALSE);
934  g_return_val_if_fail (child != NULL, FALSE);
935 
936  ENTER("model %p, iter %p, child %p (%s)",
937  tree_model, iter, child, iter_to_string(child));
938  model = GNC_TREE_MODEL_COMMODITY (tree_model);
939  priv = GNC_TREE_MODEL_COMMODITY_GET_PRIVATE(model);
940 
941  if (child->user_data == ITER_IS_NAMESPACE)
942  {
943  LEAVE("ns has no parent");
944  return FALSE;
945  }
946 
947  ct = priv->commodity_table;
949  name_space = gnc_commodity_get_namespace_ds((gnc_commodity*)child->user_data2);
950 
951  iter->stamp = model->stamp;
952  iter->user_data = ITER_IS_NAMESPACE;
953  iter->user_data2 = name_space;
954  iter->user_data3 = GINT_TO_POINTER(g_list_index(list, name_space));
955  LEAVE("ns iter %p (%s)", iter, iter_to_string(iter));
956  return TRUE;
957 }
958 
959 /************************************************************/
960 /* Commodity Tree View Functions */
961 /************************************************************/
962 
963 /*
964  * Convert a model/commodity pair into a gtk_tree_model_iter. This
965  * routine should only be called from the file
966  * gnc-tree-view-commodity.c.
967  */
968 gboolean
970  gnc_commodity *commodity,
971  GtkTreeIter *iter)
972 {
973  gnc_commodity_namespace *name_space;
974  GList *list;
975  gint n;
976 
977  g_return_val_if_fail (GNC_IS_TREE_MODEL_COMMODITY (model), FALSE);
978  g_return_val_if_fail ((commodity != NULL), FALSE);
979  g_return_val_if_fail ((iter != NULL), FALSE);
980 
981  ENTER("model %p, commodity %p, iter %p", model, commodity, iter);
982 
983  name_space = gnc_commodity_get_namespace_ds(commodity);
984  if (name_space == NULL)
985  {
986  LEAVE("no namespace");
987  return FALSE;
988  }
989 
991  if (list == NULL)
992  {
993  LEAVE("empty list");
994  return FALSE;
995  }
996 
997  n = g_list_index(list, commodity);
998  if (n == -1)
999  {
1000  LEAVE("not in list");
1001  return FALSE;
1002  }
1003 
1004  iter->stamp = model->stamp;
1005  iter->user_data = ITER_IS_COMMODITY;
1006  iter->user_data2 = commodity;
1007  iter->user_data3 = GINT_TO_POINTER(n);
1008  LEAVE("iter %s", iter_to_string(iter));
1009  return TRUE;
1010 }
1011 
1012 /*
1013  * Convert a model/commodity pair into a gtk_tree_model_path. This
1014  * routine should only be called from the file
1015  * gnc-tree-view-commodity.c.
1016  */
1017 GtkTreePath *
1019  gnc_commodity *commodity)
1020 {
1021  GtkTreeIter tree_iter;
1022  GtkTreePath *tree_path;
1023 
1024  g_return_val_if_fail (GNC_IS_TREE_MODEL_COMMODITY (model), NULL);
1025  g_return_val_if_fail (commodity != NULL, NULL);
1026  ENTER("model %p, commodity %p", model, commodity);
1027 
1028  if (!gnc_tree_model_commodity_get_iter_from_commodity (model, commodity, &tree_iter))
1029  {
1030  LEAVE("no iter");
1031  return NULL;
1032  }
1033 
1034  tree_path = gtk_tree_model_get_path (GTK_TREE_MODEL(model), &tree_iter);
1035  if (tree_path)
1036  {
1037  gchar *path_string = gtk_tree_path_to_string(tree_path);
1038  LEAVE("path (2) %s", path_string);
1039  g_free(path_string);
1040  }
1041  else
1042  {
1043  LEAVE("no path");
1044  }
1045  return tree_path;
1046 }
1047 
1048 /*
1049  * Convert a model/namespace pair into a gtk_tree_model_iter. This
1050  * routine should only be called from the file
1051  * gnc-tree-view-commodity.c.
1052  */
1053 gboolean
1055  gnc_commodity_namespace *name_space,
1056  GtkTreeIter *iter)
1057 {
1059  GList *list;
1060  gint n;
1061 
1062  g_return_val_if_fail (GNC_IS_TREE_MODEL_COMMODITY (model), FALSE);
1063  g_return_val_if_fail ((name_space != NULL), FALSE);
1064  g_return_val_if_fail ((iter != NULL), FALSE);
1065 
1066  ENTER("model %p, namespace %p, iter %p", model, name_space, iter);
1067 
1068  priv = GNC_TREE_MODEL_COMMODITY_GET_PRIVATE(model);
1069  list = gnc_commodity_table_get_namespaces_list(priv->commodity_table);
1070  if (list == NULL)
1071  {
1072  LEAVE("");
1073  return FALSE;
1074  }
1075 
1076  n = g_list_index(list, name_space);
1077  if (n == -1)
1078  {
1079  LEAVE("");
1080  return FALSE;
1081  }
1082 
1083  iter->stamp = model->stamp;
1084  iter->user_data = ITER_IS_NAMESPACE;
1085  iter->user_data2 = name_space;
1086  iter->user_data3 = GINT_TO_POINTER(n);
1087  LEAVE("iter %s", iter_to_string(iter));
1088  return TRUE;
1089 }
1090 
1091 
1092 /************************************************************/
1093 /* Commodity Tree Model - Engine Event Handling Functions */
1094 /************************************************************/
1095 
1096 typedef struct _remove_data
1097 {
1098  GncTreeModelCommodity *model;
1099  GtkTreePath *path;
1100 } remove_data;
1101 
1102 static GSList *pending_removals = NULL;
1103 
1115 static void
1116 gnc_tree_model_commodity_row_add (GncTreeModelCommodity *model,
1117  GtkTreeIter *iter)
1118 {
1119  GtkTreePath *path;
1120  GtkTreeModel *tree_model;
1121  GtkTreeIter tmp_iter;
1122 
1123  ENTER("model %p, iter (%p)%s", model, iter, iter_to_string(iter));
1124 
1125  /* We're adding a row, so the lists on which this model is based have
1126  * changed. Since existing iterators (except the one just passed in)
1127  * are all based on old indexes into those lists, we need to invalidate
1128  * them, which we can do by changing the model's stamp. */
1129  do
1130  {
1131  model->stamp++;
1132  }
1133  while (model->stamp == 0);
1134  iter->stamp = model->stamp;
1135 
1136  /* Tag the new row as inserted. */
1137  tree_model = GTK_TREE_MODEL(model);
1138  path = gnc_tree_model_commodity_get_path(tree_model, iter);
1139  gtk_tree_model_row_inserted(tree_model, path, iter);
1140 
1141  /* Inform all ancestors. */
1142  /*
1143  * Charles Day: I don't think calls to gtk_tree_model_row_changed() should
1144  * be necessary. It is just a workaround for bug #540201.
1145  */
1146  if (gtk_tree_path_up(path) &&
1147  gtk_tree_path_get_depth(path) > 0 &&
1148  gtk_tree_model_get_iter(tree_model, &tmp_iter, path))
1149  {
1150  /* Signal the change to the parent. */
1151  gtk_tree_model_row_changed(tree_model, path, &tmp_iter);
1152 
1153  /* Is this the parent's first child? */
1154  if (gtk_tree_model_iter_n_children(tree_model, &tmp_iter) == 1)
1155  gtk_tree_model_row_has_child_toggled(tree_model, path, &tmp_iter);
1156 
1157  /* Signal any other ancestors. */
1158  while (gtk_tree_path_up(path) &&
1159  gtk_tree_path_get_depth(path) > 0 &&
1160  gtk_tree_model_get_iter(tree_model, &tmp_iter, path))
1161  {
1162  gtk_tree_model_row_changed(tree_model, path, &tmp_iter);
1163  }
1164  }
1165  gtk_tree_path_free(path);
1166 
1167  /* If the new row already has children, signal that so the expander
1168  * can be shown. This can happen, for example, if a namespace is
1169  * changed in another place and gets removed and then re-added to
1170  * the commodity db. */
1171  if (gnc_tree_model_commodity_iter_has_child(tree_model, iter))
1172  {
1173  path = gnc_tree_model_commodity_get_path(tree_model, iter);
1174  gtk_tree_model_row_has_child_toggled(tree_model, path, iter);
1175  gtk_tree_path_free(path);
1176  }
1177 
1178  LEAVE(" ");
1179 }
1180 
1192 static void
1193 gnc_tree_model_commodity_row_delete (GncTreeModelCommodity *model,
1194  GtkTreePath *path)
1195 {
1196  GtkTreeModel *tree_model;
1197  GtkTreeIter iter;
1198 
1199  g_return_if_fail(GNC_IS_TREE_MODEL_COMMODITY(model));
1200  g_return_if_fail(path);
1201 
1202  debug_path(ENTER, path);
1203 
1204  tree_model = GTK_TREE_MODEL(model);
1205 
1206  /* We're removing a row, so the lists on which this model is based have
1207  * changed. Since existing iterators are all based on old indexes into
1208  * those lists, we need to invalidate them, which we can do by changing
1209  * the model's stamp. */
1210  do
1211  {
1212  model->stamp++;
1213  }
1214  while (model->stamp == 0);
1215 
1216  /* Signal that the path has been deleted. */
1217  gtk_tree_model_row_deleted(tree_model, path);
1218 
1219  /* Issue any appropriate signals to ancestors. */
1220  if (gtk_tree_path_up(path) &&
1221  gtk_tree_path_get_depth(path) > 0 &&
1222  gtk_tree_model_get_iter(tree_model, &iter, path) &&
1223  !gtk_tree_model_iter_has_child(tree_model, &iter))
1224  {
1225  DEBUG("parent toggled, iter %s", iter_to_string(&iter));
1226  gtk_tree_model_row_has_child_toggled(tree_model, path, &iter);
1227  }
1228 
1229  LEAVE(" ");
1230 }
1231 
1232 
1249 static gboolean
1250 gnc_tree_model_commodity_do_deletions (gpointer unused)
1251 {
1252  ENTER(" ");
1253 
1254  /* Go through the list of paths needing removal. */
1255  while (pending_removals)
1256  {
1257  remove_data *data = pending_removals->data;
1258  pending_removals = g_slist_delete_link(pending_removals, pending_removals);
1259 
1260  if (data)
1261  {
1262  debug_path(DEBUG, data->path);
1263 
1264  /* Remove the path. */
1265  gnc_tree_model_commodity_row_delete(data->model, data->path);
1266 
1267  gtk_tree_path_free(data->path);
1268  g_free(data);
1269  }
1270  }
1271 
1272  LEAVE(" ");
1273  /* Don't call me again. */
1274  return FALSE;
1275 }
1276 
1277 
1309 static void
1310 gnc_tree_model_commodity_event_handler (QofInstance *entity,
1311  QofEventId event_type,
1312  gpointer user_data,
1313  gpointer event_data)
1314 {
1315  GncTreeModelCommodity *model;
1316  GtkTreePath *path;
1317  GtkTreeIter iter;
1318  remove_data *data;
1319  const gchar *name;
1320 
1321  model = (GncTreeModelCommodity *)user_data;
1322 
1323  /* hard failures */
1324  g_return_if_fail(GNC_IS_TREE_MODEL_COMMODITY(model));
1325 
1326  ENTER("entity %p, event %d, model %p, event data %p",
1327  entity, event_type, user_data, event_data);
1328 
1329  /* Do deletions if any are pending. */
1330  if (pending_removals)
1331  gnc_tree_model_commodity_do_deletions(NULL);
1332 
1333  /* get type specific data */
1334  if (GNC_IS_COMMODITY(entity))
1335  {
1336  gnc_commodity *commodity;
1337 
1338  commodity = GNC_COMMODITY(entity);
1339  name = gnc_commodity_get_mnemonic(commodity);
1340  if (event_type != QOF_EVENT_DESTROY)
1341  {
1342  if (!gnc_tree_model_commodity_get_iter_from_commodity (model, commodity, &iter))
1343  {
1344  LEAVE("no iter");
1345  return;
1346  }
1347  }
1348  }
1349  else if (GNC_IS_COMMODITY_NAMESPACE(entity))
1350  {
1351  gnc_commodity_namespace *name_space;
1352 
1353  name_space = GNC_COMMODITY_NAMESPACE(entity);
1354  name = gnc_commodity_namespace_get_name(name_space);
1355  if (event_type != QOF_EVENT_DESTROY)
1356  {
1357  if (!gnc_tree_model_commodity_get_iter_from_namespace (model, name_space, &iter))
1358  {
1359  LEAVE("no iter");
1360  return;
1361  }
1362  }
1363  }
1364  else
1365  {
1366  LEAVE("");
1367  return;
1368  }
1369 
1370  switch (event_type)
1371  {
1372  case QOF_EVENT_ADD:
1373  /* Tell the filters/views where the new account was added. */
1374  DEBUG("add %s", name);
1375  gnc_tree_model_commodity_row_add (model, &iter);
1376  break;
1377 
1378  case QOF_EVENT_REMOVE:
1379  /* Record the path of this account for later use in destruction */
1380  DEBUG("remove %s", name);
1381  path = gtk_tree_model_get_path (GTK_TREE_MODEL(model), &iter);
1382  if (path == NULL)
1383  {
1384  LEAVE("not in model");
1385  return;
1386  }
1387 
1388  data = g_new0 (remove_data, 1);
1389  data->model = model;
1390  data->path = path;
1391  pending_removals = g_slist_append (pending_removals, data);
1392  g_idle_add_full(G_PRIORITY_HIGH_IDLE,
1393  gnc_tree_model_commodity_do_deletions, NULL, NULL);
1394 
1395  LEAVE(" ");
1396  return;
1397 
1398  case QOF_EVENT_MODIFY:
1399  DEBUG("change %s", name);
1400  path = gtk_tree_model_get_path (GTK_TREE_MODEL(model), &iter);
1401  if (path == NULL)
1402  {
1403  LEAVE("not in model");
1404  return;
1405  }
1406  gtk_tree_model_row_changed(GTK_TREE_MODEL(model), path, &iter);
1407  gtk_tree_path_free(path);
1408  LEAVE(" ");
1409  return;
1410 
1411  default:
1412  LEAVE("ignored event for %s", name);
1413  return;
1414  }
1415  LEAVE(" new stamp %u", model->stamp);
1416 }
GtkTreeModel implementation for gnucash commodities.
const char * gnc_commodity_get_cusip(const gnc_commodity *cm)
int gnc_commodity_get_fraction(const gnc_commodity *cm)
gnc_commodity * gnc_tree_model_commodity_get_commodity(GncTreeModelCommodity *model, GtkTreeIter *iter)
gboolean gnc_tree_model_commodity_get_iter_from_commodity(GncTreeModelCommodity *model, gnc_commodity *commodity, GtkTreeIter *iter)
const GList * gnc_gobject_tracking_get_list(const gchar *name)
const char * gnc_commodity_get_mnemonic(const gnc_commodity *cm)
GtkTreePath * gnc_tree_model_commodity_get_path_from_commodity(GncTreeModelCommodity *model, gnc_commodity *commodity)
utility functions for the GnuCash UI
gboolean gnc_commodity_get_quote_flag(const gnc_commodity *cm)
const char * gnc_commodity_get_quote_tz(const gnc_commodity *cm)
#define DEBUG(format, args...)
Definition: qoflog.h:255
gnc_commodity_namespace * gnc_tree_model_commodity_get_namespace(GncTreeModelCommodity *model, GtkTreeIter *iter)
#define ENTER(format, args...)
Definition: qoflog.h:261
GList * gnc_commodity_namespace_get_commodity_list(const gnc_commodity_namespace *name_space)
const char * gnc_commodity_namespace_get_name(const gnc_commodity_namespace *ns)
gint qof_event_register_handler(QofEventHandler handler, gpointer handler_data)
Register a handler for events.
gint QofEventId
Definition: qofevent.h:45
Gobject helper routines.
GType gnc_tree_model_commodity_get_type(void)
void qof_event_unregister_handler(gint handler_id)
Unregister an event handler.
GtkTreeModel * gnc_tree_model_commodity_new(QofBook *book, gnc_commodity_table *ct)
gboolean gnc_tree_model_commodity_get_iter_from_namespace(GncTreeModelCommodity *model, gnc_commodity_namespace *name_space, GtkTreeIter *iter)
const char * gnc_commodity_get_fullname(const gnc_commodity *cm)
const char * gnc_commodity_get_nice_symbol(const gnc_commodity *cm)
All type declarations for the whole Gnucash engine.
const char * gnc_commodity_get_printname(const gnc_commodity *cm)
gboolean gnc_tree_model_commodity_iter_is_commodity(GncTreeModelCommodity *model, GtkTreeIter *iter)
gnc_quote_source * gnc_commodity_get_quote_source(const gnc_commodity *cm)
gboolean gnc_tree_model_commodity_iter_is_namespace(GncTreeModelCommodity *model, GtkTreeIter *iter)
gnc_commodity_namespace * gnc_commodity_get_namespace_ds(const gnc_commodity *cm)
#define LEAVE(format, args...)
Definition: qoflog.h:271
const char * gnc_commodity_get_unique_name(const gnc_commodity *cm)
const char * gnc_quote_source_get_internal_name(const gnc_quote_source *source)
GList * gnc_commodity_table_get_namespaces_list(const gnc_commodity_table *table)
const gchar * QofLogModule
Definition: qofid.h:89