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)
778 if (event->hardware_keycode == VK_DECIMAL)
779 event->keyval = GDK_KEY_KP_Decimal;
782 switch (event->keyval)
784 case GDK_KEY_KP_Decimal:
785 if (event->keyval == GDK_KEY_KP_Decimal)
787 struct lconv *lc = gnc_localeconv ();
788 event->keyval = lc->mon_decimal_point[0];
789 event->string[0] = lc->mon_decimal_point[0];
793 case GDK_KEY_ISO_Left_Tab:
795 shifted =
event->state & GDK_SHIFT_MASK;
796 gtk_tree_view_get_cursor (tv, &path, &col);
799 data = g_object_get_data (G_OBJECT(col),
"period_num");
800 period_num = GPOINTER_TO_UINT(data);
801 num_periods = gnc_budget_get_num_periods (priv->budget);
803 if (period_num >= num_periods)
804 period_num = num_periods - 1;
811 if (period_num >= num_periods)
814 if (gtk_tree_view_row_expanded (tv, path))
816 gtk_tree_path_down (path);
820 gtk_tree_path_next (path);
821 while (!gnc_tree_view_path_is_valid (GNC_TREE_VIEW(tv), path) &&
822 gtk_tree_path_get_depth (path) > 1)
824 gtk_tree_path_up (path);
825 gtk_tree_path_next (path);
829 else if (period_num < 0)
831 period_num = num_periods - 1;
832 if (!gtk_tree_path_prev (path))
833 gtk_tree_path_up (path);
836 while (gtk_tree_view_row_expanded (tv, path))
838 gtk_tree_path_down (path);
841 gtk_tree_path_next (path);
843 gnc_tree_view_path_is_valid (GNC_TREE_VIEW(tv), path));
844 gtk_tree_path_prev (path);
849 col = g_list_nth_data (priv->period_col_list, period_num);
854 gtk_cell_editable_editing_done (priv->temp_ce);
855 gtk_cell_editable_remove_widget (priv->temp_ce);
857 while (gtk_events_pending())
858 gtk_main_iteration ();
861 if (gnc_tree_view_path_is_valid (GNC_TREE_VIEW(tv), path))
862 gtk_tree_view_set_cursor (tv, path, col, TRUE);
863 gtk_tree_path_free (path);
875 gbv_treeview_resized_cb (GtkWidget *widget, GtkAllocation *allocation,
876 GncBudgetView *budget_view)
879 GList *columns = gtk_tree_view_get_columns (GTK_TREE_VIEW(priv->tree_view));
880 GList *total_columns = gtk_tree_view_get_columns (GTK_TREE_VIEW (priv->totals_tree_view));
884 for (GList *node = columns, *total_node = total_columns;
885 node; node = g_list_next (node))
887 GtkTreeViewColumn *tree_view_col = node->data;
888 const gchar *name = g_object_get_data (G_OBJECT(tree_view_col), PREF_NAME);
891 if ((g_strcmp0 (name,
"account-code") == 0) && (!priv->show_account_code))
892 total_node = g_list_next (total_node);
896 if ((g_strcmp0 (name,
"description") == 0) && (!priv->show_account_desc))
897 total_node = g_list_next (total_node);
899 if (gtk_tree_view_column_get_visible (tree_view_col) && total_node != NULL)
901 gint col_width = gtk_tree_view_column_get_width (tree_view_col);
902 GtkTreeViewColumn *totals_view_col = total_node->data;
903 if (GTK_IS_TREE_VIEW_COLUMN(totals_view_col))
904 gtk_tree_view_column_set_fixed_width (totals_view_col, col_width);
905 total_node = g_list_next (total_node);
910 g_list_free (columns);
911 g_list_free (total_columns);
918 gbv_row_activated_cb (GtkTreeView *treeview, GtkTreePath *path,
919 GtkTreeViewColumn *col, GncBudgetView *budget_view)
923 g_return_if_fail (GNC_IS_BUDGET_VIEW(budget_view));
926 GNC_TREE_VIEW_ACCOUNT(treeview), path);
930 g_signal_emit_by_name (budget_view,
"account-activated", account);
934 query_tooltip_tree_view_cb (GtkWidget *widget, gint x, gint y,
935 gboolean keyboard_tip, GtkTooltip *tooltip,
938 GtkTreeView *tree_view = GTK_TREE_VIEW(widget);
940 GtkTreePath *path = NULL;
941 GtkTreeViewColumn *column = NULL;
946 gtk_tree_view_convert_widget_to_bin_window_coords (tree_view, x, y, &x, &y);
948 if (keyboard_tip || !gtk_tree_view_get_path_at_pos (tree_view, x, y, &path,
949 &column, NULL, NULL))
951 gtk_tree_path_free (path);
957 gtk_tree_path_free (path);
961 period_num = GPOINTER_TO_UINT(g_object_get_data (G_OBJECT(column),
"period_num"));
962 if (!period_num && priv->period_col_list->data != column)
964 gtk_tree_path_free (path);
968 GNC_TREE_VIEW_ACCOUNT(widget), path);
969 note = gnc_budget_get_account_period_note (priv->budget, account, period_num);
972 gtk_tree_path_free (path);
976 gtk_tooltip_set_text (tooltip, note);
977 gtk_tree_view_set_tooltip_cell (tree_view, tooltip, path, column, NULL);
978 gtk_tree_path_free (path);
987 gbv_selection_changed_cb (GtkTreeSelection *selection, GncBudgetView *budget_view)
989 GtkTreeView *tree_view;
997 g_return_if_fail (GTK_IS_TREE_SELECTION(selection));
998 tree_view = gtk_tree_selection_get_tree_view (selection);
1000 GNC_TREE_VIEW_ACCOUNT(tree_view));
1003 sensitive = (g_list_length (acct_list) > 0);
1004 g_list_free (acct_list);
1022 gnc_commodity *total_currency;
1030 budget_accum_helper (
Account *account, gpointer data)
1034 gnc_commodity *currency;
1038 if (gnc_budget_is_account_period_value_set (info->budget, account, info->period_num))
1040 numeric = gnc_budget_get_account_period_value (info->budget, account,
1043 info->pdb,
numeric, currency, info->total_currency,
1050 numeric = gbv_get_accumulated_budget_amount (info->budget, account,
1053 info->pdb,
numeric, currency, info->total_currency,
1066 gbv_get_accumulated_budget_amount (GncBudget *budget,
Account *account, guint period_num)
1070 info.total = gnc_numeric_zero ();
1071 info.budget = budget;
1072 info.period_num = period_num;
1076 if (!gnc_budget_is_account_period_value_set (budget, account, period_num))
1079 info.total = gnc_budget_get_account_period_value (budget, account, period_num);
1093 budget_col_source (
Account *account, GtkTreeViewColumn *col,
1094 GtkCellRenderer *cell)
1096 GncBudgetView *budget_view;
1103 budget_view = GNC_BUDGET_VIEW(g_object_get_data (G_OBJECT(col),
"budget_view"));
1104 period_num = GPOINTER_TO_UINT(g_object_get_data (G_OBJECT(col),
"period_num"));
1106 priv = GNC_BUDGET_VIEW_GET_PRIVATE(budget_view);
1108 if (!gnc_budget_is_account_period_value_set (priv->budget, account, period_num))
1115 GtkStyleContext *stylectxt = gtk_widget_get_style_context (GTK_WIDGET(priv->tree_view));
1116 gtk_style_context_get_color (stylectxt, GTK_STATE_FLAG_NORMAL, &color);
1118 numeric = gbv_get_accumulated_budget_amount (priv->budget, account, period_num);
1120 if (gnc_reverse_balance (account))
1125 g_object_set (cell,
"foreground",
1131 g_object_set (cell,
"foreground",
1140 numeric = gnc_budget_get_account_period_value (priv->budget, account,
1143 strcpy (amtbuff,
"error");
1146 if (gnc_reverse_balance (account))
1150 gnc_account_print_info (account, FALSE));
1154 gchar *color = gnc_get_negative_color ();
1155 g_object_set (cell,
"foreground", color, NULL);
1159 g_object_set (cell,
"foreground", NULL, NULL);
1163 note = gnc_budget_get_account_period_note (priv->budget, account, period_num);
1164 g_object_set (cell,
"flagged", note != NULL, NULL);
1166 return g_strdup (amtbuff);
1173 bgv_get_total_for_account (
Account *account, GncBudget *budget, gnc_commodity *new_currency)
1178 gnc_numeric total = gnc_numeric_zero ();
1180 gnc_commodity *currency;
1188 num_periods = gnc_budget_get_num_periods (budget);
1189 for (period_num = 0; period_num < num_periods; ++period_num)
1191 if (!gnc_budget_is_account_period_value_set (budget, account, period_num))
1195 numeric = gbv_get_accumulated_budget_amount (budget, account, period_num);
1200 pdb,
numeric, currency, new_currency,
1208 numeric = gnc_budget_get_account_period_value (budget, account, period_num);
1214 pdb,
numeric, currency, new_currency,
1228 budget_total_col_source (
Account *account, GtkTreeViewColumn *col,
1229 GtkCellRenderer *cell)
1231 GncBudgetView *budget_view;
1236 budget_view = GNC_BUDGET_VIEW(g_object_get_data (G_OBJECT(col),
"budget_view"));
1237 priv = GNC_BUDGET_VIEW_GET_PRIVATE(budget_view);
1239 total = bgv_get_total_for_account (account, priv->budget, NULL);
1240 if (gnc_reverse_balance (account))
1247 gchar *color = gnc_get_negative_color ();
1248 g_object_set (cell,
"foreground", color, NULL);
1252 g_object_set (cell,
"foreground", NULL, NULL);
1254 return g_strdup (amtbuff);
1265 budget_col_edited (
Account *account, GtkTreeViewColumn *col,
1266 const gchar *new_text)
1268 GncBudgetView *budget_view;
1277 !(new_text && *new_text ==
'\0'))
1280 period_num = GPOINTER_TO_UINT(g_object_get_data (G_OBJECT(col),
"period_num"));
1282 budget_view = GNC_BUDGET_VIEW(g_object_get_data (G_OBJECT(col),
"budget_view"));
1283 priv = GNC_BUDGET_VIEW_GET_PRIVATE(budget_view);
1285 if (new_text && *new_text ==
'\0')
1286 gnc_budget_unset_account_period_value (priv->budget, account, period_num);
1289 if (gnc_reverse_balance (account))
1291 gnc_budget_set_account_period_value (priv->budget, account, period_num,
1309 totals_col_source (GtkTreeViewColumn *col, GtkCellRenderer *cell,
1310 GtkTreeModel *s_model, GtkTreeIter *s_iter,
1313 gnc_numeric total = gnc_numeric_zero ();
1314 GncBudgetView *budget_view = GNC_BUDGET_VIEW(user_data);
1316 gint period_num = GPOINTER_TO_INT(g_object_get_data (G_OBJECT(col),
"period_num"));
1322 gtk_tree_model_get (s_model, s_iter, 1, &row_type, -1);
1326 for (GList *node = top_level_accounts; node; node = g_list_next (node))
1328 Account *account = node->data;
1341 value = bgv_get_total_for_account (account, priv->budget, total_currency);
1345 value = gbv_get_accumulated_budget_amount
1346 (priv->budget, account, period_num);
1349 (pdb, value, currency, total_currency,
1359 GNCPrintAmountInfo pinfo = gnc_commodity_print_info (total_currency, period_num < 0);
1361 gnc_get_negative_color () : NULL;
1363 g_object_set (G_OBJECT(cell),
1366 "foreground", color,
1370 g_list_free (top_level_accounts);
1379 gbv_refresh_col_titles (GncBudgetView *budget_view)
1383 GDate date, nextdate;
1386 g_return_if_fail (budget_view != NULL);
1387 priv = GNC_BUDGET_VIEW_GET_PRIVATE(budget_view);
1390 r = gnc_budget_get_recurrence (priv->budget);
1392 for (GList *node = priv->period_col_list; node; node = g_list_next (node))
1394 GtkTreeViewColumn *col = GTK_TREE_VIEW_COLUMN (node->data);
1398 gtk_tree_view_column_set_title (col, title);
1400 recurrenceNextInstance (r, &date, &nextdate);
1406 gbv_renderer_add_padding (GtkCellRenderer *renderer)
1410 gtk_cell_renderer_get_padding (renderer, &xpad, &ypad);
1412 gtk_cell_renderer_set_padding (renderer, 5, ypad);
1417 static GtkTreeViewColumn*
1418 gbv_create_totals_column (GncBudgetView *budget_view, gint period_num)
1420 GtkTreeViewColumn *col;
1421 GtkCellRenderer* renderer;
1423 g_return_val_if_fail (budget_view != NULL, NULL);
1425 renderer = gtk_cell_renderer_text_new ();
1426 col = gtk_tree_view_column_new_with_attributes (
"", renderer, NULL);
1429 gbv_renderer_add_padding (renderer);
1431 gtk_tree_view_column_set_cell_data_func (col, renderer, totals_col_source, budget_view, NULL);
1432 g_object_set_data (G_OBJECT(col),
"budget_view", budget_view);
1433 g_object_set_data (G_OBJECT(col),
"period_num", GUINT_TO_POINTER(period_num));
1434 gtk_tree_view_column_set_sizing (col, GTK_TREE_VIEW_COLUMN_FIXED);
1444 gbv_col_edited_cb (GtkCellRendererText *cell, gchar *path_string,
1445 gchar *new_text, gpointer user_data)
1447 GncBudgetView *budget_view = GNC_BUDGET_VIEW(user_data);
1450 gtk_widget_queue_draw (GTK_WIDGET(priv->totals_tree_view));
1456 gdv_editing_started_cb (GtkCellRenderer *cr, GtkCellEditable *editable,
1457 const gchar *path_string, gpointer user_data)
1462 priv->temp_ce = editable;
1464 g_signal_connect (G_OBJECT(editable),
"key-press-event",
1465 G_CALLBACK(gbv_key_press_cb), user_data);
1469 gdv_editing_canceled_cb (GtkCellRenderer *cr, gpointer user_data)
1473 priv->temp_cr = NULL;
1474 priv->temp_ce = NULL;
1488 description_column = 2,
1489 startPeriods_column = 3
1495 gint num_periods_visible;
1496 GtkTreeViewColumn *col, *code_col, *desc_col;
1498 GList *totals_col_list;
1499 GdkRGBA *note_color, *note_color_selected;
1500 GtkStyleContext *stylectxt;
1502 ENTER(
"view %p", budget_view);
1504 g_return_if_fail (budget_view != NULL);
1505 priv = GNC_BUDGET_VIEW_GET_PRIVATE(budget_view);
1507 stylectxt = gtk_widget_get_style_context (GTK_WIDGET(priv->tree_view));
1508 gtk_style_context_get (stylectxt, GTK_STATE_FLAG_SELECTED,
"background-color", ¬e_color, NULL);
1509 gtk_style_context_get (stylectxt, GTK_STATE_FLAG_NORMAL,
"background-color", ¬e_color_selected, NULL);
1511 num_periods = gnc_budget_get_num_periods (priv->budget);
1513 col_list = g_list_reverse (priv->period_col_list);
1514 totals_col_list = g_list_reverse (priv->totals_col_list);
1515 num_periods_visible = g_list_length (col_list);
1518 while (num_periods_visible > num_periods)
1520 col = GTK_TREE_VIEW_COLUMN (col_list->data);
1521 gtk_tree_view_remove_column (GTK_TREE_VIEW(priv->tree_view), col);
1522 col_list = g_list_delete_link (col_list, col_list);
1523 num_periods_visible--;
1525 col = GTK_TREE_VIEW_COLUMN(totals_col_list->data);
1526 gtk_tree_view_remove_column (GTK_TREE_VIEW(priv->totals_tree_view), col);
1527 totals_col_list = g_list_delete_link (totals_col_list, totals_col_list);
1534 gtk_tree_view_column_set_visible (code_col, priv->show_account_code);
1535 code_col = gtk_tree_view_get_column (GTK_TREE_VIEW(priv->totals_tree_view), code_column);
1536 gtk_tree_view_column_set_visible (code_col, priv->show_account_code);
1540 gtk_tree_view_column_set_visible (desc_col, priv->show_account_desc);
1541 desc_col = gtk_tree_view_get_column (GTK_TREE_VIEW(priv->totals_tree_view), description_column);
1542 gtk_tree_view_column_set_visible (desc_col, priv->show_account_desc);
1547 if (num_periods_visible != 0 && num_periods > num_periods_visible)
1550 col = priv->total_col;
1551 gtk_tree_view_remove_column (GTK_TREE_VIEW(priv->tree_view), col);
1552 priv->total_col = NULL;
1553 col = gtk_tree_view_get_column (GTK_TREE_VIEW(priv->totals_tree_view),
1554 startPeriods_column + num_periods_visible);
1555 gtk_tree_view_remove_column (GTK_TREE_VIEW(priv->totals_tree_view), col);
1559 while (num_periods_visible < num_periods)
1561 GtkCellRenderer *renderer = gnc_cell_renderer_text_flag_new ();
1562 g_object_set (renderer,
"flag-color-rgba", note_color, NULL);
1563 g_object_set (renderer,
"flag-color-rgba-selected", note_color_selected, NULL);
1565 col = gnc_tree_view_account_add_custom_column_renderer (
1566 GNC_TREE_VIEW_ACCOUNT(priv->tree_view),
"",
1567 budget_col_source, budget_col_edited, renderer);
1568 g_object_set_data (G_OBJECT(col),
"budget_view", budget_view);
1569 g_object_set_data (G_OBJECT(col),
"period_num", GUINT_TO_POINTER(num_periods_visible));
1570 col_list = g_list_prepend (col_list, col);
1573 gbv_renderer_add_padding (renderer);
1575 g_signal_connect (G_OBJECT(renderer),
"edited", (GCallback)gbv_col_edited_cb, budget_view);
1576 g_signal_connect (G_OBJECT(renderer),
"editing-started",
1577 (GCallback)gdv_editing_started_cb, budget_view);
1578 g_signal_connect (G_OBJECT(renderer),
"editing-canceled",
1579 (GCallback)gdv_editing_canceled_cb, budget_view);
1580 col = gbv_create_totals_column (budget_view, num_periods_visible);
1583 gtk_tree_view_append_column (priv->totals_tree_view, col);
1584 totals_col_list = g_list_prepend (totals_col_list, col);
1587 num_periods_visible++;
1590 gdk_rgba_free (note_color);
1591 gdk_rgba_free (note_color_selected);
1593 priv->period_col_list = g_list_reverse (col_list);
1594 priv->totals_col_list = g_list_reverse (totals_col_list);
1596 if (priv->total_col == NULL)
1601 GtkCellRenderer* renderer;
1604 GNC_TREE_VIEW_ACCOUNT(priv->tree_view), _(
"Total"),
1605 budget_total_col_source, NULL);
1608 gtk_tree_view_column_set_alignment (priv->total_col, 1.0);
1611 date = g_date_new_dmy (31, 12, 2018);
1615 PangoLayout *layout = gtk_widget_create_pango_layout (GTK_WIDGET(budget_view), title);
1616 PangoRectangle logical_rect;
1617 pango_layout_set_width (layout, -1);
1618 pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
1619 g_object_unref (layout);
1621 gtk_tree_view_column_set_min_width (priv->total_col, logical_rect.width);
1624 g_object_set_data (G_OBJECT(priv->total_col),
"budget_view", budget_view);
1630 gbv_renderer_add_padding (renderer);
1632 col = gbv_create_totals_column (budget_view, -1);
1634 gtk_tree_view_append_column (priv->totals_tree_view, col);
1636 gbv_refresh_col_titles (budget_view);
1638 PINFO(
"Number of columns is %d, totals columns is %d",
1639 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.