38 #include <glib/gi18n.h>
41 #include "gnc-plugin-page-register2.h"
48 #include "dialog-transfer.h"
49 #include "dialog-utils.h"
50 #include "assistant-hierarchy.h"
51 #include "gnc-account-sel.h"
52 #include "gnc-component-manager.h"
56 #include "gnc-icons.h"
59 #include "gnc-session.h"
60 #include "gnc-split-reg.h"
66 #include "dialog-lot-viewer.h"
67 #include "window-reconcile.h"
68 #include "window-autoclear.h"
69 #include "window-main-summarybar.h"
75 #define PLUGIN_PAGE_ACCT_TREE_CM_CLASS "plugin-page-acct-tree"
76 #define STATE_SECTION "Account Hierarchy"
78 #define DELETE_DIALOG_FILTER "filter"
79 #define DELETE_DIALOG_ACCOUNT "account"
80 #define DELETE_DIALOG_TRANS_MAS "trans_mas"
81 #define DELETE_DIALOG_SA_MAS "sa_mas"
82 #define DELETE_DIALOG_SA_TRANS_MAS "sa_trans_mas"
83 #define DELETE_DIALOG_OK_BUTTON "deletebutton"
94 GtkTreeView *tree_view;
99 #define GNC_PLUGIN_PAGE_ACCOUNT_TREE_GET_PRIVATE(o) \
100 (G_TYPE_INSTANCE_GET_PRIVATE ((o), GNC_TYPE_PLUGIN_PAGE_ACCOUNT_TREE, GncPluginPageAccountTreePrivate))
102 static GObjectClass *parent_class = NULL;
110 static void gnc_plugin_page_account_tree_finalize (GObject *
object);
111 static void gnc_plugin_page_account_tree_selected (GObject *
object, gpointer user_data);
113 static GtkWidget *gnc_plugin_page_account_tree_create_widget (
GncPluginPage *plugin_page);
114 static void gnc_plugin_page_account_tree_destroy_widget (
GncPluginPage *plugin_page);
115 static void gnc_plugin_page_account_tree_save_page (
GncPluginPage *plugin_page, GKeyFile *file,
const gchar *group);
116 static GncPluginPage *gnc_plugin_page_account_tree_recreate_page (GtkWidget *window, GKeyFile *file,
const gchar *group);
119 static void gnc_plugin_page_account_tree_summarybar_position_changed(gpointer prefs, gchar* pref, gpointer user_data);
120 static gboolean gnc_plugin_page_account_tree_button_press_cb (GtkWidget *widget,
121 GdkEventButton *event,
123 static void gnc_plugin_page_account_tree_double_click_cb (GtkTreeView *treeview,
125 GtkTreeViewColumn *col,
128 static void gnc_plugin_page_account_tree_selection_changed_cb (GtkTreeSelection *selection,
130 void gppat_populate_trans_mas_list(GtkToggleButton *sa_mrb, GtkWidget *dialog);
131 void gppat_set_insensitive_iff_rb_active(GtkWidget *widget, GtkToggleButton *b);
134 static void gnc_plugin_page_account_tree_cmd_new_account (GtkAction *action,
GncPluginPageAccountTree *plugin_page);
135 static void gnc_plugin_page_account_tree_cmd_file_new_hierarchy (GtkAction *action,
GncPluginPageAccountTree *plugin_page);
141 static void gnc_plugin_page_account_tree_cmd_view_filter_by (GtkAction *action,
GncPluginPageAccountTree *plugin_page);
155 static guint plugin_page_signals[LAST_SIGNAL] = { 0 };
158 static GtkActionEntry gnc_plugin_page_account_tree_actions [] =
161 {
"FakeToplevel", NULL,
"", NULL, NULL, NULL },
165 "FileNewAccountAction", GNC_STOCK_NEW_ACCOUNT, N_(
"New _Account..."), NULL,
166 N_(
"Create a new Account"),
167 G_CALLBACK (gnc_plugin_page_account_tree_cmd_new_account)
170 "FileAddAccountHierarchyAssistantAction", GNC_STOCK_NEW_ACCOUNT, N_(
"New Account _Hierarchy..."), NULL,
171 N_(
"Extend the current book by merging with new account type categories"),
172 G_CALLBACK (gnc_plugin_page_account_tree_cmd_file_new_hierarchy)
174 #ifdef REGISTER2_ENABLED
176 "FileOpenAccount2Action", GNC_STOCK_OPEN_ACCOUNT, N_(
"Open _Account"), NULL,
177 N_(
"Open the selected account"),
178 G_CALLBACK (gnc_plugin_page_account_tree_cmd_open2_account)
181 "FileOpenAccountAction", GNC_STOCK_OPEN_ACCOUNT, N_(
"Open _Old Style Register Account"), NULL,
182 N_(
"Open the old style register selected account"),
183 G_CALLBACK (gnc_plugin_page_account_tree_cmd_open_account)
187 "FileOpenAccountAction", GNC_STOCK_OPEN_ACCOUNT, N_(
"Open _Account"), NULL,
188 N_(
"Open the selected account"),
189 G_CALLBACK (gnc_plugin_page_account_tree_cmd_open_account)
193 #ifdef REGISTER2_ENABLED
195 "FileOpenSubaccounts2Action", GNC_STOCK_OPEN_ACCOUNT, N_(
"Open _SubAccounts"), NULL,
196 N_(
"Open the selected account and all its subaccounts"),
197 G_CALLBACK (gnc_plugin_page_account_tree_cmd_open2_subaccounts)
200 "FileOpenSubaccountsAction", GNC_STOCK_OPEN_ACCOUNT, N_(
"Open Old St_yle Subaccounts"), NULL,
201 N_(
"Open the old style register selected account and all its subaccounts"),
202 G_CALLBACK (gnc_plugin_page_account_tree_cmd_open_subaccounts)
206 "FileOpenSubaccountsAction", GNC_STOCK_OPEN_ACCOUNT, N_(
"Open _SubAccounts"), NULL,
207 N_(
"Open the selected account and all its subaccounts"),
208 G_CALLBACK (gnc_plugin_page_account_tree_cmd_open_subaccounts)
214 "EditEditAccountAction", GNC_STOCK_EDIT_ACCOUNT, N_(
"Edit _Account"),
"<control>e",
215 N_(
"Edit the selected account"),
216 G_CALLBACK (gnc_plugin_page_account_tree_cmd_edit_account)
219 "EditDeleteAccountAction", GNC_STOCK_DELETE_ACCOUNT, N_(
"_Delete Account..."),
"Delete",
220 N_(
"Delete selected account"),
221 G_CALLBACK (gnc_plugin_page_account_tree_cmd_delete_account)
224 "EditRenumberSubaccountsAction", NULL, N_(
"_Renumber Subaccounts..."), NULL,
225 N_(
"Renumber the children of the selected account"),
226 G_CALLBACK (gnc_plugin_page_account_tree_cmd_renumber_accounts)
231 "ViewFilterByAction", NULL, N_(
"_Filter By..."), NULL, NULL,
232 G_CALLBACK (gnc_plugin_page_account_tree_cmd_view_filter_by)
237 "ActionsReconcileAction", NULL, N_(
"_Reconcile..."), NULL,
238 N_(
"Reconcile the selected account"),
239 G_CALLBACK (gnc_plugin_page_account_tree_cmd_reconcile)
242 "ActionsAutoClearAction", NULL, N_(
"_Auto-clear..."), NULL,
243 N_(
"Automatically clear individual transactions, given a cleared amount"),
244 G_CALLBACK (gnc_plugin_page_account_tree_cmd_autoclear)
247 "ActionsTransferAction", NULL, N_(
"_Transfer..."),
"<control>t",
248 N_(
"Transfer funds from one account to another"),
249 G_CALLBACK (gnc_plugin_page_account_tree_cmd_transfer)
252 "ActionsStockSplitAction", NULL, N_(
"Stoc_k Split..."), NULL,
253 N_(
"Record a stock split or a stock merger"),
254 G_CALLBACK (gnc_plugin_page_account_tree_cmd_stock_split)
257 "ActionsLotsAction", NULL, N_(
"View _Lots..."), NULL,
258 N_(
"Bring up the lot viewer/editor window"),
259 G_CALLBACK (gnc_plugin_page_account_tree_cmd_lots)
262 "ScrubAction", NULL, N_(
"Check & Repair A_ccount"), NULL,
263 N_(
"Check for and repair unbalanced transactions and orphan splits " "in this account"),
264 G_CALLBACK (gnc_plugin_page_account_tree_cmd_scrub)
267 "ScrubSubAction", NULL, N_(
"Check & Repair Su_baccounts"), NULL,
268 N_(
"Check for and repair unbalanced transactions and orphan splits "
269 "in this account and its subaccounts"),
270 G_CALLBACK (gnc_plugin_page_account_tree_cmd_scrub_sub)
273 "ScrubAllAction", NULL, N_(
"Check & Repair A_ll"), NULL,
274 N_(
"Check for and repair unbalanced transactions and orphan splits " "in all accounts"),
275 G_CALLBACK (gnc_plugin_page_account_tree_cmd_scrub_all)
278 {
"Register2TestAction", NULL, N_(
"_Register2"), NULL, NULL, NULL },
280 "Register2TestAccountAction", GNC_STOCK_OPEN_ACCOUNT, N_(
"Open _Account"), NULL,
281 N_(
"Open the selected account"),
282 G_CALLBACK (gnc_plugin_page_account_tree_cmd_open2_account)
285 "Register2TestSubAccountAction", GNC_STOCK_OPEN_ACCOUNT, N_(
"Open _SubAccounts"), NULL,
286 N_(
"Open the selected account and all its subaccounts"),
287 G_CALLBACK (gnc_plugin_page_account_tree_cmd_open2_subaccounts)
291 static guint gnc_plugin_page_account_tree_n_actions = G_N_ELEMENTS (gnc_plugin_page_account_tree_actions);
296 static const gchar *actions_requiring_account_rw[] =
298 "EditEditAccountAction",
299 "EditDeleteAccountAction",
300 "ActionsReconcileAction",
301 "ActionsAutoClearAction",
307 static const gchar *actions_requiring_account_always[] =
309 "FileOpenAccountAction",
310 #ifdef REGISTER2_ENABLED
311 "FileOpenAccount2Action",
313 "FileOpenSubaccountsAction",
319 static const gchar* readonly_inactive_actions[] =
321 "FileNewAccountAction",
322 "FileAddAccountHierarchyAssistantAction",
323 "EditEditAccountAction",
324 "EditDeleteAccountAction",
325 "EditRenumberSubaccountsAction",
326 "ActionsTransferAction",
327 "ActionsReconcileAction",
328 "ActionsAutoClearAction",
329 "ActionsStockSplitAction",
339 {
"FileOpenAccountAction", N_(
"Open") },
340 #ifdef REGISTER2_ENABLED
341 {
"FileOpenAccount2Action", N_(
"Open2") },
343 {
"EditEditAccountAction", N_(
"Edit") },
344 {
"FileNewAccountAction", N_(
"New") },
345 {
"EditDeleteAccountAction", N_(
"Delete") },
353 static GType gnc_plugin_page_account_tree_type = 0;
355 if (gnc_plugin_page_account_tree_type == 0)
357 static const GTypeInfo our_info =
362 (GClassInitFunc) gnc_plugin_page_account_tree_class_init,
367 (GInstanceInitFunc) gnc_plugin_page_account_tree_init
370 gnc_plugin_page_account_tree_type = g_type_register_static (GNC_TYPE_PLUGIN_PAGE,
371 GNC_PLUGIN_PAGE_ACCOUNT_TREE_NAME,
375 return gnc_plugin_page_account_tree_type;
384 plugin_page = g_object_new (GNC_TYPE_PLUGIN_PAGE_ACCOUNT_TREE,
387 LEAVE(
"new account tree page %p", plugin_page);
388 return GNC_PLUGIN_PAGE (plugin_page);
394 GObjectClass *object_class = G_OBJECT_CLASS (klass);
397 parent_class = g_type_class_peek_parent (klass);
399 object_class->finalize = gnc_plugin_page_account_tree_finalize;
401 gnc_plugin_class->
tab_icon = GNC_STOCK_ACCOUNT;
402 gnc_plugin_class->
plugin_name = GNC_PLUGIN_PAGE_ACCOUNT_TREE_NAME;
403 gnc_plugin_class->
create_widget = gnc_plugin_page_account_tree_create_widget;
404 gnc_plugin_class->
destroy_widget = gnc_plugin_page_account_tree_destroy_widget;
405 gnc_plugin_class->
save_page = gnc_plugin_page_account_tree_save_page;
406 gnc_plugin_class->
recreate_page = gnc_plugin_page_account_tree_recreate_page;
410 plugin_page_signals[ACCOUNT_SELECTED] =
411 g_signal_new (
"account_selected",
412 G_OBJECT_CLASS_TYPE (object_class),
416 g_cclosure_marshal_VOID__POINTER,
424 GtkActionGroup *action_group;
427 const GList *page_list;
429 ENTER(
"page %p", plugin_page);
430 priv = GNC_PLUGIN_PAGE_ACCOUNT_TREE_GET_PRIVATE(plugin_page);
433 parent = GNC_PLUGIN_PAGE(plugin_page);
434 #ifdef REGISTER2_ENABLED
435 g_object_set(G_OBJECT(plugin_page),
436 "page-name", _(
"Accounts"),
437 "page-uri",
"default:",
438 "ui-description",
"gnc-plugin-page-account-tree2-ui.xml",
441 g_object_set(G_OBJECT(plugin_page),
442 "page-name", _(
"Accounts"),
443 "page-uri",
"default:",
444 "ui-description",
"gnc-plugin-page-account-tree-ui.xml",
447 g_signal_connect (G_OBJECT (plugin_page),
"selected",
448 G_CALLBACK (gnc_plugin_page_account_tree_selected), plugin_page);
456 if (plugin_page == page_list->data)
458 g_object_set_data(G_OBJECT(plugin_page), PLUGIN_PAGE_IMMUTABLE,
465 "GncPluginPageAccountTreeActions");
466 gtk_action_group_add_actions(action_group,
467 gnc_plugin_page_account_tree_actions,
468 gnc_plugin_page_account_tree_n_actions,
473 priv->fd.visible_types = -1;
474 priv->fd.show_hidden = FALSE;
475 priv->fd.show_zero_total = TRUE;
477 LEAVE(
"page %p, priv %p, action group %p",
478 plugin_page, priv, action_group);
482 gnc_plugin_page_account_tree_finalize (GObject *
object)
487 ENTER(
"object %p",
object);
488 page = GNC_PLUGIN_PAGE_ACCOUNT_TREE (
object);
489 g_return_if_fail (GNC_IS_PLUGIN_PAGE_ACCOUNT_TREE (page));
490 priv = GNC_PLUGIN_PAGE_ACCOUNT_TREE_GET_PRIVATE(page);
491 g_return_if_fail (priv != NULL);
493 G_OBJECT_CLASS (parent_class)->finalize (
object);
503 priv = GNC_PLUGIN_PAGE_ACCOUNT_TREE_GET_PRIVATE(page);
504 ENTER(
"page %p (tree view %p)", page, priv->tree_view);
512 LEAVE(
"account %p", account);
520 gnc_plugin_page_account_refresh_cb (GHashTable *changes, gpointer user_data)
525 g_return_if_fail(GNC_IS_PLUGIN_PAGE_ACCOUNT_TREE(page));
531 priv = GNC_PLUGIN_PAGE_ACCOUNT_TREE_GET_PRIVATE(page);
532 gtk_widget_queue_draw(priv->widget);
536 gnc_plugin_page_account_tree_close_cb (gpointer user_data)
543 gnc_plugin_page_account_tree_create_widget (
GncPluginPage *plugin_page)
547 GtkTreeSelection *selection;
548 GtkTreeView *tree_view;
549 GtkWidget *scrolled_window;
550 GtkTreeViewColumn *col;
552 ENTER(
"page %p", plugin_page);
553 page = GNC_PLUGIN_PAGE_ACCOUNT_TREE (plugin_page);
554 priv = GNC_PLUGIN_PAGE_ACCOUNT_TREE_GET_PRIVATE(page);
555 if (priv->widget != NULL)
557 LEAVE(
"widget = %p", priv->widget);
561 priv->widget = gtk_vbox_new (FALSE, 0);
562 gtk_widget_show (priv->widget);
564 scrolled_window = gtk_scrolled_window_new (NULL, NULL);
565 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
566 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
567 gtk_widget_show (scrolled_window);
568 gtk_box_pack_start (GTK_BOX (priv->widget), scrolled_window,
573 GNC_TREE_VIEW(tree_view),
"description");
574 g_object_set_data(G_OBJECT(col), DEFAULT_VISIBLE, GINT_TO_POINTER(1));
576 GNC_TREE_VIEW(tree_view),
"total");
577 g_object_set_data(G_OBJECT(col), DEFAULT_VISIBLE, GINT_TO_POINTER(1));
579 g_object_set(G_OBJECT(tree_view),
580 "state-section", STATE_SECTION,
581 "show-column-menu", TRUE,
586 gnc_tree_view_account_set_code_edited(GNC_TREE_VIEW_ACCOUNT(tree_view),
587 gnc_tree_view_account_code_edited_cb);
588 gnc_tree_view_account_set_description_edited(GNC_TREE_VIEW_ACCOUNT(tree_view),
589 gnc_tree_view_account_description_edited_cb);
590 gnc_tree_view_account_set_notes_edited(GNC_TREE_VIEW_ACCOUNT(tree_view),
591 gnc_tree_view_account_notes_edited_cb);
593 priv->tree_view = tree_view;
594 selection = gtk_tree_view_get_selection(tree_view);
595 g_signal_connect (G_OBJECT (selection),
"changed",
596 G_CALLBACK (gnc_plugin_page_account_tree_selection_changed_cb), page);
597 g_signal_connect (G_OBJECT (tree_view),
"button-press-event",
598 G_CALLBACK (gnc_plugin_page_account_tree_button_press_cb), page);
599 g_signal_connect (G_OBJECT (tree_view),
"row-activated",
600 G_CALLBACK (gnc_plugin_page_account_tree_double_click_cb), page);
602 gtk_tree_view_set_headers_visible(tree_view, TRUE);
603 gnc_plugin_page_account_tree_selection_changed_cb (NULL, page);
604 gtk_widget_show (GTK_WIDGET (tree_view));
605 gtk_container_add (GTK_CONTAINER (scrolled_window), GTK_WIDGET(tree_view));
607 priv->fd.tree_view = GNC_TREE_VIEW_ACCOUNT(priv->tree_view);
609 GNC_TREE_VIEW_ACCOUNT(tree_view),
613 gnc_register_gui_component(PLUGIN_PAGE_ACCT_TREE_CM_CLASS,
614 gnc_plugin_page_account_refresh_cb,
615 gnc_plugin_page_account_tree_close_cb,
617 gnc_gui_component_set_session (priv->component_id,
618 gnc_get_current_session());
620 plugin_page->
summarybar = gnc_main_window_summary_new();
621 gtk_box_pack_start (GTK_BOX (priv->widget), plugin_page->
summarybar,
624 gnc_plugin_page_account_tree_summarybar_position_changed(NULL, NULL, page);
626 GNC_PREF_SUMMARYBAR_POSITION_TOP,
627 gnc_plugin_page_account_tree_summarybar_position_changed,
630 GNC_PREF_SUMMARYBAR_POSITION_BOTTOM,
631 gnc_plugin_page_account_tree_summarybar_position_changed,
634 LEAVE(
"widget = %p", priv->widget);
639 gnc_plugin_page_account_tree_destroy_widget (
GncPluginPage *plugin_page)
644 ENTER(
"page %p", plugin_page);
645 page = GNC_PLUGIN_PAGE_ACCOUNT_TREE (plugin_page);
646 priv = GNC_PLUGIN_PAGE_ACCOUNT_TREE_GET_PRIVATE(page);
649 GNC_PREF_SUMMARYBAR_POSITION_TOP,
650 gnc_plugin_page_account_tree_summarybar_position_changed,
653 GNC_PREF_SUMMARYBAR_POSITION_BOTTOM,
654 gnc_plugin_page_account_tree_summarybar_position_changed,
659 g_object_unref(G_OBJECT(priv->widget));
663 if (priv->component_id)
665 gnc_unregister_gui_component(priv->component_id);
666 priv->component_id = 0;
669 LEAVE(
"widget destroyed");
672 static void update_inactive_actions(
GncPluginPage *plugin_page)
674 GtkActionGroup *action_group;
678 g_return_if_fail(plugin_page);
679 g_return_if_fail(GNC_IS_PLUGIN_PAGE(plugin_page));
683 g_return_if_fail(GTK_IS_ACTION_GROUP (action_group));
687 "sensitive", is_sensitive);
694 static void gnc_plugin_page_account_tree_selected (GObject *
object, gpointer user_data)
697 g_return_if_fail (GNC_IS_PLUGIN_PAGE (plugin_page));
698 update_inactive_actions(plugin_page);
711 gnc_plugin_page_account_tree_save_page (
GncPluginPage *plugin_page,
713 const gchar *group_name)
718 g_return_if_fail (GNC_IS_PLUGIN_PAGE_ACCOUNT_TREE(plugin_page));
719 g_return_if_fail (key_file != NULL);
720 g_return_if_fail (group_name != NULL);
722 ENTER(
"page %p, key_file %p, group_name %s", plugin_page, key_file,
725 account_page = GNC_PLUGIN_PAGE_ACCOUNT_TREE(plugin_page);
726 priv = GNC_PLUGIN_PAGE_ACCOUNT_TREE_GET_PRIVATE(account_page);
728 gnc_tree_view_account_save(GNC_TREE_VIEW_ACCOUNT(priv->tree_view),
729 &priv->fd, key_file, group_name);
745 gnc_plugin_page_account_tree_recreate_page (GtkWidget *window,
747 const gchar *group_name)
753 g_return_val_if_fail(key_file, NULL);
754 g_return_val_if_fail(group_name, NULL);
755 ENTER(
"key_file %p, group_name %s", key_file, group_name);
759 account_page = GNC_PLUGIN_PAGE_ACCOUNT_TREE(page);
760 priv = GNC_PLUGIN_PAGE_ACCOUNT_TREE_GET_PRIVATE(account_page);
765 gnc_tree_view_account_restore(GNC_TREE_VIEW_ACCOUNT(priv->tree_view),
766 &priv->fd, key_file, group_name);
775 gnc_plugin_page_account_tree_summarybar_position_changed(gpointer prefs, gchar* pref, gpointer user_data)
780 GtkPositionType position = GTK_POS_BOTTOM;
782 g_return_if_fail(user_data != NULL);
784 plugin_page = GNC_PLUGIN_PAGE(user_data);
785 page = GNC_PLUGIN_PAGE_ACCOUNT_TREE (user_data);
786 priv = GNC_PLUGIN_PAGE_ACCOUNT_TREE_GET_PRIVATE(page);
789 position = GTK_POS_TOP;
791 gtk_box_reorder_child(GTK_BOX(priv->widget),
793 (position == GTK_POS_TOP ? 0 : -1) );
804 gnc_plugin_page_account_tree_button_press_cb (GtkWidget *widget,
805 GdkEventButton *event,
809 g_return_val_if_fail(GNC_IS_PLUGIN_PAGE(page), FALSE);
811 ENTER(
"widget %p, event %p, page %p", widget, event, page);
825 gboolean include_subs)
833 window = GNC_PLUGIN_PAGE (page)->window;
843 gboolean include_subs)
851 window = GNC_PLUGIN_PAGE (page)->window;
858 gnc_plugin_page_account_tree_double_click_cb (GtkTreeView *treeview,
860 GtkTreeViewColumn *col,
866 g_return_if_fail (GNC_IS_PLUGIN_PAGE_ACCOUNT_TREE (page));
867 g_return_if_fail (treeview);
869 model = gtk_tree_view_get_model(treeview);
870 if (gtk_tree_model_get_iter(model, &iter, path))
878 if (gtk_tree_model_iter_has_child(model, &iter))
882 if (gtk_tree_view_row_expanded(treeview, path))
883 gtk_tree_view_collapse_row(treeview, path);
885 gtk_tree_view_expand_row(treeview, path, FALSE);
891 #ifdef REGISTER2_ENABLED
892 gppat_open2_account_common (page, account, FALSE);
894 gppat_open_account_common (page, account, FALSE);
901 gnc_plugin_page_account_tree_selection_changed_cb (GtkTreeSelection *selection,
904 GtkActionGroup *action_group;
909 gboolean subaccounts;
912 g_return_if_fail(GNC_IS_PLUGIN_PAGE_ACCOUNT_TREE(page));
921 g_return_if_fail(GTK_IS_TREE_SELECTION(selection));
922 view = gtk_tree_selection_get_tree_view (selection);
924 sensitive = (account != NULL);
932 "sensitive", is_readwrite && sensitive);
934 "sensitive", sensitive);
935 g_signal_emit (page, plugin_page_signals[ACCOUNT_SELECTED], 0, account);
937 action = gtk_action_group_get_action (action_group,
"EditRenumberSubaccountsAction");
938 g_object_set (G_OBJECT(action),
"sensitive",
939 is_readwrite && sensitive && subaccounts, NULL);
942 "sensitive", is_readwrite && sensitive);
944 "sensitive", sensitive);
960 gnc_ui_hierarchy_assistant(FALSE);
964 gnc_plugin_page_account_tree_cmd_open_account (GtkAction *action,
969 g_return_if_fail (GNC_IS_PLUGIN_PAGE_ACCOUNT_TREE (page));
971 gppat_open_account_common (page, account, FALSE);
975 gnc_plugin_page_account_tree_cmd_open_subaccounts (GtkAction *action,
980 g_return_if_fail (GNC_IS_PLUGIN_PAGE_ACCOUNT_TREE (page));
982 gppat_open_account_common (page, account, TRUE);
989 gnc_plugin_page_account_tree_cmd_open2_account (GtkAction *action,
994 g_return_if_fail (GNC_IS_PLUGIN_PAGE_ACCOUNT_TREE (page));
996 gppat_open2_account_common (page, account, FALSE);
1000 gnc_plugin_page_account_tree_cmd_open2_subaccounts (GtkAction *action,
1005 g_return_if_fail (GNC_IS_PLUGIN_PAGE_ACCOUNT_TREE (page));
1007 gppat_open2_account_common (page, account, TRUE);
1017 ENTER(
"action %p, page %p", action, page);
1020 g_return_if_fail (account != NULL);
1034 gboolean has_splits;
1035 gboolean has_ro_splits;
1039 delete_account_helper (
Account * account, gpointer data)
1047 helper_res->has_splits = TRUE;
1050 Split *s = splits->data;
1054 helper_res->has_ro_splits = TRUE;
1057 splits = splits->next;
1061 return GINT_TO_POINTER (helper_res->has_splits || helper_res->has_ro_splits);
1069 set_ok_sensitivity(GtkWidget *dialog)
1072 GtkWidget *sa_mas, *trans_mas;
1073 gint sa_mas_cnt, trans_mas_cnt;
1076 sa_mas = g_object_get_data(G_OBJECT(dialog), DELETE_DIALOG_SA_MAS);
1077 trans_mas = g_object_get_data(G_OBJECT(dialog), DELETE_DIALOG_TRANS_MAS);
1078 sa_mas_cnt = gnc_account_sel_get_num_account(GNC_ACCOUNT_SEL(sa_mas));
1079 trans_mas_cnt = gnc_account_sel_get_num_account(GNC_ACCOUNT_SEL(trans_mas));
1081 sensitive = (((NULL == sa_mas) ||
1082 (!gtk_widget_is_sensitive(sa_mas) || sa_mas_cnt)) &&
1083 ((NULL == trans_mas) ||
1084 (!gtk_widget_is_sensitive(trans_mas) || trans_mas_cnt)));
1086 button = g_object_get_data(G_OBJECT(dialog), DELETE_DIALOG_OK_BUTTON);
1087 gtk_widget_set_sensitive(button, sensitive);
1091 gppat_populate_gas_list(GtkWidget *dialog,
1093 gboolean exclude_subaccounts)
1098 g_return_if_fail(GTK_IS_DIALOG(dialog));
1101 account = g_object_get_data(G_OBJECT(dialog), DELETE_DIALOG_ACCOUNT);
1102 filter = g_object_get_data(G_OBJECT(dialog), DELETE_DIALOG_FILTER);
1105 gnc_account_sel_set_acct_filters (gas, filter, NULL);
1108 gnc_account_sel_purge_account( gas, account, exclude_subaccounts);
1111 set_ok_sensitivity(dialog);
1115 gppat_populate_trans_mas_list(GtkToggleButton *sa_mrb,
1118 GtkWidget *trans_mas;
1120 g_return_if_fail(GTK_IS_DIALOG(dialog));
1123 trans_mas = g_object_get_data(G_OBJECT(dialog), DELETE_DIALOG_TRANS_MAS);
1124 gppat_populate_gas_list(dialog, GNC_ACCOUNT_SEL(trans_mas), !gtk_toggle_button_get_active(sa_mrb));
1133 gppat_set_insensitive_iff_rb_active(GtkWidget *widget, GtkToggleButton *b)
1135 gtk_widget_set_sensitive(widget, !gtk_toggle_button_get_active(b));
1136 set_ok_sensitivity(gtk_widget_get_toplevel(widget));
1146 GtkWidget *trans_mas = NULL;
1147 GtkWidget *sa_mas = NULL;
1148 GtkWidget *sa_trans_mas = NULL;
1156 if (NULL == account)
1164 #define EXPLANATION "The list below shows objects which make use of the account which you want to delete.\nBefore you can delete it, you must either delete those objects or else modify them so they make use\nof another account"
1166 gnc_ui_object_references_show( _(EXPLANATION), list);
1175 acct_name = g_strdup (_(
"(no name)"));
1186 GList *filter = NULL;
1187 GtkBuilder *builder = NULL;
1188 GtkWidget *dialog = NULL;
1189 GtkWidget *box = NULL;
1190 GtkWidget *widget = NULL;
1191 gchar *title = NULL;
1193 builder = gtk_builder_new();
1194 gnc_builder_add_from_file (builder,
"dialog-account.glade",
"Delete Account");
1196 dialog = GTK_WIDGET(gtk_builder_get_object (builder,
"Delete Account"));
1197 gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(window));
1199 widget = GTK_WIDGET(gtk_builder_get_object (builder,
"header"));
1200 title = g_strdup_printf(_(
"Deleting account %s"), acct_name);
1201 gtk_label_set_text(GTK_LABEL(widget), title);
1204 widget = GTK_WIDGET(gtk_builder_get_object (builder, DELETE_DIALOG_OK_BUTTON));
1205 g_object_set_data(G_OBJECT(dialog), DELETE_DIALOG_OK_BUTTON, widget);
1212 g_object_set_data(G_OBJECT(dialog), DELETE_DIALOG_FILTER, filter);
1213 g_object_set_data(G_OBJECT(dialog), DELETE_DIALOG_ACCOUNT, account);
1223 trans_mas = gnc_account_sel_new();
1224 box = GTK_WIDGET(gtk_builder_get_object (builder,
"trans_mas_hbox"));
1225 gtk_box_pack_start (GTK_BOX(box), trans_mas, TRUE, TRUE, 0);
1226 g_object_set_data(G_OBJECT(dialog), DELETE_DIALOG_TRANS_MAS, trans_mas);
1227 gppat_populate_gas_list(dialog, GNC_ACCOUNT_SEL(trans_mas), FALSE);
1229 delete_account_helper(account, &delete_res2);
1230 if (delete_res2.has_ro_splits)
1232 gtk_widget_destroy(GTK_WIDGET(gtk_builder_get_object (builder,
"trans_rw")));
1233 widget = GTK_WIDGET(gtk_builder_get_object (builder,
"trans_drb"));
1234 gtk_widget_set_sensitive(widget, FALSE);
1238 gtk_widget_destroy(GTK_WIDGET(gtk_builder_get_object (builder,
"trans_ro")));
1243 gtk_widget_destroy(GTK_WIDGET(gtk_builder_get_object (builder,
"transactions")));
1256 if (delete_res.has_ro_splits)
1258 gtk_widget_destroy(GTK_WIDGET(gtk_builder_get_object (builder,
"sa_trans_rw")));
1259 widget = GTK_WIDGET(gtk_builder_get_object (builder,
"sa_trans_drb"));
1260 gtk_widget_set_sensitive(widget, FALSE);
1262 else if (delete_res.has_splits)
1264 gtk_widget_destroy(GTK_WIDGET(gtk_builder_get_object (builder,
"sa_trans_ro")));
1268 gtk_widget_destroy(GTK_WIDGET(gtk_builder_get_object (builder,
"subaccount_trans")));
1271 sa_mas = gnc_account_sel_new();
1272 box = GTK_WIDGET(gtk_builder_get_object (builder,
"sa_mas_hbox"));
1273 gtk_box_pack_start (GTK_BOX(box), sa_mas, TRUE, TRUE, 0);
1274 g_object_set_data(G_OBJECT(dialog), DELETE_DIALOG_SA_MAS, sa_mas);
1275 gppat_populate_gas_list(dialog, GNC_ACCOUNT_SEL(sa_mas), TRUE);
1277 sa_trans_mas = gnc_account_sel_new();
1278 box = GTK_WIDGET(gtk_builder_get_object (builder,
"sa_trans_mas_hbox"));
1279 gtk_box_pack_start (GTK_BOX(box), sa_trans_mas, TRUE, TRUE, 0);
1280 g_object_set_data(G_OBJECT(dialog), DELETE_DIALOG_SA_TRANS_MAS, sa_trans_mas);
1281 gppat_populate_gas_list(dialog, GNC_ACCOUNT_SEL(sa_trans_mas), TRUE);
1285 gtk_widget_destroy(GTK_WIDGET(gtk_builder_get_object (builder,
"subaccounts")));
1286 gtk_widget_destroy(GTK_WIDGET(gtk_builder_get_object (builder,
"subaccount_trans")));
1290 gtk_dialog_set_default_response (GTK_DIALOG(dialog), GTK_RESPONSE_CANCEL);
1292 gtk_builder_connect_signals(builder, dialog);
1293 g_object_unref(G_OBJECT(builder));
1299 gtk_widget_show_all(dialog);
1300 response = gtk_dialog_run(GTK_DIALOG(dialog));
1301 if (GTK_RESPONSE_ACCEPT != response)
1304 gtk_widget_destroy(dialog);
1305 g_list_free(filter);
1309 if (trans_mas && gtk_widget_is_sensitive(trans_mas))
1310 ta = gnc_account_sel_get_account(GNC_ACCOUNT_SEL(trans_mas));
1311 if (sa_mas && gtk_widget_is_sensitive(sa_mas))
1312 saa = gnc_account_sel_get_account(GNC_ACCOUNT_SEL(sa_mas));
1313 if (sa_trans_mas && gtk_widget_is_sensitive(sa_trans_mas))
1314 sta = gnc_account_sel_get_account(GNC_ACCOUNT_SEL(sa_trans_mas));
1315 gtk_widget_destroy(dialog);
1316 g_list_free(filter);
1324 const char *format = _(
"The account %s will be deleted.");
1331 lines[0] = g_strdup_printf(format, acct_name);
1337 format = _(
"All transactions in this account will be moved to "
1339 lines[++i] = g_strdup_printf(format, name);
1343 format = _(
"All transactions in this account will be deleted.");
1344 lines[++i] = g_strdup_printf(
"%s", format);
1352 format = _(
"All of its sub-accounts will be moved to "
1354 lines[++i] = g_strdup_printf(format, name);
1358 format = _(
"All of its subaccounts will be deleted.");
1359 lines[++i] = g_strdup_printf(
"%s", format);
1363 format = _(
"All sub-account transactions will be moved to "
1365 lines[++i] = g_strdup_printf(format, name);
1367 else if (delete_res.has_splits)
1369 format = _(
"All sub-account transactions will be deleted.");
1370 lines[++i] = g_strdup_printf(
"%s", format);
1374 lines[++i] = _(
"Are you sure you want to do this?");
1377 message = g_strjoinv(
" ", lines);
1383 dialog = gtk_message_dialog_new(GTK_WINDOW(window),
1384 GTK_DIALOG_DESTROY_WITH_PARENT,
1385 GTK_MESSAGE_QUESTION,
1389 gtk_dialog_add_buttons(GTK_DIALOG(dialog),
1390 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1391 GTK_STOCK_DELETE, GTK_RESPONSE_ACCEPT,
1393 gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_CANCEL);
1394 response = gtk_dialog_run(GTK_DIALOG(dialog));
1395 gtk_widget_destroy(dialog);
1397 if (GTK_RESPONSE_ACCEPT == response)
1399 GList *acct_list, *ptr;
1403 gnc_set_busy_cursor(NULL, TRUE);
1404 gnc_suspend_gui_refresh ();
1413 for (ptr = acct_list; ptr; ptr = g_list_next(ptr))
1415 g_list_free(acct_list);
1418 else if (NULL != sta)
1436 for (ptr = acct_list; ptr; ptr = g_list_next(ptr))
1442 g_list_free(acct_list);
1456 gnc_resume_gui_refresh ();
1457 gnc_unset_busy_cursor(NULL);
1464 gnc_plugin_page_account_tree_cmd_renumber_accounts (GtkAction *action,
1472 if (!window || !account)
1475 gnc_account_renumber_create_dialog(window, account);
1481 gnc_plugin_page_account_tree_cmd_view_filter_by (GtkAction *action,
1486 g_return_if_fail(GNC_IS_PLUGIN_PAGE_ACCOUNT_TREE(page));
1487 ENTER(
"(action %p, page %p)", action, page);
1489 priv = GNC_PLUGIN_PAGE_ACCOUNT_TREE_GET_PRIVATE(page);
1490 account_filter_dialog_create(&priv->fd, GNC_PLUGIN_PAGE(page));
1495 gnc_plugin_page_account_tree_cmd_reconcile (GtkAction *action,
1503 g_return_if_fail (account != NULL);
1505 window = GNC_PLUGIN_PAGE (page)->window;
1506 recnData = recnWindow (window, account);
1507 gnc_ui_reconcile_window_raise (recnData);
1511 gnc_plugin_page_account_tree_cmd_autoclear (GtkAction *action,
1519 g_return_if_fail (account != NULL);
1521 window = GNC_PLUGIN_PAGE (page)->window;
1522 autoClearData = autoClearWindow (window, account);
1523 gnc_ui_autoclear_window_raise (autoClearData);
1527 gnc_plugin_page_account_tree_cmd_transfer (GtkAction *action,
1534 window = GNC_PLUGIN_PAGE (page)->window;
1535 gnc_xfer_dialog (window, account);
1539 gnc_plugin_page_account_tree_cmd_stock_split (GtkAction *action,
1546 window = GNC_PLUGIN_PAGE (page)->window;
1547 gnc_stock_split_dialog (window, account);
1551 gnc_plugin_page_account_tree_cmd_lots (GtkAction *action,
1557 gnc_lot_viewer_dialog (account);
1565 g_return_if_fail (account != NULL);
1567 gnc_suspend_gui_refresh ();
1570 xaccAccountScrubImbalance (account);
1573 if (g_getenv(
"GNC_AUTO_SCRUB_LOTS") != NULL)
1579 gnc_resume_gui_refresh ();
1587 g_return_if_fail (account != NULL);
1589 gnc_suspend_gui_refresh ();
1592 xaccAccountTreeScrubImbalance (account);
1595 if (g_getenv(
"GNC_AUTO_SCRUB_LOTS") != NULL)
1596 xaccAccountTreeScrubLots(account);
1600 gnc_resume_gui_refresh ();
1606 Account *root = gnc_get_current_root_account ();
1608 gnc_suspend_gui_refresh ();
1611 xaccAccountTreeScrubImbalance (root);
1613 if (g_getenv(
"GNC_AUTO_SCRUB_LOTS") != NULL)
1614 xaccAccountTreeScrubLots(root);
1618 gnc_resume_gui_refresh ();
GncPluginPage * gnc_plugin_page_register_new(Account *account, gboolean subaccounts)
Account * gnc_plugin_page_account_tree_get_current_account(GncPluginPageAccountTree *page)
Functions to load, save and get gui state.
High-Level API for imposing Lot constraints.
GtkWidget * gnc_plugin_page_get_window(GncPluginPage *page)
void gnc_account_append_child(Account *new_parent, Account *child)
const GList * gnc_gobject_tracking_get_list(const gchar *name)
GncPluginPage *(* recreate_page)(GtkWidget *window, GKeyFile *file, const gchar *group)
gboolean gnc_main_window_button_press_cb(GtkWidget *whatever, GdkEventButton *event, GncPluginPage *page)
SplitList * xaccAccountGetSplitList(const Account *acc)
gulong gnc_prefs_register_cb(const char *group, const gchar *pref_name, gpointer func, gpointer user_data)
Dialog for create/edit an account.
void gnc_account_foreach_descendant(const Account *acc, AccountCb thunk, gpointer user_data)
GncPluginPage * gnc_plugin_page_account_tree_new(void)
utility functions for the GnuCash UI
GNCAccountType xaccAccountGetType(const Account *acc)
void gncScrubBusinessAccountLots(Account *acc)
gint gnc_state_drop_sections_for(const gchar *partial_name)
gpointer gnc_account_foreach_descendant_until(const Account *acc, AccountCb2 thunk, gpointer user_data)
GncPluginPage * gnc_plugin_page_register2_new(Account *account, gboolean subaccounts)
Transaction * xaccSplitGetParent(const Split *split)
gchar * guid_to_string_buff(const GncGUID *guid, gchar *buff)
void xaccAccountScrubLots(Account *acc)
void xaccAccountMoveAllSplits(Account *accfrom, Account *accto)
GtkActionGroup * gnc_plugin_page_get_action_group(GncPluginPage *page)
GtkTreeViewColumn * gnc_tree_view_find_column_by_name(GncTreeView *view, const gchar *wanted)
#define ENTER(format, args...)
Cleanup functions for business objects.
void gnc_main_window_open_page(GncMainWindow *window, GncPluginPage *page)
void gnc_ui_edit_account_window(Account *account)
void xaccAccountDestroy(Account *acc)
#define xaccAccountGetGUID(X)
convert single-entry accounts to clean double-entry
void gnc_tree_view_account_set_filter(GncTreeViewAccount *view, gnc_tree_view_account_filter_func func, gpointer data, GSourceFunc destroy)
gchar * gnc_account_get_full_name(const Account *account)
Functions providing a register page for the GnuCash UI.
GtkTreeView implementation for gnucash account tree.
#define GUID_ENCODING_LENGTH
void(* destroy_widget)(GncPluginPage *plugin_page)
GtkTreeView * gnc_tree_view_account_new(gboolean show_root)
void gnc_tree_view_configure_columns(GncTreeView *view)
GType gnc_plugin_page_account_tree_get_type(void)
gboolean gnc_plugin_page_account_tree_filter_accounts(Account *account, gpointer user_data)
const gchar * plugin_name
void xaccAccountScrubOrphans(Account *acc)
Account * gnc_tree_view_account_get_account_from_path(GncTreeViewAccount *view, GtkTreePath *s_path)
Gnome specific utility functions.
gint gnc_account_n_children(const Account *account)
const char * xaccTransGetReadOnly(const Transaction *trans)
All type declarations for the whole Gnucash engine.
GtkTreeModel implementation to display account types in a GtkTreeView.
GList * qof_instance_get_referring_object_list(const QofInstance *inst)
Generic api to store and retrieve preferences.
Functions providing a chart of account page.
gboolean qof_book_is_readonly(const QofBook *book)
GList * gnc_account_get_children(const Account *account)
void xaccAccountBeginEdit(Account *acc)
void gnc_ui_new_account_window(QofBook *book, Account *parent)
GtkWidget *(* create_widget)(GncPluginPage *plugin_page)
gboolean xaccAccountGetPlaceholder(const Account *acc)
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Provide the menus to create a chart of account page.
void gnc_main_window_close_page(GncPluginPage *page)
Account * gnc_tree_view_account_get_selected_account(GncTreeViewAccount *view)
#define LEAVE(format, args...)
void(* save_page)(GncPluginPage *page, GKeyFile *file, const gchar *group)
void gnc_plugin_page_add_book(GncPluginPage *page, QofBook *book)
void xaccAccountTreeScrubOrphans(Account *acc)
GtkActionGroup * gnc_plugin_page_create_action_group(GncPluginPage *page, const gchar *group_name)
void gncScrubBusinessAccountTreeLots(Account *acc)
API for Transactions and Splits (journal entries)
void xaccAccountCommitEdit(Account *acc)
const gchar * QofLogModule
void gnc_prefs_remove_cb_by_func(const gchar *group, const gchar *pref_name, gpointer func, gpointer user_data)