26 #include <glib/gi18n.h> 27 #include <glib/gstdio.h> 28 #include <dialog-options.hpp> 40 #include <sys/types.h> 42 #ifdef MAC_INTEGRATION 43 #include <Foundation/Foundation.h> 45 #include "gnc-account-merge.h" 46 #include "dialog-new-user.h" 47 #include "dialog-utils.h" 49 #include "assistant-hierarchy.h" 50 #include "gnc-amount-edit.h" 52 #include "gnc-exp-parser.h" 53 #include "gnc-general-select.h" 56 #include "gnc-hooks.h" 57 #include "gnc-component-manager.h" 59 #include "gnc-gui-query.h" 63 #include "io-example-account.h" 64 #include "top-level.h" 70 static QofLogModule log_module = GNC_MOD_IMPORT;
72 #define GNC_PREFS_GROUP "dialogs.new-hierarchy" 73 #define GNC_PREF_SHOW_ON_NEW_FILE "show-on-new-file" 74 #define DIALOG_BOOK_OPTIONS_CM_CLASS "dialog-book-options" 80 COL_SHORT_DESCRIPTION,
93 GtkWidget *currency_selector;
94 GtkWidget *currency_selector_label;
96 GtkWidget *language_combo;
97 GtkWidget *region_combo;
98 GtkWidget *region_label;
100 gchar *gnc_accounts_dir;
102 GtkTreeView *categories_tree;
103 GtkTreeRowReference *initial_category;
104 GtkTextView *category_description;
105 GtkWidget *category_accounts_container;
106 GtkLabel *category_accounts_label;
107 GtkTreeView *category_accounts_tree;
108 gboolean category_set_changed;
110 GncTreeViewAccount *final_account_tree;
111 GtkWidget *final_account_tree_container;
119 gboolean account_list_added;
120 gboolean use_defaults;
126 GncHierarchyAssistantFinishedCallback when_completed;
132 void on_prepare (GtkAssistant *assistant, GtkWidget *page,
135 void on_cancel (GtkAssistant *gtkassistant,
hierarchy_data *data);
136 void on_finish (GtkAssistant *gtkassistant,
hierarchy_data *data);
138 void select_all_clicked (GtkButton *button,
140 void clear_all_clicked (GtkButton *button,
148 static void add_one_category (GncExampleAccount *acc,
hierarchy_data *data);
150 static void categories_tree_selection_changed (GtkTreeSelection *selection,
hierarchy_data *data);
156 gnc_save_window_size(GNC_PREFS_GROUP, GTK_WINDOW(data->dialog));
157 gtk_widget_destroy (data->dialog);
161 destroy_hash_helper (gpointer key, gpointer value, gpointer user_data)
163 auto balance{
static_cast<gnc_numeric*
>(value)};
172 hash = data->balance_hash;
175 g_hash_table_foreach (hash, destroy_hash_helper,
nullptr);
176 g_hash_table_destroy (hash);
177 data->balance_hash =
nullptr;
180 g_free (data->gnc_accounts_dir);
184 get_final_balance (GHashTable *hash,
Account *account)
186 if (!hash || !account)
187 return gnc_numeric_zero ();
189 auto balance{
static_cast<gnc_numeric*
>(g_hash_table_lookup(hash, account))};
192 return gnc_numeric_zero ();
196 set_final_balance (GHashTable *hash,
Account *account, gnc_numeric in_balance)
198 if (!hash || !account)
201 auto balance{
static_cast<gnc_numeric*
>(g_hash_table_lookup(hash, account))};
204 *balance = in_balance;
208 balance = g_new (gnc_numeric, 1);
209 *balance = in_balance;
210 g_hash_table_insert (hash, account, balance);
213 #ifdef MAC_INTEGRATION 220 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]
init];
221 NSLocale* locale = [NSLocale currentLocale];
222 NSString* locale_str;
223 char *retval =
nullptr;
226 locale_str =[[[locale objectForKey: NSLocaleLanguageCode]
227 stringByAppendingString:
@"_"]
228 stringByAppendingString:
229 [locale objectForKey: NSLocaleCountryCode]];
231 @catch (NSException *err)
236 if ([locale_str isEqualToString:
@"_"])
237 locale_str =
@"en_US";
238 retval = g_strdup([locale_str UTF8String]);
244 gnc_get_ea_locale_dir(
const char *top_dir)
246 static const char* default_locale =
"C";
252 #if PLATFORM(WINDOWS) 259 const gchar *env_locale;
260 env_locale = g_getenv(
"LANG");
261 if (g_strcmp0(env_locale,
"Swedish_Sweden") == 0)
262 locale = g_strdup(
"sv_SE");
263 else if (g_strcmp0(env_locale,
"Swedish_Finland") == 0)
264 locale =g_strdup(
"sv_FI");
265 else if (g_strcmp0(env_locale,
"Swedish_Ă…land Islands") == 0)
266 locale =g_strdup(
"sv_AX");
269 locale = g_win32_getlocale();
272 PWARN (
"Couldn't retrieve locale. Falling back to default one.");
273 locale = g_strdup (
"C");
276 #elif defined MAC_INTEGRATION 277 locale = mac_locale();
279 locale = g_strdup(setlocale(LC_MESSAGES,
nullptr));
283 ret = g_build_filename(top_dir, locale, (
char *)
nullptr);
285 while (g_stat(ret, &buf) != 0)
291 ret = g_build_filename(top_dir, default_locale, (
char *)
nullptr);
296 ret = g_build_filename(top_dir, locale, (
char *)
nullptr);
310 }GncLanguageRegionCombos;
313 region_combo_changed_cb (GtkComboBox *widget,
hierarchy_data *data)
315 GtkTreeModel *filter_model = gtk_combo_box_get_model (GTK_COMBO_BOX(data->region_combo));
316 GtkTreeModel *region_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER(filter_model));
317 GtkTreeIter filter_iter, region_iter;
318 gchar *lang_reg =
nullptr;
319 gchar *account_path =
nullptr;
321 if (gtk_combo_box_get_active_iter (widget, &filter_iter))
323 GtkListStore *cat_list = GTK_LIST_STORE(gtk_tree_view_get_model (data->categories_tree));
324 GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(data->categories_tree));
328 gtk_tree_model_filter_convert_iter_to_child_iter (GTK_TREE_MODEL_FILTER(filter_model),
332 gtk_tree_model_get (region_model, ®ion_iter, LANG_REG_STRING, &lang_reg, -1);
334 gnc_suspend_gui_refresh ();
337 if (data->category_accounts_tree)
338 gtk_widget_destroy(GTK_WIDGET(data->category_accounts_tree));
339 data->category_accounts_tree =
nullptr;
343 gtk_list_store_clear (cat_list);
345 account_path = g_build_filename (data->gnc_accounts_dir, lang_reg,
nullptr);
348 list = gnc_load_example_account_list (account_path);
351 if (data->initial_category)
353 gtk_tree_row_reference_free (data->initial_category);
354 data->initial_category =
nullptr;
358 g_slist_foreach (list, (GFunc)add_one_category, data);
360 if (data->initial_category)
362 path = gtk_tree_row_reference_get_path (data->initial_category);
363 gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW(data->categories_tree),
364 path,
nullptr, TRUE, 0.5, 0.5);
367 path = gtk_tree_path_new_first ();
369 gtk_tree_selection_select_path (selection, path);
370 gtk_tree_path_free (path);
373 categories_tree_selection_changed (selection, data);
375 gnc_resume_gui_refresh ();
379 g_free (account_path);
385 region_combo_change_filter_cb (GtkComboBox *widget,
hierarchy_data *data)
387 GtkTreeModel *filter_model = gtk_combo_box_get_model (GTK_COMBO_BOX(data->region_combo));
388 GtkTreeModel *region_model = gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER(filter_model));
389 GtkTreeIter language_iter, region_iter, sorted_iter;
390 gboolean have_one_region = FALSE;
392 if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX(data->language_combo), &sorted_iter))
394 GtkTreeModel *sort_model = gtk_combo_box_get_model (GTK_COMBO_BOX(data->language_combo));
395 GtkTreeModel *language_model = gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT(sort_model));
396 GtkTreeIter *iter =
nullptr;
397 gchar *language =
nullptr;
401 gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT(sort_model),
405 gtk_tree_model_get (language_model, &language_iter, LANGUAGE_STRING, &language, -1);
406 valid = gtk_tree_model_get_iter_first (region_model, ®ion_iter);
411 gchar *region_test =
nullptr;
413 gtk_tree_model_get (region_model, ®ion_iter,
414 LANGUAGE_STRING, ®ion_test, -1);
416 if (g_strcmp0 (language, region_test) == 0)
418 gtk_list_store_set (GTK_LIST_STORE(region_model),
419 ®ion_iter, REGION_FILTER, TRUE, -1);
421 iter = gtk_tree_iter_copy (®ion_iter);
425 gtk_list_store_set (GTK_LIST_STORE(region_model),
426 ®ion_iter, REGION_FILTER, FALSE, -1);
428 g_free (region_test);
430 valid = gtk_tree_model_iter_next (region_model, ®ion_iter);
436 gchar *region_label =
nullptr;
437 GtkTreeIter filter_iter;
438 gtk_tree_model_filter_convert_child_iter_to_iter (GTK_TREE_MODEL_FILTER(filter_model),
442 gtk_combo_box_set_active_iter (GTK_COMBO_BOX(data->region_combo), &filter_iter);
444 have_one_region = TRUE;
446 gtk_tree_model_get (region_model, iter, REGION_STRING, ®ion_label, -1);
448 gtk_label_set_text (GTK_LABEL(data->region_label), region_label);
449 g_free (region_label);
454 if (gtk_combo_box_get_active (GTK_COMBO_BOX(data->region_combo)) == -1)
456 GtkTreeIter filter_iter;
458 gtk_tree_model_filter_convert_child_iter_to_iter (GTK_TREE_MODEL_FILTER(filter_model),
462 gtk_combo_box_set_active_iter (GTK_COMBO_BOX(data->region_combo), &filter_iter);
465 gtk_widget_set_visible (GTK_WIDGET(data->region_label), have_one_region);
466 gtk_widget_set_visible (GTK_WIDGET(data->region_combo), !have_one_region);
468 gtk_tree_iter_free (iter);
475 update_language_region_combos (
hierarchy_data *data,
const gchar *locale_dir)
477 GtkListStore *language_store = gtk_list_store_new (1, G_TYPE_STRING);
478 GtkListStore *region_store = gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN);
479 GtkTreeModel *filter_model = gtk_tree_model_filter_new (GTK_TREE_MODEL(region_store),
nullptr);
480 GtkTreeModel *sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL(language_store));
481 GtkTreeIter language_iter, region_iter;
482 gchar *start_region =
nullptr;
486 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE(sort_model), LANGUAGE_STRING, GTK_SORT_ASCENDING);
488 gtk_combo_box_set_model (GTK_COMBO_BOX(data->language_combo), GTK_TREE_MODEL(sort_model));
489 gtk_combo_box_set_model (GTK_COMBO_BOX(data->region_combo), GTK_TREE_MODEL(filter_model));
491 gtk_tree_model_filter_set_visible_column (GTK_TREE_MODEL_FILTER(filter_model), REGION_FILTER);
493 g_signal_connect (data->language_combo,
"changed",
494 G_CALLBACK(region_combo_change_filter_cb), (gpointer)data);
496 if (g_file_test (data->gnc_accounts_dir, G_FILE_TEST_IS_DIR))
498 GHashTable *testhash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
nullptr);
499 GDir *acct_dir = g_dir_open (data->gnc_accounts_dir, 0,
nullptr);
500 const gchar *name =
"a";
502 while (name !=
nullptr)
504 name = g_dir_read_name (acct_dir);
508 gchar **parts = g_strsplit (name,
"_", -1);
511 gtk_list_store_append (region_store, ®ion_iter);
512 gtk_list_store_set (region_store, ®ion_iter, LANG_REG_STRING, name,
513 LANGUAGE_STRING, parts[0], REGION_FILTER, TRUE, -1);
516 if (g_str_has_suffix (locale_dir, name))
518 GtkTreeIter filter_iter;
519 gtk_tree_model_filter_convert_child_iter_to_iter (GTK_TREE_MODEL_FILTER(filter_model),
523 gtk_combo_box_set_active_iter (GTK_COMBO_BOX(data->region_combo), &filter_iter);
524 start_region = g_strdup (parts[0]);
527 if (parts[1] !=
nullptr)
528 gtk_list_store_set (region_store, ®ion_iter, REGION_STRING, parts[1], -1);
530 gtk_list_store_set (region_store, ®ion_iter, REGION_STRING,
"--", -1);
533 if (g_strcmp0 (name,
"C") == 0)
535 gtk_list_store_set (region_store, ®ion_iter, LANGUAGE_STRING,
"en", REGION_STRING,
"US", -1);
536 lang_name = g_strdup (
"en");
538 if (g_str_has_suffix (locale_dir, name))
540 g_free (start_region);
541 start_region = g_strdup (lang_name);
545 lang_name = g_strdup (parts[0]);
548 if (g_hash_table_lookup (testhash, lang_name) ==
nullptr)
550 static const char* t_str{
"test"};
551 gtk_list_store_append (language_store, &language_iter);
552 gtk_list_store_set (language_store, &language_iter, LANGUAGE_STRING, lang_name, -1);
554 g_hash_table_insert (testhash, g_strdup (lang_name), &t_str);
560 g_hash_table_destroy (testhash);
561 g_dir_close (acct_dir);
565 valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL(language_store), &language_iter);
568 gchar *language_test =
nullptr;
570 gtk_tree_model_get (GTK_TREE_MODEL(language_store), &language_iter, LANGUAGE_STRING, &language_test, -1);
572 if (g_strcmp0 (language_test, start_region) == 0)
574 GtkTreeIter sort_iter;
575 gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT(sort_model),
579 gtk_combo_box_set_active_iter (GTK_COMBO_BOX(data->language_combo), &sort_iter);
581 g_free (language_test);
583 valid = gtk_tree_model_iter_next (GTK_TREE_MODEL(language_store), &language_iter);
585 g_signal_connect (data->region_combo,
"changed",
586 G_CALLBACK(region_combo_changed_cb), (gpointer)data);
588 g_object_unref (language_store);
589 g_object_unref (region_store);
590 g_free (start_region);
615 account_set_checked_helper (GtkListStore *store,
622 g_return_val_if_fail(GTK_IS_LIST_STORE(store), FALSE);
624 gtk_tree_model_get (GTK_TREE_MODEL(store), iter, COL_CHECKED, &checked, -1);
644 GtkWidget *currentpage;
645 GtkAssistant *assistant = GTK_ASSISTANT(data->dialog);
647 data->next_ok = FALSE;
648 gtk_tree_model_foreach (gtk_tree_view_get_model (data->categories_tree),
649 (GtkTreeModelForeachFunc)account_set_checked_helper,
652 currentpagenum = gtk_assistant_get_current_page(assistant);
653 currentpage = gtk_assistant_get_nth_page(assistant, currentpagenum);
655 gtk_assistant_set_page_complete(assistant, currentpage, data->next_ok);
660 categories_selection_changed (GtkTreeModel *treemodel,
665 data->category_set_changed = TRUE;
666 categories_page_enable_next(data);
671 add_one_category (GncExampleAccount *acc,
678 gboolean use_defaults;
680 g_return_if_fail(acc !=
nullptr);
681 g_return_if_fail(data !=
nullptr);
683 view = data->categories_tree;
684 store = GTK_LIST_STORE(gtk_tree_view_get_model(view));
685 use_defaults = data->use_defaults && acc->start_selected;
687 gtk_list_store_append(store, &iter);
688 gtk_list_store_set(store, &iter,
689 COL_CHECKED, use_defaults,
690 COL_TITLE, acc->title,
691 COL_SHORT_DESCRIPTION, acc->short_description,
692 COL_LONG_DESCRIPTION, acc->long_description,
698 data->category_set_changed = TRUE;
699 path = gtk_tree_model_get_path(GTK_TREE_MODEL(store), &iter);
700 data->initial_category = gtk_tree_row_reference_new(GTK_TREE_MODEL(store), path);
701 gtk_tree_path_free(path);
706 category_checkbox_toggled (GtkCellRendererToggle *toggle,
713 if (!gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(store),
718 active = gtk_cell_renderer_toggle_get_active(toggle);
719 gtk_list_store_set(store, &iter, COL_CHECKED, !active, -1);
727 GtkTreeView *tree_view;
729 GtkTreeViewColumn *column;
730 GtkCellRenderer *renderer;
731 GtkTreeSelection *selection;
734 data->gnc_accounts_dir = gnc_path_get_accountsdir ();
735 locale_dir = gnc_get_ea_locale_dir (data->gnc_accounts_dir);
738 list = gnc_load_example_account_list (locale_dir);
741 update_language_region_combos (data, locale_dir);
746 tree_view = data->categories_tree;
747 model = gtk_list_store_new(NUM_COLUMNS, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING,
748 G_TYPE_STRING, G_TYPE_POINTER);
749 gtk_tree_view_set_model (tree_view, GTK_TREE_MODEL(model));
750 g_object_unref (model);
752 g_slist_foreach(list, (GFunc)add_one_category, data);
754 g_signal_connect (G_OBJECT (model),
"row_changed",
755 G_CALLBACK (categories_selection_changed),
758 renderer = gtk_cell_renderer_toggle_new ();
759 g_object_set (G_OBJECT (renderer),
"activatable", TRUE,
nullptr);
760 column = gtk_tree_view_column_new_with_attributes (_(
"Selected"),
762 "active", COL_CHECKED,
764 gtk_tree_view_append_column (tree_view, column);
765 gtk_tree_view_column_set_sort_column_id (column, COL_CHECKED);
766 g_signal_connect (G_OBJECT (renderer),
"toggled",
767 G_CALLBACK (category_checkbox_toggled),
771 renderer = gtk_cell_renderer_text_new ();
772 column = gtk_tree_view_column_new_with_attributes (_(
"Account Types"),
776 gtk_tree_view_append_column (tree_view, column);
777 gtk_tree_view_column_set_sort_column_id (column, COL_TITLE);
787 gtk_tree_view_set_headers_clickable(tree_view, TRUE);
788 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE(model),
792 selection = gtk_tree_view_get_selection (tree_view);
794 if (data->initial_category)
796 path = gtk_tree_row_reference_get_path (data->initial_category);
797 gtk_tree_view_scroll_to_cell (tree_view, path,
nullptr, TRUE, 0.5, 0.5);
800 path = gtk_tree_path_new_first ();
802 gtk_tree_selection_select_path (selection, path);
803 gtk_tree_path_free (path);
808 void on_prepare (GtkAssistant *assistant, GtkWidget *page,
811 const int currency_page = data->new_book ? 2 : 1;
812 const int selection_page = data->new_book ? 3 : 2;
813 const int final_page = data->new_book ? 4 : 3;
814 const int current_page = gtk_assistant_get_current_page (assistant);
816 if (current_page == currency_page)
817 on_select_currency_prepare (data);
819 if (current_page == selection_page)
820 on_choose_account_categories_prepare (data);
822 if (current_page == final_page)
823 on_final_account_prepare (data);
829 GtkTextBuffer* buffer;
831 if (!data->account_list_added)
834 if (data->category_accounts_tree)
835 gtk_widget_destroy(GTK_WIDGET(data->category_accounts_tree));
836 data->category_accounts_tree =
nullptr;
837 buffer = gtk_text_view_get_buffer(data->category_description);
838 gtk_text_buffer_set_text(buffer,
"", -1);
840 data->account_list_added = TRUE;
843 gnc_suspend_gui_refresh ();
844 account_categories_tree_view_prepare (data);
845 gnc_resume_gui_refresh ();
847 categories_page_enable_next(data);
851 categories_tree_selection_changed (GtkTreeSelection *selection,
854 GtkTreeView *tree_view;
856 GtkTreeViewColumn *column;
858 GncExampleAccount *gea;
859 GtkTextBuffer* buffer;
863 if (data->category_accounts_tree)
864 gtk_widget_destroy(GTK_WIDGET(data->category_accounts_tree));
865 data->category_accounts_tree =
nullptr;
868 if (gtk_tree_selection_get_selected (selection, &model, &iter))
871 gtk_tree_model_get (model, &iter, COL_ACCOUNT, &gea, -1);
873 text2 = g_strdup_printf(_(
"Accounts in '%s'"), gea->title);
874 text = g_strdup_printf(
"<b>%s</b>", text2);
875 gtk_label_set_markup(data->category_accounts_label, text);
878 buffer = gtk_text_view_get_buffer(data->category_description);
879 gtk_text_buffer_set_text(buffer, gea->long_description ?
880 gea->long_description :
881 _(
"No description provided."), -1);
885 column = gtk_tree_view_get_column(GTK_TREE_VIEW(tree_view), 0);
886 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
888 data->category_accounts_tree = tree_view;
889 gtk_tree_view_expand_all (tree_view);
890 gtk_container_add(GTK_CONTAINER(data->category_accounts_container), GTK_WIDGET(tree_view));
891 gtk_widget_show(GTK_WIDGET(tree_view));
896 text = g_strdup_printf (
"<b>%s</b>", _(
"Accounts in Category"));
897 gtk_label_set_markup(data->category_accounts_label, text);
899 buffer = gtk_text_view_get_buffer(data->category_description);
900 gtk_text_buffer_set_text(buffer,
"", -1);
905 select_helper (GtkListStore *store,
910 GncExampleAccount *gea;
912 g_return_val_if_fail(GTK_IS_LIST_STORE(store), FALSE);
914 gtk_tree_model_get (GTK_TREE_MODEL(store), iter, COL_ACCOUNT, &gea, -1);
915 if ((gea !=
nullptr) && !gea->exclude_from_select_all)
917 gtk_list_store_set(store, iter,
918 COL_CHECKED, GPOINTER_TO_INT(data),
926 select_all_clicked (GtkButton *button,
929 gtk_tree_model_foreach (gtk_tree_view_get_model (data->categories_tree),
930 (GtkTreeModelForeachFunc)select_helper,
931 GINT_TO_POINTER(TRUE));
935 clear_all_clicked (GtkButton *button,
938 gtk_tree_model_foreach (gtk_tree_view_get_model (data->categories_tree),
939 (GtkTreeModelForeachFunc)select_helper,
940 GINT_TO_POINTER(FALSE));
950 if (data->our_account_tree !=
nullptr)
954 data->our_account_tree =
nullptr;
959 clone_account (
const Account* from, gnc_commodity *com)
978 add_groups_for_each (
Account *toadd, gpointer data)
987 foundact = clone_account (toadd, dadata->com);
991 else if (dadata->parent)
995 g_warning (
"add_groups_for_each: no valid parent");
1004 downdata.to = foundact;
1005 downdata.parent = foundact;
1006 downdata.com = dadata->com;
1014 add_new_accounts_with_random_guids (
Account *into,
Account *from,
1019 data.parent =
nullptr;
1026 hierarchy_merge_accounts (GSList *dalist, gnc_commodity *com)
1031 for (mark = dalist; mark; mark = mark->next)
1033 auto xea{
static_cast<GncExampleAccount*
>(mark->data)};
1035 add_new_accounts_with_random_guids (ret, xea->root, com);
1042 accumulate_accounts (GtkListStore *store,
1047 GncExampleAccount *gea;
1050 g_return_val_if_fail(GTK_IS_LIST_STORE(store), FALSE);
1052 gtk_tree_model_get (GTK_TREE_MODEL(store), iter,
1053 COL_CHECKED, &active,
1057 *list = g_slist_prepend(*list, gea);
1064 get_selected_account_list (GtkTreeView *tree_view)
1066 GSList *actlist =
nullptr;
1067 GtkTreeModel *model;
1069 model = gtk_tree_view_get_model (tree_view);
1070 gtk_tree_model_foreach (model,
1071 (GtkTreeModelForeachFunc)accumulate_accounts,
1077 balance_cell_data_func (GtkTreeViewColumn *tree_column,
1078 GtkCellRenderer *cell,
1079 GtkTreeModel *model,
1084 gnc_numeric balance;
1085 const gchar *string;
1088 gboolean allow_value;
1090 g_return_if_fail (GTK_TREE_MODEL (model));
1093 balance = get_final_balance (data->balance_hash, account);
1100 print_info = gnc_account_print_info (account, FALSE);
1107 allow_value = FALSE;
1112 GncAccountMergeDisposition disp;
1113 disp = determine_merge_disposition(gnc_book_get_root_account(gnc_get_current_book()), account);
1114 if (disp == GNC_ACCOUNT_MERGE_DISPOSITION_CREATE_NEW)
1120 allow_value = FALSE;
1121 string = _(
"existing account");
1124 g_object_set (G_OBJECT (cell),
1126 "editable", allow_value,
1127 "sensitive", allow_value,
1132 balance_cell_edited (GtkCellRendererText *cell,
1142 g_return_if_fail(data !=
nullptr);
1145 if (account ==
nullptr)
1147 g_critical(
"account is null");
1151 error_loc =
nullptr;
1152 if (!gnc_exp_parser_parse (new_text, &amount, &error_loc))
1154 amount = gnc_numeric_zero();
1155 g_object_set (G_OBJECT(cell),
"text",
"",
nullptr);
1166 set_final_balance (data->balance_hash, account, amount);
1167 qof_event_gen (QOF_INSTANCE(account), QOF_EVENT_MODIFY,
nullptr);
1171 placeholder_cell_data_func (GtkTreeViewColumn *tree_column,
1172 GtkCellRenderer *cell,
1173 GtkTreeModel *model,
1178 gboolean willbe_placeholder = FALSE;
1179 GncAccountMergeDisposition disp;
1181 g_return_if_fail (GTK_TREE_MODEL (model));
1183 root = gnc_book_get_root_account(gnc_get_current_book());
1184 disp = determine_merge_disposition(root, account);
1187 case GNC_ACCOUNT_MERGE_DISPOSITION_USE_EXISTING:
1198 case GNC_ACCOUNT_MERGE_DISPOSITION_CREATE_NEW:
1203 gtk_cell_renderer_toggle_set_active(GTK_CELL_RENDERER_TOGGLE(cell), willbe_placeholder);
1207 placeholder_cell_toggled (GtkCellRendererToggle *cell_renderer,
1208 gchar *path, gpointer user_data)
1212 GtkTreePath *treepath;
1215 g_return_if_fail(data !=
nullptr);
1217 treepath = gtk_tree_path_new_from_string (path);
1221 state = gtk_cell_renderer_toggle_get_active (cell_renderer);
1229 set_final_balance (data->balance_hash, account, gnc_numeric_zero());
1230 qof_event_gen (QOF_INSTANCE(account), QOF_EVENT_MODIFY,
nullptr);
1232 gtk_tree_path_free (treepath);
1236 use_existing_account_data_func(GtkTreeViewColumn *tree_column,
1237 GtkCellRenderer *cell,
1238 GtkTreeModel *tree_model,
1243 GncAccountMergeDisposition disposition;
1244 auto to_user{
"(error; unknown condition)"};
1246 g_return_if_fail (GTK_TREE_MODEL (tree_model));
1250 g_object_set (G_OBJECT(cell),
"text",
"(null account)",
nullptr);
1254 real_root = gnc_book_get_root_account(gnc_get_current_book());
1255 disposition = determine_merge_disposition(real_root, new_acct);
1256 switch (disposition)
1258 case GNC_ACCOUNT_MERGE_DISPOSITION_USE_EXISTING:
1261 case GNC_ACCOUNT_MERGE_DISPOSITION_CREATE_NEW:
1266 g_object_set(G_OBJECT(cell),
"text", to_user,
nullptr);
1273 GtkTreeView *tree_view;
1274 GtkTreeSelection *selection;
1275 GtkCellRenderer *renderer;
1276 GtkTreeViewColumn *column;
1280 if (!data->category_set_changed)
1282 data->category_set_changed = FALSE;
1284 gnc_suspend_gui_refresh ();
1287 if (data->final_account_tree)
1289 gtk_widget_destroy(GTK_WIDGET(data->final_account_tree));
1290 data->final_account_tree =
nullptr;
1292 delete_our_account_tree (data);
1296 actlist = get_selected_account_list (data->categories_tree);
1298 data->our_account_tree = hierarchy_merge_accounts (actlist, com);
1302 data->final_account_tree
1304 tree_view = GTK_TREE_VIEW(data->final_account_tree);
1305 gnc_tree_view_account_set_name_edited(data->final_account_tree,
1306 gnc_tree_view_account_name_edited_cb);
1307 gnc_tree_view_account_set_code_edited(data->final_account_tree,
1308 gnc_tree_view_account_code_edited_cb);
1309 gnc_tree_view_account_set_description_edited(data->final_account_tree,
1310 gnc_tree_view_account_description_edited_cb);
1311 gnc_tree_view_account_set_notes_edited(data->final_account_tree,
1312 gnc_tree_view_account_notes_edited_cb);
1314 gtk_tree_view_set_headers_visible (tree_view, TRUE);
1316 GNC_TREE_VIEW(data->final_account_tree),
"type");
1317 g_object_set_data(G_OBJECT(column), DEFAULT_VISIBLE, GINT_TO_POINTER(1));
1322 selection = gtk_tree_view_get_selection (tree_view);
1323 gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
1329 renderer = gtk_cell_renderer_toggle_new();
1330 g_object_set(G_OBJECT (renderer),
1331 "activatable", TRUE,
1335 g_signal_connect (G_OBJECT (renderer),
"toggled",
1336 G_CALLBACK (placeholder_cell_toggled),
1339 column = gtk_tree_view_column_new_with_attributes(_(
"Placeholder"),
1341 gtk_tree_view_column_set_cell_data_func (column, renderer,
1342 placeholder_cell_data_func,
1343 (gpointer)data,
nullptr);
1349 renderer = gtk_cell_renderer_text_new ();
1350 g_object_set (G_OBJECT (renderer),
1353 g_signal_connect (G_OBJECT (renderer),
"edited",
1354 G_CALLBACK (balance_cell_edited),
1356 column = gtk_tree_view_column_new_with_attributes (_(
"Opening Balance"),
1359 gtk_tree_view_column_set_cell_data_func (column, renderer,
1360 balance_cell_data_func,
1361 (gpointer)data,
nullptr);
1374 GNC_TREE_VIEW_COLUMN_DATA_NONE,
1375 GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS,
1377 renderers = gtk_cell_layout_get_cells(GTK_CELL_LAYOUT(column));
1378 g_object_set(G_OBJECT(renderer),
"xalign", 1.0, (
char*)
nullptr);
1379 gtk_tree_view_column_set_cell_data_func(column, GTK_CELL_RENDERER(renderers->data),
1380 use_existing_account_data_func, (gpointer)data,
nullptr);
1381 g_list_free(renderers);
1384 gtk_container_add(GTK_CONTAINER(data->final_account_tree_container),
1385 GTK_WIDGET(data->final_account_tree));
1388 gtk_tree_view_expand_all (tree_view);
1389 gtk_widget_show(GTK_WIDGET(data->final_account_tree));
1390 gnc_resume_gui_refresh ();
1394 on_cancel (GtkAssistant *gtkassistant,
1397 gnc_suspend_gui_refresh ();
1399 delete data->optionwin;
1401 delete_hierarchy_dialog (data);
1402 delete_our_account_tree (data);
1404 gnc_resume_gui_refresh ();
1410 gnc_numeric balance;
1412 balance = get_final_balance (data->balance_hash, account);
1413 if (gnc_reverse_balance(account))
1417 gnc_account_create_opening_balance (account, balance,
1419 gnc_get_current_book ());
1423 on_finish (GtkAssistant *gtkassistant,
1426 GncHierarchyAssistantFinishedCallback when_completed;
1432 if (!gnc_using_equity_type_opening_balance_account (gnc_get_current_book()))
1433 gnc_set_use_equity_type_opening_balance_account (gnc_get_current_book());
1435 if (data->our_account_tree)
1437 gnc_account_foreach_descendant (data->our_account_tree,
1438 (AccountCb)starting_balance_helper,
1444 if (data->initial_category)
1445 gtk_tree_row_reference_free(data->initial_category);
1446 delete_hierarchy_dialog (data);
1448 gnc_suspend_gui_refresh ();
1450 delete data->optionwin;
1452 account_trees_merge(gnc_get_current_root_account(), data->our_account_tree);
1454 delete_our_account_tree (data);
1456 when_completed = data->when_completed;
1459 root = gnc_get_current_root_account();
1462 gnc_resume_gui_refresh ();
1466 (*when_completed)();
1486 gtk_label_set_text (GTK_LABEL(data->currency_selector_label),
1487 ( _(
"Please choose the currency to use for new accounts.") ));
1488 gtk_widget_set_sensitive(data->currency_selector, TRUE);
1512 auto options{
static_cast<GncOptionDB*
>(user_data)};
1521 GtkWidget *vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
1522 gtk_box_set_homogeneous (GTK_BOX (vbox), FALSE);
1532 DIALOG_BOOK_OPTIONS_CM_CLASS,
1534 data->optionwin->build_contents(data->options,
false);
1536 data->optionwin->set_close_cb(book_options_dialog_close_cb,
1537 (gpointer)data->options);
1540 auto options = data->optionwin->get_notebook();
1541 auto parent = gtk_widget_get_parent (options);
1543 g_object_ref (options);
1544 gtk_container_remove (GTK_CONTAINER(parent), options);
1545 gtk_container_add (GTK_CONTAINER(vbox), options);
1546 g_object_unref (options);
1548 gtk_widget_show_all (vbox);
1549 gtk_assistant_insert_page (GTK_ASSISTANT(data->dialog), vbox, 1);
1550 gtk_assistant_set_page_title (GTK_ASSISTANT(data->dialog), vbox, _(
"New Book Options"));
1551 gtk_assistant_set_page_complete (GTK_ASSISTANT(data->dialog), vbox, TRUE);
1556 gnc_create_hierarchy_assistant (gboolean use_defaults, GncHierarchyAssistantFinishedCallback when_completed)
1560 GtkTreeView *tree_view;
1562 GtkBuilder *builder;
1571 data->new_book = gnc_is_new_book();
1573 builder = gtk_builder_new();
1574 gnc_builder_add_from_file (builder,
"assistant-hierarchy.glade",
"hierarchy_assistant");
1576 dialog = GTK_WIDGET(gtk_builder_get_object (builder,
"hierarchy_assistant"));
1577 data->dialog = dialog;
1580 gtk_widget_set_name (GTK_WIDGET(dialog),
"gnc-id-assistant-account-hierarchy");
1583 gtk_assistant_set_page_complete (GTK_ASSISTANT (dialog),
1584 GTK_WIDGET(gtk_builder_get_object(builder,
"intro_page_label")),
1586 gtk_assistant_set_page_complete (GTK_ASSISTANT (dialog),
1587 GTK_WIDGET(gtk_builder_get_object(builder,
"currency_book_option_page_vbox")),
1589 gtk_assistant_set_page_complete (GTK_ASSISTANT (dialog),
1590 GTK_WIDGET(gtk_builder_get_object(builder,
"final_account_vbox")),
1592 gtk_assistant_set_page_complete (GTK_ASSISTANT (dialog),
1593 GTK_WIDGET(gtk_builder_get_object(builder,
"finish_page_label")),
1600 gtk_widget_show (data->currency_selector);
1601 box = GTK_WIDGET(gtk_builder_get_object (builder,
"currency_chooser_hbox"));
1602 data->currency_selector_label = GTK_WIDGET(gtk_builder_get_object (builder,
1603 "choose_currency_label"));
1604 gtk_box_pack_start(GTK_BOX(box), data->currency_selector, TRUE, TRUE, 0);
1607 tree_view = GTK_TREE_VIEW(gtk_builder_get_object (builder,
"account_categories_tree_view"));
1608 g_signal_connect (G_OBJECT (gtk_tree_view_get_selection (tree_view)),
"changed",
1609 G_CALLBACK (categories_tree_selection_changed), data);
1610 gtk_tree_selection_set_mode (gtk_tree_view_get_selection (tree_view), GTK_SELECTION_SINGLE);
1611 data->categories_tree = tree_view;
1613 data->language_combo = GTK_WIDGET(gtk_builder_get_object (builder,
"language_combo"));
1614 data->region_combo = GTK_WIDGET(gtk_builder_get_object (builder,
"region_combo"));
1615 data->region_label = GTK_WIDGET(gtk_builder_get_object (builder,
"region_label"));
1617 data->category_accounts_label = GTK_LABEL(gtk_builder_get_object (builder,
"accounts_in_category_label"));
1618 data->category_accounts_container = GTK_WIDGET(gtk_builder_get_object (builder,
"accounts_in_category"));
1619 data->category_description = GTK_TEXT_VIEW(gtk_builder_get_object (builder,
"account_types_description"));
1620 data->account_list_added = FALSE;
1624 assistant_insert_book_options_page (data);
1627 data->final_account_tree_container = GTK_WIDGET(gtk_builder_get_object (builder,
"final_account_tree_box"));
1628 data->final_account_tree =
nullptr;
1630 data->balance_hash = g_hash_table_new(
nullptr,
nullptr);
1632 gnc_restore_window_size (GNC_PREFS_GROUP,
1635 g_signal_connect (G_OBJECT(dialog),
"destroy",
1636 G_CALLBACK (gnc_hierarchy_destroy_cb), data);
1638 gtk_builder_connect_signals(builder, data);
1639 g_object_unref(G_OBJECT(builder));
1641 data->when_completed = when_completed;
1642 data->use_defaults = use_defaults;
1643 gtk_widget_show_all (dialog);
1648 gnc_ui_hierarchy_assistant(gboolean use_defaults)
1650 return gnc_create_hierarchy_assistant(use_defaults,
nullptr);
1654 gnc_ui_hierarchy_assistant_with_callback(gboolean use_defaults,
1655 GncHierarchyAssistantFinishedCallback when_finished)
1657 return gnc_create_hierarchy_assistant(use_defaults, when_finished);
1661 after_assistant(
void)
1668 gnc_ui_hierarchy_assistant_hook (
void)
1672 gnc_ui_hierarchy_assistant_with_callback(TRUE, after_assistant);
1677 gnc_ui_hierarchy_assistant_initialize (
void)
1679 gnc_hook_add_dangler(HOOK_NEW_BOOK,
1680 (GFunc)gnc_ui_hierarchy_assistant_hook,
Holds all of the options for a book, report, or stylesheet, organized by GncOptionSections.
void gnc_option_db_clean(GncOptionDB *odb)
Reset all ui_items to the option value.
gboolean gnc_commodity_is_currency(const gnc_commodity *cm)
Checks to see if the specified commodity is an ISO 4217 recognized currency or a legacy currency...
void qof_book_load_options(QofBook *book, GncOptionLoad load_cb, GncOptionDB *odb)
Load a GncOptionsDB from KVP data.
void gnc_account_append_child(Account *new_parent, Account *child)
This function will remove from the child account any pre-existing parent relationship, and will then add the account as a child of the new parent.
gint gnc_account_n_descendants(const Account *account)
Return the number of descendants of the specified account.
void gnc_currency_edit_set_currency(GNCCurrencyEdit *gce, const gnc_commodity *currency)
Set the widget to display a certain currency name.
GtkWindow * gnc_ui_get_main_window(GtkWidget *widget)
Get a pointer to the final GncMainWindow widget is rooted in.
utility functions for the GnuCash UI
GNCAccountType xaccAccountGetType(const Account *acc)
Returns the account's account type.
int xaccAccountGetCommoditySCU(const Account *acc)
Return the SCU for the account.
gnc_numeric gnc_numeric_neg(gnc_numeric a)
Returns a newly created gnc_numeric that is the negative of the given gnc_numeric value...
const char * xaccPrintAmount(gnc_numeric val, GNCPrintAmountInfo info)
Make a string representation of a gnc_numeric.
GHashTable * balance_hash
Map<Account*,gnc_numeric*>
gboolean gnc_numeric_zero_p(gnc_numeric a)
Returns 1 if the given gnc_numeric is 0 (zero), else returns 0.
C public interface for the Options Database.
void gnc_tree_view_set_show_column_menu(GncTreeView *view, gboolean visible)
This function is called to set the "show-column-menu" property on this 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.
Functions for adding content to a window.
gnc_commodity * gnc_default_currency(void)
Return the default currency set by the user.
Account used to record multiple commodity transactions.
void xaccAccountDestroy(Account *acc)
The xaccAccountDestroy() routine can be used to get rid of an account.
Account * gnc_account_lookup_by_name(const Account *parent, const char *name)
The gnc_account_lookup_by_name() subroutine fetches the account by name from the descendants of the s...
#define PWARN(format, args...)
Log a warning.
gint gnc_tree_view_append_column(GncTreeView *view, GtkTreeViewColumn *column)
Add a column to a view based upon a GncTreeView.
Currency selection widget.
void gnc_options_dialog_set_new_book_option_values(GncOptionDB *odb)
Set the initial values of new book options to values specified in user preferences.
gchar * gnc_account_get_full_name(const Account *account)
The gnc_account_get_full_name routine returns the fully qualified name of the account using the given...
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 '...
void xaccAccountSetPlaceholder(Account *acc, gboolean val)
Set the "placeholder" flag for an account.
GtkTreeView implementation for gnucash account tree.
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...
GtkTreeView * gnc_tree_view_account_new_with_root(Account *root, gboolean show_root)
Create a new account tree view.
void gnc_option_db_load(GncOptionDB *odb, QofBook *book)
Load a book's options into the GncOptionDB.
void gnc_option_db_destroy(GncOptionDB *odb)
Destruct and release a GncOptionDB.
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_book_options_dialog_apply_helper(GncOptionDB *options)
Processes selected options in the Book Options dialog: checks book_currency and use_split_action_for_...
gnc_commodity * gnc_currency_edit_get_currency(GNCCurrencyEdit *gce)
Retrieve the displayed currency of the widget.
Account * gnc_tree_view_account_get_account_from_iter(GtkTreeModel *s_model, GtkTreeIter *s_iter)
This function returns the account associated with the specified iter.
Account * gnc_account_lookup_by_full_name(const Account *any_acc, const gchar *name)
The gnc_account_lookup_full_name() subroutine works like gnc_account_lookup_by_name, but uses fully-qualified names using the given separator.
Account * gnc_tree_view_account_get_account_from_path(GncTreeViewAccount *view, GtkTreePath *s_path)
This function returns the account associated with the specified path.
Gnome specific utility functions.
Account * xaccCloneAccount(const Account *from, QofBook *book)
The xaccCloneAccount() routine makes a simple copy of the indicated account, placing it in the indica...
gint gnc_account_n_children(const Account *account)
Return the number of children of the specified account.
All type declarations for the whole Gnucash engine.
void qof_book_mark_session_dirty(QofBook *book)
The qof_book_mark_dirty() routine marks the book as having been modified.
Generic api to store and retrieve preferences.
Functions providing a chart of account page.
GtkWidget * gnc_currency_edit_new(void)
Create a new GNCCurrencyEdit widget which can be used to provide an easy way to enter ISO currency co...
void qof_event_suspend(void)
Suspend all engine events.
void xaccAccountBeginEdit(Account *acc)
The xaccAccountBeginEdit() subroutine is the first phase of a two-phase-commit wrapper for account up...
gnc_commodity * xaccAccountGetCommodity(const Account *acc)
Get the account's commodity.
void qof_event_resume(void)
Resume engine event generation.
GtkTreeViewColumn * gnc_tree_view_add_text_column(GncTreeView *view, const gchar *column_title, const gchar *pref_name, const gchar *icon_name, const gchar *sizing_text, gint model_data_column, gint model_visibility_column, GtkTreeIterCompareFunc column_sort_fn)
This function adds a new text column to a GncTreeView base view.
gboolean xaccAccountGetPlaceholder(const Account *acc)
Get the "placeholder" flag for an account.
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Get a boolean value from the preferences backend.
Account * gnc_tree_view_account_get_selected_account(GncTreeViewAccount *view)
This function returns the account associated with the selected item in the account tree view...
#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...
Account * xaccMallocAccount(QofBook *book)
Constructor.
time64 gnc_time(time64 *tbuf)
get the current time
This file contains the functions to present a GUI to select a file or a database connection.
const char * xaccAccountGetName(const Account *acc)
Get the account's name.
Equity account is used to balance the balance sheet.
void qof_event_gen(QofInstance *entity, QofEventId event_id, gpointer event_data)
Invoke all registered event handlers using the given arguments.
void gnc_option_db_book_options(GncOptionDB *odb)
Register the standard option set for a QofBook.
void xaccAccountSetCommodity(Account *acc, gnc_commodity *com)
Set the account's commodity.
GncOptionDB * gnc_option_db_new(void)
Create an empty option database.