27 #include <glib/gi18n.h>
31 #include "assistant-xml-encoding.h"
32 #include "dialog-utils.h"
33 #include "assistant-utils.h"
35 #include "gnc-component-manager.h"
37 #include "gnc-module.h"
53 GtkWidget *default_encoding_combo;
54 GtkWidget *default_encoding_hbox;
55 GtkWidget *summary_label;
56 GtkWidget *impossible_label;
57 GtkWidget *string_box;
58 GtkWidget *string_box_container;
59 GtkWidget *encodings_dialog;
60 GtkWidget *custom_enc_entry;
61 GtkTreeView *available_encs_view;
62 GtkTreeView *selected_encs_view;
65 GQuark default_encoding;
73 GHashTable *ambiguous_ht;
76 GList *ambiguous_list;
103 gchar *byte_sequence;
129 void gxi_prepare_cb (GtkAssistant *assistant, GtkWidget *page,
GncXmlImportData *data);
133 void gxi_conversion_prepare (GtkAssistant *assistant, gpointer data );
134 void gxi_conversion_next (GtkAssistant *assistant, gpointer data);
143 static void gxi_update_progress_bar (
const gchar *message,
double percentage);
149 static void gxi_default_enc_combo_changed_cb (GtkComboBox *combo,
GncXmlImportData *data);
150 static void gxi_string_combo_changed_cb (GtkComboBox *combo,
GncXmlImportData *data);
151 void gxi_edit_encodings_clicked_cb (GtkButton *button,
GncXmlImportData *data);
152 void gxi_available_enc_activated_cb (GtkTreeView *view, GtkTreePath *path, GtkTreeViewColumn *column,
GncXmlImportData *data);
155 void gxi_add_custom_enc_clicked_cb (GtkButton *button,
GncXmlImportData *data);
156 void gxi_selected_enc_activated_cb (GtkTreeView *view, GtkTreePath *path, GtkTreeViewColumn *column,
GncXmlImportData *data);
159 static const gchar *encodings_doc_string = N_(
160 "\nThe file you are trying to load is from an older version of "
161 "GnuCash. The file format in the older versions was missing the "
162 "detailed specification of the character encoding being used. This "
163 "means the text in your data file could be read in multiple ambiguous "
164 "ways. This ambiguity cannot be resolved automatically, but the new "
165 "GnuCash 2.0.0 file format will include all necessary specifications so "
166 "that you do not have to go through this step again."
168 "GnuCash will try to guess the correct character encoding for your data "
169 "file. On the next page GnuCash will show the resulting texts when "
170 "using this guess. You have to check whether the words look as "
171 "expected. Either everything looks fine and you can simply press "
172 "'Forward'. Or the words contain unexpected characters, in which "
173 "case you should select different character encodings to see "
174 "different results. You may have to edit the list of character "
175 "encodings by clicking on the respective button."
177 "Press 'Forward' now to select the correct character encoding for "
178 "your data file.\n");
180 static const gchar *encodings_doc_page_title = N_(
"Ambiguous character encoding");
182 static const gchar *finish_convert_string = N_(
183 "The file has been loaded successfully. If you click 'Apply' it will be saved "
184 "and reloaded into the main application. That way you will have a working "
185 "file as backup in the same directory.\n\n"
186 "You can also go back and verify your selections by clicking on 'Back'.");
192 static GtkWidget *progress_window = NULL;
193 static GtkProgressBar *progress_bar = NULL;
206 { N_(
"Unicode"), NULL, 2 },
207 {
"UTF-8",
"UTF-8", 0 },
208 { N_(
"European"), NULL, 2 },
209 { N_(
"ISO-8859-1 (West European)"),
"ISO-8859-1", 0 },
210 { N_(
"ISO-8859-2 (East European)"),
"ISO-8859-2", 1 },
211 { N_(
"ISO-8859-3 (South European)"),
"ISO-8859-3", 1 },
212 { N_(
"ISO-8859-4 (North European)"),
"ISO-8859-4", 1 },
213 { N_(
"ISO-8859-5 (Cyrillic)"),
"ISO-8859-5", 1 },
214 { N_(
"ISO-8859-6 (Arabic)"),
"ISO-8859-6", 1 },
215 { N_(
"ISO-8859-7 (Greek)"),
"ISO-8859-7", 1 },
216 { N_(
"ISO-8859-8 (Hebrew)"),
"ISO-8859-8", 1 },
217 { N_(
"ISO-8859-9 (Turkish)"),
"ISO-8859-9", 1 },
218 { N_(
"ISO-8859-10 (Nordic)"),
"ISO-8859-10", 1 },
219 { N_(
"ISO-8859-11 (Thai)"),
"ISO-8859-11", 1 },
220 { N_(
"ISO-8859-13 (Baltic)"),
"ISO-8859-13", 1 },
221 { N_(
"ISO-8859-14 (Celtic)"),
"ISO-8859-14", 1 },
222 { N_(
"ISO-8859-15 (West European, Euro sign)"),
"ISO-8859-15", 1 },
223 { N_(
"ISO-8859-16 (South-East European)"),
"ISO-8859-16", 1 },
224 { N_(
"Cyrillic"), NULL, 2 },
225 { N_(
"KOI8-R (Russian)"),
"KOI8-R", 0 },
226 { N_(
"KOI8-U (Ukrainian)"),
"KOI8-U", 1 },
228 static guint n_system_encodings = G_N_ELEMENTS (system_encodings);
231 void gxi_prepare_cb (GtkAssistant *assistant, GtkWidget *page,
234 switch (gtk_assistant_get_current_page(assistant))
238 gxi_conversion_prepare (assistant, data);
242 gxi_conversion_next (assistant, data);
256 GtkAssistant *assistant = GTK_ASSISTANT(data->assistant);
257 gint num = gtk_assistant_get_current_page (assistant);
258 GtkWidget *page = gtk_assistant_get_nth_page (assistant, num);
260 if (data->n_unassigned || data->n_impossible)
261 gtk_assistant_set_page_complete (assistant, page, FALSE);
263 gtk_assistant_set_page_complete (assistant, page, TRUE);
269 gnc_suspend_gui_refresh ();
270 data->canceled = TRUE;
271 gnc_resume_gui_refresh ();
278 gnc_xml_convert_single_file (
const gchar *filename)
287 data->canceled = FALSE;
290 gxi_check_file (data);
291 if (data->n_impossible == -1)
294 if (!g_hash_table_size (data->ambiguous_ht))
297 success = gxi_parse_file (data) &&
298 gxi_save_file (data);
300 gxi_data_destroy (data);
305 builder = gtk_builder_new();
306 gnc_builder_add_from_file (builder ,
"assistant-xml-encoding.glade",
"assistant_xml_encoding");
307 data->assistant = GTK_WIDGET(gtk_builder_get_object (builder,
"assistant_xml_encoding"));
309 gnc_assistant_set_colors (GTK_ASSISTANT (data->assistant));
312 gtk_assistant_set_page_complete (GTK_ASSISTANT (data->assistant),
313 GTK_WIDGET(gtk_builder_get_object(builder,
"start_page")),
315 gtk_assistant_set_page_complete (GTK_ASSISTANT (data->assistant),
316 GTK_WIDGET(gtk_builder_get_object(builder,
"conversion_page")),
318 gtk_assistant_set_page_complete (GTK_ASSISTANT (data->assistant),
319 GTK_WIDGET(gtk_builder_get_object(builder,
"end_page")),
323 gtk_assistant_set_page_title (GTK_ASSISTANT(data->assistant),
324 gtk_assistant_get_nth_page (GTK_ASSISTANT(data->assistant), 0),
325 gettext(encodings_doc_page_title));
327 widget = GTK_WIDGET(gtk_builder_get_object (builder,
"start_page"));
328 gtk_label_set_text (GTK_LABEL(widget), gettext (encodings_doc_string));
331 data->default_encoding_hbox = GTK_WIDGET(gtk_builder_get_object (builder,
"default_enc_box"));
332 data->string_box_container = GTK_WIDGET(gtk_builder_get_object (builder,
"string_box_container"));
333 data->impossible_label = GTK_WIDGET(gtk_builder_get_object (builder,
"impossible_label"));
336 widget = GTK_WIDGET(gtk_builder_get_object(builder,
"end_page"));
337 gtk_label_set_text (GTK_LABEL(widget), gettext (finish_convert_string));
339 gtk_builder_connect_signals(builder, data);
341 gtk_widget_show_all (data->assistant);
343 gxi_update_default_enc_combo (data);
344 gxi_update_string_box (data);
346 g_object_unref(G_OBJECT(builder));
354 success = gxi_save_file (data);
358 gxi_data_destroy (data);
372 g_free (data->filename);
373 data->filename = NULL;
376 gxi_session_destroy (data);
377 gxi_ambiguous_info_destroy (data);
381 g_hash_table_destroy (data->choices);
382 data->choices = NULL;
385 if (data->string_box)
387 gtk_widget_destroy (data->string_box);
388 data->string_box = NULL;
393 gtk_widget_destroy (data->assistant);
394 data->assistant = NULL;
403 g_free(conv->utf8_string);
415 new_type->encoding = conv->encoding;
416 new_type->utf8_string = g_strdup (conv->utf8_string);
422 conv_enc_cmp (
const conv_type *conv,
const GQuark *enc)
424 return conv->encoding - *enc;
430 GList *found = g_list_find_custom (amb->conv_list, &enc,
431 (GCompareFunc) conv_enc_cmp);
435 return ((
conv_type*) found->data)->utf8_string;
447 const gchar *string_a = get_decoded_string (a, data->default_encoding);
448 const gchar *string_b = get_decoded_string (b, data->default_encoding);
455 return strcmp (string_a, string_b);
473 conv_type *conv_a = g_hash_table_lookup (data->choices, a->byte_sequence);
474 conv_type *conv_b = g_hash_table_lookup (data->choices, b->byte_sequence);
475 if (conv_a && !conv_b)
return 1;
476 if (conv_b && !conv_a)
return -1;
477 return strcmp (a->byte_sequence, b->byte_sequence);
483 ambiguous_list_insert (gchar *byte_sequence, GList *conv_list,
489 amb->byte_sequence = g_strdup (byte_sequence);
490 amb->conv_list = NULL;
491 for (iter = g_list_last (conv_list); iter; iter = iter->prev)
492 amb->conv_list = g_list_prepend (amb->conv_list, conv_copy (iter->data));
494 data->ambiguous_list = g_list_prepend (data->ambiguous_list, amb);
502 g_free (amb->byte_sequence);
503 g_list_foreach (amb->conv_list, (GFunc) conv_free, NULL);
504 g_list_free (amb->conv_list);
514 g_hash_table_destroy (data->unique);
517 if (data->ambiguous_ht)
519 g_hash_table_destroy (data->ambiguous_ht);
522 if (data->ambiguous_list)
524 g_list_foreach (data->ambiguous_list, (GFunc) ambiguous_free, NULL);
525 g_list_free (data->ambiguous_list);
526 data->ambiguous_list = NULL;
536 qof_session_destroy (data->session);
538 data->session = NULL;
545 data->ambiguous_list = g_list_sort_with_data (
546 data->ambiguous_list, (GCompareDataFunc) ambiguous_cmp, data);
551 subst_insert_amb (gchar *byte_sequence, GList *conv_list,
GncXmlImportData *data)
559 choice = g_hash_table_lookup (data->choices, byte_sequence);
563 g_hash_table_insert (data->subst, g_strdup (byte_sequence),
564 g_strdup (choice->utf8_string));
568 default_conv = g_list_find_custom (conv_list, &data->default_encoding,
569 (GCompareFunc) conv_enc_cmp);
573 default_utf8 = ((
conv_type*) default_conv->data)->utf8_string;
574 g_hash_table_insert (data->subst, g_strdup (byte_sequence),
575 g_strdup (default_utf8));
580 g_hash_table_destroy (data->subst);
587 subst_insert_unique (gchar *byte_sequence,
conv_type *conv,
592 g_hash_table_insert (data->subst, g_strdup (byte_sequence),
593 g_strdup (conv->utf8_string));
597 gxi_update_progress_bar (
const gchar *message,
double percentage)
599 if (!progress_window)
601 progress_window = gtk_window_new (GTK_WINDOW_POPUP);
602 progress_bar = GTK_PROGRESS_BAR (gtk_progress_bar_new ());
603 gtk_container_set_border_width (GTK_CONTAINER (progress_window), 12);
604 gtk_container_add (GTK_CONTAINER (progress_window),
605 GTK_WIDGET (progress_bar));
606 gtk_widget_show (GTK_WIDGET (progress_bar));
611 gtk_progress_bar_set_text (progress_bar, NULL);
612 gtk_progress_bar_set_fraction (progress_bar, 0.0);
613 gtk_widget_hide (progress_window);
617 gtk_progress_bar_set_text (progress_bar, message);
618 if (percentage <= 100)
619 gtk_progress_bar_set_fraction (progress_bar, percentage / 100);
621 gtk_progress_bar_pulse (progress_bar);
622 gtk_widget_show (progress_window);
629 GtkComboBoxText *combo;
633 if (data->default_encoding_combo)
634 gtk_widget_destroy (data->default_encoding_combo);
635 data->default_encoding_combo = gtk_combo_box_text_new();
636 combo = GTK_COMBO_BOX_TEXT (data->default_encoding_combo);
638 for (enc_iter = data->encodings; enc_iter; enc_iter = enc_iter->next)
640 gtk_combo_box_text_append_text (
641 combo, g_quark_to_string (GPOINTER_TO_UINT (enc_iter->data)));
643 gtk_combo_box_set_active (GTK_COMBO_BOX(combo),
644 g_list_index (data->encodings, GUINT_TO_POINTER (data->default_encoding)));
647 g_signal_connect (G_OBJECT (combo),
"changed",
648 G_CALLBACK (gxi_default_enc_combo_changed_cb), data);
649 gtk_container_add (GTK_CONTAINER (data->default_encoding_hbox), GTK_WIDGET (combo));
650 gtk_widget_show (GTK_WIDGET (combo));
656 gchar *
string = NULL;
657 gboolean show = FALSE;
659 if (data->n_unassigned)
661 if (data->n_impossible)
663 string = g_strdup_printf (
664 _(
"There are %d unassigned and %d undecodable words. "
665 "Please add encodings."),
666 data->n_unassigned, data->n_impossible);
671 string = g_strdup_printf (
672 _(
"There are %d unassigned words. "
673 "Please decide on them or add encodings."),
680 if (data->n_impossible)
682 string = g_strdup_printf (
683 _(
"There are %d undecodable words. "
684 "Please add encodings."),
696 gtk_label_set_text (GTK_LABEL (data->summary_label),
string);
698 gtk_widget_show (data->summary_label);
702 gtk_widget_hide (data->summary_label);
714 GList *word_iter, *conv_iter;
715 GtkCellRenderer *renderer;
717 GQuark chosen_encoding;
718 GtkTreeIter *chosen_iter, *default_iter;
722 if (data->string_box)
723 gtk_widget_destroy (data->string_box);
725 data->string_box = gtk_vbox_new (FALSE, 6);
726 vbox = GTK_BOX (data->string_box);
728 data->n_unassigned = 0;
731 for (word_iter = data->ambiguous_list; word_iter; word_iter = word_iter->next)
734 store = gtk_list_store_new (WORD_NUM_COLS, G_TYPE_STRING, G_TYPE_POINTER);
735 combo = GTK_COMBO_BOX (gtk_combo_box_new_with_model (
736 GTK_TREE_MODEL (store)));
737 g_object_unref (store);
738 renderer = gtk_cell_renderer_text_new ();
739 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE);
740 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), renderer,
741 "text", WORD_COL_STRING, NULL);
745 utf8 = get_decoded_string (amb, data->default_encoding);
749 string = g_strdup_printf (
"%s (default)", utf8);
750 gtk_list_store_append (store, &iter);
751 gtk_list_store_set (store, &iter, WORD_COL_STRING,
string,
753 GUINT_TO_POINTER (data->default_encoding), -1);
755 default_iter = gtk_tree_iter_copy (&iter);
759 conv = (
conv_type*) g_hash_table_lookup (data->choices, amb->byte_sequence);
760 chosen_encoding = (conv) ? conv->encoding : 0;
764 for (conv_iter = amb->conv_list; conv_iter; conv_iter = conv_iter->next)
767 string = g_strdup_printf (
"%s (%s)", conv->utf8_string,
768 g_quark_to_string (conv->encoding));
769 gtk_list_store_append (store, &iter);
770 gtk_list_store_set (store, &iter, WORD_COL_STRING,
string,
772 GUINT_TO_POINTER (conv->encoding), -1);
775 if (chosen_encoding && conv->encoding == chosen_encoding)
777 chosen_iter = gtk_tree_iter_copy (&iter);
784 gtk_combo_box_set_active_iter (combo, chosen_iter);
785 gtk_tree_iter_free (chosen_iter);
792 gtk_combo_box_set_active_iter (combo, default_iter);
797 data->n_unassigned++;
802 g_object_set_data (G_OBJECT (combo),
"ambiguous", amb);
803 g_signal_connect (G_OBJECT (combo),
"changed",
804 G_CALLBACK (gxi_string_combo_changed_cb), data);
805 gtk_box_pack_start (vbox, GTK_WIDGET (combo), FALSE, FALSE, 0);
806 gtk_widget_show (GTK_WIDGET (combo));
811 gtk_container_add (GTK_CONTAINER (data->string_box_container), GTK_WIDGET (vbox));
812 gtk_widget_show (GTK_WIDGET (vbox));
815 if (!data->summary_label)
816 data->summary_label = data->impossible_label;
817 gxi_update_summary_label (data);
821 gxi_conversion_prepare (GtkAssistant *assistant, gpointer user_data )
825 gxi_update_string_box (data);
826 gxi_update_conversion_forward (data);
830 gxi_default_enc_combo_changed_cb (GtkComboBox *combo,
GncXmlImportData *data)
836 if (!gtk_combo_box_get_active_iter (combo, &iter))
839 gtk_tree_model_get (gtk_combo_box_get_model (combo), &iter,
841 curr_enc = g_quark_from_string (enc_string);
844 if (data->default_encoding == curr_enc)
846 if (!g_list_find (data->encodings, GUINT_TO_POINTER (curr_enc)))
849 PERR(
"invalid encoding selection");
853 data->default_encoding = curr_enc;
854 gxi_sort_ambiguous_list (data);
855 gxi_update_string_box (data);
856 gxi_update_conversion_forward (data);
863 GList *found, *default_conv;
868 GQuark prev_enc, curr_enc;
870 amb = (
ambiguous_type*) g_object_get_data (G_OBJECT (combo),
"ambiguous");
871 prev_conv = (
conv_type*) g_hash_table_lookup (data->choices,
874 prev_enc = prev_conv->encoding;
876 default_conv = g_list_find_custom (amb->conv_list, &data->default_encoding,
877 (GCompareFunc) conv_enc_cmp);
879 is_active = gtk_combo_box_get_active_iter (combo, &iter);
882 gtk_tree_model_get (gtk_combo_box_get_model (combo), &iter,
883 WORD_COL_ENCODING, &ptr, -1);
884 curr_enc = GPOINTER_TO_UINT (ptr);
885 found = g_list_find_custom (amb->conv_list, &curr_enc,
886 (GCompareFunc) conv_enc_cmp);
894 PERR(
"invalid string selection");
903 if (curr_enc == prev_enc)
907 g_hash_table_replace (data->choices, g_strdup (amb->byte_sequence),
908 conv_copy (curr_conv));
910 found = g_list_find_custom (amb->conv_list, &prev_enc,
911 (GCompareFunc) conv_enc_cmp);
912 if (!found && !default_conv)
916 data->n_unassigned--;
917 gxi_update_summary_label (data);
918 gxi_update_conversion_forward (data);
924 g_hash_table_insert (data->choices, g_strdup (amb->byte_sequence),
925 conv_copy (curr_conv));
931 data->n_unassigned--;
932 gxi_update_summary_label (data);
933 gxi_update_conversion_forward (data);
942 g_hash_table_remove (data->choices, amb->byte_sequence);
948 data->n_unassigned++;
949 gxi_update_summary_label (data);
950 gxi_update_conversion_forward (data);
958 gxi_conversion_next (GtkAssistant *assistant, gpointer user_data)
961 gxi_parse_file (data);
967 if (!data->encodings)
970 const gchar *locale_enc;
971 gchar *enc_string, **enc_array, **enc_cursor;
976 is_utf8 = g_get_charset (&locale_enc);
977 enc_string = g_ascii_strup (locale_enc, -1);
978 enc_ptr = GUINT_TO_POINTER (g_quark_from_string (enc_string));
980 data->encodings = g_list_append (NULL, enc_ptr);
985 enc_ptr = GUINT_TO_POINTER (g_quark_from_string (
"UTF-8"));
986 data->encodings = g_list_append (data->encodings, enc_ptr);
992 enc_array = g_strsplit (_(
"ISO-8859-1 KOI8-U"),
" ", 0);
995 for (enc_cursor = enc_array; *enc_cursor; enc_cursor++)
997 if (!**enc_cursor)
continue;
998 enc_string = g_ascii_strup (*enc_cursor, -1);
999 enc_ptr = GUINT_TO_POINTER (g_quark_from_string (enc_string));
1001 if (!g_list_find (data->encodings, enc_ptr))
1004 iconv = g_iconv_open (
"UTF-8", enc_string);
1005 if (iconv != (GIConv) - 1)
1007 data->encodings = g_list_append (data->encodings, enc_ptr);
1008 g_iconv_close (iconv);
1010 g_free (enc_string);
1012 g_strfreev (enc_array);
1015 if (!data->default_encoding)
1018 data->default_encoding = GPOINTER_TO_UINT (data->encodings->data);
1023 data->choices = g_hash_table_new_full (g_str_hash, g_str_equal,
1024 g_free, (GDestroyNotify) conv_free);
1027 gxi_ambiguous_info_destroy (data);
1031 data->filename, data->encodings, &data->unique, &data->ambiguous_ht, NULL);
1033 if (data->n_impossible != -1)
1036 g_hash_table_foreach (data->ambiguous_ht, (GHFunc)ambiguous_list_insert,
1038 gxi_sort_ambiguous_list (data);
1049 gchar *message = NULL;
1050 gboolean success = FALSE;
1052 if (data->n_unassigned || data->n_impossible)
1053 goto cleanup_parse_file;
1056 data->subst = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
1057 g_hash_table_foreach (data->ambiguous_ht, (GHFunc) subst_insert_amb, data);
1058 g_hash_table_foreach (data->unique, (GHFunc) subst_insert_unique, data);
1061 goto cleanup_parse_file;
1064 gxi_session_destroy (data);
1065 session = qof_session_new ();
1066 data->session = session;
1069 if (io_err != ERR_BACKEND_NO_ERR)
1071 message = _(
"The file could not be reopened.");
1072 goto cleanup_parse_file;
1076 gxi_update_progress_bar (_(
"Reading file..."), 0.0);
1077 qof_session_load (session, gxi_update_progress_bar);
1078 gxi_update_progress_bar (NULL, -1.0);
1082 if (io_err == ERR_BACKEND_NO_ERR)
1086 goto cleanup_parse_file;
1091 message = _(
"The file could not be reopened.");
1092 goto cleanup_parse_file;
1099 gxi_update_progress_bar (_(
"Parsing file..."), 0.0);
1101 gxi_update_progress_bar (NULL, -1.0);
1104 data->session = session;
1106 message = _(
"There was an error parsing the file.");
1112 g_hash_table_destroy (data->subst);
1117 gnc_error_dialog (data->assistant,
"%s", message);
1120 gxi_session_destroy (data);
1129 g_return_val_if_fail (data && data->session, FALSE);
1131 gxi_update_progress_bar (_(
"Writing file..."), 0.0);
1133 gxi_update_progress_bar (NULL, -1.0);
1137 if (io_err == ERR_BACKEND_NO_ERR)
1143 gxi_session_destroy (data);
1157 GtkBuilder *builder;
1159 GtkListStore *list_store;
1160 GtkTreeStore *tree_store;
1161 GtkTreeIter iter, parent, *parent_ptr;
1162 GList *encodings_bak, *enc_iter;
1163 const gchar *encoding;
1168 builder = gtk_builder_new();
1169 gnc_builder_add_from_file (builder,
"assistant-xml-encoding.glade",
"Encodings Dialog");
1170 dialog = GTK_WIDGET(gtk_builder_get_object (builder,
"Encodings Dialog"));
1171 data->encodings_dialog = dialog;
1173 gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, data);
1175 gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (data->assistant));
1177 data->available_encs_view = GTK_TREE_VIEW (gtk_builder_get_object (builder,
"available_encs_view"));
1179 data->custom_enc_entry = GTK_WIDGET(gtk_builder_get_object (builder,
"custom_enc_entry"));
1182 data->selected_encs_view = GTK_TREE_VIEW (gtk_builder_get_object (builder,
"selected_encs_view"));
1183 list_store = gtk_list_store_new (ENC_NUM_COLS, G_TYPE_STRING, G_TYPE_POINTER);
1184 for (enc_iter = data->encodings; enc_iter; enc_iter = enc_iter->next)
1186 encoding = g_quark_to_string (GPOINTER_TO_UINT (enc_iter->data));
1187 gtk_list_store_append (list_store, &iter);
1188 gtk_list_store_set (list_store, &iter, ENC_COL_STRING, encoding,
1189 ENC_COL_QUARK, enc_iter->data, -1);
1191 gtk_tree_view_insert_column_with_attributes (
1192 data->selected_encs_view, -1, NULL,
1193 gtk_cell_renderer_text_new (),
"text", ENC_COL_STRING, NULL);
1194 gtk_tree_view_set_model (data->selected_encs_view,
1195 GTK_TREE_MODEL (list_store));
1196 g_object_unref (list_store);
1199 data->available_encs_view = GTK_TREE_VIEW (gtk_builder_get_object (builder,
"available_encs_view"));
1200 tree_store = gtk_tree_store_new (ENC_NUM_COLS, G_TYPE_STRING, G_TYPE_POINTER);
1201 for (i = 0, system_enc = system_encodings;
1202 i < n_system_encodings;
1213 for (j = 0; j < system_enc->parent; j++)
1214 if (gtk_tree_model_iter_parent (GTK_TREE_MODEL (tree_store),
1226 if (system_enc->encoding)
1227 enc_ptr = GUINT_TO_POINTER (g_quark_from_string (system_enc->encoding));
1231 gtk_tree_store_append (tree_store, &iter, parent_ptr);
1232 gtk_tree_store_set (tree_store, &iter, ENC_COL_STRING,
1233 gettext (system_enc->text), ENC_COL_QUARK, enc_ptr, -1);
1235 gtk_tree_view_insert_column_with_attributes (
1236 data->available_encs_view, -1, NULL,
1237 gtk_cell_renderer_text_new (),
"text", ENC_COL_STRING, NULL);
1238 gtk_tree_view_set_model (data->available_encs_view,
1239 GTK_TREE_MODEL (tree_store));
1240 g_object_unref (tree_store);
1243 encodings_bak = g_list_copy (data->encodings);
1244 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
1246 g_list_free (encodings_bak);
1247 if (!g_list_find (data->encodings,
1248 GUINT_TO_POINTER (data->default_encoding)))
1251 data->default_encoding = GPOINTER_TO_UINT (data->encodings->data);
1255 gxi_check_file (data);
1256 gxi_update_default_enc_combo (data);
1257 gxi_update_string_box (data);
1258 gxi_update_conversion_forward (data);
1262 g_list_free (data->encodings);
1263 data->encodings = encodings_bak;
1265 g_object_unref(G_OBJECT(builder));
1267 gtk_widget_destroy (dialog);
1268 data->encodings_dialog = NULL;
1275 const gchar *message;
1277 GtkListStore *store;
1280 enc_string = g_ascii_strup (
1281 g_quark_to_string (GPOINTER_TO_UINT (encoding_ptr)), -1);
1282 encoding_ptr = GUINT_TO_POINTER (g_quark_from_string (enc_string));
1284 if (g_list_find (data->encodings, encoding_ptr))
1286 message = _(
"This encoding has been added to the list already.");
1287 gnc_error_dialog (data->encodings_dialog,
"%s", message);
1292 iconv = g_iconv_open (
"UTF-8", enc_string);
1293 if (iconv == (GIConv) - 1)
1295 g_iconv_close (iconv);
1296 g_free (enc_string);
1297 message = _(
"This is an invalid encoding.");
1298 gnc_error_dialog (data->encodings_dialog,
"%s", message);
1301 g_iconv_close (iconv);
1304 data->encodings = g_list_append (data->encodings, encoding_ptr);
1305 store = GTK_LIST_STORE (gtk_tree_view_get_model (data->selected_encs_view));
1306 gtk_list_store_append (store, &iter);
1307 gtk_list_store_set (store, &iter, ENC_COL_STRING, enc_string,
1308 ENC_COL_QUARK, encoding_ptr, -1);
1310 g_free (enc_string);
1312 if (!data->encodings->next)
1313 gtk_dialog_set_response_sensitive (GTK_DIALOG (data->encodings_dialog),
1314 GTK_RESPONSE_OK, TRUE);
1320 GtkTreeSelection *selection;
1321 GtkTreeModel *model;
1325 selection = gtk_tree_view_get_selection (data->available_encs_view);
1326 if (!gtk_tree_selection_get_selected (selection, &model, &iter))
1328 gtk_tree_model_get (model, &iter, ENC_COL_QUARK, &enc_ptr, -1);
1331 gxi_add_encoding (data, enc_ptr);
1340 gtk_tree_model_get (model, iter, ENC_COL_QUARK, &enc_ptr, -1);
1341 data->encodings = g_list_remove (data->encodings, enc_ptr);
1342 gtk_list_store_remove (GTK_LIST_STORE (model), iter);
1343 if (!data->encodings)
1344 gtk_dialog_set_response_sensitive (GTK_DIALOG (data->encodings_dialog),
1345 GTK_RESPONSE_OK, FALSE);
1351 GtkTreeSelection *selection;
1352 GtkTreeModel *model;
1355 selection = gtk_tree_view_get_selection (data->selected_encs_view);
1356 if (!gtk_tree_selection_get_selected (selection, &model, &iter))
1358 gxi_remove_encoding (data, model, &iter);
1362 gxi_available_enc_activated_cb (GtkTreeView *view, GtkTreePath *path,
1363 GtkTreeViewColumn *column,
1366 GtkTreeModel *model;
1370 model = gtk_tree_view_get_model (data->available_encs_view);
1371 if (!gtk_tree_model_get_iter (model, &iter, path))
1373 gtk_tree_model_get (model, &iter, ENC_COL_QUARK, &enc_ptr, -1);
1376 gxi_add_encoding (data, enc_ptr);
1382 const gchar *enc_string;
1384 enc_string = gtk_entry_get_text (entry);
1387 gxi_add_encoding (data, GUINT_TO_POINTER (g_quark_from_string (enc_string)));
1393 GtkWidget *entry = data->custom_enc_entry;
1394 gxi_custom_enc_activate_cb (GTK_ENTRY (entry), data);
1398 gxi_selected_enc_activated_cb (GtkTreeView *view, GtkTreePath *path,
1401 GtkTreeModel *model;
1404 model = gtk_tree_view_get_model (data->selected_encs_view);
1405 if (!gtk_tree_model_get_iter (model, &iter, path))
1407 gxi_remove_encoding (data, model, &iter);
void qof_session_save(QofSession *session, QofPercentageFunc percentage_func)
QofBackendError
The errors that can be reported to the GUI & other front-end users.
gboolean gnc_xml2_parse_with_subst(FileBackend *fbe, QofBook *book, GHashTable *subst)
void xaccLogDisable(void)
gchar * gnc_uri_get_path(const gchar *uri)
#define PERR(format, args...)
QofBook * qof_session_get_book(const QofSession *session)
api for GnuCash version 2 XML-based file format
QofBackendError qof_session_pop_error(QofSession *session)
QofBackendError qof_session_get_error(QofSession *session)
API for the transaction logger.
void qof_session_begin(QofSession *session, const char *book_id, gboolean ignore_lock, gboolean create, gboolean force)
gint gnc_xml2_find_ambiguous(const gchar *filename, GList *encodings, GHashTable **unique, GHashTable **ambiguous, GList **impossible)
Utility functions for convert uri in separate components and back.
load and save data to files
QofBackend * qof_book_get_backend(const QofBook *book)
Retrieve the backend used by this book.
const gchar * QofLogModule