35#include <glib/gi18n.h>
42#include "dialog-utils.h"
44#include "gnc-component-manager.h"
50#include "gnc-csv-gnumeric-popup.h"
51#include "go-charmap-sel.h"
65#define MIN_COL_WIDTH 70
66#define GNC_PREFS_GROUP "dialogs.import.csv"
67#define ASSISTANT_CSV_IMPORT_PRICE_CM_CLASS "assistant-csv-price-import"
70static QofLogModule log_module = GNC_MOD_ASSISTANT;
93 void assist_prepare_cb (GtkWidget *page);
94 void assist_file_page_prepare ();
95 void assist_preview_page_prepare ();
96 void assist_confirm_page_prepare ();
97 void assist_summary_page_prepare ();
98 void assist_finish ();
99 void assist_compmgr_close ();
101 void file_activated_cb ();
102 void file_selection_changed_cb ();
104 void preview_settings_delete ();
105 void preview_settings_save ();
106 void preview_settings_name (GtkEntry* entry);
107 void preview_settings_load ();
108 void preview_update_skipped_rows ();
109 void preview_over_write (
bool over);
113 void preview_update_date_format ();
114 void preview_update_currency_format ();
115 void preview_update_currency ();
116 void preview_update_commodity ();
117 void preview_reparse_col_type (GncPricePropType type);
121 void preview_populate_settings_combo();
122 void preview_handle_save_del_sensitivity (GtkComboBox* combo);
123 void preview_split_column (
int col,
int offset);
124 void preview_refresh_table ();
125 void preview_refresh ();
126 void preview_validate_settings ();
133 uint32_t get_new_col_rel_pos (GtkTreeViewColumn *tcol,
int dx);
134 void fixed_context_menu (GdkEventButton *event,
int col,
int dx);
136 void preview_row_fill_state_cells (GtkListStore *store, GtkTreeIter *iter,
137 std::string& err_msg,
bool skip);
139 GtkWidget* preview_cbox_factory (GtkTreeModel* model, uint32_t colnum);
141 void preview_style_column (uint32_t col_num, GtkTreeModel* model);
143 bool check_for_valid_filename ();
145 GtkAssistant *csv_imp_asst;
147 GtkWidget *file_page;
148 GtkWidget *file_chooser;
149 std::string m_fc_file_name;
150 std::string m_final_file_name;
152 GtkWidget *preview_page;
153 GtkComboBox *settings_combo;
154 GtkWidget *save_button;
155 GtkWidget *del_button;
157 GtkWidget *combo_hbox;
158 GtkSpinButton *start_row_spin;
159 GtkSpinButton *end_row_spin;
160 GtkWidget *skip_alt_rows_button;
161 GtkWidget *skip_errors_button;
162 GtkWidget *csv_button;
163 GtkWidget *fixed_button;
164 GtkWidget *over_write_cbutton;
165 GtkWidget *commodity_selector;
166 GtkWidget *currency_selector;
167 GOCharmapSel *encselector;
168 GtkWidget *separator_table;
169 GtkCheckButton *sep_button[SEP_NUM_OF_TYPES];
170 GtkCheckButton *escape_cbutton;
171 GtkWidget *fw_instructions_hbox;
172 GtkCheckButton *custom_cbutton;
173 GtkEntry *custom_entry;
174 GtkComboBoxText *date_format_combo;
175 GtkComboBoxText *currency_format_combo;
176 GtkTreeView *treeview;
177 GtkLabel *instructions_label;
178 GtkImage *instructions_image;
179 bool encoding_selected_called;
181 int fixed_context_col;
182 int fixed_context_offset;
185 GtkWidget *confirm_page;
187 GtkWidget *summary_page;
188 GtkWidget *summary_label;
190 std::unique_ptr<GncPriceImport> price_imp;
200void csv_price_imp_assist_prepare_cb (GtkAssistant *assistant, GtkWidget *page,
CsvImpPriceAssist* info);
201void csv_price_imp_assist_close_cb (GtkAssistant *gtkassistant,
CsvImpPriceAssist* info);
202void csv_price_imp_assist_finish_cb (GtkAssistant *gtkassistant,
CsvImpPriceAssist* info);
203void csv_price_imp_file_activated_changed_cb (GtkFileChooser *chooser,
CsvImpPriceAssist *info);
204void csv_price_imp_file_selection_changed_cb (GtkFileChooser *chooser,
CsvImpPriceAssist *info);
205void csv_price_imp_preview_del_settings_cb (GtkWidget *button,
CsvImpPriceAssist *info);
206void csv_price_imp_preview_save_settings_cb (GtkWidget *button,
CsvImpPriceAssist *info);
207void csv_price_imp_preview_settings_sel_changed_cb (GtkComboBox *combo,
CsvImpPriceAssist *info);
208void csv_price_imp_preview_settings_text_inserted_cb (GtkEditable *entry, gchar *new_text,
210void csv_price_imp_preview_settings_text_changed_cb (GtkEntry *entry,
CsvImpPriceAssist *info);
211void csv_price_imp_preview_srow_cb (GtkSpinButton *spin,
CsvImpPriceAssist *info);
212void csv_price_imp_preview_erow_cb (GtkSpinButton *spin,
CsvImpPriceAssist *info);
213void csv_price_imp_preview_skiprows_cb (GtkToggleButton *checkbox,
CsvImpPriceAssist *info);
214void csv_price_imp_preview_skiperrors_cb (GtkToggleButton *checkbox,
CsvImpPriceAssist *info);
215void csv_price_imp_preview_overwrite_cb (GtkToggleButton *checkbox,
CsvImpPriceAssist *info);
216void csv_price_imp_preview_sep_button_cb (GtkWidget* widget,
CsvImpPriceAssist* info);
217void csv_price_imp_preview_sep_fixed_sel_cb (GtkToggleButton* csv_button,
CsvImpPriceAssist* info);
218void csv_price_imp_preview_acct_sel_cb (GtkWidget* widget,
CsvImpPriceAssist* info);
219void csv_price_imp_preview_enc_sel_cb (GOCharmapSel* selector,
const char* encoding,
224csv_price_imp_assist_prepare_cb (GtkAssistant *assistant, GtkWidget *page,
227 info->assist_prepare_cb(page);
233 gnc_close_gui_component_by_data (ASSISTANT_CSV_IMPORT_PRICE_CM_CLASS, info);
239 info->assist_finish ();
242void csv_price_imp_file_activated_changed_cb (GtkFileChooser *chooser,
CsvImpPriceAssist *info)
244 info->file_activated_cb();
247void csv_price_imp_file_selection_changed_cb (GtkFileChooser *chooser,
CsvImpPriceAssist *info)
249 info->file_selection_changed_cb();
252void csv_price_imp_preview_del_settings_cb (GtkWidget *button,
CsvImpPriceAssist *info)
254 info->preview_settings_delete();
257void csv_price_imp_preview_save_settings_cb (GtkWidget *button,
CsvImpPriceAssist *info)
259 info->preview_settings_save();
262void csv_price_imp_preview_settings_sel_changed_cb (GtkComboBox *combo,
CsvImpPriceAssist *info)
264 info->preview_settings_load();
268csv_price_imp_preview_settings_text_inserted_cb (GtkEditable *entry, gchar *new_text,
275 auto base_txt = std::string (new_text);
276 auto mod_txt = base_txt;
277 std::replace (mod_txt.begin(), mod_txt.end(),
'[',
'(');
278 std::replace (mod_txt.begin(), mod_txt.end(),
']',
')');
279 if (base_txt == mod_txt)
281 g_signal_handlers_block_by_func (entry, (gpointer) csv_price_imp_preview_settings_text_inserted_cb, info);
282 gtk_editable_insert_text (entry, mod_txt.c_str(), mod_txt.size() , position);
283 g_signal_handlers_unblock_by_func (entry, (gpointer) csv_price_imp_preview_settings_text_inserted_cb, info);
285 g_signal_stop_emission_by_name (entry,
"insert_text");
289csv_price_imp_preview_settings_text_changed_cb (GtkEntry *entry,
CsvImpPriceAssist *info)
291 info->preview_settings_name(entry);
296 info->preview_update_skipped_rows();
301 info->preview_update_skipped_rows();
304void csv_price_imp_preview_skiprows_cb (GtkToggleButton *checkbox,
CsvImpPriceAssist *info)
306 info->preview_update_skipped_rows();
309void csv_price_imp_preview_skiperrors_cb (GtkToggleButton *checkbox,
CsvImpPriceAssist *info)
311 info->preview_update_skipped_rows();
314void csv_price_imp_preview_overwrite_cb (GtkToggleButton *checkbox,
CsvImpPriceAssist *info)
316 info->preview_over_write (gtk_toggle_button_get_active (checkbox));
319void csv_price_imp_preview_sep_button_cb (GtkWidget* widget,
CsvImpPriceAssist* info)
321 info->preview_update_separators(widget);
324void csv_price_imp_preview_sep_fixed_sel_cb (GtkToggleButton* csv_button,
CsvImpPriceAssist* info)
326 info->preview_update_file_format();
329void csv_price_imp_preview_enc_sel_cb (GOCharmapSel* selector,
const char* encoding,
332 info->preview_update_encoding(encoding);
335static void csv_price_imp_preview_date_fmt_sel_cb (GtkComboBox* format_selector,
CsvImpPriceAssist* info)
337 info->preview_update_date_format();
340static void csv_price_imp_preview_currency_fmt_sel_cb (GtkComboBox* format_selector,
CsvImpPriceAssist* info)
342 info->preview_update_currency_format();
345enum GncCommColumn {DISPLAYED_COMM, SORT_COMM, COMM_PTR, SEP};
347static void csv_price_imp_preview_currency_sel_cb (GtkComboBox* currency_selector,
CsvImpPriceAssist* info)
349 info->preview_update_currency();
352static gboolean separator_row_func (GtkTreeModel *smodel, GtkTreeIter *siter, gpointer data)
358 store = gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT(smodel));
360 gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT(smodel),
363 gtk_tree_model_get (GTK_TREE_MODEL(store), &iter, SEP, &sep_row, -1);
368static void csv_price_imp_preview_commodity_sel_cb (GtkComboBox* commodity_selector,
CsvImpPriceAssist* info)
370 info->preview_update_commodity();
373static void csv_price_imp_preview_col_type_changed_cb (GtkComboBox* cbox,
CsvImpPriceAssist* info)
375 info->preview_update_col_type (cbox);
379csv_price_imp_preview_treeview_clicked_cb (GtkTreeView* treeview, GdkEventButton* event,
382 info->preview_update_fw_columns(treeview, event);
387gnc_commodity *get_commodity_from_combo (GtkComboBox *combo)
389 GtkTreeModel *model, *sort_model;
390 GtkTreeIter iter, siter;
394 if (!gtk_combo_box_get_active_iter (combo, &siter))
397 sort_model = gtk_combo_box_get_model (combo);
398 model = gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT(sort_model));
400 gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT(sort_model),
403 gtk_tree_model_get (GTK_TREE_MODEL(model), &iter,
404 DISPLAYED_COMM, &
string, COMM_PTR, &comm, -1);
406 PINFO(
"Commodity string is %s",
string);
413set_commodity_for_combo (GtkComboBox *combo, gnc_commodity *comm)
415 GtkTreeModel *model, *sort_model;
416 GtkTreeIter iter, siter;
417 gnc_commodity *model_comm;
420 sort_model = gtk_combo_box_get_model (combo);
421 model = gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT(sort_model));
422 valid = gtk_tree_model_get_iter_first (model, &iter);
426 gtk_tree_model_get (model, &iter, COMM_PTR, &model_comm, -1);
427 if (model_comm == comm)
429 if (gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT(sort_model), &siter, &iter))
431 gtk_combo_box_set_active_iter (combo, &siter);
436 valid = gtk_tree_model_iter_next (model, &iter);
439 gtk_tree_model_get_iter_first (model, &iter);
440 if (gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT(sort_model), &siter, &iter))
441 gtk_combo_box_set_active_iter (combo, &siter);
445GtkTreeModel *get_model (
bool all_commodity)
447 GtkTreeModel *store, *model;
448 const gnc_commodity_table *commodity_table = gnc_get_current_commodities ();
449 gnc_commodity *tmp_commodity =
nullptr;
450 char *tmp_namespace =
nullptr;
454 store = GTK_TREE_MODEL(gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_STRING,
455 G_TYPE_POINTER, G_TYPE_BOOLEAN));
456 model = gtk_tree_model_sort_new_with_model (store);
458 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE(model), SORT_COMM, GTK_SORT_ASCENDING);
460 gtk_list_store_append (GTK_LIST_STORE(store), &iter);
461 gtk_list_store_set (GTK_LIST_STORE(store), &iter,
462 DISPLAYED_COMM,
" ", SORT_COMM,
" ", COMM_PTR,
nullptr, SEP,
false, -1);
464 for (
auto node = namespace_list; node; node = g_list_next (node))
466 tmp_namespace = (
char*)node->data;
467 DEBUG(
"Looking at namespace %s", tmp_namespace);
470 if (g_utf8_collate (tmp_namespace,
"template" ) != 0)
472 if ((g_utf8_collate (tmp_namespace, GNC_COMMODITY_NS_CURRENCY ) == 0) || (all_commodity ==
true))
477 if ((g_utf8_collate (tmp_namespace, GNC_COMMODITY_NS_CURRENCY) == 0) && (all_commodity ==
true))
479 gtk_list_store_append (GTK_LIST_STORE(store), &iter);
480 gtk_list_store_set (GTK_LIST_STORE(store), &iter, DISPLAYED_COMM,
" ",
481 SORT_COMM,
"CURRENCY-", COMM_PTR,
nullptr, SEP,
true, -1);
484 for (
auto node = comm_list; node; node = g_list_next (node))
486 const gchar *name_str;
488 tmp_commodity = (gnc_commodity*)node->data;
493 if (g_utf8_collate (tmp_namespace, GNC_COMMODITY_NS_CURRENCY) == 0)
494 sort_str = g_strconcat (
"CURRENCY-", name_str,
nullptr);
496 sort_str = g_strconcat (
"ALL-OTHER-", name_str,
nullptr);
498 DEBUG(
"Name string is '%s', Sort string is '%s'", name_str, sort_str);
500 gtk_list_store_append (GTK_LIST_STORE(store), &iter);
501 gtk_list_store_set (GTK_LIST_STORE(store), &iter, DISPLAYED_COMM, name_str,
502 SORT_COMM, sort_str, COMM_PTR, tmp_commodity, SEP,
false, -1);
506 g_list_free (comm_list);
510 g_list_free (namespace_list);
511 g_object_unref (store);
520CsvImpPriceAssist::CsvImpPriceAssist ()
522 auto builder = gtk_builder_new();
523 gnc_builder_add_from_file (builder ,
"assistant-csv-price-import.glade",
"start_row_adj");
524 gnc_builder_add_from_file (builder ,
"assistant-csv-price-import.glade",
"end_row_adj");
525 gnc_builder_add_from_file (builder ,
"assistant-csv-price-import.glade",
"liststore1");
526 gnc_builder_add_from_file (builder ,
"assistant-csv-price-import.glade",
"liststore2");
527 gnc_builder_add_from_file (builder ,
"assistant-csv-price-import.glade",
"CSV Price Assistant");
528 csv_imp_asst = GTK_ASSISTANT(gtk_builder_get_object (builder,
"CSV Price Assistant"));
531 gtk_widget_set_name (GTK_WIDGET(csv_imp_asst),
"gnc-id-assistant-csv-price-import");
532 gnc_widget_style_context_add_class (GTK_WIDGET(csv_imp_asst),
"gnc-class-imports");
535 gtk_assistant_set_page_complete (csv_imp_asst,
536 GTK_WIDGET(gtk_builder_get_object (builder,
"start_page")),
538 gtk_assistant_set_page_complete (csv_imp_asst,
539 GTK_WIDGET(gtk_builder_get_object (builder,
"file_page")),
541 gtk_assistant_set_page_complete (csv_imp_asst,
542 GTK_WIDGET(gtk_builder_get_object (builder,
"preview_page")),
544 gtk_assistant_set_page_complete (csv_imp_asst,
545 GTK_WIDGET(gtk_builder_get_object (builder,
"confirm_page")),
547 gtk_assistant_set_page_complete (csv_imp_asst,
548 GTK_WIDGET(gtk_builder_get_object (builder,
"summary_page")),
552 file_page = GTK_WIDGET(gtk_builder_get_object (builder,
"file_page"));
553 file_chooser = gtk_file_chooser_widget_new (GTK_FILE_CHOOSER_ACTION_OPEN);
555 g_signal_connect (G_OBJECT(file_chooser),
"selection-changed",
556 G_CALLBACK(csv_price_imp_file_selection_changed_cb),
this);
557 g_signal_connect (G_OBJECT(file_chooser),
"file-activated",
558 G_CALLBACK(csv_price_imp_file_activated_changed_cb),
this);
560 auto box = GTK_WIDGET(gtk_builder_get_object (builder,
"file_page"));
561 gtk_box_pack_start (GTK_BOX(box), file_chooser, TRUE, TRUE, 6);
562 gtk_widget_show (file_chooser);
566 preview_page = GTK_WIDGET(gtk_builder_get_object (builder,
"preview_page"));
569 auto settings_store = gtk_list_store_new (2, G_TYPE_POINTER, G_TYPE_STRING);
570 settings_combo = GTK_COMBO_BOX(gtk_combo_box_new_with_model_and_entry (GTK_TREE_MODEL(settings_store)));
571 g_object_unref (settings_store);
573 gtk_combo_box_set_entry_text_column (GTK_COMBO_BOX(settings_combo), SET_NAME);
574 gtk_combo_box_set_active (GTK_COMBO_BOX(settings_combo), 0);
576 combo_hbox = GTK_WIDGET(gtk_builder_get_object (builder,
"combo_hbox"));
577 gtk_box_pack_start (GTK_BOX(combo_hbox), GTK_WIDGET(settings_combo),
true,
true, 6);
578 gtk_widget_show (GTK_WIDGET(settings_combo));
580 g_signal_connect (G_OBJECT(settings_combo),
"changed",
581 G_CALLBACK(csv_price_imp_preview_settings_sel_changed_cb),
this);
584 auto emb_entry = gtk_bin_get_child (GTK_BIN (settings_combo));
585 g_signal_connect (G_OBJECT(emb_entry),
"changed",
586 G_CALLBACK(csv_price_imp_preview_settings_text_changed_cb),
this);
587 g_signal_connect (G_OBJECT(emb_entry),
"insert-text",
588 G_CALLBACK(csv_price_imp_preview_settings_text_inserted_cb),
this);
591 save_button = GTK_WIDGET(gtk_builder_get_object (builder,
"save_settings"));
594 del_button = GTK_WIDGET(gtk_builder_get_object (builder,
"delete_settings"));
597 start_row_spin = GTK_SPIN_BUTTON(gtk_builder_get_object (builder,
"start_row"));
598 end_row_spin = GTK_SPIN_BUTTON(gtk_builder_get_object (builder,
"end_row"));
599 skip_alt_rows_button = GTK_WIDGET(gtk_builder_get_object (builder,
"skip_rows"));
600 skip_errors_button = GTK_WIDGET(gtk_builder_get_object (builder,
"skip_errors_button"));
601 over_write_cbutton = GTK_WIDGET(gtk_builder_get_object (builder,
"over_write_button"));
602 separator_table = GTK_WIDGET(gtk_builder_get_object (builder,
"separator_table"));
603 fw_instructions_hbox = GTK_WIDGET(gtk_builder_get_object (builder,
"fw_instructions_hbox"));
607 const char* sep_button_names[] = {
615 for (
int i = 0; i < SEP_NUM_OF_TYPES; i++)
617 = GTK_CHECK_BUTTON(gtk_builder_get_object (builder, sep_button_names[i]));
622 = GTK_CHECK_BUTTON(gtk_builder_get_object (builder,
"custom_cbutton"));
626 custom_entry = GTK_ENTRY(gtk_builder_get_object (builder,
"custom_entry"));
631 = GTK_CHECK_BUTTON(gtk_builder_get_object (builder,
"escape_cbutton"));
634 encselector = GO_CHARMAP_SEL(go_charmap_sel_new(GO_CHARMAP_SEL_TO_UTF8));
636 g_signal_connect (G_OBJECT(encselector),
"charmap_changed",
637 G_CALLBACK(csv_price_imp_preview_enc_sel_cb),
this);
639 auto encoding_container = GTK_CONTAINER(gtk_builder_get_object (builder,
"encoding_container"));
640 gtk_container_add (encoding_container, GTK_WIDGET(encselector));
641 gtk_widget_set_hexpand (GTK_WIDGET(encselector),
true);
642 gtk_widget_show_all (GTK_WIDGET(encoding_container));
645 commodity_selector = GTK_WIDGET(gtk_builder_get_object (builder,
"commodity_cbox"));
646 gtk_combo_box_set_model (GTK_COMBO_BOX(commodity_selector), get_model (
true));
647 gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX(commodity_selector),
648 separator_row_func,
nullptr,
nullptr);
649 g_signal_connect (G_OBJECT(commodity_selector),
"changed",
650 G_CALLBACK(csv_price_imp_preview_commodity_sel_cb),
this);
653 currency_selector = GTK_WIDGET(gtk_builder_get_object (builder,
"currency_cbox"));
654 gtk_combo_box_set_model (GTK_COMBO_BOX(currency_selector), get_model (
false));
655 g_signal_connect(G_OBJECT(currency_selector),
"changed",
656 G_CALLBACK(csv_price_imp_preview_currency_sel_cb),
this);
659 instructions_label = GTK_LABEL(gtk_builder_get_object (builder,
"instructions_label"));
660 instructions_image = GTK_IMAGE(gtk_builder_get_object (builder,
"instructions_image"));
663 date_format_combo = GTK_COMBO_BOX_TEXT(gtk_combo_box_text_new());
664 for (
auto& date_fmt :
GncDate::c_formats)
665 gtk_combo_box_text_append_text (date_format_combo,
_(date_fmt.m_fmt.c_str()));
666 gtk_combo_box_set_active (GTK_COMBO_BOX(date_format_combo), 0);
667 g_signal_connect (G_OBJECT(date_format_combo),
"changed",
668 G_CALLBACK(csv_price_imp_preview_date_fmt_sel_cb),
this);
671 auto date_format_container = GTK_CONTAINER(gtk_builder_get_object (builder,
"date_format_container"));
672 gtk_container_add (date_format_container, GTK_WIDGET(date_format_combo));
673 gtk_widget_set_hexpand (GTK_WIDGET(date_format_combo),
true);
674 gtk_widget_show_all (GTK_WIDGET(date_format_container));
677 currency_format_combo = GTK_COMBO_BOX_TEXT(gtk_combo_box_text_new());
678 for (
int i = 0; i < num_currency_formats_price; i++)
680 gtk_combo_box_text_append_text (currency_format_combo,
_(currency_format_user_price[i]));
683 gtk_combo_box_set_active (GTK_COMBO_BOX(currency_format_combo), 0);
684 g_signal_connect (G_OBJECT(currency_format_combo),
"changed",
685 G_CALLBACK(csv_price_imp_preview_currency_fmt_sel_cb),
this);
688 auto currency_format_container = GTK_CONTAINER(gtk_builder_get_object (builder,
"currency_format_container"));
689 gtk_container_add (currency_format_container, GTK_WIDGET(currency_format_combo));
690 gtk_widget_set_hexpand (GTK_WIDGET(currency_format_combo),
true);
691 gtk_widget_show_all (GTK_WIDGET(currency_format_container));
694 csv_button = GTK_WIDGET(gtk_builder_get_object (builder,
"csv_button"));
695 fixed_button = GTK_WIDGET(gtk_builder_get_object (builder,
"fixed_button"));
698 treeview = GTK_TREE_VIEW(gtk_builder_get_object (builder,
"treeview"));
699 gtk_tree_view_set_headers_clickable (treeview,
true);
703 encoding_selected_called =
false;
707 confirm_page = GTK_WIDGET(gtk_builder_get_object (builder,
"confirm_page"));
710 summary_page = GTK_WIDGET(gtk_builder_get_object (builder,
"summary_page"));
711 summary_label = GTK_WIDGET(gtk_builder_get_object (builder,
"summary_label"));
713 gnc_restore_window_size (GNC_PREFS_GROUP,
716 gtk_builder_connect_signals (builder,
this);
717 g_object_unref (G_OBJECT(builder));
719 gtk_widget_show_all (GTK_WIDGET(csv_imp_asst));
720 gnc_window_adjust_for_screen (GTK_WINDOW(csv_imp_asst));
726CsvImpPriceAssist::~CsvImpPriceAssist ()
728 gtk_widget_destroy (GTK_WIDGET(csv_imp_asst));
738CsvImpPriceAssist::check_for_valid_filename ()
740 auto file_name = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(file_chooser));
741 if (!file_name || g_file_test (file_name, G_FILE_TEST_IS_DIR))
748 auto starting_dir = g_path_get_dirname (filepath);
750 m_fc_file_name = file_name;
751 gnc_set_default_directory (GNC_PREFS_GROUP, starting_dir);
753 DEBUG(
"file_name selected is %s", m_fc_file_name.c_str());
754 DEBUG(
"starting directory is %s", starting_dir);
758 g_free (starting_dir);
768CsvImpPriceAssist::file_activated_cb ()
770 gtk_assistant_set_page_complete (csv_imp_asst, file_page,
false);
773 if (check_for_valid_filename ())
775 gtk_assistant_set_page_complete (csv_imp_asst, file_page,
true);
776 gtk_assistant_next_page (csv_imp_asst);
785CsvImpPriceAssist::file_selection_changed_cb ()
788 gtk_assistant_set_page_complete (csv_imp_asst, file_page,
789 check_for_valid_filename ());
799void CsvImpPriceAssist::preview_populate_settings_combo()
802 auto model = gtk_combo_box_get_model (settings_combo);
803 gtk_list_store_clear (GTK_LIST_STORE(model));
807 for (
const auto& preset : presets)
810 gtk_list_store_append (GTK_LIST_STORE(model), &iter);
817 gtk_list_store_set (GTK_LIST_STORE(model), &iter, SET_GROUP, preset.get(), SET_NAME,
_(preset->m_name.c_str()), -1);
824void CsvImpPriceAssist::preview_handle_save_del_sensitivity (GtkComboBox* combo)
827 auto can_delete =
false;
828 auto can_save =
false;
829 auto entry = gtk_bin_get_child (GTK_BIN(combo));
830 auto entry_text = gtk_entry_get_text (GTK_ENTRY(entry));
832 if (gtk_combo_box_get_active_iter (combo, &iter))
835 GtkTreeModel *model = gtk_combo_box_get_model (combo);
836 gtk_tree_model_get (model, &iter, SET_GROUP, &preset, -1);
845 else if (entry_text && (strlen (entry_text) > 0) &&
849 gtk_widget_set_sensitive (save_button, can_save);
850 gtk_widget_set_sensitive (del_button, can_delete);
854CsvImpPriceAssist::preview_settings_name (GtkEntry* entry)
856 auto text = gtk_entry_get_text (entry);
858 price_imp->settings_name(text);
860 auto box = gtk_widget_get_parent (GTK_WIDGET(entry));
861 auto combo = gtk_widget_get_parent (GTK_WIDGET(box));
863 preview_handle_save_del_sensitivity (GTK_COMBO_BOX(combo));
870CsvImpPriceAssist::preview_settings_load ()
874 if (!gtk_combo_box_get_active_iter (settings_combo, &iter))
878 auto model = gtk_combo_box_get_model (settings_combo);
879 gtk_tree_model_get (model, &iter, SET_GROUP, &preset, -1);
884 price_imp->settings (*preset);
885 if (preset->m_load_error)
886 gnc_error_dialog (GTK_WINDOW(csv_imp_asst),
887 "%s",
_(
"There were problems reading some saved settings, continuing to load.\n"
888 "Please review and save again."));
891 preview_handle_save_del_sensitivity (settings_combo);
897CsvImpPriceAssist::preview_settings_delete ()
901 if (!gtk_combo_box_get_active_iter (settings_combo, &iter))
905 auto model = gtk_combo_box_get_model (settings_combo);
906 gtk_tree_model_get (model, &iter, SET_GROUP, &preset, -1);
908 auto response = gnc_ok_cancel_dialog (GTK_WINDOW(csv_imp_asst),
910 "%s",
_(
"Delete the Import Settings."));
911 if (response == GTK_RESPONSE_OK)
914 preview_populate_settings_combo();
915 gtk_combo_box_set_active (settings_combo, 0);
923CsvImpPriceAssist::preview_settings_save ()
925 auto new_name = price_imp->settings_name();
929 if (!gtk_combo_box_get_active_iter (settings_combo, &iter))
932 auto model = gtk_combo_box_get_model (settings_combo);
933 bool valid = gtk_tree_model_get_iter_first (model, &iter);
938 gtk_tree_model_get (model, &iter, SET_GROUP, &preset, -1);
940 if (preset && (preset->m_name == std::string(new_name)))
942 auto response = gnc_ok_cancel_dialog (GTK_WINDOW(csv_imp_asst),
944 "%s",
_(
"Setting name already exists, overwrite?"));
945 if (response != GTK_RESPONSE_OK)
950 valid = gtk_tree_model_iter_next (model, &iter);
955 if (!price_imp->save_settings())
957 gnc_info_dialog (GTK_WINDOW(csv_imp_asst),
958 "%s",
_(
"The settings have been saved."));
961 preview_populate_settings_combo();
962 auto model = gtk_combo_box_get_model (settings_combo);
966 bool valid = gtk_tree_model_get_iter_first (model, &iter);
970 gchar *name =
nullptr;
971 gtk_tree_model_get (model, &iter, SET_NAME, &name, -1);
973 if (g_strcmp0 (name, new_name.c_str()) == 0)
974 gtk_combo_box_set_active_iter (settings_combo, &iter);
978 valid = gtk_tree_model_iter_next (model, &iter);
982 gnc_error_dialog (GTK_WINDOW(csv_imp_asst),
983 "%s",
_(
"There was a problem saving the settings, please try again."));
988void CsvImpPriceAssist::preview_update_skipped_rows ()
991 price_imp->update_skipped_lines (gtk_spin_button_get_value_as_int (start_row_spin),
992 gtk_spin_button_get_value_as_int (end_row_spin),
993 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(skip_alt_rows_button)),
994 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(skip_errors_button)));
997 auto adj = gtk_spin_button_get_adjustment (end_row_spin);
998 gtk_adjustment_set_upper (adj, price_imp->m_parsed_lines.size()
999 - price_imp->skip_start_lines() -1);
1001 adj = gtk_spin_button_get_adjustment (start_row_spin);
1002 gtk_adjustment_set_upper (adj, price_imp->m_parsed_lines.size()
1003 - price_imp->skip_end_lines() - 1);
1005 preview_refresh_table ();
1010void CsvImpPriceAssist::preview_over_write (
bool over)
1012 price_imp->over_write (over);
1026 if (price_imp->file_format() != GncImpFileFormat::CSV)
1031 auto checked_separators = std::string();
1032 const auto stock_sep_chars = std::string (
" \t,:;-");
1033 for (
int i = 0; i < SEP_NUM_OF_TYPES; i++)
1035 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(sep_button[i])))
1036 checked_separators += stock_sep_chars[i];
1040 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(custom_cbutton)))
1042 auto custom_sep = gtk_entry_get_text (custom_entry);
1043 if (custom_sep[0] !=
'\0')
1044 checked_separators += custom_sep;
1048 price_imp->separators (checked_separators);
1049 price_imp->enable_escape (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(escape_cbutton)));
1053 if (checked_separators.empty())
1054 price_imp->set_column_type_price (0, GncPricePropType::NONE);
1061 price_imp->tokenize (
false);
1062 preview_refresh_table ();
1064 catch (std::range_error &e)
1069 gnc_error_dialog (GTK_WINDOW(csv_imp_asst),
"Error in parsing");
1075 if (widget == GTK_WIDGET(custom_entry))
1076 gtk_entry_set_text (GTK_ENTRY(widget),
"");
1079 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(widget),
1080 !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(widget)));
1095 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(csv_button)))
1097 price_imp->file_format (GncImpFileFormat::CSV);
1098 g_signal_handlers_disconnect_by_func(G_OBJECT(treeview),
1099 (gpointer)csv_price_imp_preview_treeview_clicked_cb, (gpointer)
this);
1100 gtk_widget_set_visible (separator_table,
true);
1101 gtk_widget_set_visible (fw_instructions_hbox,
false);
1105 price_imp->file_format (GncImpFileFormat::FIXED_WIDTH);
1107 g_signal_connect (G_OBJECT(treeview),
"button-press-event",
1108 G_CALLBACK(csv_price_imp_preview_treeview_clicked_cb), (gpointer)
this);
1109 gtk_widget_set_visible (separator_table,
false);
1110 gtk_widget_set_visible (fw_instructions_hbox,
true);
1113 price_imp->tokenize (
false);
1114 preview_refresh_table ();
1116 catch (std::range_error &e)
1119 gnc_error_dialog (GTK_WINDOW (csv_imp_asst),
"%s", e.what());
1125 PWARN(
"Got an error during file loading");
1143 if (encoding_selected_called)
1145 std::string previous_encoding = price_imp->m_tokenizer->encoding();
1149 price_imp->encoding (encoding);
1150 preview_refresh_table ();
1155 gnc_error_dialog (GTK_WINDOW (csv_imp_asst),
"%s", _(
"Invalid encoding selected"));
1156 go_charmap_sel_set_encoding (encselector, previous_encoding.c_str());
1159 encoding_selected_called = !encoding_selected_called;
1163CsvImpPriceAssist::preview_update_date_format ()
1165 price_imp->date_format (gtk_combo_box_get_active (GTK_COMBO_BOX(date_format_combo)));
1166 preview_refresh_table ();
1170CsvImpPriceAssist::preview_update_currency_format ()
1172 price_imp->currency_format (gtk_combo_box_get_active (GTK_COMBO_BOX(currency_format_combo)));
1173 preview_refresh_table ();
1177CsvImpPriceAssist::preview_update_currency ()
1179 gnc_commodity *comm = get_commodity_from_combo (GTK_COMBO_BOX(currency_selector));
1180 price_imp->to_currency (comm);
1181 preview_refresh_table ();
1185CsvImpPriceAssist::preview_update_commodity ()
1187 gnc_commodity *comm = get_commodity_from_combo (GTK_COMBO_BOX(commodity_selector));
1188 price_imp->from_commodity (comm);
1189 preview_refresh_table ();
1195 assist->preview_refresh_table ();
1202enum PreviewHeaderComboCols { COL_TYPE_NAME, COL_TYPE_ID };
1206enum PreviewDataTableCols {
1212 PREV_N_FIXED_COLS };
1216CsvImpPriceAssist::preview_reparse_col_type (GncPricePropType type)
1218 auto column_types = price_imp->column_types_price();
1221 auto col_type = std::find (column_types.begin(),
1222 column_types.end(), type);
1223 if (col_type != column_types.end())
1225 price_imp->set_column_type_price (col_type -column_types.begin(),
1243 auto model = gtk_combo_box_get_model (cbox);
1244 gtk_combo_box_get_active_iter (cbox, &iter);
1245 auto new_col_type = GncPricePropType::NONE;
1246 gtk_tree_model_get (model, &iter, COL_TYPE_ID, &new_col_type, -1);
1248 auto col_num = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT(cbox),
"col-num"));
1250 auto column_types = price_imp->column_types_price();
1251 auto old_col_type = column_types.at(col_num);
1253 price_imp->set_column_type_price (col_num, new_col_type);
1256 if (old_col_type == GncPricePropType::TO_CURRENCY)
1259 preview_reparse_col_type (GncPricePropType::FROM_SYMBOL);
1260 preview_reparse_col_type (GncPricePropType::FROM_NAMESPACE);
1264 if ((old_col_type == GncPricePropType::FROM_SYMBOL) ||
1265 (old_col_type == GncPricePropType::FROM_NAMESPACE))
1268 preview_reparse_col_type (GncPricePropType::TO_CURRENCY);
1274 g_idle_add ((GSourceFunc)csv_imp_preview_queue_rebuild_table,
this);
1306 CONTEXT_STF_IMPORT_MERGE_LEFT = 1,
1307 CONTEXT_STF_IMPORT_MERGE_RIGHT = 2,
1308 CONTEXT_STF_IMPORT_SPLIT = 3,
1309 CONTEXT_STF_IMPORT_WIDEN = 4,
1310 CONTEXT_STF_IMPORT_NARROW = 5
1316 N_(
"Merge with column on _left"),
"list-remove",
1317 0, 1 << CONTEXT_STF_IMPORT_MERGE_LEFT, CONTEXT_STF_IMPORT_MERGE_LEFT
1320 N_(
"Merge with column on _right"),
"list-remove",
1321 0, 1 << CONTEXT_STF_IMPORT_MERGE_RIGHT, CONTEXT_STF_IMPORT_MERGE_RIGHT
1323 {
"",
nullptr, 0, 0, 0 },
1325 N_(
"_Split this column"),
nullptr,
1326 0, 1 << CONTEXT_STF_IMPORT_SPLIT, CONTEXT_STF_IMPORT_SPLIT
1328 {
"",
nullptr, 0, 0, 0 },
1330 N_(
"_Widen this column"),
"go-next",
1331 0, 1 << CONTEXT_STF_IMPORT_WIDEN, CONTEXT_STF_IMPORT_WIDEN
1334 N_(
"_Narrow this column"),
"go-previous",
1335 0, 1 << CONTEXT_STF_IMPORT_NARROW, CONTEXT_STF_IMPORT_NARROW
1337 {
nullptr,
nullptr, 0, 0, 0 },
1340uint32_t CsvImpPriceAssist::get_new_col_rel_pos (GtkTreeViewColumn *tcol,
int dx)
1342 auto renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT(tcol));
1343 auto cell = GTK_CELL_RENDERER(renderers->data);
1344 g_list_free (renderers);
1345 PangoFontDescription *font_desc;
1346 g_object_get (G_OBJECT(cell),
"font_desc", &font_desc,
nullptr);
1348 PangoLayout *layout = gtk_widget_create_pango_layout (GTK_WIDGET(treeview),
"x");
1349 pango_layout_set_font_description (layout, font_desc);
1351 pango_layout_get_pixel_size (layout, &width,
nullptr);
1352 if (width < 1) width = 1;
1353 uint32_t charindex = (dx + width / 2) / width;
1354 g_object_unref (layout);
1355 pango_font_description_free (font_desc);
1365 auto fwtok =
dynamic_cast<GncFwTokenizer*
>(info->price_imp->m_tokenizer.get());
1367 switch (element->index)
1369 case CONTEXT_STF_IMPORT_MERGE_LEFT:
1370 fwtok->col_delete (info->fixed_context_col - 1);
1372 case CONTEXT_STF_IMPORT_MERGE_RIGHT:
1373 fwtok->col_delete (info->fixed_context_col);
1375 case CONTEXT_STF_IMPORT_SPLIT:
1376 fwtok->col_split (info->fixed_context_col, info->fixed_context_offset);
1378 case CONTEXT_STF_IMPORT_WIDEN:
1379 fwtok->col_widen (info->fixed_context_col);
1381 case CONTEXT_STF_IMPORT_NARROW:
1382 fwtok->col_narrow (info->fixed_context_col);
1390 info->price_imp->tokenize (
false);
1392 catch(std::range_error& e)
1394 gnc_error_dialog (GTK_WINDOW (info->csv_imp_asst),
"%s", e.what());
1397 info->preview_refresh_table ();
1402CsvImpPriceAssist::fixed_context_menu (GdkEventButton *event,
1403 int col,
int offset)
1405 auto fwtok =
dynamic_cast<GncFwTokenizer*
>(price_imp->m_tokenizer.get());
1406 fixed_context_col = col;
1407 fixed_context_offset = offset;
1409 int sensitivity_filter = 0;
1410 if (!fwtok->col_can_delete (col - 1))
1411 sensitivity_filter |= (1 << CONTEXT_STF_IMPORT_MERGE_LEFT);
1412 if (!fwtok->col_can_delete (col))
1413 sensitivity_filter |= (1 << CONTEXT_STF_IMPORT_MERGE_RIGHT);
1414 if (!fwtok->col_can_split (col, offset))
1415 sensitivity_filter |= (1 << CONTEXT_STF_IMPORT_SPLIT);
1416 if (!fwtok->col_can_widen (col))
1417 sensitivity_filter |= (1 << CONTEXT_STF_IMPORT_WIDEN);
1418 if (!fwtok->col_can_narrow (col))
1419 sensitivity_filter |= (1 << CONTEXT_STF_IMPORT_NARROW);
1421 gnumeric_create_popup_menu (popup_elements, &fixed_context_menu_handler_price,
1423 sensitivity_filter, event);
1429CsvImpPriceAssist::preview_split_column (
int col,
int offset)
1431 auto fwtok =
dynamic_cast<GncFwTokenizer*
>(price_imp->m_tokenizer.get());
1432 fwtok->col_split (col, offset);
1435 price_imp->tokenize (
false);
1437 catch (std::range_error& e)
1439 gnc_error_dialog (GTK_WINDOW (csv_imp_asst),
"%s", e.what());
1442 preview_refresh_table();
1458 if (event->window != gtk_tree_view_get_bin_window (treeview))
1462 GtkTreeViewColumn *tcol =
nullptr;
1464 auto success = gtk_tree_view_get_path_at_pos (treeview,
1465 (
int)event->x, (
int)event->y,
1466 nullptr, &tcol, &cell_x,
nullptr);
1472 auto tcol_list = gtk_tree_view_get_columns(treeview);
1473 auto tcol_num = g_list_index (tcol_list, tcol);
1474 g_list_free (tcol_list);
1481 auto dcol = tcol_num - 1;
1482 auto offset = get_new_col_rel_pos (tcol, cell_x);
1483 if (event->type == GDK_2BUTTON_PRESS && event->button == 1)
1485 preview_split_column (dcol, offset);
1486 else if (event->type == GDK_BUTTON_PRESS && event->button == 3)
1488 fixed_context_menu (event, dcol, offset);
1493CsvImpPriceAssist::preview_row_fill_state_cells (GtkListStore *store, GtkTreeIter *iter,
1494 std::string& err_msg,
bool skip)
1497 const char *c_err_msg =
nullptr;
1498 const char *icon_name =
nullptr;
1499 const char *fcolor =
nullptr;
1500 const char *bcolor =
nullptr;
1501 if (!skip && !err_msg.empty())
1505 c_err_msg = err_msg.c_str();
1506 icon_name =
"dialog-error";
1508 gtk_list_store_set (store, iter,
1509 PREV_COL_FCOLOR, fcolor,
1510 PREV_COL_BCOLOR, bcolor,
1511 PREV_COL_STRIKE, skip,
1512 PREV_COL_ERROR, c_err_msg,
1513 PREV_COL_ERR_ICON, icon_name, -1);
1520CsvImpPriceAssist::preview_cbox_factory (GtkTreeModel* model, uint32_t colnum)
1523 auto cbox = gtk_combo_box_new_with_model(model);
1526 auto renderer = gtk_cell_renderer_text_new();
1527 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT(cbox),
1529 gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT(cbox),
1530 renderer,
"text", COL_TYPE_NAME);
1532 auto valid = gtk_tree_model_get_iter_first (model, &iter);
1535 gint stored_col_type;
1536 gtk_tree_model_get (model, &iter,
1537 COL_TYPE_ID, &stored_col_type, -1);
1538 if (stored_col_type ==
static_cast<int>( price_imp->column_types_price()[colnum]))
1540 valid = gtk_tree_model_iter_next(model, &iter);
1543 gtk_combo_box_set_active_iter (GTK_COMBO_BOX(cbox), &iter);
1545 g_object_set_data (G_OBJECT(cbox),
"col-num", GUINT_TO_POINTER(colnum));
1546 g_signal_connect (G_OBJECT(cbox),
"changed",
1547 G_CALLBACK(csv_price_imp_preview_col_type_changed_cb), (gpointer)
this);
1549 gtk_widget_show (cbox);
1554CsvImpPriceAssist::preview_style_column (uint32_t col_num, GtkTreeModel* model)
1556 auto col = gtk_tree_view_get_column (treeview, col_num);
1557 auto renderer =
static_cast<GtkCellRenderer*
>(gtk_cell_layout_get_cells(GTK_CELL_LAYOUT(col))->data);
1562 gtk_tree_view_column_set_attributes (col, renderer,
1563 "icon-name", PREV_COL_ERR_ICON,
1564 "cell-background", PREV_COL_BCOLOR,
nullptr);
1565 g_object_set (G_OBJECT(renderer),
"stock-size", GTK_ICON_SIZE_MENU,
nullptr);
1566 g_object_set (G_OBJECT(col),
"sizing", GTK_TREE_VIEW_COLUMN_FIXED,
1567 "fixed-width", 20,
nullptr);
1568 gtk_tree_view_column_set_resizable (col,
false);
1572 gtk_tree_view_column_set_attributes (col, renderer,
1573 "foreground", PREV_COL_FCOLOR,
1574 "background", PREV_COL_BCOLOR,
1575 "strikethrough", PREV_COL_STRIKE,
1576 "text", col_num + PREV_N_FIXED_COLS -1,
nullptr);
1579 g_object_set (G_OBJECT(renderer),
"family",
"monospace",
nullptr);
1584 auto cbox = preview_cbox_factory (GTK_TREE_MODEL(model), col_num - 1);
1585 gtk_tree_view_column_set_widget (col, cbox);
1588 gtk_tree_view_column_set_resizable (col,
true);
1589 gtk_tree_view_column_set_clickable (col,
true);
1596make_column_header_model_price (
void)
1598 auto combostore = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
1599 for (
auto col_type : gnc_price_col_type_strs)
1602 gtk_list_store_append (combostore, &iter);
1603 gtk_list_store_set (combostore, &iter,
1604 COL_TYPE_NAME,
_(col_type.second),
1605 COL_TYPE_ID,
static_cast<int>(col_type.first), -1);
1607 return GTK_TREE_MODEL(combostore);
1613void CsvImpPriceAssist::preview_refresh_table ()
1615 preview_validate_settings ();
1620 auto ncols = PREV_N_FIXED_COLS + price_imp->column_types_price().size();
1621 auto model_col_types = g_new (GType, ncols);
1622 model_col_types[PREV_COL_FCOLOR] = G_TYPE_STRING;
1623 model_col_types[PREV_COL_BCOLOR] = G_TYPE_STRING;
1624 model_col_types[PREV_COL_ERROR] = G_TYPE_STRING;
1625 model_col_types[PREV_COL_ERR_ICON] = G_TYPE_STRING;
1626 model_col_types[PREV_COL_STRIKE] = G_TYPE_BOOLEAN;
1627 for (guint i = PREV_N_FIXED_COLS; i < ncols; i++)
1628 model_col_types[i] = G_TYPE_STRING;
1629 auto store = gtk_list_store_newv (ncols, model_col_types);
1630 g_free (model_col_types);
1633 for (
auto parse_line : price_imp->m_parsed_lines)
1637 gtk_list_store_append (store, &iter);
1638 preview_row_fill_state_cells (store, &iter,
1639 std::get<PL_ERROR>(parse_line), std::get<PL_SKIP>(parse_line));
1642 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++)
1644 uint32_t pos = PREV_N_FIXED_COLS + cell_str_it - std::get<PL_INPUT>(parse_line).cbegin();
1645 gtk_list_store_set (store, &iter, pos, cell_str_it->c_str(), -1);
1648 gtk_tree_view_set_model (treeview, GTK_TREE_MODEL(store));
1649 gtk_tree_view_set_tooltip_column (treeview, PREV_COL_ERROR);
1658 auto ntcols = gtk_tree_view_get_n_columns (treeview);
1664 while (ntcols > ncols - PREV_N_FIXED_COLS + 1)
1666 auto col = gtk_tree_view_get_column (treeview, ntcols - 1);
1667 gtk_tree_view_column_clear (col);
1668 ntcols = gtk_tree_view_remove_column(treeview, col);
1672 while (ntcols < ncols - PREV_N_FIXED_COLS + 1)
1676 auto renderer = (ntcols == 0) ? gtk_cell_renderer_pixbuf_new () : gtk_cell_renderer_text_new ();
1677 auto col = gtk_tree_view_column_new ();
1678 gtk_tree_view_column_pack_start (col, renderer,
false);
1679 ntcols = gtk_tree_view_append_column (treeview, col);
1683 auto combostore = make_column_header_model_price ();
1684 for (uint32_t i = 0; i < ntcols; i++)
1685 preview_style_column (i, combostore);
1687 auto column_types = price_imp->column_types_price();
1688 auto any_of_type = [](std::vector<GncPricePropType>& column_types,
1689 GncPricePropType req_column_type) ->
bool
1691 return std::any_of (column_types.begin(), column_types.end(),
1692 [&req_column_type](GncPricePropType column_type) ->
bool
1693 { return column_type == req_column_type; });
1697 if (any_of_type (column_types, GncPricePropType::FROM_NAMESPACE))
1699 g_signal_handlers_block_by_func (commodity_selector, (gpointer) csv_price_imp_preview_commodity_sel_cb,
this);
1700 set_commodity_for_combo (GTK_COMBO_BOX(commodity_selector),
nullptr);
1701 g_signal_handlers_unblock_by_func (commodity_selector, (gpointer) csv_price_imp_preview_commodity_sel_cb,
this);
1705 if (any_of_type (column_types, GncPricePropType::FROM_SYMBOL))
1707 g_signal_handlers_block_by_func (commodity_selector, (gpointer) csv_price_imp_preview_commodity_sel_cb,
this);
1708 set_commodity_for_combo (GTK_COMBO_BOX(commodity_selector),
nullptr);
1709 g_signal_handlers_unblock_by_func (commodity_selector, (gpointer) csv_price_imp_preview_commodity_sel_cb,
this);
1713 if (any_of_type (column_types, GncPricePropType::TO_CURRENCY))
1715 g_signal_handlers_block_by_func (currency_selector, (gpointer) csv_price_imp_preview_currency_sel_cb,
this);
1716 set_commodity_for_combo (GTK_COMBO_BOX(currency_selector),
nullptr);
1717 g_signal_handlers_unblock_by_func (currency_selector, (gpointer) csv_price_imp_preview_currency_sel_cb,
this);
1721 g_object_unref (store);
1722 g_object_unref (combostore);
1725 gtk_widget_show_all (GTK_WIDGET(treeview));
1732CsvImpPriceAssist::preview_refresh ()
1741 auto skip_start_lines = price_imp->skip_start_lines();
1742 auto skip_end_lines = price_imp->skip_end_lines();
1743 auto skip_alt_lines = price_imp->skip_alt_lines();
1746 auto adj = gtk_spin_button_get_adjustment (start_row_spin);
1747 gtk_adjustment_set_upper (adj, price_imp->m_parsed_lines.size());
1748 gtk_spin_button_set_value (start_row_spin, skip_start_lines);
1751 adj = gtk_spin_button_get_adjustment (end_row_spin);
1752 gtk_adjustment_set_upper (adj, price_imp->m_parsed_lines.size());
1753 gtk_spin_button_set_value (end_row_spin, skip_end_lines);
1756 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(skip_alt_rows_button),
1760 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(over_write_cbutton),
1761 price_imp->over_write());
1764 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(csv_button),
1765 (price_imp->file_format() == GncImpFileFormat::CSV));
1766 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(fixed_button),
1767 (price_imp->file_format() != GncImpFileFormat::CSV));
1770 gtk_combo_box_set_active (GTK_COMBO_BOX(date_format_combo),
1771 price_imp->date_format());
1772 gtk_combo_box_set_active (GTK_COMBO_BOX(currency_format_combo),
1773 price_imp->currency_format());
1774 go_charmap_sel_set_encoding (encselector, price_imp->encoding().c_str());
1777 set_commodity_for_combo(GTK_COMBO_BOX(commodity_selector),
1778 price_imp->from_commodity());
1780 set_commodity_for_combo(GTK_COMBO_BOX(currency_selector),
1781 price_imp->to_currency());
1787 if (price_imp->file_format() == GncImpFileFormat::CSV)
1789 auto separators = price_imp->separators();
1790 auto escape = price_imp->enable_escape();
1791 const auto stock_sep_chars = std::string (
" \t,:;-");
1793 for (
int i = 0; i < SEP_NUM_OF_TYPES; i++)
1795 g_signal_handlers_block_by_func (sep_button[i], (gpointer) csv_price_imp_preview_sep_button_cb,
this);
1796 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(sep_button[i]),
1797 separators.find (stock_sep_chars[i]) != std::string::npos);
1798 g_signal_handlers_unblock_by_func (sep_button[i], (gpointer) csv_price_imp_preview_sep_button_cb,
this);
1803 auto pos = separators.find_first_of (stock_sep_chars);
1804 while (!separators.empty() && pos != std::string::npos)
1806 separators.erase(pos);
1807 pos = separators.find_first_of (stock_sep_chars);
1809 g_signal_handlers_block_by_func (escape_cbutton, (gpointer) csv_price_imp_preview_sep_button_cb,
this);
1810 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(escape_cbutton),
1812 g_signal_handlers_unblock_by_func (escape_cbutton, (gpointer) csv_price_imp_preview_sep_button_cb,
this);
1814 g_signal_handlers_block_by_func (custom_cbutton, (gpointer) csv_price_imp_preview_sep_button_cb,
this);
1815 g_signal_handlers_block_by_func (custom_entry, (gpointer) csv_price_imp_preview_sep_button_cb,
this);
1817 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(custom_cbutton),
1818 !separators.empty());
1819 gtk_entry_set_text (GTK_ENTRY(custom_entry), separators.c_str());
1821 g_signal_handlers_unblock_by_func (custom_cbutton, (gpointer) csv_price_imp_preview_sep_button_cb,
this);
1822 g_signal_handlers_unblock_by_func (custom_entry, (gpointer) csv_price_imp_preview_sep_button_cb,
this);
1825 price_imp->tokenize (
false);
1827 catch (std::range_error& err)
1829 PERR (
"CSV Tokenization Failed: %s", err.what ());
1833 g_idle_add ((GSourceFunc)csv_imp_preview_queue_rebuild_table,
this);
1838void CsvImpPriceAssist::preview_validate_settings ()
1841 auto error_msg = price_imp->verify();
1842 gtk_assistant_set_page_complete (csv_imp_asst, preview_page, error_msg.empty());
1843 gtk_label_set_markup(GTK_LABEL(instructions_label), error_msg.c_str());
1844 gtk_widget_set_visible (GTK_WIDGET(instructions_image), !error_msg.empty());
1852CsvImpPriceAssist::assist_file_page_prepare ()
1855 gtk_assistant_set_page_complete (csv_imp_asst, file_page,
false);
1856 gtk_assistant_set_page_complete (csv_imp_asst, preview_page,
false);
1859 if (!m_final_file_name.empty())
1860 gtk_file_chooser_set_filename (GTK_FILE_CHOOSER(file_chooser),
1861 m_final_file_name.c_str());
1864 auto starting_dir = gnc_get_default_directory (GNC_PREFS_GROUP);
1867 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(file_chooser), starting_dir);
1868 g_free (starting_dir);
1874CsvImpPriceAssist::assist_preview_page_prepare ()
1876 auto go_back =
false;
1879 if (m_final_file_name != m_fc_file_name)
1886 price_imp->file_format (GncImpFileFormat::CSV);
1887 price_imp->load_file (m_fc_file_name);
1888 price_imp->tokenize (
true);
1891 preview_populate_settings_combo();
1892 gtk_combo_box_set_active (settings_combo, 0);
1895 price_imp->over_write (
false);
1898 gtk_assistant_set_page_complete (csv_imp_asst, preview_page,
false);
1900 catch (std::ifstream::failure& e)
1903 gnc_error_dialog (GTK_WINDOW(csv_imp_asst),
"%s", e.what());
1906 catch (std::range_error &e)
1909 gnc_error_dialog (GTK_WINDOW(csv_imp_asst),
"%s",
_(e.what()));
1916 gtk_assistant_previous_page (csv_imp_asst);
1919 m_final_file_name = m_fc_file_name;
1923 g_idle_add ((GSourceFunc)csv_imp_preview_queue_rebuild_table,
this);
1928CsvImpPriceAssist::assist_confirm_page_prepare ()
1934CsvImpPriceAssist::assist_summary_page_prepare ()
1936 auto text = std::string(
"<span size=\"medium\"><b>");
1938 auto added_str = g_strdup_printf (ngettext (
"%d added price",
1940 price_imp->m_prices_added),
1941 price_imp->m_prices_added);
1943 auto dupl_str = g_strdup_printf (ngettext (
"%d duplicate price",
1944 "%d duplicate prices",
1945 price_imp->m_prices_duplicated),
1946 price_imp->m_prices_duplicated);
1948 auto repl_str = g_strdup_printf (ngettext (
"%d replaced price",
1949 "%d replaced prices",
1950 price_imp->m_prices_replaced),
1951 price_imp->m_prices_replaced);
1952 auto msg = g_strdup_printf (
1953 _(
"The prices were imported from file '%s'.\n\n"
1958 m_final_file_name.c_str(), added_str, dupl_str,repl_str);
1960 text +=
"</b></span>";
1966 gtk_label_set_markup (GTK_LABEL(summary_label), text.c_str());
1970CsvImpPriceAssist::assist_prepare_cb (GtkWidget *page)
1972 if (page == file_page)
1973 assist_file_page_prepare ();
1974 else if (page == preview_page)
1975 assist_preview_page_prepare ();
1976 else if (page == confirm_page)
1977 assist_confirm_page_prepare ();
1978 else if (page == summary_page)
1979 assist_summary_page_prepare ();
1983CsvImpPriceAssist::assist_finish ()
1989 price_imp->create_prices ();
1990 gnc_gui_refresh_all ();
1992 catch (
const std::invalid_argument& err)
1997 gnc_error_dialog (GTK_WINDOW(csv_imp_asst),
1998 _(
"An unexpected error has occurred while creating prices. Please report this as a bug.\n\n"
1999 "Error message:\n%s"), err.what());
2000 gtk_assistant_set_current_page (csv_imp_asst, 2);
2005CsvImpPriceAssist::assist_compmgr_close ()
2007 gnc_save_window_size (GNC_PREFS_GROUP, GTK_WINDOW(csv_imp_asst));
2011csv_price_imp_close_handler (gpointer user_data)
2014 gnc_unregister_gui_component_by_data (ASSISTANT_CSV_IMPORT_PRICE_CM_CLASS, info);
2015 info->assist_compmgr_close();
2030 gnc_register_gui_component (ASSISTANT_CSV_IMPORT_PRICE_CM_CLASS,
2031 nullptr, csv_price_imp_close_handler,
void gnc_file_csv_price_import(void)
The gnc_file_csv_price_import() will let the user import the commodity prices from a file.
void preview_update_separators(GtkWidget *widget)
Event handler for separator changes.
void preview_update_encoding(const char *encoding)
Event handler for a new encoding.
void preview_update_fw_columns(GtkTreeView *treeview, GdkEventButton *event)
Event handler for clicking on column headers.
void preview_update_col_type(GtkComboBox *cbox)
Event handler for the user selecting a new column type.
void preview_update_file_format()
Event handler for clicking one of the format type radio buttons.
The actual PriceImport class It's intended to use in the following sequence of actions:
const preset_vec_price & get_import_presets_price(void)
Creates a vector of CsvPriceImpSettings which combines.
bool preset_is_reserved_name(const std::string &name)
Check whether name can be used as a preset name.
Class to import prices from CSV or fixed width files.
Functions to load, save and get gui state.
Class to convert a csv file into vector of string vectors.
Class convert a file with fixed with delimited contents into vector of string vectors.
utility functions for the GnuCash UI
Utility functions for convert uri in separate components and back.
const char * gnc_commodity_get_fullname(const gnc_commodity *cm)
Retrieve the full name for the specified commodity.
const char * gnc_commodity_get_printname(const gnc_commodity *cm)
Retrieve the 'print' name for the specified commodity.
GList * gnc_commodity_table_get_namespaces(const gnc_commodity_table *table)
Return a list of all namespaces in the commodity table.
CommodityList * gnc_commodity_table_get_commodities(const gnc_commodity_table *table, const char *name_space)
Return a list of all commodities in the commodity table that are in the given namespace.
GtkWindow * gnc_ui_get_main_window(GtkWidget *widget)
Get a pointer to the final GncMainWindow widget is rooted in.
#define PINFO(format, args...)
Print an informational note.
#define DEBUG(format, args...)
Print a debugging message.
#define PERR(format, args...)
Log a serious error.
#define PWARN(format, args...)
Log a warning.
gchar * gnc_uri_get_path(const gchar *uri)
Extracts the path part from a uri.
void remove(void)
Remove the preset from the state file.