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