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" 70 static 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 GtkWidget *fw_instructions_hbox;
171 GtkCheckButton *custom_cbutton;
172 GtkEntry *custom_entry;
173 GtkComboBoxText *date_format_combo;
174 GtkComboBoxText *currency_format_combo;
175 GtkTreeView *treeview;
176 GtkLabel *instructions_label;
177 GtkImage *instructions_image;
178 bool encoding_selected_called;
180 int fixed_context_col;
181 int fixed_context_offset;
184 GtkWidget *confirm_page;
186 GtkWidget *summary_page;
187 GtkWidget *summary_label;
189 std::unique_ptr<GncPriceImport> price_imp;
199 void csv_price_imp_assist_prepare_cb (GtkAssistant *assistant, GtkWidget *page,
CsvImpPriceAssist* info);
200 void csv_price_imp_assist_close_cb (GtkAssistant *gtkassistant,
CsvImpPriceAssist* info);
201 void csv_price_imp_assist_finish_cb (GtkAssistant *gtkassistant,
CsvImpPriceAssist* info);
202 void csv_price_imp_file_activated_changed_cb (GtkFileChooser *chooser,
CsvImpPriceAssist *info);
203 void csv_price_imp_file_selection_changed_cb (GtkFileChooser *chooser,
CsvImpPriceAssist *info);
204 void csv_price_imp_preview_del_settings_cb (GtkWidget *button,
CsvImpPriceAssist *info);
205 void csv_price_imp_preview_save_settings_cb (GtkWidget *button,
CsvImpPriceAssist *info);
206 void csv_price_imp_preview_settings_sel_changed_cb (GtkComboBox *combo,
CsvImpPriceAssist *info);
207 void csv_price_imp_preview_settings_text_inserted_cb (GtkEditable *entry, gchar *new_text,
209 void csv_price_imp_preview_settings_text_changed_cb (GtkEntry *entry,
CsvImpPriceAssist *info);
210 void csv_price_imp_preview_srow_cb (GtkSpinButton *spin,
CsvImpPriceAssist *info);
211 void csv_price_imp_preview_erow_cb (GtkSpinButton *spin,
CsvImpPriceAssist *info);
212 void csv_price_imp_preview_skiprows_cb (GtkToggleButton *checkbox,
CsvImpPriceAssist *info);
213 void csv_price_imp_preview_skiperrors_cb (GtkToggleButton *checkbox,
CsvImpPriceAssist *info);
214 void csv_price_imp_preview_overwrite_cb (GtkToggleButton *checkbox,
CsvImpPriceAssist *info);
215 void csv_price_imp_preview_sep_button_cb (GtkWidget* widget,
CsvImpPriceAssist* info);
216 void csv_price_imp_preview_sep_fixed_sel_cb (GtkToggleButton* csv_button,
CsvImpPriceAssist* info);
217 void csv_price_imp_preview_acct_sel_cb (GtkWidget* widget,
CsvImpPriceAssist* info);
218 void csv_price_imp_preview_enc_sel_cb (GOCharmapSel* selector,
const char* encoding,
223 csv_price_imp_assist_prepare_cb (GtkAssistant *assistant, GtkWidget *page,
226 info->assist_prepare_cb(page);
232 gnc_close_gui_component_by_data (ASSISTANT_CSV_IMPORT_PRICE_CM_CLASS, info);
236 csv_price_imp_assist_finish_cb (GtkAssistant *assistant,
CsvImpPriceAssist* info)
238 info->assist_finish ();
241 void csv_price_imp_file_activated_changed_cb (GtkFileChooser *chooser,
CsvImpPriceAssist *info)
243 info->file_activated_cb();
246 void csv_price_imp_file_selection_changed_cb (GtkFileChooser *chooser,
CsvImpPriceAssist *info)
248 info->file_selection_changed_cb();
251 void csv_price_imp_preview_del_settings_cb (GtkWidget *button,
CsvImpPriceAssist *info)
253 info->preview_settings_delete();
256 void csv_price_imp_preview_save_settings_cb (GtkWidget *button,
CsvImpPriceAssist *info)
258 info->preview_settings_save();
261 void csv_price_imp_preview_settings_sel_changed_cb (GtkComboBox *combo,
CsvImpPriceAssist *info)
263 info->preview_settings_load();
267 csv_price_imp_preview_settings_text_inserted_cb (GtkEditable *entry, gchar *new_text,
274 auto base_txt = std::string (new_text);
275 auto mod_txt = base_txt;
276 std::replace (mod_txt.begin(), mod_txt.end(),
'[',
'(');
277 std::replace (mod_txt.begin(), mod_txt.end(),
']',
')');
278 if (base_txt == mod_txt)
280 g_signal_handlers_block_by_func (entry, (gpointer) csv_price_imp_preview_settings_text_inserted_cb, info);
281 gtk_editable_insert_text (entry, mod_txt.c_str(), mod_txt.size() , position);
282 g_signal_handlers_unblock_by_func (entry, (gpointer) csv_price_imp_preview_settings_text_inserted_cb, info);
284 g_signal_stop_emission_by_name (entry,
"insert_text");
288 csv_price_imp_preview_settings_text_changed_cb (GtkEntry *entry,
CsvImpPriceAssist *info)
290 info->preview_settings_name(entry);
293 void csv_price_imp_preview_srow_cb (GtkSpinButton *spin,
CsvImpPriceAssist *info)
295 info->preview_update_skipped_rows();
298 void csv_price_imp_preview_erow_cb (GtkSpinButton *spin,
CsvImpPriceAssist *info)
300 info->preview_update_skipped_rows();
303 void csv_price_imp_preview_skiprows_cb (GtkToggleButton *checkbox,
CsvImpPriceAssist *info)
305 info->preview_update_skipped_rows();
308 void csv_price_imp_preview_skiperrors_cb (GtkToggleButton *checkbox,
CsvImpPriceAssist *info)
310 info->preview_update_skipped_rows();
313 void csv_price_imp_preview_overwrite_cb (GtkToggleButton *checkbox,
CsvImpPriceAssist *info)
315 info->preview_over_write (gtk_toggle_button_get_active (checkbox));
318 void csv_price_imp_preview_sep_button_cb (GtkWidget* widget,
CsvImpPriceAssist* info)
320 info->preview_update_separators(widget);
323 void csv_price_imp_preview_sep_fixed_sel_cb (GtkToggleButton* csv_button,
CsvImpPriceAssist* info)
325 info->preview_update_file_format();
328 void csv_price_imp_preview_enc_sel_cb (GOCharmapSel* selector,
const char* encoding,
331 info->preview_update_encoding(encoding);
334 static void csv_price_imp_preview_date_fmt_sel_cb (GtkComboBox* format_selector,
CsvImpPriceAssist* info)
336 info->preview_update_date_format();
339 static void csv_price_imp_preview_currency_fmt_sel_cb (GtkComboBox* format_selector,
CsvImpPriceAssist* info)
341 info->preview_update_currency_format();
344 enum GncCommColumn {DISPLAYED_COMM, SORT_COMM, COMM_PTR, SEP};
346 static void csv_price_imp_preview_currency_sel_cb (GtkComboBox* currency_selector,
CsvImpPriceAssist* info)
348 info->preview_update_currency();
351 static gboolean separator_row_func (GtkTreeModel *smodel, GtkTreeIter *siter, gpointer data)
357 store = gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT(smodel));
359 gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT(smodel),
362 gtk_tree_model_get (GTK_TREE_MODEL(store), &iter, SEP, &sep_row, -1);
367 static void csv_price_imp_preview_commodity_sel_cb (GtkComboBox* commodity_selector,
CsvImpPriceAssist* info)
369 info->preview_update_commodity();
372 static void csv_price_imp_preview_col_type_changed_cb (GtkComboBox* cbox,
CsvImpPriceAssist* info)
374 info->preview_update_col_type (cbox);
378 csv_price_imp_preview_treeview_clicked_cb (GtkTreeView* treeview, GdkEventButton* event,
381 info->preview_update_fw_columns(treeview, event);
386 gnc_commodity *get_commodity_from_combo (GtkComboBox *combo)
388 GtkTreeModel *model, *sort_model;
389 GtkTreeIter iter, siter;
393 if (!gtk_combo_box_get_active_iter (combo, &siter))
396 sort_model = gtk_combo_box_get_model (combo);
397 model = gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT(sort_model));
399 gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT(sort_model),
402 gtk_tree_model_get (GTK_TREE_MODEL(model), &iter,
403 DISPLAYED_COMM, &
string, COMM_PTR, &comm, -1);
405 PINFO(
"Commodity string is %s",
string);
412 set_commodity_for_combo (GtkComboBox *combo, gnc_commodity *comm)
414 GtkTreeModel *model, *sort_model;
415 GtkTreeIter iter, siter;
416 gnc_commodity *model_comm;
419 sort_model = gtk_combo_box_get_model (combo);
420 model = gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT(sort_model));
421 valid = gtk_tree_model_get_iter_first (model, &iter);
425 gtk_tree_model_get (model, &iter, COMM_PTR, &model_comm, -1);
426 if (model_comm == comm)
428 if (gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT(sort_model), &siter, &iter))
430 gtk_combo_box_set_active_iter (combo, &siter);
435 valid = gtk_tree_model_iter_next (model, &iter);
438 gtk_tree_model_get_iter_first (model, &iter);
439 if (gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT(sort_model), &siter, &iter))
440 gtk_combo_box_set_active_iter (combo, &siter);
444 GtkTreeModel *get_model (
bool all_commodity)
446 GtkTreeModel *store, *model;
447 const gnc_commodity_table *commodity_table = gnc_get_current_commodities ();
448 gnc_commodity *tmp_commodity =
nullptr;
449 char *tmp_namespace =
nullptr;
453 store = GTK_TREE_MODEL(gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_STRING,
454 G_TYPE_POINTER, G_TYPE_BOOLEAN));
455 model = gtk_tree_model_sort_new_with_model (store);
457 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE(model), SORT_COMM, GTK_SORT_ASCENDING);
459 gtk_list_store_append (GTK_LIST_STORE(store), &iter);
460 gtk_list_store_set (GTK_LIST_STORE(store), &iter,
461 DISPLAYED_COMM,
" ", SORT_COMM,
" ", COMM_PTR,
nullptr, SEP,
false, -1);
463 for (
auto node = namespace_list; node; node = g_list_next (node))
465 tmp_namespace = (
char*)node->data;
466 DEBUG(
"Looking at namespace %s", tmp_namespace);
469 if (g_utf8_collate (tmp_namespace,
"template" ) != 0)
471 if ((g_utf8_collate (tmp_namespace, GNC_COMMODITY_NS_CURRENCY ) == 0) || (all_commodity ==
true))
476 if ((g_utf8_collate (tmp_namespace, GNC_COMMODITY_NS_CURRENCY) == 0) && (all_commodity ==
true))
478 gtk_list_store_append (GTK_LIST_STORE(store), &iter);
479 gtk_list_store_set (GTK_LIST_STORE(store), &iter, DISPLAYED_COMM,
" ",
480 SORT_COMM,
"CURRENCY-", COMM_PTR,
nullptr, SEP,
true, -1);
483 for (
auto node = comm_list; node; node = g_list_next (node))
485 const gchar *name_str;
487 tmp_commodity = (gnc_commodity*)node->data;
492 if (g_utf8_collate (tmp_namespace, GNC_COMMODITY_NS_CURRENCY) == 0)
493 sort_str = g_strconcat (
"CURRENCY-", name_str,
nullptr);
495 sort_str = g_strconcat (
"ALL-OTHER-", name_str,
nullptr);
497 DEBUG(
"Name string is '%s', Sort string is '%s'", name_str, sort_str);
499 gtk_list_store_append (GTK_LIST_STORE(store), &iter);
500 gtk_list_store_set (GTK_LIST_STORE(store), &iter, DISPLAYED_COMM, name_str,
501 SORT_COMM, sort_str, COMM_PTR, tmp_commodity, SEP,
false, -1);
505 g_list_free (comm_list);
509 g_list_free (namespace_list);
510 g_object_unref (store);
519 CsvImpPriceAssist::CsvImpPriceAssist ()
521 auto builder = gtk_builder_new();
522 gnc_builder_add_from_file (builder ,
"assistant-csv-price-import.glade",
"start_row_adj");
523 gnc_builder_add_from_file (builder ,
"assistant-csv-price-import.glade",
"end_row_adj");
524 gnc_builder_add_from_file (builder ,
"assistant-csv-price-import.glade",
"liststore1");
525 gnc_builder_add_from_file (builder ,
"assistant-csv-price-import.glade",
"liststore2");
526 gnc_builder_add_from_file (builder ,
"assistant-csv-price-import.glade",
"CSV Price Assistant");
527 csv_imp_asst = GTK_ASSISTANT(gtk_builder_get_object (builder,
"CSV Price Assistant"));
530 gtk_widget_set_name (GTK_WIDGET(csv_imp_asst),
"gnc-id-assistant-csv-price-import");
531 gnc_widget_style_context_add_class (GTK_WIDGET(csv_imp_asst),
"gnc-class-imports");
534 gtk_assistant_set_page_complete (csv_imp_asst,
535 GTK_WIDGET(gtk_builder_get_object (builder,
"start_page")),
537 gtk_assistant_set_page_complete (csv_imp_asst,
538 GTK_WIDGET(gtk_builder_get_object (builder,
"file_page")),
540 gtk_assistant_set_page_complete (csv_imp_asst,
541 GTK_WIDGET(gtk_builder_get_object (builder,
"preview_page")),
543 gtk_assistant_set_page_complete (csv_imp_asst,
544 GTK_WIDGET(gtk_builder_get_object (builder,
"confirm_page")),
546 gtk_assistant_set_page_complete (csv_imp_asst,
547 GTK_WIDGET(gtk_builder_get_object (builder,
"summary_page")),
551 file_page = GTK_WIDGET(gtk_builder_get_object (builder,
"file_page"));
552 file_chooser = gtk_file_chooser_widget_new (GTK_FILE_CHOOSER_ACTION_OPEN);
554 g_signal_connect (G_OBJECT(file_chooser),
"selection-changed",
555 G_CALLBACK(csv_price_imp_file_selection_changed_cb),
this);
556 g_signal_connect (G_OBJECT(file_chooser),
"file-activated",
557 G_CALLBACK(csv_price_imp_file_activated_changed_cb),
this);
559 auto box = GTK_WIDGET(gtk_builder_get_object (builder,
"file_page"));
560 gtk_box_pack_start (GTK_BOX(box), file_chooser, TRUE, TRUE, 6);
561 gtk_widget_show (file_chooser);
565 preview_page = GTK_WIDGET(gtk_builder_get_object (builder,
"preview_page"));
568 auto settings_store = gtk_list_store_new (2, G_TYPE_POINTER, G_TYPE_STRING);
569 settings_combo = GTK_COMBO_BOX(gtk_combo_box_new_with_model_and_entry (GTK_TREE_MODEL(settings_store)));
570 g_object_unref (settings_store);
572 gtk_combo_box_set_entry_text_column (GTK_COMBO_BOX(settings_combo), SET_NAME);
573 gtk_combo_box_set_active (GTK_COMBO_BOX(settings_combo), 0);
575 combo_hbox = GTK_WIDGET(gtk_builder_get_object (builder,
"combo_hbox"));
576 gtk_box_pack_start (GTK_BOX(combo_hbox), GTK_WIDGET(settings_combo),
true,
true, 6);
577 gtk_widget_show (GTK_WIDGET(settings_combo));
579 g_signal_connect (G_OBJECT(settings_combo),
"changed",
580 G_CALLBACK(csv_price_imp_preview_settings_sel_changed_cb),
this);
583 auto emb_entry = gtk_bin_get_child (GTK_BIN (settings_combo));
584 g_signal_connect (G_OBJECT(emb_entry),
"changed",
585 G_CALLBACK(csv_price_imp_preview_settings_text_changed_cb),
this);
586 g_signal_connect (G_OBJECT(emb_entry),
"insert-text",
587 G_CALLBACK(csv_price_imp_preview_settings_text_inserted_cb),
this);
590 save_button = GTK_WIDGET(gtk_builder_get_object (builder,
"save_settings"));
593 del_button = GTK_WIDGET(gtk_builder_get_object (builder,
"delete_settings"));
596 start_row_spin = GTK_SPIN_BUTTON(gtk_builder_get_object (builder,
"start_row"));
597 end_row_spin = GTK_SPIN_BUTTON(gtk_builder_get_object (builder,
"end_row"));
598 skip_alt_rows_button = GTK_WIDGET(gtk_builder_get_object (builder,
"skip_rows"));
599 skip_errors_button = GTK_WIDGET(gtk_builder_get_object (builder,
"skip_errors_button"));
600 over_write_cbutton = GTK_WIDGET(gtk_builder_get_object (builder,
"over_write_button"));
601 separator_table = GTK_WIDGET(gtk_builder_get_object (builder,
"separator_table"));
602 fw_instructions_hbox = GTK_WIDGET(gtk_builder_get_object (builder,
"fw_instructions_hbox"));
606 const char* sep_button_names[] = {
614 for (
int i = 0; i < SEP_NUM_OF_TYPES; i++)
616 = (GtkCheckButton*)GTK_WIDGET(gtk_builder_get_object (builder, sep_button_names[i]));
621 = (GtkCheckButton*)GTK_WIDGET(gtk_builder_get_object (builder,
"custom_cbutton"));
625 custom_entry = (GtkEntry*)GTK_WIDGET(gtk_builder_get_object (builder,
"custom_entry"));
628 encselector = GO_CHARMAP_SEL(go_charmap_sel_new(GO_CHARMAP_SEL_TO_UTF8));
630 g_signal_connect (G_OBJECT(encselector),
"charmap_changed",
631 G_CALLBACK(csv_price_imp_preview_enc_sel_cb),
this);
633 auto encoding_container = GTK_CONTAINER(gtk_builder_get_object (builder,
"encoding_container"));
634 gtk_container_add (encoding_container, GTK_WIDGET(encselector));
635 gtk_widget_set_hexpand (GTK_WIDGET(encselector),
true);
636 gtk_widget_show_all (GTK_WIDGET(encoding_container));
639 commodity_selector = GTK_WIDGET(gtk_builder_get_object (builder,
"commodity_cbox"));
640 gtk_combo_box_set_model (GTK_COMBO_BOX(commodity_selector), get_model (
true));
641 gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX(commodity_selector),
642 separator_row_func,
nullptr,
nullptr);
643 g_signal_connect (G_OBJECT(commodity_selector),
"changed",
644 G_CALLBACK(csv_price_imp_preview_commodity_sel_cb),
this);
647 currency_selector = GTK_WIDGET(gtk_builder_get_object (builder,
"currency_cbox"));
648 gtk_combo_box_set_model (GTK_COMBO_BOX(currency_selector), get_model (
false));
649 g_signal_connect(G_OBJECT(currency_selector),
"changed",
650 G_CALLBACK(csv_price_imp_preview_currency_sel_cb),
this);
653 instructions_label = GTK_LABEL(gtk_builder_get_object (builder,
"instructions_label"));
654 instructions_image = GTK_IMAGE(gtk_builder_get_object (builder,
"instructions_image"));
657 date_format_combo = GTK_COMBO_BOX_TEXT(gtk_combo_box_text_new());
659 gtk_combo_box_text_append_text (date_format_combo, _(date_fmt.m_fmt.c_str()));
660 gtk_combo_box_set_active (GTK_COMBO_BOX(date_format_combo), 0);
661 g_signal_connect (G_OBJECT(date_format_combo),
"changed",
662 G_CALLBACK(csv_price_imp_preview_date_fmt_sel_cb),
this);
665 auto date_format_container = GTK_CONTAINER(gtk_builder_get_object (builder,
"date_format_container"));
666 gtk_container_add (date_format_container, GTK_WIDGET(date_format_combo));
667 gtk_widget_set_hexpand (GTK_WIDGET(date_format_combo),
true);
668 gtk_widget_show_all (GTK_WIDGET(date_format_container));
671 currency_format_combo = GTK_COMBO_BOX_TEXT(gtk_combo_box_text_new());
672 for (
int i = 0; i < num_currency_formats_price; i++)
674 gtk_combo_box_text_append_text (currency_format_combo, _(currency_format_user_price[i]));
677 gtk_combo_box_set_active (GTK_COMBO_BOX(currency_format_combo), 0);
678 g_signal_connect (G_OBJECT(currency_format_combo),
"changed",
679 G_CALLBACK(csv_price_imp_preview_currency_fmt_sel_cb),
this);
682 auto currency_format_container = GTK_CONTAINER(gtk_builder_get_object (builder,
"currency_format_container"));
683 gtk_container_add (currency_format_container, GTK_WIDGET(currency_format_combo));
684 gtk_widget_set_hexpand (GTK_WIDGET(currency_format_combo),
true);
685 gtk_widget_show_all (GTK_WIDGET(currency_format_container));
688 csv_button = GTK_WIDGET(gtk_builder_get_object (builder,
"csv_button"));
689 fixed_button = GTK_WIDGET(gtk_builder_get_object (builder,
"fixed_button"));
692 treeview = (GtkTreeView*)GTK_WIDGET(gtk_builder_get_object (builder,
"treeview"));
693 gtk_tree_view_set_headers_clickable (treeview,
true);
697 encoding_selected_called =
false;
701 confirm_page = GTK_WIDGET(gtk_builder_get_object (builder,
"confirm_page"));
704 summary_page = GTK_WIDGET(gtk_builder_get_object (builder,
"summary_page"));
705 summary_label = GTK_WIDGET(gtk_builder_get_object (builder,
"summary_label"));
707 gnc_restore_window_size (GNC_PREFS_GROUP,
710 gtk_builder_connect_signals (builder,
this);
711 g_object_unref (G_OBJECT(builder));
713 gtk_widget_show_all (GTK_WIDGET(csv_imp_asst));
714 gnc_window_adjust_for_screen (GTK_WINDOW(csv_imp_asst));
720 CsvImpPriceAssist::~CsvImpPriceAssist ()
722 gtk_widget_destroy (GTK_WIDGET(csv_imp_asst));
732 CsvImpPriceAssist::check_for_valid_filename ()
734 auto file_name = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(file_chooser));
735 if (!file_name || g_file_test (file_name, G_FILE_TEST_IS_DIR))
742 auto starting_dir = g_path_get_dirname (filepath);
744 m_fc_file_name = file_name;
745 gnc_set_default_directory (GNC_PREFS_GROUP, starting_dir);
747 DEBUG(
"file_name selected is %s", m_fc_file_name.c_str());
748 DEBUG(
"starting directory is %s", starting_dir);
752 g_free (starting_dir);
762 CsvImpPriceAssist::file_activated_cb ()
764 gtk_assistant_set_page_complete (csv_imp_asst, file_page,
false);
767 if (check_for_valid_filename ())
769 gtk_assistant_set_page_complete (csv_imp_asst, file_page,
true);
770 gtk_assistant_next_page (csv_imp_asst);
779 CsvImpPriceAssist::file_selection_changed_cb ()
782 gtk_assistant_set_page_complete (csv_imp_asst, file_page,
783 check_for_valid_filename ());
793 void CsvImpPriceAssist::preview_populate_settings_combo()
796 auto model = gtk_combo_box_get_model (settings_combo);
797 gtk_list_store_clear (GTK_LIST_STORE(model));
801 for (
const auto& preset : presets)
804 gtk_list_store_append (GTK_LIST_STORE(model), &iter);
811 gtk_list_store_set (GTK_LIST_STORE(model), &iter, SET_GROUP, preset.get(), SET_NAME, _(preset->m_name.c_str()), -1);
818 void CsvImpPriceAssist::preview_handle_save_del_sensitivity (GtkComboBox* combo)
821 auto can_delete =
false;
822 auto can_save =
false;
823 auto entry = gtk_bin_get_child (GTK_BIN(combo));
824 auto entry_text = gtk_entry_get_text (GTK_ENTRY(entry));
826 if (gtk_combo_box_get_active_iter (combo, &iter))
829 GtkTreeModel *model = gtk_combo_box_get_model (combo);
830 gtk_tree_model_get (model, &iter, SET_GROUP, &preset, -1);
839 else if (entry_text && (strlen (entry_text) > 0) &&
843 gtk_widget_set_sensitive (save_button, can_save);
844 gtk_widget_set_sensitive (del_button, can_delete);
848 CsvImpPriceAssist::preview_settings_name (GtkEntry* entry)
850 auto text = gtk_entry_get_text (entry);
852 price_imp->settings_name(text);
854 auto box = gtk_widget_get_parent (GTK_WIDGET(entry));
855 auto combo = gtk_widget_get_parent (GTK_WIDGET(box));
857 preview_handle_save_del_sensitivity (GTK_COMBO_BOX(combo));
864 CsvImpPriceAssist::preview_settings_load ()
868 if (!gtk_combo_box_get_active_iter (settings_combo, &iter))
872 auto model = gtk_combo_box_get_model (settings_combo);
873 gtk_tree_model_get (model, &iter, SET_GROUP, &preset, -1);
878 price_imp->settings (*preset);
879 if (preset->m_load_error)
880 gnc_error_dialog (GTK_WINDOW(csv_imp_asst),
881 "%s", _(
"There were problems reading some saved settings, continuing to load.\n" 882 "Please review and save again."));
885 preview_handle_save_del_sensitivity (settings_combo);
891 CsvImpPriceAssist::preview_settings_delete ()
895 if (!gtk_combo_box_get_active_iter (settings_combo, &iter))
899 auto model = gtk_combo_box_get_model (settings_combo);
900 gtk_tree_model_get (model, &iter, SET_GROUP, &preset, -1);
902 auto response = gnc_ok_cancel_dialog (GTK_WINDOW(csv_imp_asst),
904 "%s", _(
"Delete the Import Settings."));
905 if (response == GTK_RESPONSE_OK)
908 preview_populate_settings_combo();
909 gtk_combo_box_set_active (settings_combo, 0);
917 CsvImpPriceAssist::preview_settings_save ()
919 auto new_name = price_imp->settings_name();
923 if (!gtk_combo_box_get_active_iter (settings_combo, &iter))
926 auto model = gtk_combo_box_get_model (settings_combo);
927 bool valid = gtk_tree_model_get_iter_first (model, &iter);
932 gtk_tree_model_get (model, &iter, SET_GROUP, &preset, -1);
934 if (preset && (preset->m_name == std::string(new_name)))
936 auto response = gnc_ok_cancel_dialog (GTK_WINDOW(csv_imp_asst),
938 "%s", _(
"Setting name already exists, overwrite?"));
939 if (response != GTK_RESPONSE_OK)
944 valid = gtk_tree_model_iter_next (model, &iter);
949 if (!price_imp->save_settings())
951 gnc_info_dialog (GTK_WINDOW(csv_imp_asst),
952 "%s", _(
"The settings have been saved."));
955 preview_populate_settings_combo();
956 auto model = gtk_combo_box_get_model (settings_combo);
960 bool valid = gtk_tree_model_get_iter_first (model, &iter);
964 gchar *name =
nullptr;
965 gtk_tree_model_get (model, &iter, SET_NAME, &name, -1);
967 if (g_strcmp0 (name, new_name.c_str()) == 0)
968 gtk_combo_box_set_active_iter (settings_combo, &iter);
972 valid = gtk_tree_model_iter_next (model, &iter);
976 gnc_error_dialog (GTK_WINDOW(csv_imp_asst),
977 "%s", _(
"There was a problem saving the settings, please try again."));
982 void CsvImpPriceAssist::preview_update_skipped_rows ()
985 price_imp->update_skipped_lines (gtk_spin_button_get_value_as_int (start_row_spin),
986 gtk_spin_button_get_value_as_int (end_row_spin),
987 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(skip_alt_rows_button)),
988 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(skip_errors_button)));
991 auto adj = gtk_spin_button_get_adjustment (end_row_spin);
992 gtk_adjustment_set_upper (adj, price_imp->m_parsed_lines.size()
993 - price_imp->skip_start_lines() -1);
995 adj = gtk_spin_button_get_adjustment (start_row_spin);
996 gtk_adjustment_set_upper (adj, price_imp->m_parsed_lines.size()
997 - price_imp->skip_end_lines() - 1);
999 preview_refresh_table ();
1004 void CsvImpPriceAssist::preview_over_write (
bool over)
1006 price_imp->over_write (over);
1020 if (price_imp->file_format() != GncImpFileFormat::CSV)
1025 auto checked_separators = std::string();
1026 const auto stock_sep_chars = std::string (
" \t,:;-");
1027 for (
int i = 0; i < SEP_NUM_OF_TYPES; i++)
1029 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(sep_button[i])))
1030 checked_separators += stock_sep_chars[i];
1034 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(custom_cbutton)))
1036 auto custom_sep = gtk_entry_get_text (custom_entry);
1037 if (custom_sep[0] !=
'\0')
1038 checked_separators += custom_sep;
1042 price_imp->separators (checked_separators);
1046 if (checked_separators.empty())
1047 price_imp->set_column_type_price (0, GncPricePropType::NONE);
1054 price_imp->tokenize (
false);
1055 preview_refresh_table ();
1057 catch (std::range_error &e)
1062 gnc_error_dialog (GTK_WINDOW(csv_imp_asst),
"Error in parsing");
1068 if (widget == GTK_WIDGET(custom_entry))
1069 gtk_entry_set_text (GTK_ENTRY(widget),
"");
1072 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(widget),
1073 !gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(widget)));
1088 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(csv_button)))
1090 price_imp->file_format (GncImpFileFormat::CSV);
1091 g_signal_handlers_disconnect_by_func(G_OBJECT(treeview),
1092 (gpointer)csv_price_imp_preview_treeview_clicked_cb, (gpointer)
this);
1093 gtk_widget_set_visible (separator_table,
true);
1094 gtk_widget_set_visible (fw_instructions_hbox,
false);
1098 price_imp->file_format (GncImpFileFormat::FIXED_WIDTH);
1100 g_signal_connect (G_OBJECT(treeview),
"button-press-event",
1101 G_CALLBACK(csv_price_imp_preview_treeview_clicked_cb), (gpointer)
this);
1102 gtk_widget_set_visible (separator_table,
false);
1103 gtk_widget_set_visible (fw_instructions_hbox,
true);
1106 price_imp->tokenize (
false);
1107 preview_refresh_table ();
1109 catch (std::range_error &e)
1112 gnc_error_dialog (GTK_WINDOW (csv_imp_asst),
"%s", e.what());
1118 PWARN(
"Got an error during file loading");
1136 if (encoding_selected_called)
1138 std::string previous_encoding = price_imp->m_tokenizer->encoding();
1142 price_imp->encoding (encoding);
1143 preview_refresh_table ();
1148 gnc_error_dialog (GTK_WINDOW (csv_imp_asst),
"%s", _(
"Invalid encoding selected"));
1149 go_charmap_sel_set_encoding (encselector, previous_encoding.c_str());
1152 encoding_selected_called = !encoding_selected_called;
1156 CsvImpPriceAssist::preview_update_date_format ()
1158 price_imp->date_format (gtk_combo_box_get_active (GTK_COMBO_BOX(date_format_combo)));
1159 preview_refresh_table ();
1163 CsvImpPriceAssist::preview_update_currency_format ()
1165 price_imp->currency_format (gtk_combo_box_get_active (GTK_COMBO_BOX(currency_format_combo)));
1166 preview_refresh_table ();
1170 CsvImpPriceAssist::preview_update_currency ()
1172 gnc_commodity *comm = get_commodity_from_combo (GTK_COMBO_BOX(currency_selector));
1173 price_imp->to_currency (comm);
1174 preview_refresh_table ();
1178 CsvImpPriceAssist::preview_update_commodity ()
1180 gnc_commodity *comm = get_commodity_from_combo (GTK_COMBO_BOX(commodity_selector));
1181 price_imp->from_commodity (comm);
1182 preview_refresh_table ();
1188 assist->preview_refresh_table ();
1195 enum PreviewHeaderComboCols { COL_TYPE_NAME, COL_TYPE_ID };
1199 enum PreviewDataTableCols {
1205 PREV_N_FIXED_COLS };
1209 CsvImpPriceAssist::preview_reparse_col_type (GncPricePropType type)
1211 auto column_types = price_imp->column_types_price();
1214 auto col_type = std::find (column_types.begin(),
1215 column_types.end(), type);
1216 if (col_type != column_types.end())
1218 price_imp->set_column_type_price (col_type -column_types.begin(),
1236 auto model = gtk_combo_box_get_model (cbox);
1237 gtk_combo_box_get_active_iter (cbox, &iter);
1238 auto new_col_type = GncPricePropType::NONE;
1239 gtk_tree_model_get (model, &iter, COL_TYPE_ID, &new_col_type, -1);
1241 auto col_num = GPOINTER_TO_UINT (g_object_get_data (G_OBJECT(cbox),
"col-num"));
1243 auto column_types = price_imp->column_types_price();
1244 auto old_col_type = column_types.at(col_num);
1246 price_imp->set_column_type_price (col_num, new_col_type);
1249 if (old_col_type == GncPricePropType::TO_CURRENCY)
1252 preview_reparse_col_type (GncPricePropType::FROM_SYMBOL);
1253 preview_reparse_col_type (GncPricePropType::FROM_NAMESPACE);
1257 if ((old_col_type == GncPricePropType::FROM_SYMBOL) ||
1258 (old_col_type == GncPricePropType::FROM_NAMESPACE))
1261 preview_reparse_col_type (GncPricePropType::TO_CURRENCY);
1267 g_idle_add ((GSourceFunc)csv_imp_preview_queue_rebuild_table,
this);
1299 CONTEXT_STF_IMPORT_MERGE_LEFT = 1,
1300 CONTEXT_STF_IMPORT_MERGE_RIGHT = 2,
1301 CONTEXT_STF_IMPORT_SPLIT = 3,
1302 CONTEXT_STF_IMPORT_WIDEN = 4,
1303 CONTEXT_STF_IMPORT_NARROW = 5
1309 N_(
"Merge with column on _left"),
"list-remove",
1310 0, 1 << CONTEXT_STF_IMPORT_MERGE_LEFT, CONTEXT_STF_IMPORT_MERGE_LEFT
1313 N_(
"Merge with column on _right"),
"list-remove",
1314 0, 1 << CONTEXT_STF_IMPORT_MERGE_RIGHT, CONTEXT_STF_IMPORT_MERGE_RIGHT
1316 {
"",
nullptr, 0, 0, 0 },
1318 N_(
"_Split this column"),
nullptr,
1319 0, 1 << CONTEXT_STF_IMPORT_SPLIT, CONTEXT_STF_IMPORT_SPLIT
1321 {
"",
nullptr, 0, 0, 0 },
1323 N_(
"_Widen this column"),
"go-next",
1324 0, 1 << CONTEXT_STF_IMPORT_WIDEN, CONTEXT_STF_IMPORT_WIDEN
1327 N_(
"_Narrow this column"),
"go-previous",
1328 0, 1 << CONTEXT_STF_IMPORT_NARROW, CONTEXT_STF_IMPORT_NARROW
1330 {
nullptr,
nullptr, 0, 0, 0 },
1333 uint32_t CsvImpPriceAssist::get_new_col_rel_pos (GtkTreeViewColumn *tcol,
int dx)
1335 auto renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT(tcol));
1336 auto cell = GTK_CELL_RENDERER(renderers->data);
1337 g_list_free (renderers);
1338 PangoFontDescription *font_desc;
1339 g_object_get (G_OBJECT(cell),
"font_desc", &font_desc,
nullptr);
1341 PangoLayout *layout = gtk_widget_create_pango_layout (GTK_WIDGET(treeview),
"x");
1342 pango_layout_set_font_description (layout, font_desc);
1344 pango_layout_get_pixel_size (layout, &width,
nullptr);
1345 if (width < 1) width = 1;
1346 uint32_t charindex = (dx + width / 2) / width;
1347 g_object_unref (layout);
1348 pango_font_description_free (font_desc);
1358 auto fwtok =
dynamic_cast<GncFwTokenizer*
>(info->price_imp->m_tokenizer.get());
1360 switch (element->index)
1362 case CONTEXT_STF_IMPORT_MERGE_LEFT:
1363 fwtok->col_delete (info->fixed_context_col - 1);
1365 case CONTEXT_STF_IMPORT_MERGE_RIGHT:
1366 fwtok->col_delete (info->fixed_context_col);
1368 case CONTEXT_STF_IMPORT_SPLIT:
1369 fwtok->col_split (info->fixed_context_col, info->fixed_context_offset);
1371 case CONTEXT_STF_IMPORT_WIDEN:
1372 fwtok->col_widen (info->fixed_context_col);
1374 case CONTEXT_STF_IMPORT_NARROW:
1375 fwtok->col_narrow (info->fixed_context_col);
1383 info->price_imp->tokenize (
false);
1385 catch(std::range_error& e)
1387 gnc_error_dialog (GTK_WINDOW (info->csv_imp_asst),
"%s", e.what());
1390 info->preview_refresh_table ();
1395 CsvImpPriceAssist::fixed_context_menu (GdkEventButton *event,
1396 int col,
int offset)
1398 auto fwtok =
dynamic_cast<GncFwTokenizer*
>(price_imp->m_tokenizer.get());
1399 fixed_context_col = col;
1400 fixed_context_offset = offset;
1402 int sensitivity_filter = 0;
1403 if (!fwtok->col_can_delete (col - 1))
1404 sensitivity_filter |= (1 << CONTEXT_STF_IMPORT_MERGE_LEFT);
1405 if (!fwtok->col_can_delete (col))
1406 sensitivity_filter |= (1 << CONTEXT_STF_IMPORT_MERGE_RIGHT);
1407 if (!fwtok->col_can_split (col, offset))
1408 sensitivity_filter |= (1 << CONTEXT_STF_IMPORT_SPLIT);
1409 if (!fwtok->col_can_widen (col))
1410 sensitivity_filter |= (1 << CONTEXT_STF_IMPORT_WIDEN);
1411 if (!fwtok->col_can_narrow (col))
1412 sensitivity_filter |= (1 << CONTEXT_STF_IMPORT_NARROW);
1414 gnumeric_create_popup_menu (popup_elements, &fixed_context_menu_handler_price,
1416 sensitivity_filter, event);
1422 CsvImpPriceAssist::preview_split_column (
int col,
int offset)
1424 auto fwtok =
dynamic_cast<GncFwTokenizer*
>(price_imp->m_tokenizer.get());
1425 fwtok->col_split (col, offset);
1428 price_imp->tokenize (
false);
1430 catch (std::range_error& e)
1432 gnc_error_dialog (GTK_WINDOW (csv_imp_asst),
"%s", e.what());
1435 preview_refresh_table();
1451 if (event->window != gtk_tree_view_get_bin_window (treeview))
1455 GtkTreeViewColumn *tcol =
nullptr;
1457 auto success = gtk_tree_view_get_path_at_pos (treeview,
1458 (
int)event->x, (
int)event->y,
1459 nullptr, &tcol, &cell_x,
nullptr);
1465 auto tcol_list = gtk_tree_view_get_columns(treeview);
1466 auto tcol_num = g_list_index (tcol_list, tcol);
1467 g_list_free (tcol_list);
1474 auto dcol = tcol_num - 1;
1475 auto offset = get_new_col_rel_pos (tcol, cell_x);
1476 if (event->type == GDK_2BUTTON_PRESS && event->button == 1)
1478 preview_split_column (dcol, offset);
1479 else if (event->type == GDK_BUTTON_PRESS && event->button == 3)
1481 fixed_context_menu (event, dcol, offset);
1486 CsvImpPriceAssist::preview_row_fill_state_cells (GtkListStore *store, GtkTreeIter *iter,
1487 std::string& err_msg,
bool skip)
1490 const char *c_err_msg =
nullptr;
1491 const char *icon_name =
nullptr;
1492 const char *fcolor =
nullptr;
1493 const char *bcolor =
nullptr;
1494 if (!skip && !err_msg.empty())
1498 c_err_msg = err_msg.c_str();
1499 icon_name =
"dialog-error";
1501 gtk_list_store_set (store, iter,
1502 PREV_COL_FCOLOR, fcolor,
1503 PREV_COL_BCOLOR, bcolor,
1504 PREV_COL_STRIKE, skip,
1505 PREV_COL_ERROR, c_err_msg,
1506 PREV_COL_ERR_ICON, icon_name, -1);
1513 CsvImpPriceAssist::preview_cbox_factory (GtkTreeModel* model, uint32_t colnum)
1516 auto cbox = gtk_combo_box_new_with_model(model);
1519 auto renderer = gtk_cell_renderer_text_new();
1520 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT(cbox),
1522 gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT(cbox),
1523 renderer,
"text", COL_TYPE_NAME);
1525 auto valid = gtk_tree_model_get_iter_first (model, &iter);
1528 gint stored_col_type;
1529 gtk_tree_model_get (model, &iter,
1530 COL_TYPE_ID, &stored_col_type, -1);
1531 if (stored_col_type == static_cast<int>( price_imp->column_types_price()[colnum]))
1533 valid = gtk_tree_model_iter_next(model, &iter);
1536 gtk_combo_box_set_active_iter (GTK_COMBO_BOX(cbox), &iter);
1538 g_object_set_data (G_OBJECT(cbox),
"col-num", GUINT_TO_POINTER(colnum));
1539 g_signal_connect (G_OBJECT(cbox),
"changed",
1540 G_CALLBACK(csv_price_imp_preview_col_type_changed_cb), (gpointer)
this);
1542 gtk_widget_show (cbox);
1547 CsvImpPriceAssist::preview_style_column (uint32_t col_num, GtkTreeModel* model)
1549 auto col = gtk_tree_view_get_column (treeview, col_num);
1550 auto renderer =
static_cast<GtkCellRenderer*
>(gtk_cell_layout_get_cells(GTK_CELL_LAYOUT(col))->data);
1555 gtk_tree_view_column_set_attributes (col, renderer,
1556 "icon-name", PREV_COL_ERR_ICON,
1557 "cell-background", PREV_COL_BCOLOR,
nullptr);
1558 g_object_set (G_OBJECT(renderer),
"stock-size", GTK_ICON_SIZE_MENU,
nullptr);
1559 g_object_set (G_OBJECT(col),
"sizing", GTK_TREE_VIEW_COLUMN_FIXED,
1560 "fixed-width", 20,
nullptr);
1561 gtk_tree_view_column_set_resizable (col,
false);
1565 gtk_tree_view_column_set_attributes (col, renderer,
1566 "foreground", PREV_COL_FCOLOR,
1567 "background", PREV_COL_BCOLOR,
1568 "strikethrough", PREV_COL_STRIKE,
1569 "text", col_num + PREV_N_FIXED_COLS -1,
nullptr);
1572 g_object_set (G_OBJECT(renderer),
"family",
"monospace",
nullptr);
1577 auto cbox = preview_cbox_factory (GTK_TREE_MODEL(model), col_num - 1);
1578 gtk_tree_view_column_set_widget (col, cbox);
1581 gtk_tree_view_column_set_resizable (col,
true);
1582 gtk_tree_view_column_set_clickable (col,
true);
1588 static GtkTreeModel*
1589 make_column_header_model_price (
void)
1591 auto combostore = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
1592 for (
auto col_type : gnc_price_col_type_strs)
1595 gtk_list_store_append (combostore, &iter);
1596 gtk_list_store_set (combostore, &iter,
1597 COL_TYPE_NAME, _(col_type.second),
1598 COL_TYPE_ID, static_cast<int>(col_type.first), -1);
1600 return GTK_TREE_MODEL(combostore);
1606 void CsvImpPriceAssist::preview_refresh_table ()
1608 preview_validate_settings ();
1613 auto ncols = PREV_N_FIXED_COLS + price_imp->column_types_price().size();
1614 auto model_col_types = g_new (GType, ncols);
1615 model_col_types[PREV_COL_FCOLOR] = G_TYPE_STRING;
1616 model_col_types[PREV_COL_BCOLOR] = G_TYPE_STRING;
1617 model_col_types[PREV_COL_ERROR] = G_TYPE_STRING;
1618 model_col_types[PREV_COL_ERR_ICON] = G_TYPE_STRING;
1619 model_col_types[PREV_COL_STRIKE] = G_TYPE_BOOLEAN;
1620 for (guint i = PREV_N_FIXED_COLS; i < ncols; i++)
1621 model_col_types[i] = G_TYPE_STRING;
1622 auto store = gtk_list_store_newv (ncols, model_col_types);
1623 g_free (model_col_types);
1626 for (
auto parse_line : price_imp->m_parsed_lines)
1630 gtk_list_store_append (store, &iter);
1631 preview_row_fill_state_cells (store, &iter,
1632 std::get<PL_ERROR>(parse_line), std::get<PL_SKIP>(parse_line));
1635 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++)
1637 uint32_t pos = PREV_N_FIXED_COLS + cell_str_it - std::get<PL_INPUT>(parse_line).cbegin();
1638 gtk_list_store_set (store, &iter, pos, cell_str_it->c_str(), -1);
1641 gtk_tree_view_set_model (treeview, GTK_TREE_MODEL(store));
1642 gtk_tree_view_set_tooltip_column (treeview, PREV_COL_ERROR);
1651 auto ntcols = gtk_tree_view_get_n_columns (treeview);
1657 while (ntcols > ncols - PREV_N_FIXED_COLS + 1)
1659 auto col = gtk_tree_view_get_column (treeview, ntcols - 1);
1660 gtk_tree_view_column_clear (col);
1661 ntcols = gtk_tree_view_remove_column(treeview, col);
1665 while (ntcols < ncols - PREV_N_FIXED_COLS + 1)
1669 auto renderer = (ntcols == 0) ? gtk_cell_renderer_pixbuf_new () : gtk_cell_renderer_text_new ();
1670 auto col = gtk_tree_view_column_new ();
1671 gtk_tree_view_column_pack_start (col, renderer,
false);
1672 ntcols = gtk_tree_view_append_column (treeview, col);
1676 auto combostore = make_column_header_model_price ();
1677 for (uint32_t i = 0; i < ntcols; i++)
1678 preview_style_column (i, combostore);
1680 auto column_types = price_imp->column_types_price();
1681 auto any_of_type = [](std::vector<GncPricePropType>& column_types,
1682 GncPricePropType req_column_type) ->
bool 1684 return std::any_of (column_types.begin(), column_types.end(),
1685 [&req_column_type](GncPricePropType column_type) ->
bool 1686 {
return column_type == req_column_type; });
1690 if (any_of_type (column_types, GncPricePropType::FROM_NAMESPACE))
1692 g_signal_handlers_block_by_func (commodity_selector, (gpointer) csv_price_imp_preview_commodity_sel_cb,
this);
1693 set_commodity_for_combo (GTK_COMBO_BOX(commodity_selector),
nullptr);
1694 g_signal_handlers_unblock_by_func (commodity_selector, (gpointer) csv_price_imp_preview_commodity_sel_cb,
this);
1698 if (any_of_type (column_types, GncPricePropType::FROM_SYMBOL))
1700 g_signal_handlers_block_by_func (commodity_selector, (gpointer) csv_price_imp_preview_commodity_sel_cb,
this);
1701 set_commodity_for_combo (GTK_COMBO_BOX(commodity_selector),
nullptr);
1702 g_signal_handlers_unblock_by_func (commodity_selector, (gpointer) csv_price_imp_preview_commodity_sel_cb,
this);
1706 if (any_of_type (column_types, GncPricePropType::TO_CURRENCY))
1708 g_signal_handlers_block_by_func (currency_selector, (gpointer) csv_price_imp_preview_currency_sel_cb,
this);
1709 set_commodity_for_combo (GTK_COMBO_BOX(currency_selector),
nullptr);
1710 g_signal_handlers_unblock_by_func (currency_selector, (gpointer) csv_price_imp_preview_currency_sel_cb,
this);
1714 g_object_unref (store);
1715 g_object_unref (combostore);
1718 gtk_widget_show_all (GTK_WIDGET(treeview));
1725 CsvImpPriceAssist::preview_refresh ()
1734 auto skip_start_lines = price_imp->skip_start_lines();
1735 auto skip_end_lines = price_imp->skip_end_lines();
1736 auto skip_alt_lines = price_imp->skip_alt_lines();
1739 auto adj = gtk_spin_button_get_adjustment (start_row_spin);
1740 gtk_adjustment_set_upper (adj, price_imp->m_parsed_lines.size());
1741 gtk_spin_button_set_value (start_row_spin, skip_start_lines);
1744 adj = gtk_spin_button_get_adjustment (end_row_spin);
1745 gtk_adjustment_set_upper (adj, price_imp->m_parsed_lines.size());
1746 gtk_spin_button_set_value (end_row_spin, skip_end_lines);
1749 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(skip_alt_rows_button),
1753 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(over_write_cbutton),
1754 price_imp->over_write());
1757 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(csv_button),
1758 (price_imp->file_format() == GncImpFileFormat::CSV));
1759 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(fixed_button),
1760 (price_imp->file_format() != GncImpFileFormat::CSV));
1763 gtk_combo_box_set_active (GTK_COMBO_BOX(date_format_combo),
1764 price_imp->date_format());
1765 gtk_combo_box_set_active (GTK_COMBO_BOX(currency_format_combo),
1766 price_imp->currency_format());
1767 go_charmap_sel_set_encoding (encselector, price_imp->encoding().c_str());
1770 set_commodity_for_combo(GTK_COMBO_BOX(commodity_selector),
1771 price_imp->from_commodity());
1773 set_commodity_for_combo(GTK_COMBO_BOX(currency_selector),
1774 price_imp->to_currency());
1780 if (price_imp->file_format() == GncImpFileFormat::CSV)
1782 auto separators = price_imp->separators();
1783 const auto stock_sep_chars = std::string (
" \t,:;-");
1785 for (
int i = 0; i < SEP_NUM_OF_TYPES; i++)
1787 g_signal_handlers_block_by_func (sep_button[i], (gpointer) csv_price_imp_preview_sep_button_cb,
this);
1788 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(sep_button[i]),
1789 separators.find (stock_sep_chars[i]) != std::string::npos);
1790 g_signal_handlers_unblock_by_func (sep_button[i], (gpointer) csv_price_imp_preview_sep_button_cb,
this);
1795 auto pos = separators.find_first_of (stock_sep_chars);
1796 while (!separators.empty() && pos != std::string::npos)
1798 separators.erase(pos);
1799 pos = separators.find_first_of (stock_sep_chars);
1801 g_signal_handlers_block_by_func (custom_cbutton, (gpointer) csv_price_imp_preview_sep_button_cb,
this);
1802 g_signal_handlers_block_by_func (custom_entry, (gpointer) csv_price_imp_preview_sep_button_cb,
this);
1804 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(custom_cbutton),
1805 !separators.empty());
1806 gtk_entry_set_text (GTK_ENTRY(custom_entry), separators.c_str());
1808 g_signal_handlers_unblock_by_func (custom_cbutton, (gpointer) csv_price_imp_preview_sep_button_cb,
this);
1809 g_signal_handlers_unblock_by_func (custom_entry, (gpointer) csv_price_imp_preview_sep_button_cb,
this);
1812 price_imp->tokenize (
false);
1814 catch (std::range_error& err)
1816 PERR (
"CSV Tokenization Failed: %s", err.what ());
1820 g_idle_add ((GSourceFunc)csv_imp_preview_queue_rebuild_table,
this);
1825 void CsvImpPriceAssist::preview_validate_settings ()
1828 auto error_msg = price_imp->verify();
1829 gtk_assistant_set_page_complete (csv_imp_asst, preview_page, error_msg.empty());
1830 gtk_label_set_markup(GTK_LABEL(instructions_label), error_msg.c_str());
1831 gtk_widget_set_visible (GTK_WIDGET(instructions_image), !error_msg.empty());
1839 CsvImpPriceAssist::assist_file_page_prepare ()
1842 gtk_assistant_set_page_complete (csv_imp_asst, file_page,
false);
1843 gtk_assistant_set_page_complete (csv_imp_asst, preview_page,
false);
1846 if (!m_final_file_name.empty())
1847 gtk_file_chooser_set_filename (GTK_FILE_CHOOSER(file_chooser),
1848 m_final_file_name.c_str());
1851 auto starting_dir = gnc_get_default_directory (GNC_PREFS_GROUP);
1854 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(file_chooser), starting_dir);
1855 g_free (starting_dir);
1861 CsvImpPriceAssist::assist_preview_page_prepare ()
1863 auto go_back =
false;
1866 if (m_final_file_name != m_fc_file_name)
1873 price_imp->file_format (GncImpFileFormat::CSV);
1874 price_imp->load_file (m_fc_file_name);
1875 price_imp->tokenize (
true);
1878 preview_populate_settings_combo();
1879 gtk_combo_box_set_active (settings_combo, 0);
1882 price_imp->over_write (
false);
1885 gtk_assistant_set_page_complete (csv_imp_asst, preview_page,
false);
1887 catch (std::ifstream::failure& e)
1890 gnc_error_dialog (GTK_WINDOW(csv_imp_asst),
"%s", e.what());
1893 catch (std::range_error &e)
1896 gnc_error_dialog (GTK_WINDOW(csv_imp_asst),
"%s", _(e.what()));
1902 gtk_assistant_previous_page (csv_imp_asst);
1905 m_final_file_name = m_fc_file_name;
1909 g_idle_add ((GSourceFunc)csv_imp_preview_queue_rebuild_table,
this);
1914 CsvImpPriceAssist::assist_confirm_page_prepare ()
1920 CsvImpPriceAssist::assist_summary_page_prepare ()
1922 auto text = std::string(
"<span size=\"medium\"><b>");
1924 auto added_str = g_strdup_printf (ngettext (
"%d added price",
1926 price_imp->m_prices_added),
1927 price_imp->m_prices_added);
1929 auto dupl_str = g_strdup_printf (ngettext (
"%d duplicate price",
1930 "%d duplicate prices",
1931 price_imp->m_prices_duplicated),
1932 price_imp->m_prices_duplicated);
1934 auto repl_str = g_strdup_printf (ngettext (
"%d replaced price",
1935 "%d replaced prices",
1936 price_imp->m_prices_replaced),
1937 price_imp->m_prices_replaced);
1938 auto msg = g_strdup_printf (
1939 _(
"The prices were imported from file '%s'.\n\n" 1944 m_final_file_name.c_str(), added_str, dupl_str,repl_str);
1946 text +=
"</b></span>";
1952 gtk_label_set_markup (GTK_LABEL(summary_label), text.c_str());
1956 CsvImpPriceAssist::assist_prepare_cb (GtkWidget *page)
1958 if (page == file_page)
1959 assist_file_page_prepare ();
1960 else if (page == preview_page)
1961 assist_preview_page_prepare ();
1962 else if (page == confirm_page)
1963 assist_confirm_page_prepare ();
1964 else if (page == summary_page)
1965 assist_summary_page_prepare ();
1969 CsvImpPriceAssist::assist_finish ()
1975 price_imp->create_prices ();
1976 gnc_gui_refresh_all ();
1978 catch (
const std::invalid_argument& err)
1983 gnc_error_dialog (GTK_WINDOW(csv_imp_asst),
1984 _(
"An unexpected error has occurred while creating prices. Please report this as a bug.\n\n" 1985 "Error message:\n%s"), err.what());
1986 gtk_assistant_set_current_page (csv_imp_asst, 2);
1991 CsvImpPriceAssist::assist_compmgr_close ()
1993 gnc_save_window_size (GNC_PREFS_GROUP, GTK_WINDOW(csv_imp_asst));
1997 csv_price_imp_close_handler (gpointer user_data)
2000 gnc_unregister_gui_component_by_data (ASSISTANT_CSV_IMPORT_PRICE_CM_CLASS, info);
2001 info->assist_compmgr_close();
2016 gnc_register_gui_component (ASSISTANT_CSV_IMPORT_PRICE_CM_CLASS,
2017 nullptr, csv_price_imp_close_handler,
Functions to load, save and get gui state.
void preview_update_separators(GtkWidget *widget)
Event handler for separator changes.
The actual PriceImport class It's intended to use in the following sequence of actions: ...
GtkWindow * gnc_ui_get_main_window(GtkWidget *widget)
Get a pointer to the final GncMainWindow widget is rooted in.
utility functions for the GnuCash UI
#define PINFO(format, args...)
Print an informational note.
Class to convert a csv file into vector of string vectors.
#define DEBUG(format, args...)
Print a debugging message.
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.
#define PERR(format, args...)
Log a serious error.
void preview_update_col_type(GtkComboBox *cbox)
Event handler for the user selecting a new column type.
const preset_vec_price & get_import_presets_price(void)
Creates a vector of CsvPriceImpSettings which combines.
#define PWARN(format, args...)
Log a warning.
bool preset_is_reserved_name(const std::string &name)
Check whether name can be used as a preset name.
void preview_update_encoding(const char *encoding)
Event handler for a new encoding.
GList * gnc_commodity_table_get_namespaces(const gnc_commodity_table *table)
Return a list of all namespaces in the commodity table.
void preview_update_file_format()
Event handler for clicking one of the format type radio buttons.
void preview_update_fw_columns(GtkTreeView *treeview, GdkEventButton *event)
Event handler for clicking on column headers.
const char * gnc_commodity_get_fullname(const gnc_commodity *cm)
Retrieve the full name for the specified commodity.
Class to import prices from CSV or fixed width files.
Class convert a file with fixed with delimited contents into vector of string vectors.
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.
const char * gnc_commodity_get_printname(const gnc_commodity *cm)
Retrieve the 'print' name for the specified commodity.
Utility functions for convert uri in separate components and back.
void gnc_file_csv_price_import(void)
The gnc_file_csv_price_import() will let the user import the commodity prices from a file...
static const std::vector< GncDateFormat > c_formats
A vector with all the date formats supported by the string constructor.