38 #ifdef __G_IR_SCANNER__ 39 #undef __G_IR_SCANNER__ 41 #include <gdk/gdkkeysyms.h> 42 #include <glib/gi18n.h> 43 #include "gnc-date-edit.h" 45 #include "swig-runtime.h" 47 #include <guile-mappings.h> 54 #include "dialog-utils.h" 56 #include "misc-gnome-utils.h" 58 #include "gnc-icons.h" 60 #include "gnc-plugin-budget.h" 63 #include "gnc-session.h" 69 #include "gnc-component-manager.h" 73 #include "gnc-recurrence.h" 74 #include "Recurrence.h" 79 static QofLogModule log_module = GNC_MOD_BUDGET;
81 #define PLUGIN_PAGE_BUDGET_CM_CLASS "plugin-page-budget" 87 static void gnc_plugin_page_budget_finalize (GObject *
object);
90 gnc_plugin_page_budget_create_widget (
GncPluginPage *plugin_page);
91 static gboolean gnc_plugin_page_budget_focus_widget (
GncPluginPage *plugin_page);
92 static void gnc_plugin_page_budget_destroy_widget (
GncPluginPage *plugin_page);
93 static void gnc_plugin_page_budget_save_page (
GncPluginPage *plugin_page,
96 static GncPluginPage *gnc_plugin_page_budget_recreate_page (GtkWidget *window,
99 static gboolean gppb_button_press_cb (GtkWidget *widget,
100 GdkEventButton *event,
102 static void gppb_account_activated_cb (GncBudgetView* view,
106 static void gppb_selection_changed_cb (GtkTreeSelection *selection,
110 static void gnc_plugin_page_budget_cmd_view_filter_by (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
111 static void gnc_plugin_page_budget_cmd_open_account (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
112 static void gnc_plugin_page_budget_cmd_open_subaccounts (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
113 static void gnc_plugin_page_budget_cmd_delete_budget (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
114 static void gnc_plugin_page_budget_cmd_view_options (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
115 static void gnc_plugin_page_budget_cmd_estimate_budget (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
116 static void gnc_plugin_page_budget_cmd_allperiods_budget (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
117 static void gnc_plugin_page_budget_cmd_refresh (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
118 static void gnc_plugin_page_budget_cmd_budget_note (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
119 static void gnc_plugin_page_budget_cmd_budget_report (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
120 static void gnc_plugin_page_budget_cmd_edit_tax_options (GSimpleAction *simple, GVariant *parameter, gpointer user_data);
122 static void allperiods_budget_helper (GtkTreeModel *model, GtkTreePath *path,
123 GtkTreeIter *iter, gpointer data);
125 static GActionEntry gnc_plugin_page_budget_actions [] =
127 {
"OpenAccountAction", gnc_plugin_page_budget_cmd_open_account, NULL, NULL, NULL },
128 {
"OpenSubaccountsAction", gnc_plugin_page_budget_cmd_open_subaccounts, NULL, NULL, NULL },
129 {
"DeleteBudgetAction", gnc_plugin_page_budget_cmd_delete_budget, NULL, NULL, NULL },
130 {
"OptionsBudgetAction", gnc_plugin_page_budget_cmd_view_options, NULL, NULL, NULL },
131 {
"EstimateBudgetAction", gnc_plugin_page_budget_cmd_estimate_budget, NULL, NULL, NULL },
132 {
"AllPeriodsBudgetAction", gnc_plugin_page_budget_cmd_allperiods_budget, NULL, NULL, NULL },
133 {
"BudgetNoteAction", gnc_plugin_page_budget_cmd_budget_note, NULL, NULL, NULL },
134 {
"BudgetReportAction", gnc_plugin_page_budget_cmd_budget_report, NULL, NULL, NULL },
135 {
"ViewFilterByAction", gnc_plugin_page_budget_cmd_view_filter_by, NULL, NULL, NULL },
136 {
"ViewRefreshAction", gnc_plugin_page_budget_cmd_refresh, NULL, NULL, NULL },
137 {
"EditTaxOptionsAction", gnc_plugin_page_budget_cmd_edit_tax_options, NULL, NULL, NULL },
139 static guint gnc_plugin_page_budget_n_actions = G_N_ELEMENTS(gnc_plugin_page_budget_actions);
142 static const gchar *gnc_plugin_load_ui_items [] =
154 static const gchar *writeable_actions[] =
157 "DeleteBudgetAction",
158 "OptionsBudgetAction",
159 "EstimateBudgetAction",
160 "AllPeriodsBudgetAction",
166 static const gchar *actions_requiring_account[] =
169 "OpenSubaccountsAction",
177 {
"OpenAccountAction", N_(
"Open") },
178 {
"DeleteBudgetAction", N_(
"Delete") },
179 {
"OptionsBudgetAction", N_(
"Options") },
180 {
"EstimateBudgetAction", N_(
"Estimate") },
181 {
"AllPeriodsBudgetAction", N_(
"All Periods") },
182 {
"BudgetNoteAction", N_(
"Note") },
183 {
"BudgetReportAction", N_(
"Run Report") },
187 typedef enum allperiods_action
198 GSimpleActionGroup *simple_action_group;
200 GncBudgetView* budget_view;
201 GtkTreeView *tree_view;
209 gboolean delete_budget;
219 gnc_numeric allValue;
220 allperiods_action action;
228 G_DEFINE_TYPE_WITH_PRIVATE(
GncPluginPageBudget, gnc_plugin_page_budget, GNC_TYPE_PLUGIN_PAGE)
230 #define GNC_PLUGIN_PAGE_BUDGET_GET_PRIVATE(o) \ 231 ((GncPluginPageBudgetPrivate*)gnc_plugin_page_budget_get_instance_private((GncPluginPageBudget*)o)) 240 g_return_val_if_fail (GNC_IS_BUDGET(budget), NULL);
245 for ( ; item; item = g_list_next (item))
247 auto plugin_page = GNC_PLUGIN_PAGE_BUDGET(item->data);
248 priv = GNC_PLUGIN_PAGE_BUDGET_GET_PRIVATE(plugin_page);
249 if (priv->budget == budget)
251 LEAVE(
"existing budget page %p", plugin_page);
252 return GNC_PLUGIN_PAGE(plugin_page);
256 auto plugin_page = GNC_PLUGIN_PAGE_BUDGET (g_object_new (GNC_TYPE_PLUGIN_PAGE_BUDGET,
nullptr));
258 priv = GNC_PLUGIN_PAGE_BUDGET_GET_PRIVATE(plugin_page);
259 priv->budget = budget;
260 priv->delete_budget = FALSE;
261 priv->key = *gnc_budget_get_guid (budget);
262 priv->reportPage = NULL;
263 label = g_strdup_printf (
"%s: %s", _(
"Budget"), gnc_budget_get_name (budget));
264 g_object_set (G_OBJECT(plugin_page),
"page-name", label, NULL);
266 LEAVE(
"new budget page %p", plugin_page);
267 return GNC_PLUGIN_PAGE(plugin_page);
274 GObjectClass *object_class = G_OBJECT_CLASS(klass);
277 object_class->finalize = gnc_plugin_page_budget_finalize;
279 gnc_plugin_class->
tab_icon = GNC_ICON_BUDGET;
280 gnc_plugin_class->
plugin_name = GNC_PLUGIN_PAGE_BUDGET_NAME;
281 gnc_plugin_class->
create_widget = gnc_plugin_page_budget_create_widget;
282 gnc_plugin_class->
destroy_widget = gnc_plugin_page_budget_destroy_widget;
283 gnc_plugin_class->
save_page = gnc_plugin_page_budget_save_page;
284 gnc_plugin_class->
recreate_page = gnc_plugin_page_budget_recreate_page;
292 GSimpleActionGroup *simple_action_group;
296 ENTER(
"page %p", plugin_page);
297 priv = GNC_PLUGIN_PAGE_BUDGET_GET_PRIVATE(plugin_page);
300 parent = GNC_PLUGIN_PAGE(plugin_page);
301 g_object_set (G_OBJECT(plugin_page),
302 "page-name", _(
"Budget"),
303 "ui-description",
"gnc-plugin-page-budget.ui",
311 g_action_map_add_action_entries (G_ACTION_MAP(simple_action_group),
312 gnc_plugin_page_budget_actions,
313 gnc_plugin_page_budget_n_actions,
321 priv->fd.visible_types = -1;
322 priv->fd.show_hidden = FALSE;
323 priv->fd.show_unused = TRUE;
324 priv->fd.show_zero_total = TRUE;
325 priv->fd.filter_override = g_hash_table_new (g_direct_hash, g_direct_equal);
328 priv->useAvg = FALSE;
329 recurrenceSet (&priv->r, 1, PERIOD_MONTH, NULL, WEEKEND_ADJ_NONE);
331 LEAVE(
"page %p, priv %p, action group %p",
332 plugin_page, priv, simple_action_group);
337 gnc_plugin_page_budget_finalize (GObject *
object)
341 ENTER(
"object %p",
object);
342 page = GNC_PLUGIN_PAGE_BUDGET(
object);
343 g_return_if_fail (GNC_IS_PLUGIN_PAGE_BUDGET(page));
345 G_OBJECT_CLASS (gnc_plugin_page_budget_parent_class)->finalize (
object);
352 gnc_plugin_page_budget_close_cb (gpointer user_data)
364 gnc_plugin_page_budget_focus_widget (
GncPluginPage *budget_plugin_page)
366 if (GNC_IS_PLUGIN_PAGE_BUDGET(budget_plugin_page))
369 GncBudgetView *budget_view = priv->budget_view;
370 GtkWidget *account_view = gnc_budget_view_get_account_tree_view (budget_view);
374 g_simple_action_set_enabled (G_SIMPLE_ACTION(action), FALSE);
377 g_simple_action_set_enabled (G_SIMPLE_ACTION(action), FALSE);
380 g_simple_action_set_enabled (G_SIMPLE_ACTION(action), FALSE);
384 gnc_plugin_load_ui_items);
389 if (!gtk_widget_is_focus (GTK_WIDGET(account_view)))
390 gtk_widget_grab_focus (GTK_WIDGET(account_view));
397 gnc_plugin_page_budget_refresh_cb (GHashTable *changes, gpointer user_data)
403 page = GNC_PLUGIN_PAGE_BUDGET(user_data);
404 priv = GNC_PLUGIN_PAGE_BUDGET_GET_PRIVATE(page);
407 ei = gnc_gui_get_entity_events (changes, &priv->key);
410 if (ei->event_mask & QOF_EVENT_DESTROY)
416 priv->delete_budget = TRUE;
417 gnc_budget_view_delete_budget (priv->budget_view);
418 gnc_plugin_page_budget_close_cb (user_data);
421 if (ei->event_mask & QOF_EVENT_MODIFY)
423 DEBUG(
"refreshing budget view because budget was modified");
435 gnc_plugin_page_budget_create_widget (
GncPluginPage *plugin_page)
440 ENTER(
"page %p", plugin_page);
441 page = GNC_PLUGIN_PAGE_BUDGET(plugin_page);
442 priv = GNC_PLUGIN_PAGE_BUDGET_GET_PRIVATE(page);
443 if (priv->budget_view != NULL)
445 LEAVE(
"widget = %p", priv->budget_view);
446 return GTK_WIDGET(priv->budget_view);
452 g_signal_connect (G_OBJECT(selection),
"changed",
453 G_CALLBACK(gppb_selection_changed_cb), plugin_page);
455 g_signal_connect (G_OBJECT(priv->budget_view),
"button-press-event",
456 G_CALLBACK(gppb_button_press_cb), plugin_page);
457 g_signal_connect (G_OBJECT(priv->budget_view),
"account-activated",
458 G_CALLBACK(gppb_account_activated_cb), page);
461 gnc_register_gui_component (PLUGIN_PAGE_BUDGET_CM_CLASS,
462 gnc_plugin_page_budget_refresh_cb,
463 gnc_plugin_page_budget_close_cb,
466 gnc_gui_component_set_session (priv->component_id,
467 gnc_get_current_session ());
469 gnc_gui_component_watch_entity (priv->component_id,
470 gnc_budget_get_guid (priv->budget),
471 QOF_EVENT_DESTROY | QOF_EVENT_MODIFY);
473 g_signal_connect (G_OBJECT(plugin_page),
"inserted",
477 LEAVE(
"widget = %p", priv->budget_view);
478 return GTK_WIDGET(priv->budget_view);
483 gnc_plugin_page_budget_destroy_widget (
GncPluginPage *plugin_page)
487 ENTER(
"page %p", plugin_page);
488 priv = GNC_PLUGIN_PAGE_BUDGET_GET_PRIVATE(plugin_page);
494 g_idle_remove_by_data (plugin_page);
496 if (priv->budget_view)
499 gnc_budget_view_save_account_filter (priv->budget_view);
501 if (priv->delete_budget)
503 gnc_budget_view_delete_budget (priv->budget_view);
506 g_object_unref (G_OBJECT(priv->budget_view));
507 priv->budget_view = NULL;
511 g_hash_table_destroy (priv->fd.filter_override);
513 gnc_gui_component_clear_watches (priv->component_id);
515 if (priv->component_id != NO_COMPONENT)
517 gnc_unregister_gui_component (priv->component_id);
518 priv->component_id = NO_COMPONENT;
521 LEAVE(
"widget destroyed");
525 #define BUDGET_GUID "Budget GncGUID" 539 gnc_plugin_page_budget_save_page (
GncPluginPage *plugin_page,
540 GKeyFile *key_file,
const gchar *group_name)
546 g_return_if_fail (GNC_IS_PLUGIN_PAGE_BUDGET(plugin_page));
547 g_return_if_fail (key_file != NULL);
548 g_return_if_fail (group_name != NULL);
550 ENTER(
"page %p, key_file %p, group_name %s", plugin_page, key_file,
553 budget_page = GNC_PLUGIN_PAGE_BUDGET(plugin_page);
554 priv = GNC_PLUGIN_PAGE_BUDGET_GET_PRIVATE(budget_page);
557 g_key_file_set_string (key_file, group_name, BUDGET_GUID, guid_str);
560 gnc_budget_view_save (priv->budget_view, key_file, group_name);
578 gnc_plugin_page_budget_recreate_page (GtkWidget *window, GKeyFile *key_file,
579 const gchar *group_name)
584 GError *error = NULL;
590 g_return_val_if_fail (key_file, NULL);
591 g_return_val_if_fail (group_name, NULL);
592 ENTER(
"key_file %p, group_name %s", key_file, group_name);
594 guid_str = g_key_file_get_string (key_file, group_name, BUDGET_GUID,
598 g_warning(
"error reading group %s key %s: %s",
599 group_name, BUDGET_GUID, error->message);
600 g_error_free (error);
612 bgt = gnc_budget_lookup (&guid, book);
620 budget_page = GNC_PLUGIN_PAGE_BUDGET(page);
621 priv = GNC_PLUGIN_PAGE_BUDGET_GET_PRIVATE(budget_page);
627 if (!gnc_budget_view_restore (priv->budget_view, key_file, group_name))
645 gppb_button_press_cb (GtkWidget *widget, GdkEventButton *event,
650 g_return_val_if_fail (GNC_IS_PLUGIN_PAGE(page), FALSE);
652 ENTER(
"widget %p, event %p, page %p", widget, event, page);
659 gppb_account_activated_cb (GncBudgetView* view,
Account* account,
665 g_return_if_fail (GNC_IS_PLUGIN_PAGE_BUDGET (page));
667 window = GNC_PLUGIN_PAGE(page)->window;
675 gppb_selection_changed_cb (GtkTreeSelection *selection,
678 GSimpleActionGroup *simple_action_group;
683 g_return_if_fail (GNC_IS_PLUGIN_PAGE_BUDGET(page));
689 g_return_if_fail (GTK_IS_TREE_SELECTION(selection));
690 view = gtk_tree_selection_get_tree_view (selection);
692 GNC_TREE_VIEW_ACCOUNT(view));
695 sensitive = (g_list_length (acct_list) > 0);
696 g_list_free (acct_list);
710 gnc_plugin_page_budget_cmd_open_account (GSimpleAction *simple,
714 auto page = GNC_PLUGIN_PAGE_BUDGET (user_data);
718 GList *acct_list, *tmp;
720 g_return_if_fail (GNC_IS_PLUGIN_PAGE_BUDGET(page));
721 priv = GNC_PLUGIN_PAGE_BUDGET_GET_PRIVATE(page);
722 acct_list = gnc_budget_view_get_selected_accounts (priv->budget_view);
724 window = GNC_PLUGIN_PAGE(page)->window;
725 for (tmp = acct_list; tmp; tmp = g_list_next (tmp))
727 auto account = GNC_ACCOUNT (tmp->data);
731 g_list_free (acct_list);
736 gnc_plugin_page_budget_cmd_open_subaccounts (GSimpleAction *simple,
740 auto page = GNC_PLUGIN_PAGE_BUDGET (user_data);
744 GList *acct_list, *tmp;
746 g_return_if_fail (GNC_IS_PLUGIN_PAGE_BUDGET(page));
747 priv = GNC_PLUGIN_PAGE_BUDGET_GET_PRIVATE(page);
748 acct_list = gnc_budget_view_get_selected_accounts (priv->budget_view);
750 window = GNC_PLUGIN_PAGE(page)->window;
751 for (tmp = acct_list; tmp; tmp = g_list_next (tmp))
753 auto account = GNC_ACCOUNT(tmp->data);
757 g_list_free (acct_list);
762 gnc_plugin_page_budget_cmd_delete_budget (GSimpleAction *simple,
766 auto page = GNC_PLUGIN_PAGE_BUDGET (user_data);
770 priv = GNC_PLUGIN_PAGE_BUDGET_GET_PRIVATE(page);
771 budget = priv->budget;
772 g_return_if_fail (GNC_IS_BUDGET(budget));
773 priv->delete_budget = TRUE;
774 gnc_budget_gui_delete_budget (budget);
780 gnc_plugin_page_budget_cmd_edit_tax_options (GSimpleAction *simple,
784 auto page = GNC_PLUGIN_PAGE_BUDGET (user_data);
786 GtkTreeSelection *selection;
790 page = GNC_PLUGIN_PAGE_BUDGET(page);
792 g_return_if_fail (GNC_IS_PLUGIN_PAGE_BUDGET(page));
794 ENTER (
"(action %p, page %p)", simple, page);
795 priv = GNC_PLUGIN_PAGE_BUDGET_GET_PRIVATE(page);
798 window = GNC_PLUGIN_PAGE(page)->window;
800 if (gtk_tree_selection_count_selected_rows (selection) == 1)
802 GList *acc_list = gnc_budget_view_get_selected_accounts (priv->budget_view);
803 account = GNC_ACCOUNT (acc_list->data);
804 g_list_free (acc_list);
806 gnc_tax_info_dialog (window, account);
814 gnc_plugin_page_budget_cmd_view_options (GSimpleAction *simple,
818 auto page = GNC_PLUGIN_PAGE_BUDGET (user_data);
826 GtkWidget *gbname, *gbtreeview, *gbnumperiods, *gbhb;
829 GtkTextBuffer *buffer;
830 GtkTextIter start, end;
831 GtkWidget *show_account_code, *show_account_desc;
832 gboolean show_ac, show_ad;
834 g_return_if_fail (GNC_IS_PLUGIN_PAGE_BUDGET(page));
835 priv = GNC_PLUGIN_PAGE_BUDGET_GET_PRIVATE(page);
839 builder = gtk_builder_new ();
840 gnc_builder_add_from_file (builder,
"gnc-plugin-page-budget.glade",
"NumPeriods_Adj");
841 gnc_builder_add_from_file (builder,
"gnc-plugin-page-budget.glade",
"budget_options_container_dialog");
843 priv->dialog = GTK_WIDGET(gtk_builder_get_object (builder,
"budget_options_container_dialog"));
845 gtk_window_set_transient_for (GTK_WINDOW(priv->dialog),
848 gbname = GTK_WIDGET(gtk_builder_get_object (builder,
"BudgetName"));
849 gtk_entry_set_text (GTK_ENTRY(gbname), gnc_budget_get_name (priv->budget));
851 gbtreeview = GTK_WIDGET(gtk_builder_get_object (builder,
"BudgetDescription"));
852 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(gbtreeview));
853 gtk_text_buffer_set_text (buffer, gnc_budget_get_description (priv->budget), -1);
855 gbhb = GTK_WIDGET(gtk_builder_get_object (builder,
"BudgetPeriod"));
856 gr = GNC_RECURRENCE(gnc_recurrence_new ());
857 gnc_recurrence_set (gr, gnc_budget_get_recurrence (priv->budget));
858 gtk_box_pack_start (GTK_BOX(gbhb), GTK_WIDGET(gr), TRUE, TRUE, 0);
859 gtk_widget_show (GTK_WIDGET(gr));
861 gbnumperiods = GTK_WIDGET(gtk_builder_get_object (builder,
"BudgetNumPeriods"));
862 gtk_spin_button_set_value (GTK_SPIN_BUTTON(gbnumperiods), gnc_budget_get_num_periods (priv->budget));
864 show_account_code = GTK_WIDGET(gtk_builder_get_object (builder,
"ShowAccountCode"));
865 show_account_desc = GTK_WIDGET(gtk_builder_get_object (builder,
"ShowAccountDescription"));
867 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(show_account_code),
868 gnc_budget_view_get_show_account_code (priv->budget_view));
870 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(show_account_desc),
871 gnc_budget_view_get_show_account_description (priv->budget_view));
873 gtk_widget_show_all (priv->dialog);
874 result = gtk_dialog_run (GTK_DIALOG(priv->dialog));
878 case GTK_RESPONSE_OK:
879 name = (gchar *) gtk_entry_get_text (GTK_ENTRY(gbname));
885 label = g_strdup_printf (
"%s: %s", _(
"Budget"), name);
890 gtk_text_buffer_get_bounds (gtk_text_view_get_buffer (GTK_TEXT_VIEW(gbtreeview)), &start, &end);
891 desc = gtk_text_buffer_get_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW(gbtreeview)), &start, &end, TRUE);
896 show_ac = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(show_account_code));
897 gnc_budget_view_set_show_account_code (priv->budget_view, show_ac);
899 show_ad = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(show_account_desc));
900 gnc_budget_view_set_show_account_description (priv->budget_view, show_ad);
903 if ((show_ac || show_ad) && (!gnc_features_check_used (gnc_get_current_book (),
904 GNC_FEATURE_BUDGET_SHOW_EXTRA_ACCOUNT_COLS)))
909 num_periods = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(gbnumperiods));
912 r = gnc_recurrence_get (gr);
913 gnc_budget_set_recurrence (priv->budget, r);
915 case GTK_RESPONSE_CANCEL:
920 g_object_unref (G_OBJECT(builder));
921 gtk_widget_destroy (priv->dialog);
928 gnc_budget_gui_delete_budget (GncBudget *budget)
932 g_return_if_fail (GNC_IS_BUDGET(budget));
933 name = gnc_budget_get_name (budget);
935 name = _(
"Unnamed Budget");
937 if (gnc_verify_dialog (NULL, FALSE, _(
"Delete %s?"), name))
939 QofBook* book = gnc_get_current_book ();
941 gnc_suspend_gui_refresh ();
947 PWARN (
"No budgets left. Removing feature BUDGET_UNREVERSED.");
950 gnc_resume_gui_refresh ();
956 estimate_budget_helper (GtkTreeModel *model, GtkTreePath *path,
957 GtkTreeIter *iter, gpointer data)
960 guint num_periods, i;
963 auto page = GNC_PLUGIN_PAGE_BUDGET(data);
965 g_return_if_fail(GNC_IS_PLUGIN_PAGE_BUDGET(page));
966 priv = GNC_PLUGIN_PAGE_BUDGET_GET_PRIVATE(page);
968 acct = gnc_budget_view_get_account_from_path (priv->budget_view, path);
970 num_periods = gnc_budget_get_num_periods (priv->budget);
972 if (priv->useAvg && num_periods)
974 num = xaccAccountGetNoclosingBalanceChangeForPeriod
975 (acct, recurrenceGetPeriodTime (&priv->r, 0, FALSE),
976 recurrenceGetPeriodTime (&priv->r, num_periods - 1, TRUE), TRUE);
979 gnc_numeric_create (num_periods, 1),
984 for (i = 0; i < num_periods; i++)
986 gnc_budget_set_account_period_value (priv->budget, acct, i, num);
991 for (i = 0; i < num_periods; i++)
993 num = xaccAccountGetNoclosingBalanceChangeForPeriod
994 (acct, recurrenceGetPeriodTime (&priv->r, i, FALSE),
995 recurrenceGetPeriodTime (&priv->r, i, TRUE), TRUE);
1002 gnc_budget_set_account_period_value (priv->budget, acct, i, num);
1013 gnc_plugin_page_budget_cmd_estimate_budget (GSimpleAction *simple,
1014 GVariant *parameter,
1017 auto page = GNC_PLUGIN_PAGE_BUDGET (user_data);
1019 GtkTreeSelection *sel;
1020 GtkWidget *dialog, *gde, *dtr, *hb, *avg;
1024 GtkBuilder *builder;
1026 g_return_if_fail (GNC_IS_PLUGIN_PAGE_BUDGET(page));
1027 priv = GNC_PLUGIN_PAGE_BUDGET_GET_PRIVATE(page);
1031 if (gtk_tree_selection_count_selected_rows (sel) <= 0)
1033 dialog = gtk_message_dialog_new (
1035 (GtkDialogFlags)(GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL),
1036 GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
"%s",
1037 _(
"You must select at least one account to estimate."));
1038 gtk_dialog_run (GTK_DIALOG(dialog));
1039 gtk_widget_destroy (dialog);
1043 builder = gtk_builder_new ();
1044 gnc_builder_add_from_file (builder,
"gnc-plugin-page-budget.glade",
"DigitsToRound_Adj");
1045 gnc_builder_add_from_file (builder,
"gnc-plugin-page-budget.glade",
"budget_estimate_dialog");
1047 dialog = GTK_WIDGET(gtk_builder_get_object (builder,
"budget_estimate_dialog"));
1049 gtk_window_set_transient_for (GTK_WINDOW(dialog),
1052 hb = GTK_WIDGET(gtk_builder_get_object (builder,
"StartDate_hbox"));
1053 gde = gnc_date_edit_new (time (NULL), FALSE, FALSE);
1054 gtk_box_pack_start (GTK_BOX(hb), gde, TRUE, TRUE, 0);
1055 gtk_widget_show (gde);
1057 date = recurrenceGetDate (&priv->r);
1058 gnc_date_edit_set_gdate (GNC_DATE_EDIT(gde), &date);
1060 dtr = GTK_WIDGET(gtk_builder_get_object (builder,
"DigitsToRound"));
1061 gtk_spin_button_set_value (GTK_SPIN_BUTTON(dtr),
1062 (gdouble)priv->sigFigs);
1064 avg = GTK_WIDGET(gtk_builder_get_object (builder,
"UseAverage"));
1065 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(avg), priv->useAvg);
1067 gtk_widget_show_all (dialog);
1068 result = gtk_dialog_run (GTK_DIALOG(dialog));
1071 case GTK_RESPONSE_OK:
1072 r = gnc_budget_get_recurrence (priv->budget);
1074 gnc_date_edit_get_gdate (GNC_DATE_EDIT(gde), &date);
1075 recurrenceSet (&priv->r, recurrenceGetMultiplier (r),
1076 recurrenceGetPeriodType (r), &date,
1077 recurrenceGetWeekendAdjust (r));
1079 gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(dtr));
1081 priv->useAvg = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(avg));
1083 gnc_budget_begin_edit (priv->budget);
1084 gtk_tree_selection_selected_foreach (sel, estimate_budget_helper, page);
1085 gnc_budget_commit_edit (priv->budget);
1090 gtk_widget_destroy (dialog);
1091 g_object_unref (G_OBJECT(builder));
1095 allperiods_budget_helper (GtkTreeModel *model, GtkTreePath *path,
1096 GtkTreeIter *iter, gpointer data)
1099 guint num_periods, i;
1100 gnc_numeric num, allvalue;
1102 auto page = GNC_PLUGIN_PAGE_BUDGET(data);
1104 g_return_if_fail(GNC_IS_PLUGIN_PAGE_BUDGET(page));
1105 priv = GNC_PLUGIN_PAGE_BUDGET_GET_PRIVATE(page);
1106 acct = gnc_budget_view_get_account_from_path (priv->budget_view, path);
1107 num_periods = gnc_budget_get_num_periods (priv->budget);
1108 allvalue = priv->allValue;
1110 if (gnc_reverse_balance (acct))
1113 for (i = 0; i < num_periods; i++)
1115 switch (priv->action)
1118 num = gnc_budget_get_account_period_value (priv->budget, acct, i);
1122 gnc_budget_set_account_period_value (priv->budget, acct, i, num);
1125 num = gnc_budget_get_account_period_value (priv->budget, acct, i);
1129 gnc_budget_set_account_period_value (priv->budget, acct, i, num);
1132 gnc_budget_unset_account_period_value (priv->budget, acct, i);
1135 gnc_budget_set_account_period_value (priv->budget, acct, i,
1146 gnc_plugin_page_budget_cmd_allperiods_budget (GSimpleAction *simple,
1147 GVariant *parameter,
1150 auto page = GNC_PLUGIN_PAGE_BUDGET (user_data);
1152 GtkTreeSelection *sel;
1153 GtkWidget *dialog, *val, *dtr, *add, *mult;
1155 GtkBuilder *builder;
1158 g_return_if_fail(GNC_IS_PLUGIN_PAGE_BUDGET(page));
1159 priv = GNC_PLUGIN_PAGE_BUDGET_GET_PRIVATE(page);
1162 if (gtk_tree_selection_count_selected_rows (sel) <= 0)
1164 dialog = gtk_message_dialog_new (
1166 (GtkDialogFlags)(GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL),
1167 GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
"%s",
1168 _(
"You must select at least one account to edit."));
1169 gtk_dialog_run (GTK_DIALOG(dialog));
1170 gtk_widget_destroy (dialog);
1174 builder = gtk_builder_new ();
1175 gnc_builder_add_from_file (builder,
"gnc-plugin-page-budget.glade",
1176 "DigitsToRound_Adj");
1177 gnc_builder_add_from_file (builder,
"gnc-plugin-page-budget.glade",
1178 "budget_allperiods_dialog");
1180 dialog = GTK_WIDGET(
1181 gtk_builder_get_object (builder,
"budget_allperiods_dialog"));
1183 gtk_window_set_transient_for (
1187 val = GTK_WIDGET(gtk_builder_get_object (builder,
"Value"));
1188 gtk_entry_set_text (GTK_ENTRY(val),
"");
1190 dtr = GTK_WIDGET(gtk_builder_get_object (builder,
"DigitsToRound1"));
1191 gtk_spin_button_set_value (GTK_SPIN_BUTTON(dtr), (gdouble)priv->sigFigs);
1193 add = GTK_WIDGET(gtk_builder_get_object (builder,
"RB_Add"));
1194 mult = GTK_WIDGET(gtk_builder_get_object (builder,
"RB_Multiply"));
1196 gtk_widget_show_all (dialog);
1197 result = gtk_dialog_run (GTK_DIALOG(dialog));
1200 case GTK_RESPONSE_OK:
1202 priv->sigFigs = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(dtr));
1203 priv->action = REPLACE;
1204 txt = gtk_entry_get_text (GTK_ENTRY(val));
1206 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(add)))
1208 else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(mult)))
1209 priv->action = MULTIPLY;
1211 if (priv->action == REPLACE &&
1212 !gtk_entry_get_text_length (GTK_ENTRY(val)))
1213 priv->action = UNSET;
1216 priv->action == UNSET)
1218 gnc_budget_begin_edit (priv->budget);
1219 gtk_tree_selection_selected_foreach (sel, allperiods_budget_helper,
1221 gnc_budget_commit_edit (priv->budget);
1227 gtk_widget_destroy (dialog);
1228 g_object_unref (G_OBJECT(builder));
1232 gnc_plugin_page_budget_cmd_budget_note (GSimpleAction *simple,
1233 GVariant *parameter,
1236 auto page = GNC_PLUGIN_PAGE_BUDGET (user_data);
1238 GtkWidget *dialog, *note;
1240 GtkBuilder *builder;
1242 GtkTreeViewColumn *col = NULL;
1243 GtkTreePath *path = NULL;
1244 guint period_num = 0;
1247 g_return_if_fail(GNC_IS_PLUGIN_PAGE_BUDGET(page));
1248 priv = GNC_PLUGIN_PAGE_BUDGET_GET_PRIVATE(page);
1249 gtk_tree_view_get_cursor(
1250 GTK_TREE_VIEW(gnc_budget_view_get_account_tree_view(priv->budget_view)),
1255 period_num = col ? GPOINTER_TO_UINT(
1256 g_object_get_data(G_OBJECT(col),
"period_num"))
1259 acc = gnc_budget_view_get_account_from_path(priv->budget_view, path);
1260 gtk_tree_path_free(path);
1265 dialog = gtk_message_dialog_new(
1267 (GtkDialogFlags)(GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL),
1268 GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
"%s",
1269 _(
"You must select one budget cell to edit."));
1270 gtk_dialog_run(GTK_DIALOG(dialog));
1271 gtk_widget_destroy(dialog);
1275 builder = gtk_builder_new();
1276 gnc_builder_add_from_file(builder,
"gnc-plugin-page-budget.glade",
1277 "budget_note_dialog");
1279 dialog = GTK_WIDGET(gtk_builder_get_object(builder,
"budget_note_dialog"));
1281 gtk_window_set_transient_for(
1285 note = GTK_WIDGET(gtk_builder_get_object(builder,
"BudgetNote"));
1286 xxxgtk_textview_set_text(GTK_TEXT_VIEW(note),
1287 gnc_budget_get_account_period_note(priv->budget, acc, period_num));
1289 gtk_widget_show_all(dialog);
1290 result = gtk_dialog_run(GTK_DIALOG(dialog));
1293 case GTK_RESPONSE_OK:
1294 txt = xxxgtk_textview_get_text(GTK_TEXT_VIEW(note));
1295 gnc_budget_set_account_period_note (priv->budget, acc, period_num,
1296 (txt && *txt) ? txt : NULL);
1302 gtk_widget_destroy(dialog);
1303 g_object_unref(G_OBJECT(builder));
1307 equal_fn (gpointer
find_data, gpointer elt_data)
1319 gnc_plugin_page_budget_cmd_budget_report (GSimpleAction *simple,
1320 GVariant *parameter,
1323 auto page = GNC_PLUGIN_PAGE_BUDGET (user_data);
1326 g_return_if_fail (GNC_IS_PLUGIN_PAGE_BUDGET (page));
1328 priv = GNC_PLUGIN_PAGE_BUDGET_GET_PRIVATE (page);
1330 if (gnc_find_first_gui_component (WINDOW_REPORT_CM_CLASS, equal_fn,
1332 gnc_plugin_page_report_reload (GNC_PLUGIN_PAGE_REPORT (priv->reportPage));
1335 SCM func = scm_c_eval_string (
"gnc:budget-report-create");
1336 SCM arg = SWIG_NewPointerObj (priv->budget, SWIG_TypeQuery (
"_p_budget_s"), 0);
1339 g_return_if_fail (scm_is_procedure (func));
1341 arg = scm_apply_0 (func, scm_list_1 (arg));
1342 g_return_if_fail (scm_is_exact (arg));
1344 report_id = scm_to_int (arg);
1345 g_return_if_fail (report_id >= 0);
1354 gnc_plugin_page_budget_cmd_view_filter_by (GSimpleAction *simple,
1355 GVariant *parameter,
1358 auto page = GNC_PLUGIN_PAGE_BUDGET (user_data);
1361 g_return_if_fail(GNC_IS_PLUGIN_PAGE_BUDGET(page));
1362 ENTER(
"(action %p, page %p)", simple, page);
1364 priv = GNC_PLUGIN_PAGE_BUDGET_GET_PRIVATE(page);
1365 account_filter_dialog_create (&priv->fd, GNC_PLUGIN_PAGE(page));
1371 gnc_plugin_page_budget_cmd_refresh (GSimpleAction *simple,
1372 GVariant *parameter,
1375 auto page = GNC_PLUGIN_PAGE_BUDGET (user_data);
1378 g_return_if_fail (GNC_IS_PLUGIN_PAGE_BUDGET(page));
1379 ENTER(
"(action %p, page %p)", simple, page);
1381 priv = GNC_PLUGIN_PAGE_BUDGET_GET_PRIVATE(page);
void gnc_budget_set_num_periods(GncBudget *budget, guint num_periods)
Set/Get the number of periods in the Budget.
GncPluginPage * gnc_plugin_page_register_new(Account *account, gboolean subaccounts)
Create a new "register" plugin page, given a pointer to an account.
GtkWidget * gnc_plugin_page_get_window(GncPluginPage *page)
Retrieve a pointer to the GncMainWindow (GtkWindow) containing this page.
void gnc_budget_destroy(GncBudget *budget)
Deletes the given budget object.
const gchar * tab_icon
The relative name of the icon that should be shown on the tab for this page.
gboolean xaccParseAmount(const char *in_str, gboolean monetary, gnc_numeric *result, char **endstr)
Parses in_str to obtain a numeric result.
gboolean(* focus_page_function)(GncPluginPage *plugin_page)
This function performs specific actions to set the focus on a specific widget.
void gnc_main_window_update_menu_and_toolbar(GncMainWindow *window, GncPluginPage *page, const gchar **ui_updates)
Update the main window menu with the placeholders listed in ui_updates and load the page specific too...
The instance data structure for a content plugin.
const GList * gnc_gobject_tracking_get_list(const gchar *name)
Get a list of all known objects of a specified type.
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.
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...
utility functions for the GnuCash UI
GncPluginPage *(* recreate_page)(GtkWidget *window, GKeyFile *file, const gchar *group)
Create a new page based on the information saved during a previous instantiation of gnucash...
gnc_numeric gnc_numeric_neg(gnc_numeric a)
Returns a newly created gnc_numeric that is the negative of the given gnc_numeric value...
void gnc_main_window_init_short_names(GncMainWindow *window, GncToolBarShortNames *toolbar_labels)
Update the labels of the toolbar items with short names.
#define DEBUG(format, args...)
Print a debugging message.
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...
Functions that are supported by all types of windows.
void gnc_features_set_used(QofBook *book, const gchar *feature)
Indicate that the current book uses the given feature.
GSimpleActionGroup * gnc_plugin_page_get_action_group(GncPluginPage *page)
Retrieve the GSimpleActionGroup object associated with this page.
gnc_numeric gnc_numeric_add(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Return a+b.
GtkWidget * window
The window that contains the display widget for this plugin.
GncPluginPage * gnc_plugin_page_budget_new(GncBudget *budget)
Create a new "budget" plugin page.
GSimpleActionGroup * gnc_plugin_page_create_action_group(GncPluginPage *page, const gchar *group_name)
Create the GSimpleActionGroup object associated with this page.
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.
#define ENTER(format, args...)
Print a function entry debugging message.
void gnc_main_window_open_page(GncMainWindow *window, GncPluginPage *page)
Display a data plugin page in a window.
Functions for adding content to a window.
void(* destroy_widget)(GncPluginPage *plugin_page)
Function called to destroy the display widget for a particular type of plugin.
#define PWARN(format, args...)
Log a warning.
QofBook * qof_session_get_book(const QofSession *session)
Returns the QofBook of this session.
Functions providing a register page for the GnuCash UI.
gnc_numeric gnc_numeric_convert(gnc_numeric n, gint64 denom, gint how)
Change the denominator of a gnc_numeric value to the specified denominator under standard arguments '...
The class data structure for a content plugin.
GtkTreeView implementation for gnucash account tree.
GAction * gnc_main_window_find_action(GncMainWindow *window, const gchar *action_name)
Find the GAction in the main window.
gnc_numeric gnc_numeric_mul(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Multiply a times b, returning the product.
#define GUID_ENCODING_LENGTH
Number of characters needed to encode a guid as a string not including the null terminator.
void gnc_plugin_page_disconnect_page_changed(GncPluginPage *page)
Disconnect the page_changed_id signal callback.
GncBudgetView * gnc_budget_view_new(GncBudget *budget, AccountFilterDialog *fd)
Create new gnc budget view.
void gnc_features_set_unused(QofBook *book, const gchar *feature)
Indicate that the current book does not use the given feature.
const gchar * plugin_name
The textual name of this plugin.
GtkWidget *(* create_widget)(GncPluginPage *plugin_page)
Function called to create the display widget for a particular type of plugin.
Gnome specific utility functions.
gnc_numeric gnc_numeric_div(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Division.
void(* save_page)(GncPluginPage *page, GKeyFile *file, const gchar *group)
Save enough information about this page so that it can be recreated next time the user starts gnucash...
GncPluginPage * gnc_plugin_page_report_new(int reportId)
GtkTreeModel implementation to display account types in a GtkTreeView.
void gnc_budget_set_name(GncBudget *budget, const gchar *name)
Set/Get the name of the Budget.
gboolean qof_book_is_readonly(const QofBook *book)
Return whether the book is read only.
void gnc_budget_set_description(GncBudget *budget, const gchar *description)
Set/Get the description of the Budget.
void gnc_plugin_page_inserted_cb(GncPluginPage *page, gpointer user_data)
Set up the page_changed callback for when the current page is changed.
void gnc_main_window_close_page(GncPluginPage *page)
Remove a data plugin page from a window and display the previous page.
#define LEAVE(format, args...)
Print a function exit debugging message.
Round to the nearest integer, rounding away from zero when there are two equidistant nearest integers...
void gnc_plugin_page_add_book(GncPluginPage *page, QofBook *book)
Add a book reference to the specified page.
GNCNumericErrorCode gnc_numeric_check(gnc_numeric in)
Check for error signal in value.
QofCollection * qof_book_get_collection(const QofBook *book, QofIdType entity_type)
Return The table of entities of the given type.
guint qof_collection_count(const QofCollection *col)
return the number of entities in the collection.
#define GNC_DENOM_AUTO
Values that can be passed as the 'denom' argument.
The type used to store guids in C.
void main_window_update_page_name(GncPluginPage *page, const gchar *name_in)
Update the name of the page in the main window.
void gnc_budget_view_refresh(GncBudgetView *budget_view)
refreshes the current budget view
#define GNC_HOW_DENOM_SIGFIGS(n)
Build a 'how' value that will generate a denominator that will keep at least n significant figures in...
Utility functions for file access.