GnuCash c935c2f+
Loading...
Searching...
No Matches
Public Member Functions | Friends
CsvImpTransAssist Class Reference

Public Member Functions

 CsvImpTransAssist (const CsvImpTransAssist &)=delete
 
CsvImpTransAssistoperator= (const CsvImpTransAssist &)=delete
 
 CsvImpTransAssist (CsvImpTransAssist &&)=delete
 
CsvImpTransAssistoperator= (CsvImpTransAssist &&)=delete
 
void assist_prepare_cb (GtkWidget *page)
 
void assist_file_page_prepare ()
 
void assist_preview_page_prepare ()
 
void assist_account_match_page_prepare ()
 
void assist_doc_page_prepare ()
 
void assist_match_page_prepare ()
 
void assist_summary_page_prepare ()
 
void assist_finish ()
 
void assist_compmgr_close ()
 
void file_activated_cb ()
 
void file_selection_changed_cb ()
 
void preview_settings_delete ()
 
void preview_settings_save ()
 
void preview_settings_name (GtkEntry *entry)
 
void preview_settings_load ()
 
void preview_update_skipped_rows ()
 
void preview_multi_split (bool multi)
 
void preview_update_separators (GtkWidget *widget)
 Event handler for separator changes.
 
void preview_update_file_format ()
 Event handler for clicking one of the format type radio buttons.
 
void preview_update_account ()
 
void preview_update_encoding (const char *encoding)
 Event handler for a new encoding.
 
void preview_update_date_format ()
 
void preview_update_currency_format ()
 
void preview_update_col_type (GtkComboBox *cbox)
 Event handler for the user selecting a new column type.
 
void preview_update_fw_columns (GtkTreeView *treeview, GdkEventButton *event)
 Event handler for clicking on column headers.
 
void preview_populate_settings_combo ()
 
void preview_handle_save_del_sensitivity (GtkComboBox *combo)
 
void preview_split_column (int col, int offset)
 
void preview_refresh_table ()
 
void preview_refresh ()
 
void preview_validate_settings ()
 
void acct_match_via_button ()
 
bool acct_match_via_view_dblclick (GdkEventButton *event)
 
void acct_match_select (GtkTreeModel *model, GtkTreeIter *iter)
 
void acct_match_set_accounts ()
 

Friends

gboolean fixed_context_menu_handler (GnumericPopupMenuElement const *element, gpointer userdata)
 

Detailed Description

Definition at line 152 of file assistant-csv-trans-import.cpp.

Constructor & Destructor Documentation

◆ CsvImpTransAssist()

CsvImpTransAssist::CsvImpTransAssist ( )

Definition at line 469 of file assistant-csv-trans-import.cpp.

470{
471 auto builder = gtk_builder_new();
472 gnc_builder_add_from_file (builder , "assistant-csv-trans-import.glade", "start_row_adj");
473 gnc_builder_add_from_file (builder , "assistant-csv-trans-import.glade", "end_row_adj");
474 gnc_builder_add_from_file (builder , "assistant-csv-trans-import.glade", "account_match_store");
475 gnc_builder_add_from_file (builder , "assistant-csv-trans-import.glade", "csv_transaction_assistant");
476 csv_imp_asst = GTK_ASSISTANT(gtk_builder_get_object (builder, "csv_transaction_assistant"));
477
478 // Set the name for this assistant so it can be easily manipulated with css
479 gtk_widget_set_name (GTK_WIDGET(csv_imp_asst), "gnc-id-assistant-csv-transaction-import");
480 gnc_widget_style_context_add_class (GTK_WIDGET(csv_imp_asst), "gnc-class-imports");
481
482 /* Enable buttons on all page. */
483 gtk_assistant_set_page_complete (csv_imp_asst,
484 GTK_WIDGET(gtk_builder_get_object (builder, "start_page")),
485 true);
486 gtk_assistant_set_page_complete (csv_imp_asst,
487 GTK_WIDGET(gtk_builder_get_object (builder, "file_page")),
488 false);
489 gtk_assistant_set_page_complete (csv_imp_asst,
490 GTK_WIDGET(gtk_builder_get_object (builder, "preview_page")),
491 false);
492 gtk_assistant_set_page_complete (csv_imp_asst,
493 GTK_WIDGET(gtk_builder_get_object (builder, "account_match_page")),
494 false);
495 gtk_assistant_set_page_complete (csv_imp_asst,
496 GTK_WIDGET(gtk_builder_get_object (builder, "doc_page")),
497 true);
498 gtk_assistant_set_page_complete (csv_imp_asst,
499 GTK_WIDGET(gtk_builder_get_object (builder, "match_page")),
500 true);
501 gtk_assistant_set_page_complete (csv_imp_asst,
502 GTK_WIDGET(gtk_builder_get_object (builder, "summary_page")),
503 true);
504
505 /* File chooser Page */
506 file_page = GTK_WIDGET(gtk_builder_get_object (builder, "file_page"));
507 file_chooser = gtk_file_chooser_widget_new (GTK_FILE_CHOOSER_ACTION_OPEN);
508 g_signal_connect (G_OBJECT(file_chooser), "selection-changed",
509 G_CALLBACK(csv_tximp_file_selection_changed_cb), this);
510 g_signal_connect (G_OBJECT(file_chooser), "file-activated",
511 G_CALLBACK(csv_tximp_file_activated_cb), this);
512
513 auto box = GTK_WIDGET(gtk_builder_get_object (builder, "file_page"));
514 gtk_box_pack_start (GTK_BOX(box), file_chooser, TRUE, TRUE, 6);
515 gtk_widget_show (file_chooser);
516
517 /* Preview Settings Page */
518 {
519 preview_page = GTK_WIDGET(gtk_builder_get_object (builder, "preview_page"));
520
521 // Add Settings combo
522 auto settings_store = gtk_list_store_new (2, G_TYPE_POINTER, G_TYPE_STRING);
523 settings_combo = GTK_COMBO_BOX(gtk_combo_box_new_with_model_and_entry (GTK_TREE_MODEL(settings_store)));
524 g_object_unref (settings_store);
525 gtk_combo_box_set_entry_text_column (GTK_COMBO_BOX(settings_combo), SET_NAME);
526 gtk_combo_box_set_active (GTK_COMBO_BOX(settings_combo), 0);
527
528 combo_hbox = GTK_WIDGET(gtk_builder_get_object (builder, "combo_hbox"));
529 gtk_box_pack_start (GTK_BOX(combo_hbox), GTK_WIDGET(settings_combo), true, true, 6);
530 gtk_widget_show (GTK_WIDGET(settings_combo));
531
532 g_signal_connect (G_OBJECT(settings_combo), "changed",
533 G_CALLBACK(csv_tximp_preview_settings_sel_changed_cb), this);
534
535 // Additionally connect to the changed signal of the embedded GtkEntry
536 auto emb_entry = gtk_bin_get_child (GTK_BIN (settings_combo));
537 g_signal_connect (G_OBJECT(emb_entry), "changed",
538 G_CALLBACK(csv_tximp_preview_settings_text_changed_cb), this);
539 g_signal_connect (G_OBJECT(emb_entry), "insert-text",
540 G_CALLBACK(csv_tximp_preview_settings_text_inserted_cb), this);
541
542 // Add Save Settings button
543 save_button = GTK_WIDGET(gtk_builder_get_object (builder, "save_settings"));
544
545 // Add Delete Settings button
546 del_button = GTK_WIDGET(gtk_builder_get_object (builder, "delete_settings"));
547
548 /* The table containing the separator configuration widgets */
549 start_row_spin = GTK_SPIN_BUTTON(gtk_builder_get_object (builder, "start_row"));
550 end_row_spin = GTK_SPIN_BUTTON(gtk_builder_get_object (builder, "end_row"));
551 skip_alt_rows_button = GTK_WIDGET(gtk_builder_get_object (builder, "skip_rows"));
552 skip_errors_button = GTK_WIDGET(gtk_builder_get_object (builder, "skip_errors_button"));
553 multi_split_cbutton = GTK_WIDGET(gtk_builder_get_object (builder, "multi_split_button"));
554 separator_table = GTK_WIDGET(gtk_builder_get_object (builder, "separator_table"));
555 fw_instructions_hbox = GTK_WIDGET(gtk_builder_get_object (builder, "fw_instructions_hbox"));
556
557 /* Load the separator buttons from the glade builder file into the
558 * sep_buttons array. */
559 const char* sep_button_names[] = {
560 "space_cbutton",
561 "tab_cbutton",
562 "comma_cbutton",
563 "colon_cbutton",
564 "semicolon_cbutton",
565 "hyphen_cbutton"
566 };
567 for (int i = 0; i < SEP_NUM_OF_TYPES; i++)
568 sep_button[i]
569 = GTK_CHECK_BUTTON(gtk_builder_get_object (builder, sep_button_names[i]));
570
571 /* Load and connect the custom separator checkbutton in the same way
572 * as the other separator buttons. */
573 custom_cbutton
574 = GTK_CHECK_BUTTON(gtk_builder_get_object (builder, "custom_cbutton"));
575
576 /* Load the entry for the custom separator entry. Connect it to the
577 * sep_button_clicked event handler as well. */
578 custom_entry = GTK_ENTRY(gtk_builder_get_object (builder, "custom_entry"));
579
580 /* Load and connect the escape checkbutton in the same way
581 * as the other separator buttons. */
582 escape_cbutton
583 = GTK_CHECK_BUTTON(gtk_builder_get_object (builder, "escape_cbutton"));
584
585 /* Add account selection widget */
586 acct_selector = gnc_account_sel_new();
587 auto account_hbox = GTK_WIDGET(gtk_builder_get_object (builder, "account_hbox"));
588 gtk_box_pack_start (GTK_BOX(account_hbox), acct_selector, TRUE, TRUE, 6);
589 gtk_widget_show (acct_selector);
590
591 g_signal_connect(G_OBJECT(acct_selector), "account_sel_changed",
592 G_CALLBACK(csv_tximp_preview_acct_sel_cb), this);
593
594
595 /* Create the encoding selector widget and add it to the assistant */
596 encselector = GO_CHARMAP_SEL(go_charmap_sel_new(GO_CHARMAP_SEL_TO_UTF8));
597 /* Connect the selector to the encoding_selected event handler. */
598 g_signal_connect (G_OBJECT(encselector), "charmap_changed",
599 G_CALLBACK(csv_tximp_preview_enc_sel_cb), this);
600
601 auto encoding_container = GTK_CONTAINER(gtk_builder_get_object (builder, "encoding_container"));
602 gtk_container_add (encoding_container, GTK_WIDGET(encselector));
603 gtk_widget_set_hexpand (GTK_WIDGET(encselector), true);
604 gtk_widget_show_all (GTK_WIDGET(encoding_container));
605
606 /* The instructions label and image */
607 instructions_label = GTK_LABEL(gtk_builder_get_object (builder, "instructions_label"));
608 instructions_image = GTK_IMAGE(gtk_builder_get_object (builder, "instructions_image"));
609
610 /* Add in the date format combo box and hook it up to an event handler. */
611 date_format_combo = GTK_COMBO_BOX_TEXT(gtk_combo_box_text_new());
612 for (auto& date_fmt : GncDate::c_formats)
613 gtk_combo_box_text_append_text (date_format_combo, _(date_fmt.m_fmt.c_str()));
614 gtk_combo_box_set_active (GTK_COMBO_BOX(date_format_combo), 0);
615 g_signal_connect (G_OBJECT(date_format_combo), "changed",
616 G_CALLBACK(csv_tximp_preview_date_fmt_sel_cb), this);
617
618 /* Add it to the assistant. */
619 auto date_format_container = GTK_CONTAINER(gtk_builder_get_object (builder, "date_format_container"));
620 gtk_container_add (date_format_container, GTK_WIDGET(date_format_combo));
621 gtk_widget_set_hexpand (GTK_WIDGET(date_format_combo), true);
622 gtk_widget_show_all (GTK_WIDGET(date_format_container));
623
624 /* Add in the currency format combo box and hook it up to an event handler. */
625 currency_format_combo = GTK_COMBO_BOX_TEXT(gtk_combo_box_text_new());
626 for (int i = 0; i < num_currency_formats; i++)
627 {
628 gtk_combo_box_text_append_text (currency_format_combo, _(currency_format_user[i]));
629 }
630 /* Default will the locale */
631 gtk_combo_box_set_active (GTK_COMBO_BOX(currency_format_combo), 0);
632 g_signal_connect (G_OBJECT(currency_format_combo), "changed",
633 G_CALLBACK(csv_tximp_preview_currency_fmt_sel_cb), this);
634
635 /* Add it to the assistant. */
636 auto currency_format_container = GTK_CONTAINER(gtk_builder_get_object (builder, "currency_format_container"));
637 gtk_container_add (currency_format_container, GTK_WIDGET(currency_format_combo));
638 gtk_widget_set_hexpand (GTK_WIDGET(currency_format_combo), true);
639 gtk_widget_show_all (GTK_WIDGET(currency_format_container));
640
641 /* Connect the CSV/Fixed-Width radio button event handler. */
642 csv_button = GTK_WIDGET(gtk_builder_get_object (builder, "csv_button"));
643 fixed_button = GTK_WIDGET(gtk_builder_get_object (builder, "fixed_button"));
644
645 /* Load the data treeview and connect it to its resizing event handler. */
646 treeview = GTK_TREE_VIEW(gtk_builder_get_object (builder, "treeview"));
647 gtk_tree_view_set_headers_clickable (treeview, true);
648
649 /* This is true only after encoding_selected is called, so we must
650 * set it initially to false. */
651 encoding_selected_called = false;
652 }
653
654 /* Account Match Page */
655 account_match_page = GTK_WIDGET(gtk_builder_get_object (builder, "account_match_page"));
656 account_match_view = GTK_WIDGET(gtk_builder_get_object (builder, "account_match_view"));
657 account_match_label = GTK_WIDGET(gtk_builder_get_object (builder, "account_match_label"));
658 account_match_btn = GTK_WIDGET(gtk_builder_get_object (builder, "account_match_change"));
659
660 /* Doc Page */
661 doc_page = GTK_WIDGET(gtk_builder_get_object (builder, "doc_page"));
662
663 /* Matcher page */
664 match_page = GTK_WIDGET(gtk_builder_get_object (builder, "match_page"));
665 match_label = GTK_WIDGET(gtk_builder_get_object (builder, "match_label"));
666
667 /* Create the generic transaction importer GUI.
668 Note, this will call g_new0 internally. The returned object is g_freed again
669 either directly by the main matcher or in our assistant_finish code of the matcher
670 is never reached. */
671 gnc_csv_importer_gui = gnc_gen_trans_assist_new (GTK_WIDGET(csv_imp_asst),
672 match_page, nullptr, false, 42);
673
674 /* Summary Page */
675 summary_page = GTK_WIDGET(gtk_builder_get_object (builder, "summary_page"));
676 summary_label = GTK_WIDGET(gtk_builder_get_object (builder, "summary_label"));
677
678 gnc_restore_window_size (GNC_PREFS_GROUP,
679 GTK_WINDOW(csv_imp_asst), gnc_ui_get_main_window(nullptr));
680
681 gtk_builder_connect_signals (builder, this);
682 g_object_unref (G_OBJECT(builder));
683
684 gtk_widget_show_all (GTK_WIDGET(csv_imp_asst));
685 gnc_window_adjust_for_screen (GTK_WINDOW(csv_imp_asst));
686
687 /* In order to trigger a book options display on the creation of a new book,
688 * we need to detect when we are dealing with a new book. */
689 new_book = gnc_is_new_book();
690}
GnuCash Date class.
GtkWindow * gnc_ui_get_main_window(GtkWidget *widget)
Get a pointer to the final GncMainWindow widget is rooted in.
GNCImportMainMatcher * gnc_gen_trans_assist_new(GtkWidget *parent, GtkWidget *assistant_page, const gchar *heading, bool all_from_same_account, gint match_date_hardlimit)
Add the Transaction matcher to an existing page of an assistant.

◆ ~CsvImpTransAssist()

CsvImpTransAssist::~CsvImpTransAssist ( )

Definition at line 696 of file assistant-csv-trans-import.cpp.

697{
698 /* This function is safe to call on a null pointer */
699 gnc_gen_trans_list_delete (gnc_csv_importer_gui);
700 /* The call above frees gnc_csv_importer_gui but can't nullify it.
701 * Do it here so no one accidentally can access it still */
702 gnc_csv_importer_gui = nullptr;
703 gtk_widget_destroy (GTK_WIDGET(csv_imp_asst));
704}
void gnc_gen_trans_list_delete(GNCImportMainMatcher *info)
Deletes the given object.

Member Function Documentation

◆ acct_match_select()

void CsvImpTransAssist::acct_match_select ( GtkTreeModel *  model,
GtkTreeIter *  iter 
)

Definition at line 1897 of file assistant-csv-trans-import.cpp.

1898{
1899 // Get the stored string and account (if any)
1900 gchar *text = nullptr;
1901 Account *account = nullptr;
1902 gtk_tree_model_get (model, iter, MAPPING_STRING, &text,
1903 MAPPING_ACCOUNT, &account, -1);
1904
1905 auto acct_name = csv_tximp_acct_match_text_parse (text);
1906 auto gnc_acc = gnc_import_select_account (GTK_WIDGET(csv_imp_asst), nullptr, true,
1907 acct_name.c_str(), nullptr, ACCT_TYPE_NONE, account, nullptr);
1908
1909 if (gnc_acc) // We may have canceled
1910 {
1911 auto fullpath = gnc_account_get_full_name (gnc_acc);
1912 gtk_list_store_set (GTK_LIST_STORE(model), iter,
1913 MAPPING_ACCOUNT, gnc_acc,
1914 MAPPING_FULLPATH, fullpath, -1);
1915
1916 // Update the account kvp mappings
1917 if (text && *text)
1918 {
1919 gnc_account_imap_delete_account (account, IMAP_CAT_CSV, text);
1920 gnc_account_imap_add_account (gnc_acc, IMAP_CAT_CSV, text, gnc_acc);
1921 }
1922
1923 // Force reparsing of account columns - may impact multi-currency mode
1924 auto col_types = tx_imp->column_types();
1925 auto col_type_it = std::find (col_types.cbegin(),
1926 col_types.cend(), GncTransPropType::ACCOUNT);
1927 if (col_type_it != col_types.cend())
1928 tx_imp->set_column_type(col_type_it - col_types.cbegin(),
1929 GncTransPropType::ACCOUNT, true);
1930 col_type_it = std::find (col_types.cbegin(),
1931 col_types.cend(), GncTransPropType::TACCOUNT);
1932 if (col_type_it != col_types.cend())
1933 tx_imp->set_column_type(col_type_it - col_types.cbegin(),
1934 GncTransPropType::TACCOUNT, true);
1935
1936 g_free (fullpath);
1937 }
1938 g_free (text);
1939
1940
1941 /* Enable the "Next" Assistant Button */
1942 auto all_checked = csv_tximp_acct_match_check_all (model);
1943 gtk_assistant_set_page_complete (csv_imp_asst, account_match_page,
1944 all_checked);
1945
1946 /* Update information message and whether to display account errors */
1947 m_req_mapped_accts = all_checked;
1948 auto errs = tx_imp->verify(m_req_mapped_accts);
1949 gtk_label_set_text (GTK_LABEL(account_match_label), errs.c_str());
1950}
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...
Definition Account.cpp:3305
@ ACCT_TYPE_NONE
Not a type.
Definition Account.h:105
Account * gnc_import_select_account(GtkWidget *parent, const gchar *account_online_id_value, gboolean prompt_on_no_match, const gchar *account_human_description, const gnc_commodity *new_account_default_commodity, GNCAccountType new_account_default_type, Account *default_selection, gboolean *ok_pressed)
Must be called with a string containing a unique identifier for the account.
STRUCTS.

◆ acct_match_set_accounts()

void CsvImpTransAssist::acct_match_set_accounts ( )

Definition at line 1788 of file assistant-csv-trans-import.cpp.

1789{
1790 auto store = gtk_tree_view_get_model (GTK_TREE_VIEW(account_match_view));
1791 gtk_list_store_clear (GTK_LIST_STORE(store));
1792
1793 auto accts = tx_imp->accounts();
1794 for (auto acct : accts)
1795 {
1796 GtkTreeIter acct_iter;
1797 gtk_list_store_append (GTK_LIST_STORE(store), &acct_iter);
1798 gtk_list_store_set (GTK_LIST_STORE(store), &acct_iter, MAPPING_STRING, acct.c_str(),
1799 MAPPING_FULLPATH, _("No Linked Account"), MAPPING_ACCOUNT, nullptr, -1);
1800 }
1801}

◆ acct_match_via_button()

void CsvImpTransAssist::acct_match_via_button ( )

Definition at line 1953 of file assistant-csv-trans-import.cpp.

1954{
1955 auto model = gtk_tree_view_get_model (GTK_TREE_VIEW(account_match_view));
1956 auto selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(account_match_view));
1957
1958 GtkTreeIter iter;
1959 if (gtk_tree_selection_get_selected (selection, &model, &iter))
1960 acct_match_select (model, &iter);
1961}

◆ acct_match_via_view_dblclick()

bool CsvImpTransAssist::acct_match_via_view_dblclick ( GdkEventButton *  event)

Definition at line 1966 of file assistant-csv-trans-import.cpp.

1967{
1968 /* This is for a double click */
1969 if (event->button == 1 && event->type == GDK_2BUTTON_PRESS)
1970 {
1971 auto window = gtk_tree_view_get_bin_window (GTK_TREE_VIEW (account_match_view));
1972 if (event->window != window)
1973 return false;
1974
1975 /* Get tree path for row that was clicked, true if row exists */
1976 GtkTreePath *path;
1977 if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (account_match_view), (gint) event->x, (gint) event->y,
1978 &path, nullptr, nullptr, nullptr))
1979 {
1980 DEBUG("event->x is %d and event->y is %d", (gint)event->x, (gint)event->y);
1981
1982 auto model = gtk_tree_view_get_model (GTK_TREE_VIEW(account_match_view));
1983 GtkTreeIter iter;
1984 if (gtk_tree_model_get_iter (model, &iter, path))
1985 acct_match_select (model, &iter);
1986 gtk_tree_path_free (path);
1987 }
1988 return true;
1989 }
1990 return false;
1991}
#define DEBUG(format, args...)
Print a debugging message.
Definition qoflog.h:264

◆ assist_account_match_page_prepare()

void CsvImpTransAssist::assist_account_match_page_prepare ( )

Definition at line 2071 of file assistant-csv-trans-import.cpp.

2072{
2073
2074 // Load the account strings into the store
2075 acct_match_set_accounts ();
2076
2077 // Match the account strings to account maps from previous imports
2078 auto store = gtk_tree_view_get_model (GTK_TREE_VIEW(account_match_view));
2079 csv_tximp_acct_match_load_mappings (store);
2080
2081 // Enable the view, possibly after an error
2082 gtk_widget_set_sensitive (account_match_view, true);
2083 gtk_widget_set_sensitive (account_match_btn, true);
2084
2085 /* Enable the "Next" Assistant Button */
2086 auto all_checked = csv_tximp_acct_match_check_all (store);
2087 gtk_assistant_set_page_complete (csv_imp_asst, account_match_page,
2088 all_checked);
2089
2090 /* Update information message and whether to display account errors */
2091 m_req_mapped_accts = all_checked;
2092 auto text = tx_imp->verify (m_req_mapped_accts);
2093 gtk_label_set_text (GTK_LABEL(account_match_label), text.c_str());
2094}

◆ assist_compmgr_close()

void CsvImpTransAssist::assist_compmgr_close ( )

Definition at line 2287 of file assistant-csv-trans-import.cpp.

2288{
2289 gnc_save_window_size (GNC_PREFS_GROUP, GTK_WINDOW(csv_imp_asst));
2290}

◆ assist_doc_page_prepare()

void CsvImpTransAssist::assist_doc_page_prepare ( )

Definition at line 2098 of file assistant-csv-trans-import.cpp.

2099{
2100 if (!tx_imp->verify (true).empty())
2101 {
2102 /* New accounts can change the multi-currency situation and hence
2103 * may require more column tweaks. If so
2104 * inform the user and go back to the preview page.
2105 */
2106 gtk_assistant_set_current_page (csv_imp_asst, 2);
2107 }
2108
2109 /* Block going back */
2110 gtk_assistant_commit (csv_imp_asst);
2111
2112 /* Before creating transactions, if this is a new book, let user specify
2113 * book options, since they affect how transactions are created */
2114 if (new_book)
2115 new_book = gnc_new_book_option_display (GTK_WIDGET(csv_imp_asst));
2116
2117 /* Add the Cancel button for the matcher */
2118 cancel_button = gtk_button_new_with_mnemonic (_("_Cancel"));
2119 gtk_assistant_add_action_widget (csv_imp_asst, cancel_button);
2120 auto button_area = gtk_widget_get_parent (cancel_button);
2121
2122 if (GTK_IS_HEADER_BAR(button_area))
2123 gtk_container_child_set (GTK_CONTAINER(button_area),
2124 cancel_button,
2125 "pack-type", GTK_PACK_START,
2126 nullptr);
2127
2128 g_signal_connect (cancel_button, "clicked",
2129 G_CALLBACK(csv_tximp_assist_close_cb), this);
2130 gtk_widget_show (GTK_WIDGET(cancel_button));
2131}

◆ assist_file_page_prepare()

void CsvImpTransAssist::assist_file_page_prepare ( )

Definition at line 1999 of file assistant-csv-trans-import.cpp.

2000{
2001 /* Set the default directory */
2002 if (!m_final_file_name.empty())
2003 gtk_file_chooser_set_filename (GTK_FILE_CHOOSER(file_chooser),
2004 m_final_file_name.c_str());
2005 else
2006 {
2007 auto starting_dir = gnc_get_default_directory (GNC_PREFS_GROUP);
2008 if (starting_dir)
2009 {
2010 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(file_chooser), starting_dir);
2011 g_free (starting_dir);
2012 }
2013 }
2014
2015 /* Disable the "Next" Assistant Button */
2016 gtk_assistant_set_page_complete (csv_imp_asst, account_match_page, false);
2017}

◆ assist_finish()

void CsvImpTransAssist::assist_finish ( )

Definition at line 2268 of file assistant-csv-trans-import.cpp.

2269{
2270 /* Start the import */
2271 if (!tx_imp->m_transactions.empty())
2272 {
2273 /* The call to gnc_gen_trans_assist_start below will free the
2274 * object passed into it. To avoid our c++ destructor from
2275 * attempting a second free on that object, we'll release
2276 * our own reference to it here before passing it to
2277 * gnc_gen_trans_assist_start.
2278 */
2279 auto local_csv_imp_gui = gnc_csv_importer_gui;
2280 gnc_csv_importer_gui = nullptr;
2281 gnc_gen_trans_assist_start (local_csv_imp_gui);
2282 }
2283}
void gnc_gen_trans_assist_start(GNCImportMainMatcher *info)
This starts the import process for transaction from an assistant.

◆ assist_match_page_prepare()

void CsvImpTransAssist::assist_match_page_prepare ( )

Definition at line 2135 of file assistant-csv-trans-import.cpp.

2136{
2137 /* Create transactions from the parsed data */
2138 try
2139 {
2140 tx_imp->create_transactions ();
2141 }
2142 catch (const GncCsvImpParseError& err)
2143 {
2144 /* Oops! This shouldn't happen when using the import assistant !
2145 * Inform the user and go back to the preview page.
2146 */
2147 auto err_msg = std::string(err.what());
2148 auto err_msgs = err.errors();
2149 auto add_bullet_item = [](std::string& a, ErrMap::value_type& b)->std::string { return std::move(a) + "\n• " + b.second; };
2150 err_msg = std::accumulate (err_msgs.begin(), err_msgs.end(), std::move (err_msg), add_bullet_item);
2151
2152 gnc_error_dialog (GTK_WINDOW (csv_imp_asst),
2153 _("An unexpected error has occurred while creating transactions. Please report this as a bug.\n\n"
2154 "Error message:\n%s"), err_msg.c_str());
2155 gtk_assistant_set_current_page (csv_imp_asst, 2);
2156 }
2157
2158 /* Block going back */
2159 gtk_assistant_commit (csv_imp_asst);
2160
2161 auto text = std::string( "<span size=\"medium\" color=\"red\"><b>");
2162 text += _("Double click on rows to change, then click on Apply to Import");
2163 text += "</b></span>";
2164 gtk_label_set_markup (GTK_LABEL(match_label), text.c_str());
2165
2166 /* Add the help button for the matcher */
2167 help_button = gtk_button_new_with_mnemonic (_("_Help"));
2168 gtk_assistant_add_action_widget (csv_imp_asst, help_button);
2169 auto button_area = gtk_widget_get_parent (help_button);
2170
2171 if (GTK_IS_HEADER_BAR(button_area))
2172 {
2173 gtk_container_child_set (GTK_CONTAINER(button_area),
2174 help_button,
2175 "pack-type", GTK_PACK_START,
2176 nullptr);
2177 }
2178 else
2179 {
2180 // align the help button on the left side
2181 gtk_widget_set_halign (GTK_WIDGET(button_area), GTK_ALIGN_FILL);
2182 gtk_widget_set_hexpand (GTK_WIDGET(button_area), TRUE);
2183 gtk_box_set_child_packing (GTK_BOX(button_area), help_button,
2184 FALSE, FALSE, 0, GTK_PACK_START);
2185 }
2186 g_signal_connect (help_button, "clicked",
2187 G_CALLBACK(on_matcher_help_clicked), gnc_csv_importer_gui);
2188
2189 gtk_widget_show (GTK_WIDGET(help_button));
2190
2191 /* Copy all of the transactions to the importer GUI. */
2192 for (auto trans_it : tx_imp->m_transactions)
2193 {
2194 auto draft_trans = trans_it.second;
2195 if (draft_trans->trans)
2196 {
2197 auto lsplit = GNCImportLastSplitInfo {
2198 draft_trans->m_price ? static_cast<gnc_numeric>(*draft_trans->m_price) : gnc_numeric{0, 0},
2199 draft_trans->m_taction ? draft_trans->m_taction->c_str() : nullptr,
2200 draft_trans->m_tmemo ? draft_trans->m_tmemo->c_str() : nullptr,
2201 draft_trans->m_tamount ? static_cast<gnc_numeric>(*draft_trans->m_tamount) : gnc_numeric{0, 0},
2202 draft_trans->m_taccount ? *draft_trans->m_taccount : nullptr,
2203 draft_trans->m_trec_state ? *draft_trans->m_trec_state : '\0',
2204 draft_trans->m_trec_date ? static_cast<time64>(GncDateTime(*draft_trans->m_trec_date, DayPart::neutral)) : 0,
2205 };
2206
2207//A tramsaction with no splits is invalid and will crash later.
2208 if (xaccTransGetSplit(draft_trans->trans, 0))
2209 gnc_gen_trans_list_add_trans_with_split_data (gnc_csv_importer_gui, std::move (draft_trans->trans),
2210 &lsplit);
2211 else
2212 xaccTransDestroy(draft_trans->trans);
2213 draft_trans->trans = nullptr;
2214 }
2215 }
2216 /* Show the matcher dialog */
2217 gnc_gen_trans_list_show_all (gnc_csv_importer_gui);
2218}
GnuCash DateTime class.
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
Definition gnc-date.h:87
void xaccTransDestroy(Transaction *trans)
Destroys a transaction.
Split * xaccTransGetSplit(const Transaction *trans, int i)
Return a pointer to the indexed split in this transaction's split list.
void gnc_gen_trans_list_show_all(GNCImportMainMatcher *info)
Shows widgets.
void gnc_gen_trans_list_add_trans_with_split_data(GNCImportMainMatcher *gui, Transaction *trans, GNCImportLastSplitInfo *lsplit)
Add a newly imported Transaction to the Transaction Importer.
void on_matcher_help_clicked(GtkButton *button, gpointer user_data)
This allows for the transaction help dialog to be started from the assistant button callback.
Exception that will be thrown whenever a parsing error is encountered.

◆ assist_prepare_cb()

void CsvImpTransAssist::assist_prepare_cb ( GtkWidget *  page)

Definition at line 2250 of file assistant-csv-trans-import.cpp.

2251{
2252 if (page == file_page)
2253 assist_file_page_prepare ();
2254 else if (page == preview_page)
2255 assist_preview_page_prepare ();
2256 else if (page == account_match_page)
2257 assist_account_match_page_prepare ();
2258 else if (page == doc_page)
2259 assist_doc_page_prepare ();
2260 else if (page == match_page)
2261 assist_match_page_prepare ();
2262 else if (page == summary_page)
2263 assist_summary_page_prepare ();
2264}

◆ assist_preview_page_prepare()

void CsvImpTransAssist::assist_preview_page_prepare ( )

Definition at line 2021 of file assistant-csv-trans-import.cpp.

2022{
2023 auto go_back = false;
2024
2025 if (m_final_file_name != m_fc_file_name)
2026 {
2027 tx_imp = std::unique_ptr<GncTxImport>(new GncTxImport);
2028
2029 /* Assume data is CSV. User can later override to Fixed Width if needed */
2030 try
2031 {
2032 tx_imp->file_format (GncImpFileFormat::CSV);
2033 tx_imp->load_file (m_fc_file_name);
2034 tx_imp->tokenize (true);
2035 m_req_mapped_accts = false;
2036
2037 /* Get settings store and populate */
2038 preview_populate_settings_combo();
2039 gtk_combo_box_set_active (settings_combo, 0);
2040
2041 /* Disable the "Next" Assistant Button */
2042 gtk_assistant_set_page_complete (csv_imp_asst, preview_page, false);
2043 }
2044 catch (std::ifstream::failure& e)
2045 {
2046 /* File loading failed ... */
2047 gnc_error_dialog (GTK_WINDOW (csv_imp_asst), "%s", e.what());
2048 go_back = true;
2049 }
2050 catch (std::range_error &e)
2051 {
2052 /* Parsing failed ... */
2053 gnc_error_dialog (GTK_WINDOW (csv_imp_asst), "%s", _(e.what()));
2054 /* Stay in this step so user can override */
2055 go_back = false;
2056 }
2057 }
2058
2059 if (go_back)
2060 gtk_assistant_previous_page (csv_imp_asst);
2061 else
2062 {
2063 m_final_file_name = m_fc_file_name;
2064 preview_refresh ();
2065
2066 /* Load the data into the treeview. */
2067 g_idle_add ((GSourceFunc)csv_imp_preview_queue_rebuild_table, this);
2068 }
2069}
The actual TxImport class It's intended to use in the following sequence of actions:

◆ assist_summary_page_prepare()

void CsvImpTransAssist::assist_summary_page_prepare ( )

Definition at line 2222 of file assistant-csv-trans-import.cpp.

2223{
2224 /* Remove the added buttons */
2225 gtk_assistant_remove_action_widget (csv_imp_asst, help_button);
2226 gtk_assistant_remove_action_widget (csv_imp_asst, cancel_button);
2227
2228 auto text = std::string("<span size=\"medium\"><b>");
2229 try
2230 {
2231 /* Translators: {1} will be replaced with a filename */
2232 text += (bl::format (std::string{_("The transactions were imported from file '{1}'.")}) % m_final_file_name).str();
2233 text += "</b></span>";
2234 }
2235 catch (const bl::conv::conversion_error& err)
2236 {
2237 PERR("Transcoding error: %s", err.what());
2238 text += "The transactions were imported from the file.</b></span>";
2239 }
2240 catch (const bl::conv::invalid_charset_error& err)
2241 {
2242 PERR("Invalid charset error: %s", err.what());
2243 text += "The transactions were imported from the file.</b></span>";
2244 }
2245 gtk_label_set_markup (GTK_LABEL(summary_label), text.c_str());
2246}
#define PERR(format, args...)
Log a serious error.
Definition qoflog.h:244

◆ file_activated_cb()

void CsvImpTransAssist::file_activated_cb ( )

Definition at line 744 of file assistant-csv-trans-import.cpp.

745{
746 gtk_assistant_set_page_complete (csv_imp_asst, file_page, false);
747
748 /* Test for a valid filename and not a directory */
749 if (check_for_valid_filename ())
750 {
751 gtk_assistant_set_page_complete (csv_imp_asst, file_page, true);
752 gtk_assistant_next_page (csv_imp_asst);
753 }
754}

◆ file_selection_changed_cb()

void CsvImpTransAssist::file_selection_changed_cb ( )

Definition at line 761 of file assistant-csv-trans-import.cpp.

762{
763 /* Enable the "Next" button based on a valid filename */
764 gtk_assistant_set_page_complete (csv_imp_asst, file_page,
765 check_for_valid_filename ());
766}

◆ preview_handle_save_del_sensitivity()

void CsvImpTransAssist::preview_handle_save_del_sensitivity ( GtkComboBox *  combo)

Definition at line 800 of file assistant-csv-trans-import.cpp.

801{
802 GtkTreeIter iter;
803 auto can_delete = false;
804 auto can_save = false;
805 auto entry = gtk_bin_get_child (GTK_BIN(combo));
806 auto entry_text = gtk_entry_get_text (GTK_ENTRY(entry));
807 /* Handle sensitivity of the delete and save button */
808 if (gtk_combo_box_get_active_iter (combo, &iter))
809 {
810 CsvTransImpSettings *preset;
811 GtkTreeModel *model = gtk_combo_box_get_model (combo);
812 gtk_tree_model_get (model, &iter, SET_GROUP, &preset, -1);
813
814 if (preset && !preset_is_reserved_name (preset->m_name))
815 {
816 /* Current preset is not read_only, so buttons can be enabled */
817 can_delete = true;
818 can_save = true;
819 }
820 }
821 else if (entry_text && (strlen (entry_text) > 0) &&
822 !preset_is_reserved_name (std::string(entry_text)))
823 can_save = true;
824
825 gtk_widget_set_sensitive (save_button, can_save);
826 gtk_widget_set_sensitive (del_button, can_delete);
827
828}
bool preset_is_reserved_name(const std::string &name)
Check whether name can be used as a preset name.

◆ preview_multi_split()

void CsvImpTransAssist::preview_multi_split ( bool  multi)

Definition at line 986 of file assistant-csv-trans-import.cpp.

987{
988 tx_imp->multi_split(multi);
989 preview_refresh ();
990}

◆ preview_populate_settings_combo()

void CsvImpTransAssist::preview_populate_settings_combo ( )

Definition at line 775 of file assistant-csv-trans-import.cpp.

776{
777 // Clear the list store
778 auto model = gtk_combo_box_get_model (settings_combo);
779 gtk_list_store_clear (GTK_LIST_STORE(model));
780
781 // Append the default entry
782 auto presets = get_import_presets_trans ();
783 for (auto preset : presets)
784 {
785 GtkTreeIter iter;
786 gtk_list_store_append (GTK_LIST_STORE(model), &iter);
787 /* FIXME we store the raw pointer to the preset, while it's
788 * managed by a shared pointer. This is dangerous because
789 * when the shared pointer goes out of scope, our pointer will dangle.
790 * For now this is safe, because the shared pointers in this case are
791 * long-lived, but this may need refactoring.
792 */
793 gtk_list_store_set (GTK_LIST_STORE(model), &iter, SET_GROUP, preset.get(), SET_NAME, _(preset->m_name.c_str()), -1);
794 }
795}
const preset_vec_trans & get_import_presets_trans(void)
Creates a vector of CsvTransImpSettings which combines.

◆ preview_refresh()

void CsvImpTransAssist::preview_refresh ( )

Definition at line 1662 of file assistant-csv-trans-import.cpp.

1663{
1664 // Cache skip settings. Updating the widgets one by one
1665 // triggers a callback the transfers all skip widgets'
1666 // values to settings. So by the time the next widget value
1667 // is to be set, that widget's 'new' setting has already been replaced by
1668 // its old setting preventing us from using it here sensibly.
1669 // Another solution might have been to delay callbacks from running
1670 // until after all values are set.
1671 auto skip_start_lines = tx_imp->skip_start_lines();
1672 auto skip_end_lines = tx_imp->skip_end_lines();
1673 auto skip_alt_lines = tx_imp->skip_alt_lines();
1674
1675 // Set start row
1676 auto adj = gtk_spin_button_get_adjustment (start_row_spin);
1677 gtk_adjustment_set_upper (adj, tx_imp->m_parsed_lines.size());
1678 gtk_spin_button_set_value (start_row_spin, skip_start_lines);
1679
1680 // Set end row
1681 adj = gtk_spin_button_get_adjustment (end_row_spin);
1682 gtk_adjustment_set_upper (adj, tx_imp->m_parsed_lines.size());
1683 gtk_spin_button_set_value (end_row_spin, skip_end_lines);
1684
1685 // Set Alternate rows
1686 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(skip_alt_rows_button),
1687 skip_alt_lines);
1688
1689 // Set multi-split indicator
1690 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(multi_split_cbutton),
1691 tx_imp->multi_split());
1692 gtk_widget_set_sensitive (acct_selector, !tx_imp->multi_split());
1693
1694 // Set Import Format
1695 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(csv_button),
1696 (tx_imp->file_format() == GncImpFileFormat::CSV));
1697 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(fixed_button),
1698 (tx_imp->file_format() != GncImpFileFormat::CSV));
1699
1700 // Set Date & Currency Format and Character encoding
1701 gtk_combo_box_set_active (GTK_COMBO_BOX(date_format_combo),
1702 tx_imp->date_format());
1703 gtk_combo_box_set_active (GTK_COMBO_BOX(currency_format_combo),
1704 tx_imp->currency_format());
1705 go_charmap_sel_set_encoding (encselector, tx_imp->encoding().c_str());
1706
1707 // Handle separator checkboxes and custom field, only relevant if the file format is csv
1708 // Note we defer the change signal until all buttons have been updated
1709 // An early update may result in an incomplete tokenize run and that would
1710 // cause our list of saved column types to be truncated
1711 if (tx_imp->file_format() == GncImpFileFormat::CSV)
1712 {
1713 auto separators = tx_imp->separators();
1714 auto enable_escape = tx_imp->enable_escape();
1715 const auto stock_sep_chars = std::string (" \t,:;-");
1716 for (int i = 0; i < SEP_NUM_OF_TYPES; i++)
1717 {
1718 g_signal_handlers_block_by_func (sep_button[i], (gpointer) csv_tximp_preview_sep_button_cb, this);
1719 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(sep_button[i]),
1720 separators.find (stock_sep_chars[i]) != std::string::npos);
1721 g_signal_handlers_unblock_by_func (sep_button[i], (gpointer) csv_tximp_preview_sep_button_cb, this);
1722 }
1723
1724 // If there are any other separators in the separators string,
1725 // add them as custom separators
1726 auto pos = separators.find_first_of (stock_sep_chars);
1727 while (!separators.empty() && pos != std::string::npos)
1728 {
1729 separators.erase(pos);
1730 pos = separators.find_first_of (stock_sep_chars);
1731 }
1732 g_signal_handlers_block_by_func (custom_cbutton, (gpointer) csv_tximp_preview_sep_button_cb, this);
1733 g_signal_handlers_block_by_func (custom_entry, (gpointer) csv_tximp_preview_sep_button_cb, this);
1734 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(custom_cbutton),
1735 !separators.empty());
1736 gtk_entry_set_text (GTK_ENTRY(custom_entry), separators.c_str());
1737
1738 g_signal_handlers_block_by_func (escape_cbutton, (gpointer) csv_tximp_preview_sep_button_cb, this);
1739 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(escape_cbutton),
1740 enable_escape);
1741 g_signal_handlers_unblock_by_func (escape_cbutton, (gpointer) csv_tximp_preview_sep_button_cb, this);
1742
1743 g_signal_handlers_unblock_by_func (custom_cbutton, (gpointer) csv_tximp_preview_sep_button_cb, this);
1744 g_signal_handlers_unblock_by_func (custom_entry, (gpointer) csv_tximp_preview_sep_button_cb, this);
1745 g_signal_handlers_unblock_by_func (custom_cbutton, (gpointer) csv_tximp_preview_sep_button_cb, this);
1746 try
1747 {
1748 tx_imp->tokenize (false);
1749 }
1750 catch(std::range_error& err)
1751 {
1752 PERR("CSV Tokenization Failed: %s", err.what());
1753 }
1754 }
1755
1756 // Repopulate the parsed data table
1757 preview_refresh_table ();
1758}

◆ preview_refresh_table()

void CsvImpTransAssist::preview_refresh_table ( )

Definition at line 1565 of file assistant-csv-trans-import.cpp.

1566{
1567 preview_validate_settings ();
1568
1569 /* Create a new liststore to hold status and data from the file being imported.
1570 The first columns hold status information (row-color, row-errors, row-error-icon,...
1571 All following columns represent the tokenized data as strings. */
1572 auto ncols = PREV_N_FIXED_COLS + tx_imp->column_types().size();
1573 auto model_col_types = g_new (GType, ncols);
1574 model_col_types[PREV_COL_FCOLOR] = G_TYPE_STRING;
1575 model_col_types[PREV_COL_BCOLOR] = G_TYPE_STRING;
1576 model_col_types[PREV_COL_ERROR] = G_TYPE_STRING;
1577 model_col_types[PREV_COL_ERR_ICON] = G_TYPE_STRING;
1578 model_col_types[PREV_COL_STRIKE] = G_TYPE_BOOLEAN;
1579 for (guint i = PREV_N_FIXED_COLS; i < ncols; i++)
1580 model_col_types[i] = G_TYPE_STRING;
1581 auto store = gtk_list_store_newv (ncols, model_col_types);
1582 g_free (model_col_types);
1583
1584 /* Fill the data liststore with data from importer object. */
1585 for (auto parse_line : tx_imp->m_parsed_lines)
1586 {
1587 /* Fill the state cells */
1588 GtkTreeIter iter;
1589 gtk_list_store_append (store, &iter);
1590 preview_row_fill_state_cells (store, &iter,
1591 std::get<PL_ERROR>(parse_line), std::get<PL_SKIP>(parse_line));
1592
1593 /* Fill the data cells. */
1594 for (auto cell_str_it = std::get<PL_INPUT>(parse_line).cbegin(); cell_str_it != std::get<PL_INPUT>(parse_line).cend(); cell_str_it++)
1595 {
1596 uint32_t pos = PREV_N_FIXED_COLS + cell_str_it - std::get<PL_INPUT>(parse_line).cbegin();
1597 gtk_list_store_set (store, &iter, pos, cell_str_it->c_str(), -1);
1598 }
1599 }
1600 gtk_tree_view_set_model (treeview, GTK_TREE_MODEL(store));
1601 gtk_tree_view_set_tooltip_column (treeview, PREV_COL_ERROR);
1602
1603 /* Adjust treeview to go with the just created model. This consists of adding
1604 * or removing columns and resetting any parameters related to how
1605 * the columns and data should be rendered.
1606 */
1607
1608 /* Start with counting the current number of columns (ntcols)
1609 * we have in the treeview */
1610 auto ntcols = gtk_tree_view_get_n_columns (treeview);
1611
1612 /* Drop redundant columns if the model has less data columns than the new model
1613 * ntcols = n° of columns in treeview (1 error column + x data columns)
1614 * ncols = n° of columns in model (fixed state columns + x data columns)
1615 */
1616 while (ntcols > ncols - PREV_N_FIXED_COLS + 1)
1617 {
1618 auto col = gtk_tree_view_get_column (treeview, ntcols - 1);
1619 gtk_tree_view_column_clear (col);
1620 ntcols = gtk_tree_view_remove_column(treeview, col);
1621 }
1622
1623 /* Insert columns if the model has more data columns than the treeview. */
1624 while (ntcols < ncols - PREV_N_FIXED_COLS + 1)
1625 {
1626 /* Default cell renderer is text, except for the first (error) column */
1627 auto renderer = gtk_cell_renderer_text_new();
1628 if (ntcols == 0)
1629 renderer = gtk_cell_renderer_pixbuf_new(); // Error column uses an icon
1630 auto col = gtk_tree_view_column_new ();
1631 gtk_tree_view_column_pack_start (col, renderer, false);
1632 ntcols = gtk_tree_view_append_column (treeview, col);
1633 }
1634
1635 /* Reset column attributes as they are undefined after recreating the model */
1636 auto combostore = make_column_header_model (tx_imp->multi_split());
1637 for (uint32_t i = 0; i < ntcols; i++)
1638 preview_style_column (i, combostore);
1639
1640 /* Release our reference for the stores to allow proper memory management. */
1641 g_object_unref (store);
1642 g_object_unref (combostore);
1643
1644 /* Also reset the base account combo box as it's value may have changed due to column changes here */
1645 auto base_acct = gnc_account_sel_get_account(GNC_ACCOUNT_SEL(acct_selector));
1646 if (tx_imp->base_account() != base_acct)
1647 {
1648 g_signal_handlers_block_by_func (acct_selector, (gpointer) csv_tximp_preview_acct_sel_cb, this);
1649 gnc_account_sel_set_account(GNC_ACCOUNT_SEL(acct_selector),
1650 tx_imp->base_account() , false);
1651 g_signal_handlers_unblock_by_func (acct_selector, (gpointer) csv_tximp_preview_acct_sel_cb, this);
1652 }
1653
1654 /* Make the things actually appear. */
1655 gtk_widget_show_all (GTK_WIDGET(treeview));
1656}

◆ preview_settings_delete()

void CsvImpTransAssist::preview_settings_delete ( )

Definition at line 875 of file assistant-csv-trans-import.cpp.

876{
877 // Get the Active Selection
878 GtkTreeIter iter;
879 if (!gtk_combo_box_get_active_iter (settings_combo, &iter))
880 return;
881
882 CsvTransImpSettings *preset = nullptr;
883 auto model = gtk_combo_box_get_model (settings_combo);
884 gtk_tree_model_get (model, &iter, SET_GROUP, &preset, -1);
885
886 auto response = gnc_ok_cancel_dialog (GTK_WINDOW (csv_imp_asst),
887 GTK_RESPONSE_CANCEL,
888 "%s", _("Delete the Import Settings."));
889 if (response == GTK_RESPONSE_OK)
890 {
891 preset->remove();
892 preview_populate_settings_combo();
893 gtk_combo_box_set_active (settings_combo, 0); // Default
894 preview_refresh (); // Reset the widgets
895 }
896}
void remove(void)
Remove the preset from the state file.

◆ preview_settings_load()

void CsvImpTransAssist::preview_settings_load ( )

Definition at line 848 of file assistant-csv-trans-import.cpp.

849{
850 // Get the Active Selection
851 GtkTreeIter iter;
852 if (!gtk_combo_box_get_active_iter (settings_combo, &iter))
853 return;
854
855 CsvTransImpSettings *preset = nullptr;
856 auto model = gtk_combo_box_get_model (settings_combo);
857 gtk_tree_model_get (model, &iter, SET_GROUP, &preset, -1);
858
859 if (!preset)
860 return;
861
862 tx_imp->settings (*preset);
863 if (preset->m_load_error)
864 gnc_error_dialog (GTK_WINDOW (csv_imp_asst),
865 "%s", _("There were problems reading some saved settings, continuing to load.\n"
866 "Please review and save again."));
867
868 preview_refresh ();
869 preview_handle_save_del_sensitivity (settings_combo);
870}

◆ preview_settings_name()

void CsvImpTransAssist::preview_settings_name ( GtkEntry *  entry)

Definition at line 831 of file assistant-csv-trans-import.cpp.

832{
833 auto text = gtk_entry_get_text (entry);
834 if (text)
835 tx_imp->settings_name(text);
836
837 auto box = gtk_widget_get_parent (GTK_WIDGET(entry));
838 auto combo = gtk_widget_get_parent (GTK_WIDGET(box));
839
840 preview_handle_save_del_sensitivity (GTK_COMBO_BOX(combo));
841}

◆ preview_settings_save()

void CsvImpTransAssist::preview_settings_save ( )

Definition at line 901 of file assistant-csv-trans-import.cpp.

902{
903 auto new_name = tx_imp->settings_name();
904
905 /* Check if the entry text matches an already existing preset */
906 GtkTreeIter iter;
907 if (!gtk_combo_box_get_active_iter (settings_combo, &iter))
908 {
909
910 auto model = gtk_combo_box_get_model (settings_combo);
911 bool valid = gtk_tree_model_get_iter_first (model, &iter);
912 while (valid)
913 {
914 // Walk through the list, reading each row
915 CsvTransImpSettings *preset;
916 gtk_tree_model_get (model, &iter, SET_GROUP, &preset, -1);
917
918 if (preset && (preset->m_name == std::string(new_name)))
919 {
920 auto response = gnc_ok_cancel_dialog (GTK_WINDOW (csv_imp_asst),
921 GTK_RESPONSE_OK,
922 "%s", _("Setting name already exists, overwrite?"));
923 if (response != GTK_RESPONSE_OK)
924 return;
925
926 break;
927 }
928 valid = gtk_tree_model_iter_next (model, &iter);
929 }
930 }
931
932 /* All checks passed, let's save this preset */
933 if (!tx_imp->save_settings())
934 {
935 gnc_info_dialog (GTK_WINDOW (csv_imp_asst),
936 "%s", _("The settings have been saved."));
937
938 // Update the settings store
939 preview_populate_settings_combo();
940 auto model = gtk_combo_box_get_model (settings_combo);
941
942 // Get the first entry in model
943 GtkTreeIter iter;
944 bool valid = gtk_tree_model_get_iter_first (model, &iter);
945 while (valid)
946 {
947 // Walk through the list, reading each row
948 gchar *name = nullptr;
949 gtk_tree_model_get (model, &iter, SET_NAME, &name, -1);
950
951 if (g_strcmp0 (name, new_name.c_str()) == 0) // Set Active, the one Saved.
952 gtk_combo_box_set_active_iter (settings_combo, &iter);
953
954 g_free (name);
955
956 valid = gtk_tree_model_iter_next (model, &iter);
957 }
958 }
959 else
960 gnc_error_dialog (GTK_WINDOW (csv_imp_asst),
961 "%s", _("There was a problem saving the settings, please try again."));
962}

◆ preview_split_column()

void CsvImpTransAssist::preview_split_column ( int  col,
int  offset 
)

Definition at line 1359 of file assistant-csv-trans-import.cpp.

1360{
1361 auto fwtok = dynamic_cast<GncFwTokenizer*>(tx_imp->m_tokenizer.get());
1362 fwtok->col_split (col, offset);
1363 try
1364 {
1365 tx_imp->tokenize (false);
1366 }
1367 catch (std::range_error& e)
1368 {
1369 gnc_error_dialog (GTK_WINDOW (csv_imp_asst), "%s", e.what());
1370 return;
1371 }
1372 preview_refresh_table();
1373}

◆ preview_update_account()

void CsvImpTransAssist::preview_update_account ( )

Definition at line 1103 of file assistant-csv-trans-import.cpp.

1104{;
1105 auto acct = gnc_account_sel_get_account( GNC_ACCOUNT_SEL(acct_selector) );
1106 tx_imp->base_account(acct);
1107 preview_refresh_table ();
1108}

◆ preview_update_col_type()

void CsvImpTransAssist::preview_update_col_type ( GtkComboBox *  cbox)

Event handler for the user selecting a new column type.

When the user selects a new column type, that column's text must be changed to the selection, and any other columns containing that selection must be changed to "None" because we don't allow duplicates.

Parameters
cboxThe combo box the user just clicked to make a change

Definition at line 1188 of file assistant-csv-trans-import.cpp.

1189{
1190 /* Get the new text */
1191 GtkTreeIter iter;
1192 auto model = gtk_combo_box_get_model (cbox);
1193 gtk_combo_box_get_active_iter (cbox, &iter);
1194 auto new_col_type = GncTransPropType::NONE;
1195 gtk_tree_model_get (model, &iter, COL_TYPE_ID, &new_col_type, -1);
1196
1197 auto col_num = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT(cbox), "col-num"));
1198 tx_imp->set_column_type (col_num, new_col_type);
1199
1200 /* Delay rebuilding our data table to avoid critical warnings due to
1201 * pending events still acting on them after this event is processed.
1202 */
1203 g_idle_add ((GSourceFunc)csv_imp_preview_queue_rebuild_table, this);
1204
1205}

◆ preview_update_currency_format()

void CsvImpTransAssist::preview_update_currency_format ( )

Definition at line 1154 of file assistant-csv-trans-import.cpp.

1155{
1156 tx_imp->currency_format (gtk_combo_box_get_active (GTK_COMBO_BOX(currency_format_combo)));
1157 preview_refresh_table ();
1158}

◆ preview_update_date_format()

void CsvImpTransAssist::preview_update_date_format ( )

Definition at line 1146 of file assistant-csv-trans-import.cpp.

1147{
1148 tx_imp->date_format (gtk_combo_box_get_active (GTK_COMBO_BOX(date_format_combo)));
1149 preview_refresh_table ();
1150}

◆ preview_update_encoding()

void CsvImpTransAssist::preview_update_encoding ( const char *  encoding)

Event handler for a new encoding.

This is called when the user selects a new encoding; the data is reparsed and shown to the user.

Parameters
encodingThe encoding that the user selected

Definition at line 1117 of file assistant-csv-trans-import.cpp.

1118{
1119 /* This gets called twice every time a new encoding is selected. The
1120 * second call actually passes the correct data; thus, we only do
1121 * something the second time this is called. */
1122
1123 /* If this is the second time the function is called ... */
1124 if (encoding_selected_called)
1125 {
1126 std::string previous_encoding = tx_imp->m_tokenizer->encoding();
1127 /* Try converting the new encoding and reparsing. */
1128 try
1129 {
1130 tx_imp->encoding (encoding);
1131 preview_refresh_table ();
1132 }
1133 catch (...)
1134 {
1135 /* If it fails, change back to the old encoding. */
1136 gnc_error_dialog (GTK_WINDOW (csv_imp_asst), "%s", _("Invalid encoding selected"));
1137 go_charmap_sel_set_encoding (encselector, previous_encoding.c_str());
1138 }
1139 }
1140
1141 encoding_selected_called = !encoding_selected_called;
1142}

◆ preview_update_file_format()

void CsvImpTransAssist::preview_update_file_format ( )

Event handler for clicking one of the format type radio buttons.

This occurs if the format (Fixed-Width or CSV) is changed.

Definition at line 1062 of file assistant-csv-trans-import.cpp.

1063{
1064 /* Set the parsing type correctly. */
1065 try
1066 {
1067 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(csv_button)))
1068 {
1069 tx_imp->file_format (GncImpFileFormat::CSV);
1070 g_signal_handlers_disconnect_by_func(G_OBJECT(treeview),
1071 (gpointer)csv_tximp_preview_treeview_clicked_cb, (gpointer)this);
1072 gtk_widget_set_visible (separator_table, true);
1073 gtk_widget_set_visible (fw_instructions_hbox, false);
1074 }
1075 else
1076 {
1077 tx_imp->file_format (GncImpFileFormat::FIXED_WIDTH);
1078 /* Enable context menu for adding/removing columns. */
1079 g_signal_connect (G_OBJECT(treeview), "button-press-event",
1080 G_CALLBACK(csv_tximp_preview_treeview_clicked_cb), (gpointer)this);
1081 gtk_widget_set_visible (separator_table, false);
1082 gtk_widget_set_visible (fw_instructions_hbox, true);
1083
1084 }
1085
1086 tx_imp->tokenize (false);
1087 preview_refresh_table ();
1088 }
1089 catch (std::range_error &e)
1090 {
1091 /* Parsing failed ... */
1092 gnc_error_dialog (GTK_WINDOW (csv_imp_asst), "%s", e.what());
1093 return;
1094 }
1095 catch (...)
1096 {
1097 // FIXME Handle file loading errors (possibly thrown by file_format above)
1098 PWARN("Got an error during file loading");
1099 }
1100}
#define PWARN(format, args...)
Log a warning.
Definition qoflog.h:250

◆ preview_update_fw_columns()

void CsvImpTransAssist::preview_update_fw_columns ( GtkTreeView *  treeview,
GdkEventButton *  event 
)

Event handler for clicking on column headers.

This function is called whenever the user clicks on column headers in preview->treeview to modify columns when in fixed-width mode.

Parameters
eventThe event that happened (where the user clicked)

Definition at line 1382 of file assistant-csv-trans-import.cpp.

1383{
1384 /* Nothing to do if this was not triggered on our treeview body */
1385 if (event->window != gtk_tree_view_get_bin_window (treeview))
1386 return;
1387
1388 /* Find the column that was clicked. */
1389 GtkTreeViewColumn *tcol = nullptr;
1390 int cell_x = 0;
1391 auto success = gtk_tree_view_get_path_at_pos (treeview,
1392 (int)event->x, (int)event->y,
1393 nullptr, &tcol, &cell_x, nullptr);
1394 if (!success)
1395 return;
1396
1397 /* Stop if no column found in this treeview (-1) or
1398 * if column is the error messages column (0) */
1399 auto tcol_list = gtk_tree_view_get_columns(treeview);
1400 auto tcol_num = g_list_index (tcol_list, tcol);
1401 g_list_free (tcol_list);
1402 if (tcol_num <= 0)
1403 return;
1404
1405 /* Data columns in the treeview are offset by one
1406 * because the first column is the error column
1407 */
1408 auto dcol = tcol_num - 1;
1409 auto offset = get_new_col_rel_pos (tcol, cell_x);
1410 if (event->type == GDK_2BUTTON_PRESS && event->button == 1)
1411 /* Double clicks can split columns. */
1412 preview_split_column (dcol, offset);
1413 else if (event->type == GDK_BUTTON_PRESS && event->button == 3)
1414 /* Right clicking brings up a context menu. */
1415 fixed_context_menu (event, dcol, offset);
1416}

◆ preview_update_separators()

void CsvImpTransAssist::preview_update_separators ( GtkWidget *  widget)

Event handler for separator changes.

This function is called whenever one of the widgets for configuring the separators (the separator checkbuttons, the escape checkbutton or the custom separator entry) is changed.

Parameters
widgetThe widget that was changed

Definition at line 999 of file assistant-csv-trans-import.cpp.

1000{
1001
1002 /* Only manipulate separator characters if the currently open file is
1003 * csv separated. */
1004 if (tx_imp->file_format() != GncImpFileFormat::CSV)
1005 return;
1006
1007 /* Add the corresponding characters to checked_separators for each
1008 * button that is checked. */
1009 auto checked_separators = std::string();
1010 const auto stock_sep_chars = std::string (" \t,:;-");
1011 for (int i = 0; i < SEP_NUM_OF_TYPES; i++)
1012 {
1013 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(sep_button[i])))
1014 checked_separators += stock_sep_chars[i];
1015 }
1016
1017 /* Add the custom separator if the user checked its button. */
1018 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(custom_cbutton)))
1019 {
1020 auto custom_sep = gtk_entry_get_text (custom_entry);
1021 if (custom_sep[0] != '\0') /* Don't add a blank separator (bad things will happen!). */
1022 checked_separators += custom_sep;
1023 }
1024
1025 /* Set the parse options using the checked_separators list. */
1026 tx_imp->separators (checked_separators);
1027 tx_imp->enable_escape (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(escape_cbutton)));
1028
1029 /* Parse the data using the new options. We don't want to reguess
1030 * the column types because we want to leave the user's
1031 * configurations intact. */
1032 try
1033 {
1034 tx_imp->tokenize (false);
1035 preview_refresh_table ();
1036 }
1037 catch (std::range_error &e)
1038 {
1039 /* Warn the user there was a problem and try to undo what caused
1040 * the error. (This will cause a reparsing and ideally a usable
1041 * configuration.) */
1042 gnc_error_dialog (GTK_WINDOW (csv_imp_asst), "Error in parsing");
1043 /* If we're here because the user changed the file format, we should just wait for the user
1044 * to update the configuration */
1045 if (!widget)
1046 return;
1047 /* If the user changed the custom separator, erase that custom separator. */
1048 if (widget == GTK_WIDGET(custom_entry))
1049 gtk_entry_set_text (GTK_ENTRY(widget), "");
1050 /* If the user checked a checkbutton, toggle that checkbutton back. */
1051 else
1052 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(widget),
1053 !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(widget)));
1054 return;
1055 }
1056}

◆ preview_update_skipped_rows()

void CsvImpTransAssist::preview_update_skipped_rows ( )

Definition at line 966 of file assistant-csv-trans-import.cpp.

967{
968 /* Update skip rows in the parser */
969 tx_imp->update_skipped_lines (gtk_spin_button_get_value_as_int (start_row_spin),
970 gtk_spin_button_get_value_as_int (end_row_spin),
971 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(skip_alt_rows_button)),
972 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(skip_errors_button)));
973
974 /* And adjust maximum number of lines that can be skipped at each end accordingly */
975 auto adj = gtk_spin_button_get_adjustment (end_row_spin);
976 gtk_adjustment_set_upper (adj, tx_imp->m_parsed_lines.size()
977 - tx_imp->skip_start_lines() -1);
978
979 adj = gtk_spin_button_get_adjustment (start_row_spin);
980 gtk_adjustment_set_upper (adj, tx_imp->m_parsed_lines.size()
981 - tx_imp->skip_end_lines() - 1);
982
983 preview_refresh_table ();
984}

◆ preview_validate_settings()

void CsvImpTransAssist::preview_validate_settings ( )

Definition at line 1762 of file assistant-csv-trans-import.cpp.

1763{
1764 /* Allow the user to proceed only if there are no inconsistencies in the settings */
1765 auto has_non_acct_errors = !tx_imp->verify (false).empty();
1766 auto error_msg = tx_imp->verify (m_req_mapped_accts);
1767 gtk_assistant_set_page_complete (csv_imp_asst, preview_page, !has_non_acct_errors);
1768 gtk_label_set_markup(GTK_LABEL(instructions_label), error_msg.c_str());
1769 gtk_widget_set_visible (GTK_WIDGET(instructions_image), !error_msg.empty());
1770
1771 /* Show or hide the account match page based on whether there are
1772 * accounts in the user data according to the importer configuration
1773 * only if there are no errors
1774 */
1775 if (!has_non_acct_errors)
1776 gtk_widget_set_visible (GTK_WIDGET(account_match_page),
1777 !tx_imp->accounts().empty());
1778}

Friends And Related Symbol Documentation

◆ fixed_context_menu_handler

gboolean fixed_context_menu_handler ( GnumericPopupMenuElement const *  element,
gpointer  userdata 
)
friend

Definition at line 1291 of file assistant-csv-trans-import.cpp.

1293{
1294 auto info = (CsvImpTransAssist*)userdata;
1295 auto fwtok = dynamic_cast<GncFwTokenizer*>(info->tx_imp->m_tokenizer.get());
1296
1297 switch (element->index)
1298 {
1299 case CONTEXT_STF_IMPORT_MERGE_LEFT:
1300 fwtok->col_delete (info->fixed_context_col - 1);
1301 break;
1302 case CONTEXT_STF_IMPORT_MERGE_RIGHT:
1303 fwtok->col_delete (info->fixed_context_col);
1304 break;
1305 case CONTEXT_STF_IMPORT_SPLIT:
1306 fwtok->col_split (info->fixed_context_col, info->fixed_context_offset);
1307 break;
1308 case CONTEXT_STF_IMPORT_WIDEN:
1309 fwtok->col_widen (info->fixed_context_col);
1310 break;
1311 case CONTEXT_STF_IMPORT_NARROW:
1312 fwtok->col_narrow (info->fixed_context_col);
1313 break;
1314 default:
1315 ; /* Nothing */
1316 }
1317
1318 try
1319 {
1320 info->tx_imp->tokenize (false);
1321 }
1322 catch(std::range_error& e)
1323 {
1324 gnc_error_dialog (GTK_WINDOW (info->csv_imp_asst), "%s", e.what());
1325 return false;
1326 }
1327 info->preview_refresh_table ();
1328 return true;
1329}

The documentation for this class was generated from the following file: