28 #include <glib/gi18n.h> 36 #include "gnc-component-manager.h" 40 #include "gnc-icons.h" 47 static QofLogModule log_module = GNC_MOD_GUI;
52 static void gnc_tree_view_price_finalize (GObject *
object);
53 static void gnc_tree_view_price_destroy (GtkWidget *widget);
60 #define GNC_TREE_VIEW_PRICE_GET_PRIVATE(o) \ 61 ((GncTreeViewPricePrivate*)gnc_tree_view_price_get_instance_private((GncTreeViewPrice*)o)) 68 static GObjectClass *parent_class = NULL;
70 G_DEFINE_TYPE_WITH_PRIVATE(
GncTreeViewPrice, gnc_tree_view_price, GNC_TYPE_TREE_VIEW)
75 GObjectClass *o_class;
76 GtkWidgetClass *widget_class;
78 parent_class = g_type_class_peek_parent (klass);
80 o_class = G_OBJECT_CLASS (klass);
81 widget_class = GTK_WIDGET_CLASS (klass);
84 o_class->finalize = gnc_tree_view_price_finalize;
87 widget_class->destroy = gnc_tree_view_price_destroy;
96 gnc_tree_view_price_finalize (GObject *
object)
98 ENTER(
"view %p",
object);
102 if (G_OBJECT_CLASS (parent_class)->finalize)
103 (* G_OBJECT_CLASS (parent_class)->finalize) (
object);
108 gnc_tree_view_price_destroy (GtkWidget *widget)
110 ENTER(
"view %p", widget);
114 if (GTK_WIDGET_CLASS (parent_class)->destroy)
115 (* GTK_WIDGET_CLASS (parent_class)->destroy) (widget);
125 get_prices (GtkTreeModel *f_model,
126 GtkTreeIter *f_iter_a,
127 GtkTreeIter *f_iter_b,
132 GtkTreeModel *tree_model;
133 GtkTreeIter iter_a, iter_b;
135 tree_model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(f_model));
136 model = GNC_TREE_MODEL_PRICE(tree_model);
138 gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER(f_model),
146 gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER(f_model),
156 sort_ns_or_cm (GtkTreeModel *f_model,
157 GtkTreeIter *f_iter_a,
158 GtkTreeIter *f_iter_b)
161 GtkTreeModel *tree_model;
162 GtkTreeIter iter_a, iter_b;
163 gnc_commodity_namespace *ns_a, *ns_b;
164 gnc_commodity *comm_a, *comm_b;
166 tree_model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(f_model));
167 model = GNC_TREE_MODEL_PRICE(tree_model);
169 gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER(f_model),
172 gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER(f_model),
191 default_sort (GNCPrice *price_a, GNCPrice *price_b)
193 gnc_commodity *curr_a, *curr_b;
200 curr_a = gnc_price_get_currency (price_a);
201 curr_b = gnc_price_get_currency (price_b);
205 if (result != 0)
return result;
209 if (result != 0)
return result;
212 time_a = gnc_price_get_time64 (price_a);
213 time_b = gnc_price_get_time64 (price_b);
214 result = time_a < time_b ? -1 : time_a > time_b ? 1 : 0;
221 gnc_price_get_value (price_b));
225 sort_by_name (GtkTreeModel *f_model,
226 GtkTreeIter *f_iter_a,
227 GtkTreeIter *f_iter_b,
230 GNCPrice *price_a, *price_b;
232 if (!get_prices (f_model, f_iter_a, f_iter_b, &price_a, &price_b))
233 return sort_ns_or_cm (f_model, f_iter_a, f_iter_b);
235 return default_sort (price_a, price_b);
239 sort_by_date (GtkTreeModel *f_model,
240 GtkTreeIter *f_iter_a,
241 GtkTreeIter *f_iter_b,
244 GNCPrice *price_a, *price_b;
248 if (!get_prices (f_model, f_iter_a, f_iter_b, &price_a, &price_b))
249 return sort_ns_or_cm (f_model, f_iter_a, f_iter_b);
252 time_a = gnc_price_get_time64 (price_a);
253 time_b = gnc_price_get_time64 (price_b);
254 result = time_a < time_b ? -1 : time_a > time_b ? 1 : 0;
259 return default_sort (price_a, price_b);
263 sort_by_source (GtkTreeModel *f_model,
264 GtkTreeIter *f_iter_a,
265 GtkTreeIter *f_iter_b,
268 GNCPrice *price_a, *price_b;
271 if (!get_prices (f_model, f_iter_a, f_iter_b, &price_a, &price_b))
272 return sort_ns_or_cm (f_model, f_iter_a, f_iter_b);
275 result = gnc_price_get_source (price_a) < gnc_price_get_source (price_b);
279 return default_sort (price_a, price_b);
283 sort_by_type (GtkTreeModel *f_model,
284 GtkTreeIter *f_iter_a,
285 GtkTreeIter *f_iter_b,
288 GNCPrice *price_a, *price_b;
291 if (!get_prices (f_model, f_iter_a, f_iter_b, &price_a, &price_b))
292 return sort_ns_or_cm (f_model, f_iter_a, f_iter_b);
296 gnc_price_get_typestr (price_b));
300 return default_sort (price_a, price_b);
304 sort_by_value (GtkTreeModel *f_model,
305 GtkTreeIter *f_iter_a,
306 GtkTreeIter *f_iter_b,
309 gnc_commodity *comm_a, *comm_b;
310 GNCPrice *price_a, *price_b;
314 if (!get_prices (f_model, f_iter_a, f_iter_b, &price_a, &price_b))
315 return sort_ns_or_cm (f_model, f_iter_a, f_iter_b);
322 comm_a = gnc_price_get_currency (price_a);
323 comm_b = gnc_price_get_currency (price_b);
324 if (comm_a && comm_b)
341 gnc_price_get_value (price_b));
345 return default_sort (price_a, price_b);
361 const gchar *first_property_name,
365 GtkTreeModel *model, *f_model, *s_model;
366 GtkTreeViewColumn *col;
367 GNCPriceDB *price_db;
369 const gchar *sample_text;
378 f_model = gtk_tree_model_filter_new (model, NULL);
379 g_object_unref(G_OBJECT(model));
380 s_model = gtk_tree_model_sort_new_with_model (f_model);
381 g_object_unref(G_OBJECT(f_model));
384 view = g_object_new (GNC_TYPE_TREE_VIEW_PRICE,
385 "name",
"gnc-id-price-tree", NULL);
386 gtk_tree_view_set_model (GTK_TREE_VIEW (view), s_model);
387 g_object_unref(G_OBJECT(s_model));
389 DEBUG(
"model ref count is %d", G_OBJECT(model)->ref_count);
390 DEBUG(
"f_model ref count is %d", G_OBJECT(f_model)->ref_count);
391 DEBUG(
"s_model ref count is %d", G_OBJECT(s_model)->ref_count);
394 sample_text2 = g_strdup_printf(
"%s%s", sample_text, sample_text);
396 view, _(
"Security"),
"security", NULL, sample_text2,
397 GNC_TREE_MODEL_PRICE_COL_COMMODITY,
398 GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
400 g_free(sample_text2);
402 view, _(
"Currency"),
"currency", NULL, sample_text,
403 GNC_TREE_MODEL_PRICE_COL_CURRENCY,
404 GNC_TREE_MODEL_PRICE_COL_VISIBILITY,
406 g_object_set_data(G_OBJECT(col), DEFAULT_VISIBLE, GINT_TO_POINTER(1));
408 view, _(
"Date"),
"date", NULL,
"2005-05-20",
409 GNC_TREE_MODEL_PRICE_COL_DATE,
410 GNC_TREE_MODEL_PRICE_COL_VISIBILITY,
412 g_object_set_data(G_OBJECT(col), DEFAULT_VISIBLE, GINT_TO_POINTER(1));
414 view, _(
"Source"),
"source", NULL,
"Finance::Quote",
415 GNC_TREE_MODEL_PRICE_COL_SOURCE,
416 GNC_TREE_MODEL_PRICE_COL_VISIBILITY,
418 g_object_set_data(G_OBJECT(col), DEFAULT_VISIBLE, GINT_TO_POINTER(1));
420 view, _(
"Type"),
"type", NULL,
"last",
421 GNC_TREE_MODEL_PRICE_COL_TYPE,
422 GNC_TREE_MODEL_PRICE_COL_VISIBILITY,
424 g_object_set_data(G_OBJECT(col), DEFAULT_VISIBLE, GINT_TO_POINTER(1));
426 view, _(
"Price"),
"price",
"100.00000",
427 GNC_TREE_MODEL_PRICE_COL_VALUE,
428 GNC_TREE_VIEW_COLUMN_COLOR_NONE,
429 GNC_TREE_MODEL_PRICE_COL_VISIBILITY,
431 g_object_set_data(G_OBJECT(col), DEFAULT_VISIBLE, GINT_TO_POINTER(1));
436 va_start (var_args, first_property_name);
437 g_object_set_valist (G_OBJECT(view), first_property_name, var_args);
442 if (!gtk_tree_sortable_get_sort_column_id(GTK_TREE_SORTABLE(s_model),
445 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(s_model),
446 GNC_TREE_MODEL_PRICE_COL_COMMODITY,
450 gtk_widget_show(GTK_WIDGET(view));
452 return GTK_TREE_VIEW(view);
459 #define debug_path(fn, path) { \ 460 gchar *path_string = gtk_tree_path_to_string(path); \ 461 fn("tree path %s", path_string); \ 462 g_free(path_string); \ 471 GtkTreeModel *model, *f_model, *s_model;
472 GtkTreeIter iter, f_iter;
474 g_return_val_if_fail(GNC_IS_TREE_VIEW_PRICE(view), FALSE);
475 g_return_val_if_fail(price != NULL, FALSE);
476 g_return_val_if_fail(s_iter != NULL, FALSE);
478 ENTER(
"view %p, price %p", view, price);
481 s_model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
482 f_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(s_model));
483 model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(f_model));
486 LEAVE(
"model_get_iter_from_price failed");
491 gtk_tree_model_filter_convert_child_iter_to_iter (GTK_TREE_MODEL_FILTER(f_model),
493 gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT(s_model),
511 gnc_tree_view_price_cm_filter_func user_cm_fn;
512 gnc_tree_view_price_pc_filter_func user_pc_fn;
514 GDestroyNotify user_destroy;
518 gnc_tree_view_price_filter_destroy (gpointer data)
522 if (fd->user_destroy)
523 fd->user_destroy(fd->user_data);
528 gnc_tree_view_price_filter_helper (GtkTreeModel *model,
532 gnc_commodity_namespace *name_space;
533 gnc_commodity *commodity;
537 g_return_val_if_fail (GNC_IS_TREE_MODEL_PRICE (model), FALSE);
538 g_return_val_if_fail (iter != NULL, FALSE);
545 return fd->user_ns_fn(name_space, fd->user_data);
555 return fd->user_cm_fn(commodity, fd->user_data);
565 return fd->user_pc_fn(price, fd->user_data);
581 gnc_tree_view_price_cm_filter_func cm_func,
582 gnc_tree_view_price_pc_filter_func pc_func,
584 GDestroyNotify destroy)
586 GtkTreeModel *f_model, *s_model;
589 ENTER(
"view %p, ns func %p, cm func %p, pc func %p, data %p, destroy %p",
590 view, ns_func, cm_func, pc_func, data, destroy);
592 g_return_if_fail(GNC_IS_TREE_VIEW_PRICE(view));
593 g_return_if_fail((ns_func != NULL) || (cm_func != NULL));
596 fd->user_ns_fn = ns_func;
597 fd->user_cm_fn = cm_func;
598 fd->user_pc_fn = pc_func;
599 fd->user_data = data;
600 fd->user_destroy = destroy;
602 s_model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
603 f_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(s_model));
606 g_object_ref (G_OBJECT(s_model));
607 gtk_tree_view_set_model (GTK_TREE_VIEW(view), NULL);
609 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (f_model),
610 gnc_tree_view_price_filter_helper,
612 gnc_tree_view_price_filter_destroy);
620 gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (f_model));
623 gtk_tree_view_set_model (GTK_TREE_VIEW(view), s_model);
624 g_object_unref (G_OBJECT(s_model));
640 GtkTreeSelection *selection;
641 GtkTreeModel *model, *f_model, *s_model;
642 GtkTreeIter iter, f_iter, s_iter;
645 ENTER(
"view %p", view);
646 g_return_val_if_fail (GNC_IS_TREE_VIEW_PRICE (view), NULL);
648 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(view));
649 if (!gtk_tree_selection_get_selected (selection, &s_model, &s_iter))
651 LEAVE(
"no price, get_selected failed");
655 gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (s_model),
658 f_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(s_model));
659 gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (f_model),
662 model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(f_model));
665 LEAVE(
"price %p", price);
677 GtkTreeModel *model, *f_model, *s_model;
678 GtkTreePath *path, *f_path, *s_path, *parent_path;
679 GtkTreeSelection *selection;
681 ENTER(
"view %p, price %p", view, price);
684 selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
685 gtk_tree_selection_unselect_all (selection);
690 s_model = gtk_tree_view_get_model(GTK_TREE_VIEW(view));
691 f_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(s_model));
692 model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (f_model));
697 LEAVE(
"get_path_from_price failed");
700 debug_path(
DEBUG, path);
702 f_path = gtk_tree_model_filter_convert_child_path_to_path (GTK_TREE_MODEL_FILTER (f_model),
704 gtk_tree_path_free(path);
707 LEAVE(
"no filter path");
710 debug_path(
DEBUG, f_path);
712 s_path = gtk_tree_model_sort_convert_child_path_to_path (GTK_TREE_MODEL_SORT (s_model),
714 gtk_tree_path_free(f_path);
717 LEAVE(
"no sort path");
722 parent_path = gtk_tree_path_copy (s_path);
723 if (gtk_tree_path_up (parent_path))
728 gtk_tree_view_expand_to_path(GTK_TREE_VIEW(view), parent_path);
730 gtk_tree_path_free(parent_path);
732 gtk_tree_selection_select_path (selection, s_path);
733 gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW(view), s_path, NULL, FALSE, 0.0, 0.0);
734 debug_path(
LEAVE, s_path);
735 gtk_tree_path_free(s_path);
744 get_selected_prices_helper (GtkTreeModel *s_model,
749 GList **return_list = data;
750 GtkTreeModel *model, *f_model;
751 GtkTreeIter iter, f_iter;
754 gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (s_model),
757 f_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(s_model));
758 gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (f_model),
761 model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(f_model));
765 *return_list = g_list_prepend (*return_list, price);
778 GtkTreeSelection *selection;
779 GList *return_list = NULL;
781 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(view));
782 gtk_tree_selection_selected_foreach(selection, get_selected_prices_helper, &return_list);
783 return g_list_reverse (return_list);
787 get_selected_commodity_helper (GtkTreeModel *s_model,
792 GList **return_list = data;
793 GtkTreeModel *model, *f_model;
794 GtkTreeIter iter, f_iter;
795 gnc_commodity *commodity;
797 gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (s_model),
800 f_model = gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(s_model));
801 gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER (f_model),
804 model = gtk_tree_model_filter_get_model(GTK_TREE_MODEL_FILTER(f_model));
808 *return_list = g_list_prepend (*return_list, commodity);
822 GtkTreeSelection *selection;
823 GList *return_list = NULL;
825 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(view));
826 gtk_tree_selection_selected_foreach (selection, get_selected_commodity_helper, &return_list);
827 return g_list_reverse (return_list);
gboolean gnc_tree_model_price_get_iter_from_price(GncTreeModelPrice *model, GNCPrice *price, GtkTreeIter *iter)
Convert a price pointer into a GtkTreeIter.
gnc_commodity * gnc_tree_model_price_get_commodity(GncTreeModelPrice *model, GtkTreeIter *iter)
Convert a model/iter pair to a gnucash commodity.
const char * gnc_commodity_get_mnemonic(const gnc_commodity *cm)
Retrieve the mnemonic for the specified commodity.
a simple price database for gnucash
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.
GtkTreeModel implementation for gnucash price database.
gboolean(* gnc_tree_view_price_ns_filter_func)(gnc_commodity_namespace *, gpointer data)
This function attaches a filter function to the given price tree.
common utilities for manipulating a GtkTreeView within gnucash
#define DEBUG(format, args...)
Print a debugging message.
GNCPrice * gnc_tree_model_price_get_price(GncTreeModelPrice *model, GtkTreeIter *iter)
Convert a model/iter pair to a gnucash price.
GNCPrice * gnc_tree_view_price_get_selected_price(GncTreeViewPrice *view)
This function returns the price associated with the selected item in the price tree view...
GList * gnc_tree_view_price_get_selected_commodities(GncTreeViewPrice *view)
This function returns a list of commodities associated with the selected rows that are not prices but...
GList * gnc_tree_view_price_get_selected_prices(GncTreeViewPrice *view)
This function returns a list of the prices associated with the selected items in the price tree view...
const char * gnc_commodity_get_namespace(const gnc_commodity *cm)
Retrieve the namespace for the specified commodity.
gnc_commodity_namespace * gnc_tree_model_price_get_namespace(GncTreeModelPrice *model, GtkTreeIter *iter)
Convert a model/iter pair to a gnucash commodity namespace.
int gnc_numeric_compare(gnc_numeric a, gnc_numeric b)
Returns 1 if a>b, -1 if b>a, 0 if a == b.
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.
GNCPriceDB * gnc_pricedb_get_db(QofBook *book)
Return the pricedb associated with the book.
gnc_commodity * gnc_default_currency(void)
Return the default currency set by the user.
gboolean gnc_tree_model_price_iter_is_namespace(GncTreeModelPrice *model, GtkTreeIter *iter)
Determine whether or not the specified GtkTreeIter points to a "commodity namespace".
GtkTreeView implementation for gnucash price tree.
gboolean gnc_tree_model_price_iter_is_commodity(GncTreeModelPrice *model, GtkTreeIter *iter)
Determine whether or not the specified GtkTreeIter points to a commodity.
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.
Gnome specific utility functions.
gboolean gnc_tree_model_price_iter_is_price(GncTreeModelPrice *model, GtkTreeIter *iter)
Determine whether or not the specified GtkTreeIter points to a price.
All type declarations for the whole Gnucash engine.
void gnc_tree_view_price_set_selected_price(GncTreeViewPrice *view, GNCPrice *price)
This function selects an price in the price tree view.
const char * gnc_commodity_get_printname(const gnc_commodity *cm)
Retrieve the 'print' name for the specified commodity.
GtkTreeModel * gnc_tree_model_price_new(QofBook *book, GNCPriceDB *price_db)
Create a new GtkTreeModel for manipulating gnucash commodity prices.
#define gnc_leave_return_if_fail(test)
Replacement for g_return_if_fail, but calls LEAVE if the test fails.
GtkTreePath * gnc_tree_model_price_get_path_from_price(GncTreeModelPrice *model, GNCPrice *price)
Convert a price pointer into a GtkTreePath.
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.
gint64 time64
Many systems, including Microsoft Windows and BSD-derived Unixes like Darwin, are retaining the int-3...
GtkTreeView * gnc_tree_view_price_new(QofBook *book, const gchar *first_property_name,...)
Create a new price tree view.
The instance data structure for a price tree model.