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" 59 #include "gnc-icons.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" 80 static QofLogModule log_module = GNC_MOD_BUDGET;
82 #define PLUGIN_PAGE_BUDGET_CM_CLASS "budget-view" 83 #define STATE_SECTION_PREFIX "Budget" 116 static void gnc_budget_view_finalize (GObject *
object);
118 static void gbv_create_widget (GncBudgetView *budget_view);
120 static gboolean gbv_button_press_cb (GtkWidget *widget, GdkEventButton *event,
121 GncBudgetView *budget_view);
123 static gboolean gbv_key_press_cb (GtkWidget *treeview, GdkEventKey *event,
125 static void gbv_row_activated_cb (GtkTreeView *treeview, GtkTreePath *path,
126 GtkTreeViewColumn *col, GncBudgetView *budget_view);
127 static gboolean query_tooltip_tree_view_cb (GtkWidget *widget, gint x, gint y,
128 gboolean keyboard_tip,
130 GncBudgetView *budget_view);
132 static void gbv_selection_changed_cb (GtkTreeSelection *selection,
133 GncBudgetView *budget_view);
135 static void gbv_treeview_resized_cb (GtkWidget *widget, GtkAllocation *allocation,
136 GncBudgetView *budget_view);
137 static 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;
178 G_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);
212 gnc_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);
223 gnc_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());
240 gbv_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 ());
247 gnc_budget_view_set_show_account_code (GncBudgetView *budget_view, gboolean show_account_code)
250 priv->show_account_code = show_account_code;
255 gnc_budget_view_get_show_account_code (GncBudgetView *budget_view)
258 return priv->show_account_code;
262 gnc_budget_view_set_show_account_description (GncBudgetView *budget_view, gboolean show_account_desc)
265 priv->show_account_desc = show_account_desc;
270 gnc_budget_view_get_show_account_description (GncBudgetView *budget_view)
273 return priv->show_account_desc;
277 gbv_update_use_red (gpointer prefs, gchar *pref, gpointer user_data)
279 GncBudgetView *budget_view = user_data;
283 GNC_PREF_NEGATIVE_IN_RED);
287 gnc_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));
329 gnc_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);
340 gnc_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);
351 gnc_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);
362 gbv_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));
373 gbv_totals_tree_view_redraw_idle (GtkTreeView *view)
375 gtk_widget_queue_draw (GTK_WIDGET(view));
380 gbv_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);
403 gbv_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" 600 gnc_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);
633 gnc_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);
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);
691 gnc_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);
715 gnc_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)));
744 gbv_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);
763 gbv_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);
869 gbv_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);
912 gbv_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);
928 query_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);
981 gbv_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;
1024 budget_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,
1060 gbv_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);
1087 budget_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,
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);
1167 bgv_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);
1208 pdb,
numeric, currency, new_currency,
1222 budget_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);
1259 budget_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,
1303 totals_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;
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);
1373 gbv_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);
1400 gbv_renderer_add_padding (GtkCellRenderer *renderer)
1404 gtk_cell_renderer_get_padding (renderer, &xpad, &ypad);
1406 gtk_cell_renderer_set_padding (renderer, 5, ypad);
1411 static GtkTreeViewColumn*
1412 gbv_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);
1438 gbv_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));
1450 gdv_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);
1463 gdv_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));
Functions to load, save and get gui state.
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.
gboolean xaccParseAmount(const char *in_str, gboolean monetary, gnc_numeric *result, char **endstr)
Parses in_str to obtain a numeric result.
GNCAccountType xaccAccountTypeGetFundamental(GNCAccountType t)
Convenience function to return the fundamental type asset/liability/income/expense/equity given an ac...
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.
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.
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...
This total is Asset/Liab/Equity type.
utility functions for the GnuCash UI
Expense accounts are used to denote expenses.
#define PINFO(format, args...)
Print an informational note.
GNCAccountType xaccAccountGetType(const Account *acc)
Returns the account's account type.
gnc_numeric gnc_numeric_neg(gnc_numeric a)
Returns a newly created gnc_numeric that is the negative of the given gnc_numeric value...
gint gnc_state_drop_sections_for(const gchar *partial_name)
Drop all sections from the state file whose name contains partial_name.
size_t qof_print_gdate(char *buf, size_t bufflen, const GDate *gd)
Convenience; calls through to qof_print_date_dmy_buff().
gboolean string_to_guid(const gchar *string, GncGUID *guid)
Given a string, replace the given guid with the parsed one unless the given value is null...
const char * xaccPrintAmount(gnc_numeric val, GNCPrintAmountInfo info)
Make a string representation of a gnc_numeric.
gnc_numeric gnc_numeric_add(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Return a+b.
gboolean gnc_is_dark_theme(GdkRGBA *fg_color)
Return whether the current gtk theme is a dark one.
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...
GtkTreeSelection * gnc_budget_view_get_selection(GncBudgetView *budget_view)
returns the current selection in the gnc budget 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.
#define ENTER(format, args...)
Print a function entry debugging message.
GKeyFile * gnc_state_get_current(void)
Returns a pointer to the most recently loaded state.
GNCPriceDB * gnc_pricedb_get_db(QofBook *book)
Return the pricedb associated with the book.
Functions for adding content to a window.
gboolean gnc_numeric_negative_p(gnc_numeric a)
Returns 1 if a < 0, otherwise returns 0.
gnc_commodity * gnc_default_currency(void)
Return the default currency set by the user.
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.
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...
QofBook * qof_session_get_book(const QofSession *session)
Returns the QofBook of this session.
Find the least common multiple of the arguments' denominators and use that as the denominator of the ...
GtkTreeView implementation for gnucash account tree.
time64 gnc_budget_get_period_start_date(const GncBudget *budget, guint period_num)
Get the starting date of the Budget period.
Income accounts are used to denote income.
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...
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.
#define GUID_ENCODING_LENGTH
Number of characters needed to encode a guid as a string not including the null terminator.
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...
GncBudgetView * gnc_budget_view_new(GncBudget *budget, AccountFilterDialog *fd)
Create new gnc budget view.
GtkTreeView * gnc_tree_view_account_new(gboolean show_root)
Create a new account 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.
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...
Argument is not a valid number.
Account * gnc_tree_view_account_get_account_from_path(GncTreeViewAccount *view, GtkTreePath *s_path)
This function returns the account associated with the specified path.
the private budget view structure
This total is Remaining to Budget.
Gnome specific utility functions.
#define MAX_DATE_LENGTH
The maximum length of a string created by the date printers.
asset (and liability) accounts indicate generic, generalized accounts that are none of the above...
gint gnc_account_n_children(const Account *account)
Return the number of children of the specified account.
int xaccSPrintAmount(char *bufp, gnc_numeric val, GNCPrintAmountInfo info)
Make a string representation of a gnc_numeric.
GNCAccountType
The account types are used to determine how the transaction data in the account is displayed...
Action for when a selection in a gnc budget view is changed.
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.
GtkTreeModel implementation to display account types in a GtkTreeView.
const gchar * gnc_tree_view_get_state_section(GncTreeView *view)
Get the name of the state section this tree view is associated with.
This total is Income type.
Generic api to store and retrieve preferences.
gboolean qof_book_is_readonly(const QofBook *book)
Return whether the book is read only.
liability (and asset) accounts indicate generic, generalized accounts that are none of the above...
GList * gnc_account_get_children(const Account *account)
This routine returns a GList of all children accounts of the specified account.
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...
#define LEAVE(format, args...)
Print a function exit debugging message.
GNCNumericErrorCode gnc_numeric_check(gnc_numeric in)
Check for error signal in value.
Equity account is used to balance the balance sheet.
#define GNC_DENOM_AUTO
Values that can be passed as the 'denom' argument.
The type used to store guids in C.
void gnc_budget_view_refresh(GncBudgetView *budget_view)
refreshes the current budget view
This total is Expenses type.
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.
Utility functions for file access.