41#ifdef __G_IR_SCANNER__
42#undef __G_IR_SCANNER__
44#include <gdk/gdkkeysyms.h>
46# include <gdk/gdkwin32.h>
48#include <glib/gi18n.h>
49#include "gnc-date-edit.h"
55#include "dialog-utils.h"
62#include "gnc-session.h"
67#include "gnc-component-manager.h"
69#include "gnc-cell-renderer-text-flag.h"
73#include "gnc-recurrence.h"
74#include "Recurrence.h"
76#include "gnc-locale-utils.h"
80static QofLogModule log_module = GNC_MOD_BUDGET;
82#define PLUGIN_PAGE_BUDGET_CM_CLASS "budget-view"
83#define STATE_SECTION_PREFIX "Budget"
116static void gnc_budget_view_finalize (GObject *
object);
118static void gbv_create_widget (GncBudgetView *budget_view);
120static gboolean gbv_button_press_cb (GtkWidget *widget, GdkEventButton *event,
121 GncBudgetView *budget_view);
123static gboolean gbv_key_press_cb (GtkWidget *treeview, GdkEventKey *event,
125static void gbv_row_activated_cb (GtkTreeView *treeview, GtkTreePath *path,
126 GtkTreeViewColumn *col, GncBudgetView *budget_view);
127static gboolean query_tooltip_tree_view_cb (GtkWidget *widget, gint x, gint y,
128 gboolean keyboard_tip,
130 GncBudgetView *budget_view);
132static void gbv_selection_changed_cb (GtkTreeSelection *selection,
133 GncBudgetView *budget_view);
135static void gbv_treeview_resized_cb (GtkWidget *widget, GtkAllocation *allocation,
136 GncBudgetView *budget_view);
137static gnc_numeric gbv_get_accumulated_budget_amount (GncBudget *budget,
138 Account *account, guint period_num);
157 GtkTreeView *tree_view;
158 GtkTreeView *totals_tree_view;
159 GtkWidget *totals_scroll_window;
164 gboolean use_red_color;
166 GList *period_col_list;
167 GList *totals_col_list;
168 GtkTreeViewColumn *total_col;
171 gboolean show_account_code;
172 gboolean show_account_desc;
174 GtkCellRenderer *temp_cr;
175 GtkCellEditable *temp_ce;
178G_DEFINE_TYPE_WITH_PRIVATE(GncBudgetView, gnc_budget_view, GTK_TYPE_BOX)
180#define GNC_BUDGET_VIEW_GET_PRIVATE(o) \
181 ((GncBudgetViewPrivate*)gnc_budget_view_get_instance_private((GncBudgetView*)o))
190 GncBudgetView *budget_view;
193 g_return_val_if_fail (GNC_IS_BUDGET(budget), NULL);
196 budget_view = g_object_new (GNC_TYPE_BUDGET_VIEW, NULL);
198 priv = GNC_BUDGET_VIEW_GET_PRIVATE(budget_view);
199 priv->budget = budget;
200 priv->key = *gnc_budget_get_guid (budget);
202 priv->total_col = NULL;
203 priv->show_account_code = FALSE;
204 priv->show_account_desc = FALSE;
205 gbv_create_widget (budget_view);
207 LEAVE(
"new budget view %p", budget_view);
212gnc_budget_view_class_init (GncBudgetViewClass *klass)
214 GObjectClass *object_class = G_OBJECT_CLASS(klass);
216 object_class->finalize = gnc_budget_view_finalize;
218 g_signal_new (
"account-activated", GNC_TYPE_BUDGET_VIEW, G_SIGNAL_RUN_LAST,
219 0, NULL, NULL, NULL, G_TYPE_NONE, 1, GNC_TYPE_ACCOUNT);
223gnc_budget_view_init (GncBudgetView *budget_view)
227 ENTER(
"view %p", budget_view);
229 gtk_orientable_set_orientation (GTK_ORIENTABLE(budget_view), GTK_ORIENTATION_VERTICAL);
231 priv = GNC_BUDGET_VIEW_GET_PRIVATE(budget_view);
234 priv->rootAcct = gnc_book_get_root_account (gnc_get_current_book());
240gbv_treeview_update_grid_lines (gpointer prefs, gchar *pref, gpointer user_data)
242 GtkTreeView *view = user_data;
243 gtk_tree_view_set_grid_lines (GTK_TREE_VIEW(view), gnc_tree_view_get_grid_lines_pref ());
247gnc_budget_view_set_show_account_code (GncBudgetView *budget_view, gboolean show_account_code)
250 priv->show_account_code = show_account_code;
255gnc_budget_view_get_show_account_code (GncBudgetView *budget_view)
258 return priv->show_account_code;
262gnc_budget_view_set_show_account_description (GncBudgetView *budget_view, gboolean show_account_desc)
265 priv->show_account_desc = show_account_desc;
270gnc_budget_view_get_show_account_description (GncBudgetView *budget_view)
273 return priv->show_account_desc;
277gbv_update_use_red (gpointer prefs, gchar *pref, gpointer user_data)
279 GncBudgetView *budget_view = user_data;
283 GNC_PREF_NEGATIVE_IN_RED);
287gnc_budget_view_finalize (GObject *
object)
289 GncBudgetView *budget_view;
292 ENTER(
"object %p",
object);
293 budget_view = GNC_BUDGET_VIEW(
object);
294 g_return_if_fail (GNC_IS_BUDGET_VIEW(budget_view));
296 priv = GNC_BUDGET_VIEW_GET_PRIVATE(budget_view);
298 g_list_free (priv->period_col_list);
299 g_list_free (priv->totals_col_list);
302 gbv_treeview_update_grid_lines, priv->totals_tree_view);
304 gbv_treeview_update_grid_lines, priv->totals_tree_view);
306 gbv_update_use_red, budget_view);
308 G_OBJECT_CLASS(gnc_budget_view_parent_class)->finalize (
object);
322 g_return_val_if_fail (GNC_IS_BUDGET_VIEW(budget_view), NULL);
324 priv = GNC_BUDGET_VIEW_GET_PRIVATE(budget_view);
325 return gtk_tree_view_get_selection (GTK_TREE_VIEW(priv->tree_view));
329gnc_budget_view_get_account_from_path (GncBudgetView *budget_view, GtkTreePath *path)
333 g_return_val_if_fail (GNC_IS_BUDGET_VIEW(budget_view), NULL);
335 priv = GNC_BUDGET_VIEW_GET_PRIVATE(budget_view);
340gnc_budget_view_get_account_tree_view (GncBudgetView *budget_view)
344 g_return_val_if_fail (GNC_IS_BUDGET_VIEW(budget_view), NULL);
346 priv = GNC_BUDGET_VIEW_GET_PRIVATE(budget_view);
347 return GTK_WIDGET(priv->fd->tree_view);
351gnc_budget_view_get_selected_accounts (GncBudgetView *budget_view)
355 g_return_val_if_fail (GNC_IS_BUDGET_VIEW(budget_view), NULL);
357 priv = GNC_BUDGET_VIEW_GET_PRIVATE(budget_view);
362gbv_totals_scrollbar_value_changed_cb (GtkAdjustment *adj, GncBudgetView *budget_view)
366 g_return_if_fail (GNC_IS_BUDGET_VIEW(budget_view));
368 priv = GNC_BUDGET_VIEW_GET_PRIVATE(budget_view);
369 gtk_adjustment_set_value (priv->hadj, gtk_adjustment_get_value (adj));
373gbv_totals_tree_view_redraw_idle (GtkTreeView *view)
375 gtk_widget_queue_draw (GTK_WIDGET(view));
380gbv_tree_view_model_row_changed_cb (GtkTreeModel *tree_model, GtkTreePath *path,
381 GtkTreeIter *iter, gpointer user_data)
383 GncBudgetView *budget_view = user_data;
388 g_idle_remove_by_data (priv->totals_tree_view);
389 g_idle_add ((GSourceFunc)gbv_totals_tree_view_redraw_idle, priv->totals_tree_view);
403gbv_create_widget (GncBudgetView *budget_view)
406 GtkTreeSelection *selection;
407 GtkTreeView *tree_view;
408 GtkWidget *scrolled_window;
409 GtkAdjustment *h_adj;
410 GtkWidget *h_scrollbar;
412 GtkListStore *totals_tree_model;
413 GtkTreeView *totals_tree_view;
414 GtkTreeViewColumn *totals_title_col, *name_col, *code_col, *desc_col;
416 GtkWidget *h_separator;
417 gchar *state_section;
420 priv = GNC_BUDGET_VIEW_GET_PRIVATE(budget_view);
421 vbox = GTK_BOX(budget_view);
424 gtk_widget_set_name (GTK_WIDGET(vbox),
"gnc-id-budget-page");
427 scrolled_window = gtk_scrolled_window_new (NULL, NULL);
428 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(scrolled_window),
429 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
433 gtk_tree_view_set_headers_visible (tree_view, TRUE);
436 state_section = g_strjoin (
" ", STATE_SECTION_PREFIX, guidstr, NULL);
437 g_object_set (G_OBJECT(tree_view),
"state-section", state_section, NULL);
438 g_free (state_section);
441 priv->tree_view = tree_view;
442 selection = gtk_tree_view_get_selection (tree_view);
443 gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
448 gtk_tree_view_column_set_reorderable (name_col, FALSE);
451 priv->fd->tree_view = GNC_TREE_VIEW_ACCOUNT(priv->tree_view);
458 priv->show_account_code = gtk_tree_view_column_get_visible (code_col);
459 gtk_tree_view_column_set_reorderable (code_col, FALSE);
463 priv->show_account_desc = gtk_tree_view_column_get_visible (desc_col);
464 gtk_tree_view_column_set_reorderable (desc_col, FALSE);
467 gtk_container_add (GTK_CONTAINER(scrolled_window), GTK_WIDGET(tree_view));
469 g_object_set (tree_view,
"has-tooltip", TRUE, NULL);
470 g_signal_connect (G_OBJECT(tree_view),
"query-tooltip",
471 G_CALLBACK(query_tooltip_tree_view_cb), budget_view);
472 g_signal_connect (G_OBJECT(tree_view),
"row-activated",
473 G_CALLBACK(gbv_row_activated_cb), budget_view);
476 priv->hadj = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW(scrolled_window));
478 PINFO(
"Number of Created Account columns is %d", gtk_tree_view_get_n_columns (tree_view));
481 g_signal_connect (G_OBJECT(selection),
"changed",
482 G_CALLBACK(gbv_selection_changed_cb), budget_view);
483 g_signal_connect (G_OBJECT(tree_view),
"button-press-event",
484 G_CALLBACK(gbv_button_press_cb), budget_view);
485 gbv_selection_changed_cb (NULL, budget_view);
489 priv->totals_scroll_window = gtk_scrolled_window_new (NULL, NULL);
490 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(priv->totals_scroll_window),
491 GTK_POLICY_AUTOMATIC, GTK_POLICY_NEVER);
493 h_adj = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW(priv->totals_scroll_window));
494 g_signal_connect (G_OBJECT(h_adj),
"value-changed",
495 G_CALLBACK(gbv_totals_scrollbar_value_changed_cb), budget_view);
498 totals_tree_model = gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING);
499 gtk_list_store_append (totals_tree_model, &iter);
500 gtk_list_store_set (totals_tree_model, &iter, 0,
_(
"Income"),
502 gtk_list_store_append (totals_tree_model, &iter);
503 gtk_list_store_set (totals_tree_model, &iter, 0,
_(
"Expenses"),
505 gtk_list_store_append (totals_tree_model, &iter);
506 gtk_list_store_set (totals_tree_model, &iter, 0,
_(
"Transfer"),
508 gtk_list_store_append (totals_tree_model, &iter);
509 gtk_list_store_set (totals_tree_model, &iter, 0,
_(
"Remaining to Budget"),
512 totals_tree_view = GTK_TREE_VIEW(gtk_tree_view_new ());
513 priv->totals_tree_view = totals_tree_view;
514 gtk_tree_selection_set_mode (gtk_tree_view_get_selection (totals_tree_view), GTK_SELECTION_NONE);
515 gtk_tree_view_set_headers_visible (totals_tree_view, FALSE);
516 gtk_tree_view_set_model (totals_tree_view, GTK_TREE_MODEL(totals_tree_model));
517 g_object_unref (totals_tree_model);
520 totals_title_col = gtk_tree_view_column_new_with_attributes (
"", gtk_cell_renderer_text_new (),
"text", 0, NULL);
521 gtk_tree_view_column_set_expand (totals_title_col, TRUE);
522 gtk_tree_view_column_set_sizing (totals_title_col, GTK_TREE_VIEW_COLUMN_FIXED);
523 gtk_tree_view_append_column (totals_tree_view, totals_title_col);
526 code_col = gtk_tree_view_column_new_with_attributes (
"", gtk_cell_renderer_text_new(),
"text", 2, NULL);
527 gtk_tree_view_column_set_sizing (code_col, GTK_TREE_VIEW_COLUMN_FIXED);
528 gtk_tree_view_append_column (totals_tree_view, code_col);
529 gtk_tree_view_column_set_visible (code_col, priv->show_account_code);
532 desc_col = gtk_tree_view_column_new_with_attributes (
"", gtk_cell_renderer_text_new(),
"text", 3, NULL);
533 gtk_tree_view_column_set_sizing (desc_col, GTK_TREE_VIEW_COLUMN_FIXED);
534 gtk_tree_view_append_column (totals_tree_view, desc_col);
535 gtk_tree_view_column_set_visible (desc_col, priv->show_account_desc);
538 gtk_container_add (GTK_CONTAINER(priv->totals_scroll_window), GTK_WIDGET(totals_tree_view));
541 gtk_tree_view_set_grid_lines (GTK_TREE_VIEW(totals_tree_view), gnc_tree_view_get_grid_lines_pref ());
543 gbv_treeview_update_grid_lines, totals_tree_view);
545 gbv_treeview_update_grid_lines, totals_tree_view);
548 priv->use_red_color =
gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_NEGATIVE_IN_RED);
550 gbv_update_use_red, budget_view);
552 PINFO(
"Number of Created totals columns is %d", gtk_tree_view_get_n_columns (totals_tree_view));
554 gtk_box_set_homogeneous (GTK_BOX(vbox), FALSE);
556 gtk_box_pack_start (GTK_BOX(vbox), scrolled_window, TRUE, TRUE, 0);
558 h_separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
559 gtk_box_pack_end (GTK_BOX(vbox), h_separator, FALSE, TRUE, 0);
561 gtk_box_pack_start (GTK_BOX(vbox), GTK_WIDGET(priv->totals_scroll_window), FALSE, TRUE, 0);
563 gtk_widget_show_all (GTK_WIDGET(vbox));
566 h_scrollbar = gtk_scrolled_window_get_hscrollbar (GTK_SCROLLED_WINDOW(scrolled_window));
567 gtk_widget_hide (h_scrollbar);
569 g_signal_connect (G_OBJECT(tree_view),
"size-allocate",
570 G_CALLBACK(gbv_treeview_resized_cb), budget_view);
573 gnc_tree_view_account_restore_filter (GNC_TREE_VIEW_ACCOUNT(priv->tree_view),
577 GNC_TREE_VIEW(priv->tree_view)));
580 g_signal_connect (G_OBJECT(gtk_tree_view_get_model (GTK_TREE_VIEW(tree_view))),
"row-changed",
581 G_CALLBACK(gbv_tree_view_model_row_changed_cb), budget_view);
586#define BUDGET_GUID "Budget GncGUID"
600gnc_budget_view_save (GncBudgetView *budget_view, GKeyFile *key_file,
const gchar *group_name)
604 g_return_if_fail (budget_view != NULL);
605 g_return_if_fail (key_file != NULL);
606 g_return_if_fail (group_name != NULL);
608 ENTER(
"view %p, key_file %p, group_name %s", budget_view, key_file, group_name);
610 priv = GNC_BUDGET_VIEW_GET_PRIVATE(budget_view);
613 gnc_tree_view_account_save (GNC_TREE_VIEW_ACCOUNT(priv->tree_view),
614 priv->fd, key_file, group_name);
633gnc_budget_view_restore (GncBudgetView *budget_view, GKeyFile *key_file,
const gchar *group_name)
636 GError *error = NULL;
643 g_return_val_if_fail (key_file, FALSE);
644 g_return_val_if_fail (group_name, FALSE);
646 ENTER(
"key_file %p, group_name %s", key_file, group_name);
648 guid_str = g_key_file_get_string (key_file, group_name, BUDGET_GUID,
652 g_warning (
"error reading group %s key %s: %s",
653 group_name, BUDGET_GUID, error->message);
654 g_error_free (error);
658 has_guid = string_to_guid (guid_str, &guid);
667 bgt = gnc_budget_lookup (&guid, book);
674 priv = GNC_BUDGET_VIEW_GET_PRIVATE(budget_view);
677 gnc_tree_view_account_restore (GNC_TREE_VIEW_ACCOUNT(priv->tree_view),
678 priv->fd, key_file, group_name);
691gnc_budget_view_delete_budget (GncBudgetView *budget_view)
696 g_return_if_fail (budget_view != NULL);
698 ENTER(
"view %p", budget_view);
700 priv = GNC_BUDGET_VIEW_GET_PRIVATE(budget_view);
704 g_object_set (G_OBJECT(priv->tree_view),
"state-section", NULL, NULL);
715gnc_budget_view_save_account_filter (GncBudgetView *budget_view)
719 g_return_if_fail (budget_view != NULL);
721 ENTER(
"view %p", budget_view);
723 priv = GNC_BUDGET_VIEW_GET_PRIVATE(budget_view);
726 gnc_tree_view_account_save_filter (GNC_TREE_VIEW_ACCOUNT(priv->tree_view),
729 GNC_TREE_VIEW(priv->tree_view)));
744gbv_button_press_cb (GtkWidget *widget, GdkEventButton *event,
745 GncBudgetView *budget_view)
749 g_return_val_if_fail (budget_view != NULL, FALSE);
751 ENTER(
"widget %p, event %p, page %p", widget, event, page);
763gbv_key_press_cb (GtkWidget *widget, GdkEventKey *event, gpointer user_data)
765 GtkTreeViewColumn *col;
766 GtkTreePath *path = NULL;
768 GtkTreeView *tv = priv->tree_view;
770 gint period_num, num_periods;
773 if (event->type != GDK_KEY_PRESS || !priv->temp_cr)
776 switch (event->keyval)
778 case GDK_KEY_KP_Decimal:
779 if (event->keyval == GDK_KEY_KP_Decimal)
781 struct lconv *lc = gnc_localeconv ();
782 event->keyval = lc->mon_decimal_point[0];
783 event->string[0] = lc->mon_decimal_point[0];
787 case GDK_KEY_ISO_Left_Tab:
789 shifted =
event->state & GDK_SHIFT_MASK;
790 gtk_tree_view_get_cursor (tv, &path, &col);
793 data = g_object_get_data (G_OBJECT(col),
"period_num");
794 period_num = GPOINTER_TO_UINT(data);
795 num_periods = gnc_budget_get_num_periods (priv->budget);
797 if (period_num >= num_periods)
798 period_num = num_periods - 1;
805 if (period_num >= num_periods)
808 if (gtk_tree_view_row_expanded (tv, path))
810 gtk_tree_path_down (path);
814 gtk_tree_path_next (path);
815 while (!gnc_tree_view_path_is_valid (GNC_TREE_VIEW(tv), path) &&
816 gtk_tree_path_get_depth (path) > 1)
818 gtk_tree_path_up (path);
819 gtk_tree_path_next (path);
823 else if (period_num < 0)
825 period_num = num_periods - 1;
826 if (!gtk_tree_path_prev (path))
827 gtk_tree_path_up (path);
830 while (gtk_tree_view_row_expanded (tv, path))
832 gtk_tree_path_down (path);
835 gtk_tree_path_next (path);
837 gnc_tree_view_path_is_valid (GNC_TREE_VIEW(tv), path));
838 gtk_tree_path_prev (path);
843 col = g_list_nth_data (priv->period_col_list, period_num);
848 gtk_cell_editable_editing_done (priv->temp_ce);
849 gtk_cell_editable_remove_widget (priv->temp_ce);
851 while (gtk_events_pending())
852 gtk_main_iteration ();
855 if (gnc_tree_view_path_is_valid (GNC_TREE_VIEW(tv), path))
856 gtk_tree_view_set_cursor (tv, path, col, TRUE);
857 gtk_tree_path_free (path);
869gbv_treeview_resized_cb (GtkWidget *widget, GtkAllocation *allocation,
870 GncBudgetView *budget_view)
873 GList *columns = gtk_tree_view_get_columns (GTK_TREE_VIEW(priv->tree_view));
874 GList *total_columns = gtk_tree_view_get_columns (GTK_TREE_VIEW (priv->totals_tree_view));
878 for (GList *node = columns, *total_node = total_columns;
879 node; node = g_list_next (node))
881 GtkTreeViewColumn *tree_view_col = node->data;
882 const gchar *name = g_object_get_data (G_OBJECT(tree_view_col), PREF_NAME);
885 if ((g_strcmp0 (name,
"account-code") == 0) && (!priv->show_account_code))
886 total_node = g_list_next (total_node);
890 if ((g_strcmp0 (name,
"description") == 0) && (!priv->show_account_desc))
891 total_node = g_list_next (total_node);
893 if (gtk_tree_view_column_get_visible (tree_view_col) && total_node != NULL)
895 gint col_width = gtk_tree_view_column_get_width (tree_view_col);
896 GtkTreeViewColumn *totals_view_col = total_node->data;
897 if (GTK_IS_TREE_VIEW_COLUMN(totals_view_col))
898 gtk_tree_view_column_set_fixed_width (totals_view_col, col_width);
899 total_node = g_list_next (total_node);
904 g_list_free (columns);
905 g_list_free (total_columns);
912gbv_row_activated_cb (GtkTreeView *treeview, GtkTreePath *path,
913 GtkTreeViewColumn *col, GncBudgetView *budget_view)
917 g_return_if_fail (GNC_IS_BUDGET_VIEW(budget_view));
920 GNC_TREE_VIEW_ACCOUNT(treeview), path);
924 g_signal_emit_by_name (budget_view,
"account-activated", account);
928query_tooltip_tree_view_cb (GtkWidget *widget, gint x, gint y,
929 gboolean keyboard_tip, GtkTooltip *tooltip,
932 GtkTreeView *tree_view = GTK_TREE_VIEW(widget);
934 GtkTreePath *path = NULL;
935 GtkTreeViewColumn *column = NULL;
940 gtk_tree_view_convert_widget_to_bin_window_coords (tree_view, x, y, &x, &y);
942 if (keyboard_tip || !gtk_tree_view_get_path_at_pos (tree_view, x, y, &path,
943 &column, NULL, NULL))
945 gtk_tree_path_free (path);
951 gtk_tree_path_free (path);
955 period_num = GPOINTER_TO_UINT(g_object_get_data (G_OBJECT(column),
"period_num"));
956 if (!period_num && priv->period_col_list->data != column)
958 gtk_tree_path_free (path);
962 GNC_TREE_VIEW_ACCOUNT(widget), path);
963 note = gnc_budget_get_account_period_note (priv->budget, account, period_num);
966 gtk_tree_path_free (path);
970 gtk_tooltip_set_text (tooltip, note);
971 gtk_tree_view_set_tooltip_cell (tree_view, tooltip, path, column, NULL);
972 gtk_tree_path_free (path);
981gbv_selection_changed_cb (GtkTreeSelection *selection, GncBudgetView *budget_view)
983 GtkTreeView *tree_view;
991 g_return_if_fail (GTK_IS_TREE_SELECTION(selection));
992 tree_view = gtk_tree_selection_get_tree_view (selection);
994 GNC_TREE_VIEW_ACCOUNT(tree_view));
997 sensitive = (g_list_length (acct_list) > 0);
998 g_list_free (acct_list);
1016 gnc_commodity *total_currency;
1024budget_accum_helper (
Account *account, gpointer data)
1028 gnc_commodity *currency;
1032 if (gnc_budget_is_account_period_value_set (info->budget, account, info->period_num))
1034 numeric = gnc_budget_get_account_period_value (info->budget, account,
1037 info->pdb,
numeric, currency, info->total_currency,
1044 numeric = gbv_get_accumulated_budget_amount (info->budget, account,
1047 info->pdb,
numeric, currency, info->total_currency,
1060gbv_get_accumulated_budget_amount (GncBudget *budget,
Account *account, guint period_num)
1064 info.total = gnc_numeric_zero ();
1065 info.budget = budget;
1066 info.period_num = period_num;
1070 if (!gnc_budget_is_account_period_value_set (budget, account, period_num))
1073 info.total = gnc_budget_get_account_period_value (budget, account, period_num);
1087budget_col_source (
Account *account, GtkTreeViewColumn *col,
1088 GtkCellRenderer *cell)
1090 GncBudgetView *budget_view;
1097 budget_view = GNC_BUDGET_VIEW(g_object_get_data (G_OBJECT(col),
"budget_view"));
1098 period_num = GPOINTER_TO_UINT(g_object_get_data (G_OBJECT(col),
"period_num"));
1100 priv = GNC_BUDGET_VIEW_GET_PRIVATE(budget_view);
1102 if (!gnc_budget_is_account_period_value_set (priv->budget, account, period_num))
1109 GtkStyleContext *stylectxt = gtk_widget_get_style_context (GTK_WIDGET(priv->tree_view));
1110 gtk_style_context_get_color (stylectxt, GTK_STATE_FLAG_NORMAL, &color);
1112 numeric = gbv_get_accumulated_budget_amount (priv->budget, account, period_num);
1114 if (gnc_reverse_balance (account))
1119 g_object_set (cell,
"foreground",
1125 g_object_set (cell,
"foreground",
1134 numeric = gnc_budget_get_account_period_value (priv->budget, account,
1136 if (gnc_numeric_check (
numeric))
1137 strcpy (amtbuff,
"error");
1140 if (gnc_reverse_balance (account))
1144 gnc_account_print_info (account, FALSE));
1148 gchar *color = gnc_get_negative_color ();
1149 g_object_set (cell,
"foreground", color, NULL);
1153 g_object_set (cell,
"foreground", NULL, NULL);
1157 note = gnc_budget_get_account_period_note (priv->budget, account, period_num);
1158 g_object_set (cell,
"flagged", note != NULL, NULL);
1160 return g_strdup (amtbuff);
1167bgv_get_total_for_account (
Account *account, GncBudget *budget, gnc_commodity *new_currency)
1172 gnc_numeric total = gnc_numeric_zero ();
1174 gnc_commodity *currency;
1182 num_periods = gnc_budget_get_num_periods (budget);
1183 for (period_num = 0; period_num < num_periods; ++period_num)
1185 if (!gnc_budget_is_account_period_value_set (budget, account, period_num))
1189 numeric = gbv_get_accumulated_budget_amount (budget, account, period_num);
1194 pdb,
numeric, currency, new_currency,
1202 numeric = gnc_budget_get_account_period_value (budget, account, period_num);
1203 if (!gnc_numeric_check (
numeric))
1208 pdb,
numeric, currency, new_currency,
1222budget_total_col_source (
Account *account, GtkTreeViewColumn *col,
1223 GtkCellRenderer *cell)
1225 GncBudgetView *budget_view;
1230 budget_view = GNC_BUDGET_VIEW(g_object_get_data (G_OBJECT(col),
"budget_view"));
1231 priv = GNC_BUDGET_VIEW_GET_PRIVATE(budget_view);
1233 total = bgv_get_total_for_account (account, priv->budget, NULL);
1234 if (gnc_reverse_balance (account))
1241 gchar *color = gnc_get_negative_color ();
1242 g_object_set (cell,
"foreground", color, NULL);
1246 g_object_set (cell,
"foreground", NULL, NULL);
1248 return g_strdup (amtbuff);
1259budget_col_edited (
Account *account, GtkTreeViewColumn *col,
1260 const gchar *new_text)
1262 GncBudgetView *budget_view;
1271 !(new_text && *new_text ==
'\0'))
1274 period_num = GPOINTER_TO_UINT(g_object_get_data (G_OBJECT(col),
"period_num"));
1276 budget_view = GNC_BUDGET_VIEW(g_object_get_data (G_OBJECT(col),
"budget_view"));
1277 priv = GNC_BUDGET_VIEW_GET_PRIVATE(budget_view);
1279 if (new_text && *new_text ==
'\0')
1280 gnc_budget_unset_account_period_value (priv->budget, account, period_num);
1283 if (gnc_reverse_balance (account))
1285 gnc_budget_set_account_period_value (priv->budget, account, period_num,
1303totals_col_source (GtkTreeViewColumn *col, GtkCellRenderer *cell,
1304 GtkTreeModel *s_model, GtkTreeIter *s_iter,
1307 gnc_numeric total = gnc_numeric_zero ();
1308 GncBudgetView *budget_view = GNC_BUDGET_VIEW(user_data);
1310 gint period_num = GPOINTER_TO_INT(g_object_get_data (G_OBJECT(col),
"period_num"));
1316 gtk_tree_model_get (s_model, s_iter, 1, &row_type, -1);
1320 for (GList *node = top_level_accounts; node; node = g_list_next (node))
1322 Account *account = node->data;
1329 (acctype == ACCT_TYPE_ASSET || acctype == ACCT_TYPE_LIABILITY ||
1330 acctype == ACCT_TYPE_EQUITY)))
1335 value = bgv_get_total_for_account (account, priv->budget, total_currency);
1339 value = gbv_get_accumulated_budget_amount
1340 (priv->budget, account, period_num);
1343 (pdb, value, currency, total_currency,
1353 GNCPrintAmountInfo pinfo = gnc_commodity_print_info (total_currency, period_num < 0);
1355 gnc_get_negative_color () : NULL;
1357 g_object_set (G_OBJECT(cell),
1360 "foreground", color,
1364 g_list_free (top_level_accounts);
1373gbv_refresh_col_titles (GncBudgetView *budget_view)
1377 GDate date, nextdate;
1380 g_return_if_fail (budget_view != NULL);
1381 priv = GNC_BUDGET_VIEW_GET_PRIVATE(budget_view);
1384 r = gnc_budget_get_recurrence (priv->budget);
1386 for (GList *node = priv->period_col_list; node; node = g_list_next (node))
1388 GtkTreeViewColumn *col = GTK_TREE_VIEW_COLUMN (node->data);
1392 gtk_tree_view_column_set_title (col, title);
1394 recurrenceNextInstance (r, &date, &nextdate);
1400gbv_renderer_add_padding (GtkCellRenderer *renderer)
1404 gtk_cell_renderer_get_padding (renderer, &xpad, &ypad);
1406 gtk_cell_renderer_set_padding (renderer, 5, ypad);
1411static GtkTreeViewColumn*
1412gbv_create_totals_column (GncBudgetView *budget_view, gint period_num)
1414 GtkTreeViewColumn *col;
1415 GtkCellRenderer* renderer;
1417 g_return_val_if_fail (budget_view != NULL, NULL);
1419 renderer = gtk_cell_renderer_text_new ();
1420 col = gtk_tree_view_column_new_with_attributes (
"", renderer, NULL);
1423 gbv_renderer_add_padding (renderer);
1425 gtk_tree_view_column_set_cell_data_func (col, renderer, totals_col_source, budget_view, NULL);
1426 g_object_set_data (G_OBJECT(col),
"budget_view", budget_view);
1427 g_object_set_data (G_OBJECT(col),
"period_num", GUINT_TO_POINTER(period_num));
1428 gtk_tree_view_column_set_sizing (col, GTK_TREE_VIEW_COLUMN_FIXED);
1438gbv_col_edited_cb (GtkCellRendererText *cell, gchar *path_string,
1439 gchar *new_text, gpointer user_data)
1441 GncBudgetView *budget_view = GNC_BUDGET_VIEW(user_data);
1444 gtk_widget_queue_draw (GTK_WIDGET(priv->totals_tree_view));
1450gdv_editing_started_cb (GtkCellRenderer *cr, GtkCellEditable *editable,
1451 const gchar *path_string, gpointer user_data)
1456 priv->temp_ce = editable;
1458 g_signal_connect (G_OBJECT(editable),
"key-press-event",
1459 G_CALLBACK(gbv_key_press_cb), user_data);
1463gdv_editing_canceled_cb (GtkCellRenderer *cr, gpointer user_data)
1467 priv->temp_cr = NULL;
1468 priv->temp_ce = NULL;
1482 description_column = 2,
1483 startPeriods_column = 3
1489 gint num_periods_visible;
1490 GtkTreeViewColumn *col, *code_col, *desc_col;
1492 GList *totals_col_list;
1493 GdkRGBA *note_color, *note_color_selected;
1494 GtkStyleContext *stylectxt;
1496 ENTER(
"view %p", budget_view);
1498 g_return_if_fail (budget_view != NULL);
1499 priv = GNC_BUDGET_VIEW_GET_PRIVATE(budget_view);
1501 stylectxt = gtk_widget_get_style_context (GTK_WIDGET(priv->tree_view));
1502 gtk_style_context_get (stylectxt, GTK_STATE_FLAG_SELECTED,
"background-color", ¬e_color, NULL);
1503 gtk_style_context_get (stylectxt, GTK_STATE_FLAG_NORMAL,
"background-color", ¬e_color_selected, NULL);
1505 num_periods = gnc_budget_get_num_periods (priv->budget);
1507 col_list = g_list_reverse (priv->period_col_list);
1508 totals_col_list = g_list_reverse (priv->totals_col_list);
1509 num_periods_visible = g_list_length (col_list);
1512 while (num_periods_visible > num_periods)
1514 col = GTK_TREE_VIEW_COLUMN (col_list->data);
1515 gtk_tree_view_remove_column (GTK_TREE_VIEW(priv->tree_view), col);
1516 col_list = g_list_delete_link (col_list, col_list);
1517 num_periods_visible--;
1519 col = GTK_TREE_VIEW_COLUMN(totals_col_list->data);
1520 gtk_tree_view_remove_column (GTK_TREE_VIEW(priv->totals_tree_view), col);
1521 totals_col_list = g_list_delete_link (totals_col_list, totals_col_list);
1528 gtk_tree_view_column_set_visible (code_col, priv->show_account_code);
1529 code_col = gtk_tree_view_get_column (GTK_TREE_VIEW(priv->totals_tree_view), code_column);
1530 gtk_tree_view_column_set_visible (code_col, priv->show_account_code);
1534 gtk_tree_view_column_set_visible (desc_col, priv->show_account_desc);
1535 desc_col = gtk_tree_view_get_column (GTK_TREE_VIEW(priv->totals_tree_view), description_column);
1536 gtk_tree_view_column_set_visible (desc_col, priv->show_account_desc);
1541 if (num_periods_visible != 0 && num_periods > num_periods_visible)
1544 col = priv->total_col;
1545 gtk_tree_view_remove_column (GTK_TREE_VIEW(priv->tree_view), col);
1546 priv->total_col = NULL;
1547 col = gtk_tree_view_get_column (GTK_TREE_VIEW(priv->totals_tree_view),
1548 startPeriods_column + num_periods_visible);
1549 gtk_tree_view_remove_column (GTK_TREE_VIEW(priv->totals_tree_view), col);
1553 while (num_periods_visible < num_periods)
1555 GtkCellRenderer *renderer = gnc_cell_renderer_text_flag_new ();
1556 g_object_set (renderer,
"flag-color-rgba", note_color, NULL);
1557 g_object_set (renderer,
"flag-color-rgba-selected", note_color_selected, NULL);
1559 col = gnc_tree_view_account_add_custom_column_renderer (
1560 GNC_TREE_VIEW_ACCOUNT(priv->tree_view),
"",
1561 budget_col_source, budget_col_edited, renderer);
1562 g_object_set_data (G_OBJECT(col),
"budget_view", budget_view);
1563 g_object_set_data (G_OBJECT(col),
"period_num", GUINT_TO_POINTER(num_periods_visible));
1564 col_list = g_list_prepend (col_list, col);
1567 gbv_renderer_add_padding (renderer);
1569 g_signal_connect (G_OBJECT(renderer),
"edited", (GCallback)gbv_col_edited_cb, budget_view);
1570 g_signal_connect (G_OBJECT(renderer),
"editing-started",
1571 (GCallback)gdv_editing_started_cb, budget_view);
1572 g_signal_connect (G_OBJECT(renderer),
"editing-canceled",
1573 (GCallback)gdv_editing_canceled_cb, budget_view);
1574 col = gbv_create_totals_column (budget_view, num_periods_visible);
1577 gtk_tree_view_append_column (priv->totals_tree_view, col);
1578 totals_col_list = g_list_prepend (totals_col_list, col);
1581 num_periods_visible++;
1584 gdk_rgba_free (note_color);
1585 gdk_rgba_free (note_color_selected);
1587 priv->period_col_list = g_list_reverse (col_list);
1588 priv->totals_col_list = g_list_reverse (totals_col_list);
1590 if (priv->total_col == NULL)
1595 GtkCellRenderer* renderer;
1598 GNC_TREE_VIEW_ACCOUNT(priv->tree_view), _(
"Total"),
1599 budget_total_col_source, NULL);
1602 gtk_tree_view_column_set_alignment (priv->total_col, 1.0);
1605 date = g_date_new_dmy (31, 12, 2018);
1609 PangoLayout *layout = gtk_widget_create_pango_layout (GTK_WIDGET(budget_view), title);
1610 PangoRectangle logical_rect;
1611 pango_layout_set_width (layout, -1);
1612 pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
1613 g_object_unref (layout);
1615 gtk_tree_view_column_set_min_width (priv->total_col, logical_rect.width);
1618 g_object_set_data (G_OBJECT(priv->total_col),
"budget_view", budget_view);
1624 gbv_renderer_add_padding (renderer);
1626 col = gbv_create_totals_column (budget_view, -1);
1628 gtk_tree_view_append_column (priv->totals_tree_view, col);
1630 gbv_refresh_col_titles (budget_view);
1632 PINFO(
"Number of columns is %d, totals columns is %d",
1633 gtk_tree_view_get_n_columns (priv->tree_view), gtk_tree_view_get_n_columns (priv->totals_tree_view));
Utility functions for file access.
Gnome specific utility functions.
Functions for adding content to a window.
Generic api to store and retrieve preferences.
Functions to load, save and get gui state.
GtkTreeModel implementation to display account types in a GtkTreeView.
GtkTreeView implementation for gnucash account tree.
utility functions for the GnuCash UI
GNCAccountType
The account types are used to determine how the transaction data in the account is displayed.
gnc_commodity * gnc_account_get_currency_or_parent(const Account *account)
Returns a gnc_commodity that is a currency, suitable for being a Transaction's currency.
GNCAccountType xaccAccountGetType(const Account *acc)
Returns the account's account type.
GList * gnc_account_get_children(const Account *account)
This routine returns a GList of all children accounts of the specified account.
void gnc_account_foreach_child(const Account *acc, AccountCb thunk, gpointer user_data)
This method will traverse the immediate children of this accounts, calling 'func' on each account.
gint gnc_account_n_children(const Account *account)
Return the number of children of the specified account.
QofBook * qof_session_get_book(const QofSession *session)
Returns the QofBook of this session.
gboolean qof_book_is_readonly(const QofBook *book)
Return whether the book is read only.
#define MAX_DATE_LENGTH
The maximum length of a string created by the date printers.
size_t qof_print_gdate(char *buf, size_t len, const GDate *gd)
Convenience; calls through to qof_print_date_dmy_buff().
GNCAccountType xaccAccountTypeGetFundamental(GNCAccountType t)
Convenience function to return the fundamental type asset/liability/income/expense/equity given an ac...
#define GUID_ENCODING_LENGTH
Number of characters needed to encode a guid as a string not including the null terminator.
gchar * guid_to_string_buff(const GncGUID *guid, gchar *str)
The guid_to_string_buff() routine puts a null-terminated string encoding of the id into the memory po...
gboolean gnc_main_window_button_press_cb(GtkWidget *whatever, GdkEventButton *event, GncPluginPage *page)
Callback function invoked when the user clicks in the content of any Gnucash window.
gint gnc_state_drop_sections_for(const gchar *partial_name)
Drop all sections from the state file whose name contains partial_name.
GKeyFile * gnc_state_get_current(void)
Returns a pointer to the most recently loaded state.
void gnc_tree_view_configure_columns(GncTreeView *view)
Make all the correct columns visible, respecting their default visibility setting,...
GtkCellRenderer * gnc_tree_view_column_get_renderer(GtkTreeViewColumn *column)
Return the "main" cell renderer from a GtkTreeViewColumn added to a GncTreeView my one of the conveni...
const gchar * gnc_tree_view_get_state_section(GncTreeView *view)
Get the name of the state section this tree view is associated with.
void gnc_tree_view_expand_columns(GncTreeView *view, gchar *first_column_name,...)
This function set the columns that will be allocated the free space in the view.
GtkTreeViewColumn * gnc_tree_view_find_column_by_name(GncTreeView *view, const gchar *wanted)
Find a tree column given the "pref name" used with saved state.
gboolean gnc_is_dark_theme(GdkRGBA *fg_color)
Return whether the current gtk theme is a dark one.
GList * gnc_tree_view_account_get_selected_accounts(GncTreeViewAccount *view)
This function returns a list of the accounts associated with the selected items in the account tree v...
Account * gnc_tree_view_account_get_account_from_path(GncTreeViewAccount *view, GtkTreePath *s_path)
This function returns the account associated with the specified path.
GtkTreeView * gnc_tree_view_account_new(gboolean show_root)
Create a new account tree view.
gboolean gnc_plugin_page_account_tree_filter_accounts(Account *account, gpointer user_data)
This function tells the account tree view whether or not to filter out a particular account.
GtkTreeViewColumn * gnc_tree_view_account_add_custom_column(GncTreeViewAccount *account_view, const gchar *column_title, GncTreeViewAccountColumnSource col_source_cb, GncTreeViewAccountColumnTextEdited col_edited_cb)
Add a new custom column to the set of columns in an account tree view.
void gnc_tree_view_account_set_filter(GncTreeViewAccount *view, gnc_tree_view_account_filter_func func, gpointer data, GSourceFunc destroy)
This function attaches a filter function to the given account tree.
int xaccSPrintAmount(char *bufp, gnc_numeric val, GNCPrintAmountInfo info)
Make a string representation of a gnc_numeric.
const char * xaccPrintAmount(gnc_numeric val, GNCPrintAmountInfo info)
Make a string representation of a gnc_numeric.
gnc_commodity * gnc_default_currency(void)
Return the default currency set by the user.
gboolean xaccParseAmount(const char *in_str, gboolean monetary, gnc_numeric *result, char **endstr)
Parses in_str to obtain a numeric result.
#define PINFO(format, args...)
Print an informational note.
#define LEAVE(format, args...)
Print a function exit debugging message.
#define ENTER(format, args...)
Print a function entry debugging message.
#define GNC_DENOM_AUTO
Values that can be passed as the 'denom' argument.
gnc_numeric gnc_numeric_error(GNCNumericErrorCode error_code)
Create a gnc_numeric object that signals the error condition noted by error_code, rather than a numbe...
gboolean gnc_numeric_negative_p(gnc_numeric a)
Returns 1 if a < 0, otherwise returns 0.
gnc_numeric gnc_numeric_neg(gnc_numeric a)
Returns a newly created gnc_numeric that is the negative of the given gnc_numeric value.
gnc_numeric gnc_numeric_add(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Return a+b.
@ GNC_ERROR_ARG
Argument is not a valid number.
void gnc_prefs_remove_cb_by_func(const gchar *group, const gchar *pref_name, gpointer func, gpointer user_data)
Remove a function that was registered for a callback when the given preference changed.
gulong gnc_prefs_register_cb(const char *group, const gchar *pref_name, gpointer func, gpointer user_data)
Register a callback that gets triggered when the given preference changes.
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Get a boolean value from the preferences backend.
gnc_numeric gnc_pricedb_convert_balance_nearest_price_t64(GNCPriceDB *pdb, gnc_numeric balance, const gnc_commodity *balance_currency, const gnc_commodity *new_currency, time64 t)
Convert a balance from one currency to another using the price nearest to the given time.
GNCPriceDB * gnc_pricedb_get_db(QofBook *book)
Return the pricedb associated with the book.
void gnc_budget_view_refresh(GncBudgetView *budget_view)
refreshes the current budget view
GtkTreeSelection * gnc_budget_view_get_selection(GncBudgetView *budget_view)
returns the current selection in the gnc budget view.
time64 gnc_budget_get_period_start_date(const GncBudget *budget, guint period_num)
Get the starting date of the Budget period.
GncBudgetView * gnc_budget_view_new(GncBudget *budget, AccountFilterDialog *fd)
Create new gnc budget view.
@ TOTALS_TYPE_REMAINDER
This total is Remaining to Budget.
@ TOTALS_TYPE_ASSET_LIAB_EQ
This total is Asset/Liab/Equity type.
@ TOTALS_TYPE_EXPENSES
This total is Expenses type.
@ TOTALS_TYPE_INCOME
This total is Income type.
Action for when a selection in a gnc budget view is changed.
the private budget view structure
The type used to store guids in C.