39 #include <gdk/gdkkeysyms.h> 52 #define GNC_PREF_AUTO_RAISE_LISTS "auto-raise-lists" 54 typedef struct _PopBox
59 GtkListStore* tmp_store;
61 gboolean signals_connected;
68 gboolean use_quickfill_cache;
70 gboolean in_list_select;
74 gunichar complete_char;
76 GList* ignore_strings;
81 static void gnc_combo_cell_gui_realize (BasicCell* bcell, gpointer w);
82 static void gnc_combo_cell_gui_move (BasicCell* bcell);
83 static void gnc_combo_cell_gui_destroy (BasicCell* bcell);
84 static gboolean gnc_combo_cell_enter (BasicCell* bcell,
88 static void gnc_combo_cell_leave (BasicCell* bcell);
89 static void gnc_combo_cell_destroy (BasicCell* bcell);
91 static GOnce auto_pop_init_once = G_ONCE_INIT;
92 static gboolean auto_pop_combos = FALSE;
96 gnc_combo_cell_set_autopop (gpointer prefs, gchar* pref, gpointer user_data)
99 GNC_PREF_AUTO_RAISE_LISTS);
103 gnc_combo_cell_autopop_init (gpointer unused)
107 GNC_PREF_AUTO_RAISE_LISTS);
110 GNC_PREF_AUTO_RAISE_LISTS,
111 gnc_combo_cell_set_autopop,
114 gnc_prefs_set_reg_auto_raise_lists_id (
id);
119 gnc_combo_cell_new (
void)
123 g_once (&auto_pop_init_once, gnc_combo_cell_autopop_init, NULL);
127 gnc_combo_cell_init (cell);
137 gnc_basic_cell_init (& (cell->cell));
139 cell->cell.is_popup = TRUE;
141 cell->cell.destroy = gnc_combo_cell_destroy;
143 cell->cell.gui_realize = gnc_combo_cell_gui_realize;
144 cell->cell.gui_destroy = gnc_combo_cell_gui_destroy;
149 box->item_edit = NULL;
150 box->item_list = NULL;
151 box->tmp_store = gtk_list_store_new (1, G_TYPE_STRING);
152 box->signals_connected = FALSE;
153 box->list_popped = FALSE;
154 box->autosize = FALSE;
156 cell->cell.gui_private = box;
158 box->qf = gnc_quickfill_new();
159 box->use_quickfill_cache = FALSE;
161 box->in_list_select = FALSE;
165 box->complete_char =
'\0';
167 box->ignore_strings = NULL;
171 select_item_cb (
GncItemList* item_list,
char* item_string, gpointer data)
174 PopBox* box = cell->cell.gui_private;
176 box->in_list_select = TRUE;
177 gnucash_sheet_modify_current_cell (box->sheet, item_string);
178 box->in_list_select = FALSE;
180 gnc_item_edit_hide_popup (box->item_edit);
181 box->list_popped = FALSE;
185 change_item_cb (
GncItemList* item_list,
char* item_string, gpointer data)
188 PopBox* box = cell->cell.gui_private;
190 box->in_list_select = TRUE;
191 gnucash_sheet_modify_current_cell (box->sheet, item_string);
192 box->in_list_select = FALSE;
196 activate_item_cb (
GncItemList* item_list,
char* item_string, gpointer data)
199 PopBox* box = cell->cell.gui_private;
201 gnc_item_edit_hide_popup (box->item_edit);
202 box->list_popped = FALSE;
206 key_press_item_cb (
GncItemList* item_list, GdkEventKey* event, gpointer data)
209 PopBox* box = cell->cell.gui_private;
211 switch (event->keyval)
214 gnc_item_edit_hide_popup (box->item_edit);
215 box->list_popped = FALSE;
219 gtk_widget_event (GTK_WIDGET (box->sheet),
226 combo_disconnect_signals (
ComboCell* cell)
228 PopBox* box = cell->cell.gui_private;
230 if (!box->signals_connected)
233 g_signal_handlers_disconnect_matched (G_OBJECT (box->item_list),
235 0, 0, NULL, NULL, cell);
237 box->signals_connected = FALSE;
243 PopBox* box = cell->cell.gui_private;
245 if (box->signals_connected)
248 g_signal_connect (G_OBJECT (box->item_list),
"select_item",
249 G_CALLBACK (select_item_cb), cell);
251 g_signal_connect (G_OBJECT (box->item_list),
"change_item",
252 G_CALLBACK (change_item_cb), cell);
254 g_signal_connect (G_OBJECT (box->item_list),
"activate_item",
255 G_CALLBACK (activate_item_cb), cell);
257 g_signal_connect (G_OBJECT (box->item_list),
"key_press_event",
258 G_CALLBACK (key_press_item_cb), cell);
260 box->signals_connected = TRUE;
266 PopBox* box = cell->cell.gui_private;
268 if (!box->signals_connected)
271 g_signal_handlers_block_matched (G_OBJECT (box->item_list),
273 0, 0, NULL, NULL, cell);
279 PopBox* box = cell->cell.gui_private;
281 if (!box->signals_connected)
284 g_signal_handlers_unblock_matched (G_OBJECT (box->item_list),
286 0, 0, NULL, NULL, cell);
290 gnc_combo_cell_gui_destroy (BasicCell* bcell)
292 PopBox* box = bcell->gui_private;
295 if (cell->cell.gui_realize == NULL)
297 if (box != NULL && box->item_list != NULL)
299 combo_disconnect_signals (cell);
300 g_object_unref (box->item_list);
301 box->item_list = NULL;
304 if (box && box->tmp_store)
306 g_object_unref (box->tmp_store);
307 box->tmp_store = NULL;
311 cell->cell.gui_realize = gnc_combo_cell_gui_realize;
312 cell->cell.gui_move = NULL;
313 cell->cell.enter_cell = NULL;
314 cell->cell.leave_cell = NULL;
315 cell->cell.gui_destroy = NULL;
320 gnc_combo_cell_destroy (BasicCell* bcell)
323 PopBox* box = cell->cell.gui_private;
325 gnc_combo_cell_gui_destroy (& (cell->cell));
330 if (FALSE == box->use_quickfill_cache)
332 gnc_quickfill_destroy (box->qf);
336 g_list_free_full (box->ignore_strings, g_free);
337 box->ignore_strings = NULL;
340 cell->cell.gui_private = NULL;
343 cell->cell.gui_private = NULL;
344 cell->cell.gui_realize = NULL;
355 box = cell->cell.gui_private;
356 if (box->item_list == NULL)
359 block_list_signals (cell);
360 gnc_item_list_set_sort_column (box->item_list, 0);
361 unblock_list_signals (cell);
365 gnc_combo_cell_clear_menu (
ComboCell* cell)
372 box = cell->cell.gui_private;
377 if (FALSE == box->use_quickfill_cache)
379 gnc_quickfill_destroy (box->qf);
380 box->qf = gnc_quickfill_new();
383 if (box->item_list != NULL)
385 block_list_signals (cell);
387 gnc_item_list_clear (box->item_list);
388 gnc_item_edit_hide_popup (box->item_edit);
389 box->list_popped = FALSE;
390 unblock_list_signals (cell);
393 gtk_list_store_clear (box->tmp_store);
401 if (cell == NULL)
return;
403 box = cell->cell.gui_private;
404 if (NULL == box)
return;
406 if (FALSE == box->use_quickfill_cache)
408 box->use_quickfill_cache = TRUE;
409 gnc_quickfill_destroy (box->qf);
415 gnc_combo_cell_use_list_store_cache (
ComboCell* cell, gpointer data)
417 if (cell == NULL)
return;
419 cell->shared_store = data;
432 box = cell->cell.gui_private;
434 if (box->item_list != NULL)
436 block_list_signals (cell);
438 gnc_item_list_append (box->item_list, menustr);
439 if (cell->cell.value &&
440 (strcmp (menustr, cell->cell.value) == 0))
441 gnc_item_list_select (box->item_list, menustr);
443 unblock_list_signals (cell);
449 gtk_list_store_append (box->tmp_store, &iter);
450 gtk_list_store_set (box->tmp_store, &iter, 0, menustr, -1);
455 if (FALSE == box->use_quickfill_cache)
471 box = cell->cell.gui_private;
473 if (box->item_list != NULL)
475 block_list_signals (cell);
477 gnc_item_list_append (box->item_list, menustr);
478 if (cell->cell.value)
480 gchar* menu_copy = g_strdup (menustr);
481 gchar* value_copy = g_strdup (cell->cell.value);
482 g_strdelimit (menu_copy,
"-:/\\.",
' ');
483 g_strdelimit (value_copy,
"-:/\\.",
' ');
484 if (strcmp (menu_copy, value_copy) == 0)
486 gnc_combo_cell_set_value (cell, menustr);
487 gnc_item_list_select (box->item_list, menustr);
492 unblock_list_signals (cell);
497 if (FALSE == box->use_quickfill_cache)
504 gnc_combo_cell_set_value (
ComboCell* cell,
const char* str)
506 gnc_basic_cell_set_value (&cell->cell, str);
510 list_store_append (GtkListStore *store,
char*
string)
514 g_return_if_fail (store != NULL);
515 g_return_if_fail (
string != NULL);
516 gtk_list_store_append (store, &iter);
517 gtk_list_store_set (store, &iter, 0,
string, -1);
525 gnc_combo_cell_type_ahead_search (
const gchar* newval,
526 GtkListStore* full_store,
ComboCell *cell)
529 PopBox* box = cell->cell.gui_private;
531 gchar* match_str = NULL;
533 char* escaped_sep = g_regex_escape_string (sep, -1);
534 char* escaped_newval = g_regex_escape_string (newval, -1);
535 gchar* newval_rep = g_strdup_printf (
".*%s.*", escaped_sep);
536 GRegex* regex0 = g_regex_new (escaped_sep, 0, 0, NULL);
537 char* rep_str = g_regex_replace_literal (regex0, escaped_newval, -1, 0,
538 newval_rep, 0, NULL);
539 char* normal_rep_str = g_utf8_normalize (rep_str, -1, G_NORMALIZE_NFC);
540 GRegex *regex = g_regex_new (normal_rep_str, G_REGEX_CASELESS, 0, NULL);
542 gboolean valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (full_store),
548 static const gint MAX_NUM_MATCHES = 30;
550 g_free (normal_rep_str);
553 g_free (escaped_sep);
554 g_free (escaped_newval);
555 g_regex_unref (regex0);
557 block_list_signals (cell);
558 gnc_item_edit_hide_popup (box->item_edit);
559 gtk_list_store_clear (box->tmp_store);
560 unblock_list_signals (cell);
562 if (strlen (newval) == 0) {
570 gnc_item_list_set_temp_store (box->item_list, NULL);
571 gnc_item_edit_show_popup (box->item_edit);
572 box->list_popped = TRUE;
576 while (valid && num_found < MAX_NUM_MATCHES)
578 gchar* str_data = NULL;
579 gchar* normalized_str_data = NULL;
580 gtk_tree_model_get (GTK_TREE_MODEL (full_store), &iter, 0,
582 normalized_str_data = g_utf8_normalize (str_data, -1, G_NORMALIZE_NFC);
584 if (g_regex_match (regex, normalized_str_data, 0, NULL))
587 match_str = g_strdup (str_data);
589 list_store_append (box->tmp_store, str_data);
592 g_free (normalized_str_data);
593 valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (full_store), &iter);
598 gnc_item_list_set_temp_store (box->item_list, box->tmp_store);
599 gnc_item_edit_show_popup (box->item_edit);
600 box->list_popped = TRUE;
604 g_regex_unref (regex);
609 quickfill_match (QuickFill *qf,
const char *
string)
617 gnc_combo_cell_modify_verify (BasicCell* _cell,
622 int* cursor_position,
623 int* start_selection,
627 PopBox* box = cell->cell.gui_private;
628 gchar* match_str = NULL;
631 const gchar* box_str = NULL;
633 newval_chars = g_utf8_strlen (newval, newval_len);
634 change_chars = g_utf8_strlen (change, change_len);
636 if (box->in_list_select)
638 gnc_basic_cell_set_value_internal (_cell, newval);
639 *cursor_position = -1;
640 *start_selection = 0;
648 if (!gnc_item_list_using_temp (box->item_list))
651 if (change == NULL || *cursor_position < _cell->value_chars)
653 gnc_basic_cell_set_value_internal (_cell, newval);
654 *start_selection = *end_selection = *cursor_position;
658 match_str = quickfill_match (box->qf, newval);
660 if (match_str != NULL)
662 *start_selection = newval_chars;
664 *cursor_position += change_chars;
667 block_list_signals (cell);
668 gnc_item_list_select (box->item_list, match_str);
669 unblock_list_signals (cell);
674 if (match_str == NULL && cell->shared_store)
677 GtkListStore *store = cell->shared_store;
678 match_str = gnc_combo_cell_type_ahead_search (newval, store, cell);
679 *start_selection = newval_chars;
681 *cursor_position = newval_chars;
688 if (match_str == NULL)
690 block_list_signals (cell);
691 if (cell->shared_store && gnc_item_list_using_temp (box->item_list))
693 gnc_item_list_set_temp_store (box->item_list, NULL);
694 gtk_list_store_clear (box->tmp_store);
696 gnc_item_list_select (box->item_list, NULL);
697 unblock_list_signals (cell);
698 gnc_basic_cell_set_value_internal (_cell, newval);
699 *cursor_position = *start_selection = newval_chars;
704 if (!box->list_popped && auto_pop_combos)
706 gnc_item_edit_show_popup (box->item_edit);
707 box->list_popped = TRUE;
710 gnc_basic_cell_set_value_internal (_cell, box_str);
715 gnc_combo_cell_direct_update (BasicCell* bcell,
716 int* cursor_position,
717 int* start_selection,
722 PopBox* box = cell->cell.gui_private;
723 GdkEventKey*
event = gui_data;
724 gboolean keep_on_going = FALSE;
725 gboolean extra_colon;
726 gunichar unicode_value;
728 const char* match_str;
733 if (event->type != GDK_KEY_PRESS)
736 unicode_value = gdk_keyval_to_unicode (event->keyval);
737 switch (event->keyval)
740 if (! (event->state & GDK_MOD1_MASK))
742 if (unicode_value == box->complete_char)
747 keep_on_going = TRUE;
750 case GDK_KEY_ISO_Left_Tab:
751 if (gnc_item_list_using_temp (box->item_list))
754 g_signal_emit_by_name (G_OBJECT (box->item_list),
"change_item",
755 string, (gpointer)bcell);
759 if (! (event->state & GDK_CONTROL_MASK) &&
764 (box->qf, bcell->value, *cursor_position);
769 (match, &prefix_len);
775 if ((match_str != NULL) &&
776 (strncmp (match_str, bcell->value,
777 strlen (bcell->value)) == 0) &&
778 (strcmp (match_str, bcell->value) != 0))
780 gnc_basic_cell_set_value_internal (bcell,
783 block_list_signals (cell);
784 gnc_item_list_select (box->item_list,
786 unblock_list_signals (cell);
789 *cursor_position += prefix_len;
790 *start_selection = *cursor_position;
795 if (box->complete_char == 0)
798 if (unicode_value != box->complete_char)
801 if (event->state & (GDK_CONTROL_MASK | GDK_MOD1_MASK))
804 if ((*cursor_position < bcell->value_chars) &&
805 ((*end_selection < bcell->value_chars) ||
806 (*cursor_position < *start_selection)))
809 if ((*cursor_position == bcell->value_chars) &&
810 (*start_selection != *end_selection) &&
811 (*end_selection < bcell->value_chars))
815 if (*start_selection < bcell->value_chars)
817 int i = *start_selection;
821 c = g_utf8_offset_to_pointer (bcell->value, i);
824 uc = g_utf8_get_char (c);
825 if (uc == box->complete_char)
830 c = g_utf8_next_char (c);
842 new_pos = bcell->value_chars;
847 bcell->value, new_pos);
863 if ((match_str != NULL) &&
864 (strncmp (match_str, bcell->value, strlen (bcell->value)) == 0) &&
865 (strcmp (match_str, bcell->value) != 0))
867 gnc_basic_cell_set_value_internal (bcell, match_str);
869 block_list_signals (cell);
870 gnc_item_list_select (box->item_list, match_str);
871 unblock_list_signals (cell);
874 *cursor_position = new_pos;
875 *start_selection = new_pos;
882 gnc_combo_cell_gui_realize (BasicCell* bcell, gpointer data)
884 GnucashSheet* sheet = data;
885 GncItemEdit* item_edit = gnucash_sheet_get_item_edit (sheet);
887 PopBox* box = cell->cell.gui_private;
891 box->item_edit = item_edit;
892 if (cell->shared_store)
893 box->item_list = GNC_ITEM_LIST (gnc_item_list_new (cell->shared_store));
895 box->item_list = GNC_ITEM_LIST (gnc_item_list_new (box->tmp_store));
896 gtk_widget_show_all (GTK_WIDGET (box->item_list));
897 g_object_ref_sink (box->item_list);
900 cell->cell.gui_realize = NULL;
901 cell->cell.gui_move = gnc_combo_cell_gui_move;
902 cell->cell.enter_cell = gnc_combo_cell_enter;
903 cell->cell.leave_cell = gnc_combo_cell_leave;
904 cell->cell.gui_destroy = gnc_combo_cell_gui_destroy;
905 cell->cell.modify_verify = gnc_combo_cell_modify_verify;
906 cell->cell.direct_update = gnc_combo_cell_direct_update;
910 gnc_combo_cell_gui_move (BasicCell* bcell)
912 PopBox* box = bcell->gui_private;
914 combo_disconnect_signals ((
ComboCell*) bcell);
916 gnc_item_edit_set_popup (box->item_edit, NULL, NULL,
917 NULL, NULL, NULL, NULL, NULL);
919 box->list_popped = FALSE;
923 popup_get_height (GtkWidget* widget,
925 G_GNUC_UNUSED
int row_height,
929 GtkScrolledWindow* scrollwin = GNC_ITEM_LIST(widget)->scrollwin;
933 if (box->item_edit->popup_allocation_height != -1)
934 height = box->item_edit->popup_allocation_height;
936 height = gnc_item_list_get_popup_height (GNC_ITEM_LIST(widget));
938 if (height < space_available)
942 gint ret_height = height ? height : 1;
944 gtk_widget_set_size_request (GTK_WIDGET(scrollwin), -1, ret_height);
945 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollwin),
946 GTK_POLICY_AUTOMATIC, GTK_POLICY_NEVER);
950 gtk_widget_set_size_request (GTK_WIDGET(scrollwin), -1, -1);
952 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollwin),
953 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
954 return space_available;
958 popup_autosize (GtkWidget* widget,
964 if (!box || !box->autosize)
967 return gnc_item_list_autosize (GNC_ITEM_LIST (widget)) + 20;
971 popup_set_focus (GtkWidget* widget,
972 G_GNUC_UNUSED gpointer user_data)
977 if (gnc_item_list_num_entries (GNC_ITEM_LIST (widget)))
978 gtk_widget_grab_focus (GTK_WIDGET (GNC_ITEM_LIST (widget)->tree_view));
982 popup_post_show (GtkWidget* widget,
983 G_GNUC_UNUSED gpointer user_data)
985 gnc_item_list_autosize (GNC_ITEM_LIST (widget));
986 gnc_item_list_show_selected (GNC_ITEM_LIST (widget));
990 popup_get_width (GtkWidget* widget,
991 G_GNUC_UNUSED gpointer user_data)
994 gtk_widget_get_allocation (GTK_WIDGET (GNC_ITEM_LIST (widget)->tree_view),
1000 gnc_combo_cell_enter (BasicCell* bcell,
1001 int* cursor_position,
1002 int* start_selection,
1006 PopBox* box = bcell->gui_private;
1007 PopupToggle popup_toggle;
1011 find = g_list_find_custom (box->ignore_strings,
1013 (GCompareFunc) strcmp);
1017 gnc_item_edit_set_popup (box->item_edit,
1018 GTK_WIDGET (box->item_list),
1019 popup_get_height, popup_autosize,
1020 popup_set_focus, popup_post_show,
1021 popup_get_width, box);
1023 block_list_signals (cell);
1025 if (cell->shared_store && gnc_item_list_using_temp (box->item_list))
1028 gnc_item_list_set_temp_store (box->item_list, NULL);
1029 gtk_list_store_clear (box->tmp_store);
1031 gnc_item_list_select (box->item_list, bcell->value);
1032 unblock_list_signals (cell);
1034 popup_toggle = box->item_edit->popup_toggle;
1037 gtk_widget_set_sensitive (GTK_WIDGET(popup_toggle.tbutton),
1038 gnc_item_list_num_entries (box->item_list));
1040 combo_connect_signals (cell);
1042 *cursor_position = -1;
1043 *start_selection = 0;
1044 *end_selection = -1;
1050 gnc_combo_cell_leave (BasicCell* bcell)
1052 PopBox* box = bcell->gui_private;
1054 combo_disconnect_signals ((
ComboCell*) bcell);
1056 gnc_item_edit_set_popup (box->item_edit, NULL, NULL,
1057 NULL, NULL, NULL, NULL, NULL);
1059 box->list_popped = FALSE;
1065 if (gnc_item_in_list (box->item_list, bcell->value))
1068 if (g_list_find_custom (box->ignore_strings,
1070 (GCompareFunc) strcmp))
1073 gnc_basic_cell_set_value_internal (bcell,
"");
1085 box = cell->cell.gui_private;
1087 box->strict = strict;
1098 box = cell->cell.gui_private;
1100 box->complete_char = complete_char;
1105 const char* ignore_string)
1115 box = cell->cell.gui_private;
1117 box->ignore_strings = g_list_prepend (box->ignore_strings,
1118 g_strdup (ignore_string));
1129 box = cell->cell.gui_private;
1133 box->autosize = autosize;
void gnc_quickfill_insert(QuickFill *qf, const char *text, QuickFillSort sort)
Add the string "text" to the collection of searchable strings.
QuickFill * gnc_quickfill_get_char_match(QuickFill *qf, gunichar uc)
Return the subnode of the tree whose strings all hold 'c' as the next letter.
gulong gnc_prefs_register_cb(const char *group, const gchar *pref_name, gpointer func, gpointer user_data)
Register a callback that gets triggered when the given preference changes.
void gnc_combo_cell_set_sort_enabled(ComboCell *cell, gboolean enabled)
Enable sorting of the menu item's contents.
void gnc_combo_cell_add_ignore_string(ComboCell *cell, const char *ignore_string)
Add a string to a list of strings which, if the cell has that value, will cause the cell to be unedit...
void gnc_combo_cell_set_complete_char(ComboCell *cell, gunichar complete_char)
Sets a character used for special completion processing.
void gnc_combo_cell_add_account_menu_item(ComboCell *cell, char *menustr)
Add a 'account name' menu item to the list.
Account handling public routines.
The ComboCell object implements a cell handler with a "combination-box" pull-down menu in it...
QuickFill * gnc_quickfill_get_string_len_match(QuickFill *qf, const char *str, int len)
Same as gnc_quickfill_get_string_match(), except that the string length is explicitly specified...
void gnc_combo_cell_add_menu_item(ComboCell *cell, const char *menustr)
Add a menu item to the list.
Public Declarations for GncItemList class.
void gnc_combo_cell_set_strict(ComboCell *cell, gboolean strict)
Determines whether the cell will accept strings not in the menu.
QuickFill * gnc_quickfill_get_string_match(QuickFill *qf, const char *str)
Return a subnode in the tree whose strings all match the string 'str' as the next substring...
Public declarations of GnucashRegister class.
Private declarations for GnucashSheet class.
Generic api to store and retrieve preferences.
const char * gnc_quickfill_string(QuickFill *qf)
For the given node 'qf', return the best-guess matching string.
Public declarations for GncItemEdit class.
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Get a boolean value from the preferences backend.
Declarations for the Table object.
QuickFill is used to auto-complete typed user entries.
void gnc_combo_cell_use_quickfill_cache(ComboCell *cell, QuickFill *shared_qf)
Tell the combocell to use a shared QuickFill object.
QuickFill * gnc_quickfill_get_unique_len_match(QuickFill *qf, int *length)
Walk a 'unique' part of the QuickFill tree.
void gnc_combo_cell_set_autosize(ComboCell *cell, gboolean autosize)
Determines whether the popup list autosizes itself or uses all available space.
char * gnc_item_list_get_selection(GncItemList *item_list)
Retrieve the selected string from the item_list's active GtkListStore.
const gchar * gnc_get_account_separator_string(void)
Returns the account separation character chosen by the user.