GnuCash  5.6-150-g038405b370+
gnc-tree-view-commodity.c
1 /********************************************************************\
2  * gnc-tree-view-commodity.c -- GtkTreeView implementation to *
3  * display commodities in a GtkTreeView. *
4  * Copyright (C) 2003,2005 David Hampton <hampton@employees.org> *
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 <gtk/gtk.h>
28 #include <glib/gi18n.h>
29 #include <string.h>
30 
31 #include "gnc-tree-view.h"
34 
35 #include "gnc-commodity.h"
36 #include "gnc-component-manager.h"
37 #include "gnc-engine.h"
38 #include "gnc-glib-utils.h"
39 #include "gnc-gnome-utils.h"
40 #include "gnc-icons.h"
41 #include "gnc-ui-util.h"
42 
43 
46 /* This static indicates the debugging module that this .o belongs to. */
47 static QofLogModule log_module = GNC_MOD_GUI;
48 
50 static void gnc_tree_view_commodity_finalize (GObject *object);
51 static void gnc_tree_view_commodity_destroy (GtkWidget *widget);
52 
54 {
55  GncTreeView gnc_tree_view;
56  int stamp;
57 };
58 
59 /************************************************************/
60 /* g_object required functions */
61 /************************************************************/
62 
63 G_DEFINE_TYPE(GncTreeViewCommodity, gnc_tree_view_commodity, GNC_TYPE_TREE_VIEW)
64 
65 static void
66 gnc_tree_view_commodity_class_init (GncTreeViewCommodityClass *klass)
67 {
68  GObjectClass *o_class;
69  GtkWidgetClass *widget_class;
70 
71  o_class = G_OBJECT_CLASS (klass);
72  widget_class = GTK_WIDGET_CLASS (klass);
73 
74  /* GObject signals */
75  o_class->finalize = gnc_tree_view_commodity_finalize;
76 
77  /* GtkWidget signals */
78  widget_class->destroy = gnc_tree_view_commodity_destroy;
79 }
80 
81 static void
82 gnc_tree_view_commodity_init (GncTreeViewCommodity *view)
83 {
84 }
85 
86 static void
87 gnc_tree_view_commodity_finalize (GObject *object)
88 {
89  g_return_if_fail (object != NULL);
90  g_return_if_fail (GNC_IS_TREE_VIEW_COMMODITY (object));
91 
92  ENTER("view %p", object);
93  G_OBJECT_CLASS (gnc_tree_view_commodity_parent_class)->finalize (object);
94  LEAVE(" ");
95 }
96 
97 static void
98 gnc_tree_view_commodity_destroy (GtkWidget *widget)
99 {
100  g_return_if_fail (widget != NULL);
101  g_return_if_fail (GNC_IS_TREE_VIEW_COMMODITY (widget));
102 
103  ENTER("view %p", widget);
104 
105  GTK_WIDGET_CLASS (gnc_tree_view_commodity_parent_class)->destroy (widget);
106  LEAVE(" ");
107 }
108 
109 
110 /************************************************************/
111 /* sort functions */
112 /************************************************************/
113 
114 static gboolean
115 get_commodities_w_iters (GtkTreeModel *f_model,
116  GtkTreeIter *f_iter_a,
117  GtkTreeIter *f_iter_b,
118  GtkTreeModel **model_p,
119  GtkTreeIter *iter_a,
120  GtkTreeIter *iter_b,
121  gnc_commodity **comm_a,
122  gnc_commodity **comm_b)
123 {
124  GncTreeModelCommodity *model;
125  GtkTreeModel *tree_model;
126 
127  tree_model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(f_model));
128  model = GNC_TREE_MODEL_COMMODITY(tree_model);
129 
130  gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER(f_model),
131  iter_a,
132  f_iter_a);
133 
134  gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER(f_model),
135  iter_b,
136  f_iter_b);
137 
138  /* Both iters must point to commodities for this to be meaningful */
139  if (!gnc_tree_model_commodity_iter_is_commodity (model, iter_a))
140  return FALSE;
141  if (!gnc_tree_model_commodity_iter_is_commodity (model, iter_b))
142  return FALSE;
143 
144  *comm_a = gnc_tree_model_commodity_get_commodity (model, iter_a);
145  *comm_b = gnc_tree_model_commodity_get_commodity (model, iter_b);
146  if (model_p)
147  *model_p = tree_model;
148  return TRUE;
149 }
150 
151 static gboolean
152 get_commodities (GtkTreeModel *f_model,
153  GtkTreeIter *f_iter_a,
154  GtkTreeIter *f_iter_b,
155  GtkTreeModel **model_p,
156  gnc_commodity **comm_a,
157  gnc_commodity **comm_b)
158 {
159  GtkTreeIter iter_a, iter_b;
160 
161  return get_commodities_w_iters(f_model, f_iter_a, f_iter_b, model_p,
162  &iter_a, &iter_b, comm_a, comm_b);
163 }
164 
165 static gint
166 sort_namespace (GtkTreeModel *f_model,
167  GtkTreeIter *f_iter_a,
168  GtkTreeIter *f_iter_b)
169 {
170  GncTreeModelCommodity *model;
171  GtkTreeModel *tree_model;
172  GtkTreeIter iter_a, iter_b;
173  gnc_commodity_namespace *ns_a, *ns_b;
174 
175  tree_model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(f_model));
176  model = GNC_TREE_MODEL_COMMODITY(tree_model);
177 
178  gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER(f_model),
179  &iter_a,
180  f_iter_a);
181  gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER(f_model),
182  &iter_b,
183  f_iter_b);
184 
185  ns_a = gnc_tree_model_commodity_get_namespace (model, &iter_a);
186  ns_b = gnc_tree_model_commodity_get_namespace (model, &iter_b);
189 }
190 
191 static gint
192 default_sort (gnc_commodity *comm_a, gnc_commodity *comm_b)
193 {
194  gint fraction_a, fraction_b, result;
195 
197  gnc_commodity_get_namespace (comm_b));
198  if (result != 0) return result;
199 
201  gnc_commodity_get_mnemonic (comm_b));
202  if (result != 0) return result;
203 
205  gnc_commodity_get_fullname (comm_b));
206  if (result != 0) return result;
207 
208  result = safe_utf8_collate (gnc_commodity_get_cusip (comm_a),
209  gnc_commodity_get_cusip (comm_b));
210  if (result != 0) return result;
211 
212  fraction_a = gnc_commodity_get_fraction (comm_a);
213  fraction_b = gnc_commodity_get_fraction (comm_b);
214 
215  if (fraction_a < fraction_b)
216  return -1;
217 
218  if (fraction_b < fraction_a)
219  return 1;
220 
221  return 0;
222 }
223 
224 static gint
225 sort_by_commodity_string (GtkTreeModel *f_model,
226  GtkTreeIter *f_iter_a,
227  GtkTreeIter *f_iter_b,
228  gpointer user_data)
229 {
230  GtkTreeModel *model;
231  GtkTreeIter iter_a, iter_b;
232  gnc_commodity *comm_a, *comm_b;
233  gchar *str1, *str2;
234  gint column = GPOINTER_TO_INT(user_data);
235  gint result;
236 
237  if (!get_commodities_w_iters(f_model, f_iter_a, f_iter_b,
238  &model, &iter_a, &iter_b, &comm_a, &comm_b))
239  return sort_namespace (f_model, f_iter_a, f_iter_b);
240 
241  /* Get the strings. */
242  gtk_tree_model_get(GTK_TREE_MODEL(model), &iter_a, column, &str1, -1);
243  gtk_tree_model_get(GTK_TREE_MODEL(model), &iter_b, column, &str2, -1);
244 
245  result = safe_utf8_collate(str1, str2);
246  g_free(str1);
247  g_free(str2);
248  if (result != 0)
249  return result;
250  return default_sort(comm_a, comm_b);
251 }
252 
253 
254 static gint
255 sort_by_fraction (GtkTreeModel *f_model,
256  GtkTreeIter *f_iter_a,
257  GtkTreeIter *f_iter_b,
258  gpointer user_data)
259 {
260  gnc_commodity *comm_a, *comm_b;
261  gint fraction_a, fraction_b;
262 
263  if (!get_commodities (f_model, f_iter_a, f_iter_b, NULL, &comm_a, &comm_b))
264  return sort_namespace (f_model, f_iter_a, f_iter_b);
265 
266  fraction_a = gnc_commodity_get_fraction (comm_a);
267  fraction_b = gnc_commodity_get_fraction (comm_b);
268 
269  if (fraction_a < fraction_b)
270  return -1;
271 
272  if (fraction_b < fraction_a)
273  return 1;
274 
275  return default_sort(comm_a, comm_b);
276 }
277 
278 static gint
279 sort_by_quote_flag (GtkTreeModel *f_model,
280  GtkTreeIter *f_iter_a,
281  GtkTreeIter *f_iter_b,
282  gpointer user_data)
283 {
284  gnc_commodity *comm_a, *comm_b;
285  gboolean flag_a, flag_b;
286 
287  if (!get_commodities (f_model, f_iter_a, f_iter_b, NULL, &comm_a, &comm_b))
288  return sort_namespace (f_model, f_iter_a, f_iter_b);
289 
290  flag_a = gnc_commodity_get_quote_flag(comm_a);
291  flag_b = gnc_commodity_get_quote_flag(comm_b);
292 
293  if (flag_a < flag_b)
294  return -1;
295  else if (flag_a > flag_b)
296  return 1;
297  return default_sort(comm_a, comm_b);
298 }
299 
300 /************************************************************/
301 /* New View Creation */
302 /************************************************************/
303 
304 /*
305  * Create a new commodity tree view with (optional) top level root node.
306  * This view will be based on a model that is common to all view of
307  * the same set of books, but will have its own private filter on that
308  * model.
309  */
310 GtkTreeView *
312  const gchar *first_property_name,
313  ...)
314 {
315  GncTreeView *view;
316  GtkTreeModel *model, *f_model, *s_model;
317  GtkTreeViewColumn *col;
318  gnc_commodity_table *ct;
319  va_list var_args;
320 
321  ENTER(" ");
322  /* Create/get a pointer to the existing model for this set of books. */
323  ct = gnc_commodity_table_get_table (book);
324  model = gnc_tree_model_commodity_new (book, ct);
325 
326  /* Set up the view private filter on the common model. */
327  f_model = gtk_tree_model_filter_new (model, NULL);
328  g_object_unref(G_OBJECT(model));
329  s_model = gtk_tree_model_sort_new_with_model (f_model);
330  g_object_unref(G_OBJECT(f_model));
331 
332  /* Create our view */
333  view = g_object_new (GNC_TYPE_TREE_VIEW_COMMODITY,
334  "name", "gnc-id-commodity-tree", NULL);
335  gtk_tree_view_set_model (GTK_TREE_VIEW (view), s_model);
336  g_object_unref(G_OBJECT(s_model));
337 
338  DEBUG("model ref count is %d", G_OBJECT(model)->ref_count);
339  DEBUG("f_model ref count is %d", G_OBJECT(f_model)->ref_count);
340  DEBUG("s_model ref count is %d", G_OBJECT(s_model)->ref_count);
341 
342  /* Set default visibilities */
343  gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(view), FALSE);
344 
346  view, _("Namespace"), "namespace", NULL, "NASDAQ",
347  GNC_TREE_MODEL_COMMODITY_COL_NAMESPACE,
348  GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
349  sort_by_commodity_string);
351  view, _("Symbol"), "symbol", NULL, "ACMEACME",
352  GNC_TREE_MODEL_COMMODITY_COL_MNEMONIC,
353  GNC_TREE_MODEL_COMMODITY_COL_VISIBILITY,
354  sort_by_commodity_string);
355  g_object_set_data(G_OBJECT(col), DEFAULT_VISIBLE, GINT_TO_POINTER(1));
357  view, _("Name"), "name", NULL, "Acme Corporation, Inc.",
358  GNC_TREE_MODEL_COMMODITY_COL_FULLNAME,
359  GNC_TREE_MODEL_COMMODITY_COL_VISIBILITY,
360  sort_by_commodity_string);
361  g_object_set_data(G_OBJECT(col), DEFAULT_VISIBLE, GINT_TO_POINTER(1));
363  view, _("Print Name"), "printname", NULL,
364  "ACMEACME (Acme Corporation, Inc.)",
365  GNC_TREE_MODEL_COMMODITY_COL_PRINTNAME,
366  GNC_TREE_MODEL_COMMODITY_COL_VISIBILITY,
367  sort_by_commodity_string);
369  view, _("Display symbol"), "user_symbol", NULL, "ACME",
370  GNC_TREE_MODEL_COMMODITY_COL_USER_SYMBOL,
371  GNC_TREE_MODEL_COMMODITY_COL_VISIBILITY,
372  sort_by_commodity_string);
373  g_object_set_data(G_OBJECT(col), DEFAULT_VISIBLE, GINT_TO_POINTER(1));
375  view, _("Unique Name"), "uniquename", NULL,
376  "NASDAQ::ACMEACME", GNC_TREE_MODEL_COMMODITY_COL_UNIQUE_NAME,
377  GNC_TREE_MODEL_COMMODITY_COL_VISIBILITY,
378  sort_by_commodity_string);
380  /* Translators: Again replace CUSIP by the name of your
381  National Securities Identifying Number. */
382  view, _("ISIN/CUSIP"), "cusip_code", NULL, "US1234567890",
383  GNC_TREE_MODEL_COMMODITY_COL_CUSIP,
384  GNC_TREE_MODEL_COMMODITY_COL_VISIBILITY,
385  sort_by_commodity_string);
386  g_object_set_data(G_OBJECT(col), DEFAULT_VISIBLE, GINT_TO_POINTER(1));
388  view, _("Fraction"), "fraction", "10000",
389  GNC_TREE_MODEL_COMMODITY_COL_FRACTION,
390  GNC_TREE_VIEW_COLUMN_COLOR_NONE,
391  GNC_TREE_MODEL_COMMODITY_COL_VISIBILITY,
392  sort_by_fraction);
393  g_object_set_data(G_OBJECT(col), DEFAULT_VISIBLE, GINT_TO_POINTER(1));
395  view, _("Get Quotes"),
396  C_("Column letter for 'Get Quotes'", "Q"), "quote_flag",
397  GNC_TREE_MODEL_COMMODITY_COL_QUOTE_FLAG,
398  GNC_TREE_MODEL_COMMODITY_COL_VISIBILITY,
399  sort_by_quote_flag,
400  NULL);
402  view, _("Source"), "quote_source", NULL, "alphavantage",
403  GNC_TREE_MODEL_COMMODITY_COL_QUOTE_SOURCE,
404  GNC_TREE_MODEL_COMMODITY_COL_VISIBILITY,
405  sort_by_commodity_string);
407  view, _("Timezone"), "quote_timezone", NULL, "America/New_York",
408  GNC_TREE_MODEL_COMMODITY_COL_QUOTE_TZ,
409  GNC_TREE_MODEL_COMMODITY_COL_VISIBILITY,
410  sort_by_commodity_string);
411  g_object_set_data(G_OBJECT(col), DEFAULT_VISIBLE, GINT_TO_POINTER(1));
412 
414 
415  /* Set properties */
416  va_start (var_args, first_property_name);
417  g_object_set_valist (G_OBJECT(view), first_property_name, var_args);
418  va_end (var_args);
419 
420  /* Sort on the name column by default. This allows for a consistent
421  * sort if commodities are briefly removed and re-added. */
422  if (!gtk_tree_sortable_get_sort_column_id(GTK_TREE_SORTABLE(s_model),
423  NULL, NULL))
424  {
425  gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(s_model),
426  GNC_TREE_MODEL_COMMODITY_COL_FULLNAME,
427  GTK_SORT_ASCENDING);
428  }
429 
430  gtk_widget_show(GTK_WIDGET(view));
431  LEAVE(" %p", view);
432  return GTK_TREE_VIEW(view);
433 }
434 
435 /************************************************************/
436 /* Auxiliary Functions */
437 /************************************************************/
438 
439 #define debug_path(fn, path) { \
440  gchar *path_string = gtk_tree_path_to_string(path); \
441  fn("tree path %s", path_string); \
442  g_free(path_string); \
443  }
444 
445 #if 0 /* Not Used */
446 static gboolean
447 gnc_tree_view_commodity_get_iter_from_commodity (GncTreeViewCommodity *view,
448  gnc_commodity *commodity,
449  GtkTreeIter *s_iter)
450 {
451  GtkTreeModel *model, *f_model, *s_model;
452  GtkTreeIter iter, f_iter;
453 
454  g_return_val_if_fail(GNC_IS_TREE_VIEW_COMMODITY(view), FALSE);
455  g_return_val_if_fail(commodity != NULL, FALSE);
456  g_return_val_if_fail(s_iter != NULL, FALSE);
457 
458  ENTER("view %p, commodity %p (%s)", view, commodity, gnc_commodity_get_mnemonic(commodity));
459 
460  /* Reach down to the real model and get an iter for this commodity */
461  s_model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
462  f_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(s_model));
463  model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(f_model));
464  if (!gnc_tree_model_commodity_get_iter_from_commodity (GNC_TREE_MODEL_COMMODITY(model), commodity, &iter))
465  {
466  LEAVE("model_get_iter_from_commodity failed");
467  return FALSE;
468  }
469 
470  /* convert back to a sort iter */
471  gtk_tree_model_filter_convert_child_iter_to_iter (GTK_TREE_MODEL_FILTER(f_model),
472  &f_iter, &iter);
473  gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT(s_model),
474  s_iter, &f_iter);
475  LEAVE(" ");
476  return TRUE;
477 }
478 #endif /* Not Used */
479 
480 /************************************************************/
481 /* Commodity Tree View Visibility Filter */
482 /************************************************************/
483 
484 typedef struct
485 {
486  gnc_tree_view_commodity_ns_filter_func user_ns_fn;
487  gnc_tree_view_commodity_cm_filter_func user_cm_fn;
488  gpointer user_data;
489  GDestroyNotify user_destroy;
491 
492 static void
493 gnc_tree_view_commodity_filter_destroy (gpointer data)
494 {
495  filter_user_data *fd = data;
496 
497  if (fd->user_destroy)
498  fd->user_destroy(fd->user_data);
499  g_free(fd);
500 }
501 
502 static gboolean
503 gnc_tree_view_commodity_filter_helper (GtkTreeModel *model,
504  GtkTreeIter *iter,
505  gpointer data)
506 {
507  gnc_commodity_namespace *name_space;
508  gnc_commodity *commodity;
509  filter_user_data *fd = data;
510 
511  g_return_val_if_fail (GNC_IS_TREE_MODEL_COMMODITY (model), FALSE);
512  g_return_val_if_fail (iter != NULL, FALSE);
513 
514  if (gnc_tree_model_commodity_iter_is_namespace (GNC_TREE_MODEL_COMMODITY(model), iter))
515  {
516  if (fd->user_ns_fn)
517  {
518  name_space = gnc_tree_model_commodity_get_namespace (GNC_TREE_MODEL_COMMODITY(model), iter);
519  return fd->user_ns_fn(name_space, fd->user_data);
520  }
521  return TRUE;
522  }
523 
524  if (gnc_tree_model_commodity_iter_is_commodity (GNC_TREE_MODEL_COMMODITY(model), iter))
525  {
526  if (fd->user_cm_fn)
527  {
528  commodity = gnc_tree_model_commodity_get_commodity (GNC_TREE_MODEL_COMMODITY(model), iter);
529  return fd->user_cm_fn(commodity, fd->user_data);
530  }
531  return TRUE;
532  }
533 
534  return FALSE;
535 }
536 
537 /*
538  * Set an GtkTreeModel visible filter on this commodity. This filter will be
539  * called for each commodity that the tree is about to show, and the
540  * commodity will be passed to the callback function.
541  */
542 void
543 gnc_tree_view_commodity_set_filter (GncTreeViewCommodity *view,
544  gnc_tree_view_commodity_ns_filter_func ns_func,
545  gnc_tree_view_commodity_cm_filter_func cm_func,
546  gpointer data,
547  GDestroyNotify destroy)
548 {
549  GtkTreeModel *f_model, *s_model;
550  filter_user_data *fd = data;
551 
552  g_return_if_fail(GNC_IS_TREE_VIEW_COMMODITY(view));
553  g_return_if_fail((ns_func != NULL) || (cm_func != NULL));
554 
555  ENTER("view %p, ns func %p, cm func %p, data %p, destroy %p",
556  view, ns_func, cm_func, data, destroy);
557 
558  fd = g_malloc(sizeof(filter_user_data));
559  fd->user_ns_fn = ns_func;
560  fd->user_cm_fn = cm_func;
561  fd->user_data = data;
562  fd->user_destroy = destroy;
563 
564  s_model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
565  f_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(s_model));
566 
567  /* disconnect model from view */
568  g_object_ref (G_OBJECT(s_model));
569  gtk_tree_view_set_model (GTK_TREE_VIEW(view), NULL);
570 
571  gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (f_model),
572  gnc_tree_view_commodity_filter_helper,
573  fd,
574  gnc_tree_view_commodity_filter_destroy);
575 
576  /* Whack any existing levels. The top two levels have been created
577  * before this routine can be called. */
578  gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (f_model));
579 
580  /* connect model to view */
581  gtk_tree_view_set_model (GTK_TREE_VIEW(view), s_model);
582  g_object_unref (G_OBJECT(s_model));
583 
584  LEAVE(" ");
585 }
586 
587 /*
588  * Forces the entire commodity tree to be re-evaluated for visibility.
589  */
590 void
591 gnc_tree_view_commodity_refilter (GncTreeViewCommodity *view)
592 {
593  GtkTreeModel *f_model, *s_model;
594 
595  g_return_if_fail(GNC_IS_TREE_VIEW_COMMODITY(view));
596 
597  ENTER("view %p", view);
598  s_model = gtk_tree_view_get_model (GTK_TREE_VIEW(view));
599  f_model = gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (s_model));
600  gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (f_model));
601  LEAVE(" ");
602 }
603 
604 
605 /************************************************************/
606 /* Commodity Tree View Get/Set Functions */
607 /************************************************************/
608 
609 /*
610  * Retrieve the selected commodity from an commodity tree view. The
611  * commodity tree must be in single selection mode.
612  */
613 gnc_commodity *
615 {
616  GtkTreeSelection *selection;
617  GtkTreeModel *model, *f_model, *s_model;
618  GtkTreeIter iter, f_iter, s_iter;
619  gnc_commodity *commodity;
620 
621  g_return_val_if_fail (GNC_IS_TREE_VIEW_COMMODITY (view), NULL);
622 
623  ENTER("view %p", view);
624 
625  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(view));
626  if (!gtk_tree_selection_get_selected (selection, &s_model, &s_iter))
627  {
628  LEAVE("no commodity, get_selected failed");
629  return FALSE;
630  }
631 
632  gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (s_model),
633  &f_iter, &s_iter);
634 
635  f_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(s_model));
636  gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (f_model),
637  &iter, &f_iter);
638 
639  model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(f_model));
640  commodity = gnc_tree_model_commodity_get_commodity (GNC_TREE_MODEL_COMMODITY(model),
641  &iter);
642  LEAVE("commodity %p (%s)", commodity,
643  commodity ? gnc_commodity_get_mnemonic(commodity) : "");
644  return commodity;
645 }
646 
647 /*
648  * Select the commodity in the commodity tree view.
649  */
650 void
651 gnc_tree_view_commodity_select_commodity (GncTreeViewCommodity *view, gnc_commodity *commodity)
652 {
653  GtkTreeSelection *selection;
654  GtkTreeModel *model, *f_model, *s_model;
655  GtkTreePath *tree_path;
656  GtkTreePath *f_tree_path;
657  GtkTreePath *s_tree_path;
658 
659  g_return_if_fail (GNC_IS_TREE_VIEW_COMMODITY(view));
660 
661  if (!commodity)
662  return;
663 
664  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(view));
665 
666  s_model = gtk_tree_view_get_model (GTK_TREE_VIEW(view));
667  f_model = gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (s_model));
668  model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (f_model));
669 
670  tree_path = gnc_tree_model_commodity_get_path_from_commodity (GNC_TREE_MODEL_COMMODITY(model), commodity);
671 
672  if (tree_path)
673  {
674  f_tree_path = gtk_tree_model_filter_convert_child_path_to_path
675  (GTK_TREE_MODEL_FILTER (f_model), tree_path);
676 
677  s_tree_path = gtk_tree_model_sort_convert_child_path_to_path
678  (GTK_TREE_MODEL_SORT (s_model), f_tree_path);
679 
680  gtk_tree_view_expand_to_path (GTK_TREE_VIEW(view), s_tree_path);
681  gtk_tree_selection_select_path (selection, s_tree_path);
682  gtk_tree_path_free (tree_path);
683  gtk_tree_path_free (f_tree_path);
684  gtk_tree_path_free (s_tree_path);
685  }
686 }
687 
688 #if 0 /* Not Used */
689 /*
690  * This helper function is called once for each row in the tree view
691  * that is currently selected. Its task is to an the corresponding
692  * commodity to the end of a glist.
693  */
694 static void
695 get_selected_commodities_helper (GtkTreeModel *s_model,
696  GtkTreePath *s_path,
697  GtkTreeIter *s_iter,
698  gpointer data)
699 {
700  GList **return_list = data;
701  GtkTreeModel *model, *f_model;
702  GtkTreeIter iter, f_iter;
703  gnc_commodity *commodity;
704 
705  gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (s_model),
706  &f_iter, s_iter);
707 
708  f_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(s_model));
709  gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (f_model),
710  &iter, &f_iter);
711 
712  model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(f_model));
713  commodity = gnc_tree_model_commodity_get_commodity (GNC_TREE_MODEL_COMMODITY(model),
714  &iter);
715  *return_list = g_list_append(*return_list, commodity);
716 }
717 #endif /* Not Used */
GtkTreeModel implementation for gnucash commodities.
GtkTreeView * gnc_tree_view_commodity_new(QofBook *book, const gchar *first_property_name,...)
Create a new commodity tree view.
const char * gnc_commodity_get_cusip(const gnc_commodity *cm)
Retrieve the &#39;exchange code&#39; for the specified commodity.
gnc_commodity_table * gnc_commodity_table_get_table(QofBook *book)
Returns the commodity table associated with a book.
int gnc_commodity_get_fraction(const gnc_commodity *cm)
Retrieve the fraction for the specified commodity.
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_get_iter_from_commodity(GncTreeModelCommodity *model, gnc_commodity *commodity, GtkTreeIter *iter)
Convert a commodity pointer into a GtkTreeIter.
const char * gnc_commodity_get_mnemonic(const gnc_commodity *cm)
Retrieve the mnemonic for the specified commodity.
GtkTreePath * gnc_tree_model_commodity_get_path_from_commodity(GncTreeModelCommodity *model, gnc_commodity *commodity)
Convert a commodity pointer into a GtkTreePath.
void gnc_tree_view_commodity_set_filter(GncTreeViewCommodity *view, gnc_tree_view_commodity_ns_filter_func ns_func, gnc_tree_view_commodity_cm_filter_func cm_func, gpointer data, GDestroyNotify destroy)
This function attaches a filter function to the given commodity tree.
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...
utility functions for the GnuCash UI
int safe_utf8_collate(const char *da, const char *db)
Collate two UTF-8 strings.
gboolean gnc_commodity_get_quote_flag(const gnc_commodity *cm)
Retrieve the automatic price quote flag for the specified commodity.
common utilities for manipulating a GtkTreeView within gnucash
#define DEBUG(format, args...)
Print a debugging message.
Definition: qoflog.h:264
gnc_commodity_namespace * gnc_tree_model_commodity_get_namespace(GncTreeModelCommodity *model, GtkTreeIter *iter)
Convert a model/iter pair to a gnucash commodity namespace.
const char * gnc_commodity_get_namespace(const gnc_commodity *cm)
Retrieve the namespace for the specified commodity.
GtkTreeViewColumn * gnc_tree_view_add_numeric_column(GncTreeView *view, const gchar *column_title, const gchar *pref_name, const gchar *sizing_text, gint model_data_column, gint model_color_column, gint model_visibility_column, GtkTreeIterCompareFunc column_sort_fn)
This function adds a new numeric column to a GncTreeView base view.
#define ENTER(format, args...)
Print a function entry debugging message.
Definition: qoflog.h:272
GtkTreeViewColumn * gnc_tree_view_add_toggle_column(GncTreeView *view, const gchar *column_title, const gchar *column_short_title, const gchar *pref_name, gint model_data_column, gint model_visibility_column, GtkTreeIterCompareFunc column_sort_fn, renderer_toggled toggle_edited_cb)
This function adds a new toggle column to a GncTreeView base view.
void gnc_tree_view_commodity_select_commodity(GncTreeViewCommodity *view, gnc_commodity *commodity)
Select the commodity in the associated commodity tree view.
void gnc_tree_view_configure_columns(GncTreeView *view)
Make all the correct columns visible, respecting their default visibility setting, their "always" visibility setting, and the last saved state if available.
GtkTreeModel * gnc_tree_model_commodity_new(QofBook *book, gnc_commodity_table *ct)
Create a new GtkTreeModel for manipulating gnucash commodities.
const char * gnc_commodity_get_fullname(const gnc_commodity *cm)
Retrieve the full name for the specified commodity.
Gnome specific utility functions.
All type declarations for the whole Gnucash engine.
GLib helper routines.
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_iter_is_namespace(GncTreeModelCommodity *model, GtkTreeIter *iter)
Determine whether or not the specified GtkTreeIter points to a commodity namespace.
gnc_commodity * gnc_tree_view_commodity_get_selected_commodity(GncTreeViewCommodity *view)
This function returns the commodity associated with the selected item in the commodity tree view...
GtkTreeViewColumn * gnc_tree_view_add_text_column(GncTreeView *view, const gchar *column_title, const gchar *pref_name, const gchar *icon_name, const gchar *sizing_text, gint model_data_column, gint model_visibility_column, GtkTreeIterCompareFunc column_sort_fn)
This function adds a new text column to a GncTreeView base view.
#define LEAVE(format, args...)
Print a function exit debugging message.
Definition: qoflog.h:282
GtkTreeView implementation for gnucash commodity tree.
void gnc_tree_view_commodity_refilter(GncTreeViewCommodity *view)
This function forces the commodity tree filter to be evaluated.
Commodity handling public routines.