diff --git a/src/gtk/navbar_versekey.c b/src/gtk/navbar_versekey.c index 2dacd27eb..0da8942e7 100644 --- a/src/gtk/navbar_versekey.c +++ b/src/gtk/navbar_versekey.c @@ -387,6 +387,7 @@ static void on_button_history_back_clicked(GtkButton *button, gpointer user_data static void on_entry_activate(GtkEntry *entry, gpointer user_data) { + gchar *rawtext; const gchar *gkey, *buf = gtk_entry_get_text(entry); if (buf == NULL) @@ -396,6 +397,15 @@ static void on_entry_activate(GtkEntry *entry, gpointer user_data) (settings.special_anchor = strchr(buf, '!'))) /* osisref */ *settings.special_anchor = '\0'; + rawtext = + main_get_raw_text(navbar_versekey.module_name->str, + (gchar *)buf); + + if (!rawtext || (rawtext && (strlen(rawtext) < 2))) { + gtk_entry_set_text(entry, navbar_versekey.key->str); + g_free(rawtext); + return; + } gkey = main_get_valid_key(settings.MainWindowModule, (gchar *)buf); diff --git a/src/gtk/navbar_versekey_parallel.c b/src/gtk/navbar_versekey_parallel.c index 2769f6ab5..49896c928 100644 --- a/src/gtk/navbar_versekey_parallel.c +++ b/src/gtk/navbar_versekey_parallel.c @@ -38,6 +38,8 @@ #include "main/url.hh" #include "gui/debug_glib_null.h" +#include "main/xml.h" +#include "gui/preferences_dialog.h" NAVBAR_VERSEKEY navbar_parallel; gboolean sync_on; @@ -797,6 +799,99 @@ static void _connect_signals(NAVBAR_VERSEKEY navbar) #endif } +static void on_parallel_set_activate(GtkMenuItem *item, gpointer user_data) +{ + gchar *name = (gchar *)user_data; + gchar **modules; + + modules = get_parallel_set(name); + if (!modules) { + g_free(name); + return; + } + + g_strfreev(settings.parallel_list); + settings.parallel_list = modules; + + if (settings.parallel_set_current) + g_free(settings.parallel_set_current); + settings.parallel_set_current = g_strdup(name); + xml_set_or_create_value("modules", "parallel_set_current", name); + /* update Sets button label */ + gchar *label = g_strdup_printf(_("Set: %s"), name); + gtk_button_set_label(GTK_BUTTON(navbar_parallel.button_sets), label); + g_free(label); + xml_save_settings_doc(settings.fnconfigure); + + main_update_parallel_page(); + if (!settings.dockedInt && settings.parallel_list && settings.parallel_list[0]) { + gui_navbar_parallel_set_module(settings.parallel_list[0]); + settings.cvparallel = settings.currentverse; + main_update_parallel_page_detached(); + } + + g_free(name); +} + +static void on_parallel_sets_manage_clicked(GtkMenuItem *item, + gpointer user_data) +{ + gui_setup_preferences_dialog(); + gui_prefs_goto_parallel_page(); +} + +/****************************************************************************** + * Name + * on_parallel_sets_button_clicked + * + * Description + * show popup menu of saved parallel sets + * + * Return value + * void + */ +static void on_parallel_sets_button_clicked(GtkWidget *widget, + gpointer user_data) +{ + GtkWidget *menu, *item; + gchar **names; + + if (!settings.parallel_set_names || !*settings.parallel_set_names) + return; + + menu = gtk_menu_new(); + names = g_strsplit(settings.parallel_set_names, ",", -1); + + for (gint i = 0; names[i]; ++i) { + item = gtk_menu_item_new_with_label(names[i]); + g_signal_connect(G_OBJECT(item), "activate", + G_CALLBACK(on_parallel_set_activate), + g_strdup(names[i])); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); + gtk_widget_show(item); + } + g_strfreev(names); + + /* separator + Manage */ + gtk_menu_shell_append(GTK_MENU_SHELL(menu), + gtk_separator_menu_item_new()); + item = gtk_menu_item_new_with_label(_("Manage...")); + g_signal_connect(G_OBJECT(item), "activate", + G_CALLBACK(on_parallel_sets_manage_clicked), NULL); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); + gtk_widget_show_all(menu); + + #if GTK_CHECK_VERSION(3, 22, 0) + gtk_menu_popup_at_widget(GTK_MENU(menu), widget, + GDK_GRAVITY_SOUTH_WEST, + GDK_GRAVITY_NORTH_WEST, NULL); + #else + gtk_menu_popup(GTK_MENU(menu), NULL, NULL, + menu_position_under, widget, 0, + gtk_get_current_event_time()); + #endif +} + /****************************************************************************** * Name * @@ -921,6 +1016,18 @@ GtkWidget *gui_navbar_versekey_parallel_new(void) _connect_signals(navbar_parallel); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(navbar_parallel.button_sync), settings.linkedtabs); + /* parallel sets button */ + gchar *sets_label = g_strdup_printf(_("Set: %s"), + settings.parallel_set_current ? settings.parallel_set_current : "—"); + GtkWidget *button_sets = gtk_button_new_with_label(sets_label); + g_free(sets_label); + gtk_widget_set_tooltip_text(button_sets, _("Switch parallel module set")); + gtk_widget_show(button_sets); + navbar_parallel.button_sets = button_sets; + g_signal_connect(G_OBJECT(button_sets), "clicked", + G_CALLBACK(on_parallel_sets_button_clicked), NULL); + gtk_box_pack_end(GTK_BOX(navbar_parallel.navbar), button_sets, + FALSE, FALSE, 2); return navbar_parallel.navbar; } diff --git a/src/gtk/preferences_dialog.c b/src/gtk/preferences_dialog.c index 6b0d042e3..2e9ff5d5d 100644 --- a/src/gtk/preferences_dialog.c +++ b/src/gtk/preferences_dialog.c @@ -173,6 +173,9 @@ struct _parallel_select GtkWidget *mod_sel_close; GtkWidget *mod_sel_add; GtkWidget *mod_sel_treeview; + GtkWidget *sets_combo; + GtkWidget *sets_hbox; + GtkWidget *sets_delete_btn; /* button to delete current set */ }; static GtkWidget *dialog_prefs = NULL; @@ -2841,10 +2844,17 @@ static void ps_setup_listview() GtkListStore *list_store; int i; + /* remove existing columns */ + { + GtkTreeViewColumn *col; + while ((col = gtk_tree_view_get_column( + GTK_TREE_VIEW(parallel_select.listview), 0)) != NULL) + gtk_tree_view_remove_column( + GTK_TREE_VIEW(parallel_select.listview), col); + } model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING); gtk_tree_view_set_model(GTK_TREE_VIEW(parallel_select.listview), GTK_TREE_MODEL(model)); - for (i = 0; i < 2; ++i) { GtkCellRenderer *renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes("Module", @@ -3009,6 +3019,10 @@ static void on_mod_sel_add_clicked(GtkWidget *button, gchar *user_data) if (*parallels) { *(parallels + strlen(parallels) - 1) = '\0'; /* end comma */ xml_set_value("Xiphos", "modules", "parallels", parallels); + /* also save into the active parallel set */ + if (settings.parallel_set_current && *settings.parallel_set_current) + save_parallel_set(settings.parallel_set_current, settings.parallel_list); + xml_save_settings_doc(settings.fnconfigure); } g_free(parallels); } @@ -3064,9 +3078,13 @@ static void on_parallel_reordered(GtkTreeModel *model, g_string_append_c(parallels, ','); g_string_append(parallels, settings.parallel_list[i]); } + xml_set_value("Xiphos", "modules", "parallels", parallels->str); + /* also save into the active parallel set */ + if (settings.parallel_set_current && *settings.parallel_set_current) + save_parallel_set(settings.parallel_set_current, settings.parallel_list); + xml_save_settings_doc(settings.fnconfigure); g_string_free(parallels, TRUE); - g_list_free_full(items, g_free); } @@ -3147,7 +3165,11 @@ void ps_button_cut(GtkButton *button, gpointer user_data) #else if (gui_yes_no_dialog(str, GTK_STOCK_DIALOG_WARNING)) { #endif + g_signal_handlers_block_by_func( + model, on_parallel_reordered, NULL); gtk_list_store_remove(list_store, &selected); + g_signal_handlers_unblock_by_func( + model, on_parallel_reordered, NULL); GList *mods = get_current_list(GTK_TREE_VIEW(parallel_select.listview)); gchar *mod_list = get_modlist_string(mods); @@ -3163,6 +3185,10 @@ void ps_button_cut(GtkButton *button, gpointer user_data) } } xml_set_value("Xiphos", "modules", "parallels", mod_list); + /* also save into the active parallel set */ + if (settings.parallel_set_current && *settings.parallel_set_current) + save_parallel_set(settings.parallel_set_current, settings.parallel_list); + xml_save_settings_doc(settings.fnconfigure); g_free(mod_list); if (settings.parallel_list && settings.parallel_list[0]) gui_navbar_parallel_set_module(settings.parallel_list[0]); @@ -3221,6 +3247,203 @@ void ps_button_add(GtkButton *button, gpointer user_data) g_free(glade_file); } +static void on_parallel_sets_combo_changed(GtkComboBox *combo, + gpointer user_data) +{ + gchar *name = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(combo)); + + if (!name) + return; + + if (g_strcmp0(name, _("New set...")) == 0) { + /* dialog to enter new set name */ + GtkWidget *dialog = gtk_dialog_new_with_buttons( + _("New Parallel Set"), + GTK_WINDOW(dialog_prefs), + GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, + _("Cancel"), GTK_RESPONSE_CANCEL, + _("Create"), GTK_RESPONSE_OK, + NULL); + GtkWidget *content = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); + GtkWidget *hbox; + UI_HBOX(hbox, FALSE, 6); + GtkWidget *label = gtk_label_new(_("Set name:")); + GtkWidget *entry = gtk_entry_new(); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 6); + gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 6); + gtk_box_pack_start(GTK_BOX(content), hbox, FALSE, FALSE, 6); + gtk_widget_show_all(dialog); + + if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) { + const gchar *setname = gtk_entry_get_text(GTK_ENTRY(entry)); + if (setname && *setname) { + /* build new set_names */ + gchar *new_names; + if (settings.parallel_set_names && *settings.parallel_set_names) + new_names = g_strdup_printf("%s,%s", + settings.parallel_set_names, setname); + else + new_names = g_strdup(setname); + + g_free(settings.parallel_set_names); + settings.parallel_set_names = new_names; + xml_set_or_create_value("modules", "parallel_set_names", new_names); + + /* save current parallel_list as the new set */ + if (settings.parallel_list) + save_parallel_set(setname, settings.parallel_list); + + /* switch to new set */ + g_free(settings.parallel_set_current); + settings.parallel_set_current = g_strdup(setname); + xml_set_or_create_value("modules", "parallel_set_current", setname); + xml_save_settings_doc(settings.fnconfigure); + + /* rebuild combo */ + g_signal_handlers_block_by_func( + parallel_select.sets_combo, + on_parallel_sets_combo_changed, NULL); + #if GTK_CHECK_VERSION(3, 0, 0) + gtk_combo_box_text_remove_all( + GTK_COMBO_BOX_TEXT(parallel_select.sets_combo)); + #else + { + GtkTreeModel *m = gtk_combo_box_get_model( + GTK_COMBO_BOX(parallel_select.sets_combo)); + gtk_list_store_clear(GTK_LIST_STORE(m)); + } + #endif + gchar **names = g_strsplit(settings.parallel_set_names, ",", -1); + for (gint i = 0; names[i]; ++i) + gtk_combo_box_text_append_text( + GTK_COMBO_BOX_TEXT(parallel_select.sets_combo), + names[i]); + g_strfreev(names); + gtk_combo_box_text_append_text( + GTK_COMBO_BOX_TEXT(parallel_select.sets_combo), + _("New set...")); + /* select the new set */ + gchar **all = g_strsplit(settings.parallel_set_names, ",", -1); + for (gint i = 0; all[i]; ++i) { + if (g_strcmp0(all[i], setname) == 0) { + gtk_combo_box_set_active( + GTK_COMBO_BOX(parallel_select.sets_combo), i); + break; + } + } + g_strfreev(all); + g_signal_handlers_unblock_by_func( + parallel_select.sets_combo, + on_parallel_sets_combo_changed, NULL); + } + } + gtk_widget_destroy(dialog); + g_free(name); + return; + } + + /* the active set is saved automatically by on_parallel_reordered */ + /* load the new set */ + gchar **modules = get_parallel_set(name); + if (modules) { + g_strfreev(settings.parallel_list); + settings.parallel_list = modules; + } + + if (settings.parallel_set_current) + g_free(settings.parallel_set_current); + settings.parallel_set_current = name; + xml_set_or_create_value("modules", "parallel_set_current", name); + xml_save_settings_doc(settings.fnconfigure); + + /* refresh listview */ + ps_setup_listview(); + + /* refresh parallel view */ + main_update_parallel_page(); + if (!settings.dockedInt && settings.parallel_list && settings.parallel_list[0]) { + gui_navbar_parallel_set_module(settings.parallel_list[0]); + settings.cvparallel = settings.currentverse; + main_update_parallel_page_detached(); + } +} + +static void on_parallel_set_delete_clicked(GtkWidget *btn, gpointer user_data) +{ + gchar *name = gtk_combo_box_text_get_active_text( + GTK_COMBO_BOX_TEXT(parallel_select.sets_combo)); + + if (!name || g_strcmp0(name, _("New set...")) == 0) { + g_free(name); + return; + } + + /* remove from set_names */ + gchar **names = g_strsplit(settings.parallel_set_names, ",", -1); + GString *new_names = g_string_new(""); + for (gint i = 0; names[i]; ++i) { + if (g_strcmp0(names[i], name) != 0) { + if (new_names->len > 0) + g_string_append_c(new_names, ','); + g_string_append(new_names, names[i]); + } + } + g_strfreev(names); + + g_free(settings.parallel_set_names); + settings.parallel_set_names = g_string_free(new_names, FALSE); + xml_set_or_create_value("modules", "parallel_set_names", + settings.parallel_set_names); + + /* remove the set key */ + gchar *key = g_strdup_printf("parallel_set_%s", name); + xml_remove_node("modules", key, NULL); + g_free(key); + + /* reset current if needed */ + if (g_strcmp0(settings.parallel_set_current, name) == 0) { + g_free(settings.parallel_set_current); + settings.parallel_set_current = NULL; + xml_set_or_create_value("modules", "parallel_set_current", ""); + } + + xml_save_settings_doc(settings.fnconfigure); + + /* rebuild combo */ + g_signal_handlers_block_by_func(parallel_select.sets_combo, + on_parallel_sets_combo_changed, NULL); +#if GTK_CHECK_VERSION(3, 0, 0) + gtk_combo_box_text_remove_all( + GTK_COMBO_BOX_TEXT(parallel_select.sets_combo)); +#else + { + GtkTreeModel *m = gtk_combo_box_get_model( + GTK_COMBO_BOX(parallel_select.sets_combo)); + gtk_list_store_clear(GTK_LIST_STORE(m)); + } +#endif + if (settings.parallel_set_names && *settings.parallel_set_names) { + gchar **all = g_strsplit(settings.parallel_set_names, ",", -1); + for (gint i = 0; all[i]; ++i) + gtk_combo_box_text_append_text( + GTK_COMBO_BOX_TEXT(parallel_select.sets_combo), all[i]); + g_strfreev(all); + } + gtk_combo_box_text_append_text( + GTK_COMBO_BOX_TEXT(parallel_select.sets_combo), _("New set...")); + gtk_combo_box_set_active(GTK_COMBO_BOX(parallel_select.sets_combo), 0); + g_signal_handlers_unblock_by_func(parallel_select.sets_combo, + on_parallel_sets_combo_changed, NULL); + + g_free(name); +} + +void gui_prefs_goto_parallel_page(void) +{ + if (notebook) + gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), 6); +} + /****************************************************************************** * Name * gui_create_preferences_dialog @@ -3471,6 +3694,54 @@ static void create_preferences_dialog(void) G_CALLBACK(ps_button_add), NULL); ps_setup_listview(); + { + GtkWidget *vbox10 = UI_GET_ITEM(gxml, "vbox10"); + GtkWidget *hbox; + UI_HBOX(hbox, FALSE, 6); + GtkWidget *label = gtk_label_new(_("Set:")); + GtkWidget *combo = gtk_combo_box_text_new(); + + parallel_select.sets_hbox = hbox; + parallel_select.sets_combo = combo; + + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(hbox), combo, TRUE, TRUE, 0); + GtkWidget *btn_del = gtk_button_new_with_label("[-]"); + gtk_widget_set_tooltip_text(btn_del, _("Delete current set")); + parallel_select.sets_delete_btn = btn_del; + gtk_box_pack_start(GTK_BOX(hbox), btn_del, FALSE, FALSE, 0); + g_signal_connect(btn_del, "clicked", + G_CALLBACK(on_parallel_set_delete_clicked), NULL); + gtk_widget_show_all(hbox); + + /* populate with existing set names */ + if (settings.parallel_set_names && *settings.parallel_set_names) { + gchar **names = g_strsplit(settings.parallel_set_names, ",", -1); + for (gint i = 0; names[i]; ++i) + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), names[i]); + g_strfreev(names); + } + /* add "New set..." entry */ + gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), _("New set...")); + + /* select current set */ + if (settings.parallel_set_current) { + gchar **names = g_strsplit(settings.parallel_set_names ? settings.parallel_set_names : "", ",", -1); + for (gint i = 0; names[i]; ++i) { + if (g_strcmp0(names[i], settings.parallel_set_current) == 0) { + gtk_combo_box_set_active(GTK_COMBO_BOX(combo), i); + break; + } + } + g_strfreev(names); + } + + g_signal_connect(combo, "changed", + G_CALLBACK(on_parallel_sets_combo_changed), NULL); + + gtk_box_pack_start(GTK_BOX(vbox10), hbox, FALSE, FALSE, 0); + gtk_box_reorder_child(GTK_BOX(vbox10), hbox, 0); + } /* enable drag-and-drop reordering of parallel versions */ gtk_tree_view_set_reorderable(GTK_TREE_VIEW(parallel_select.listview), TRUE); diff --git a/src/gui/preferences_dialog.h b/src/gui/preferences_dialog.h index 41f568a7c..b32e59c8f 100644 --- a/src/gui/preferences_dialog.h +++ b/src/gui/preferences_dialog.h @@ -169,6 +169,7 @@ void ps_close(GtkButton *button, gpointer user_data); void ps_button_clear(GtkButton *button, gpointer user_data); void ps_button_cut(GtkButton *button, gpointer user_data); void ps_button_add(GtkButton *button, gpointer user_data); +void gui_prefs_goto_parallel_page(void); #ifdef __cplusplus } diff --git a/src/main/navbar.cc b/src/main/navbar.cc index 6418f02f7..e8d2933a9 100644 --- a/src/main/navbar.cc +++ b/src/main/navbar.cc @@ -77,6 +77,14 @@ void main_navbar_set(NAVBAR navbar, const char *key) vkey->setAutoNormalize(1); vkey->setText(key); + fprintf(stderr, + "DEBUG navbar: module=%s key_in=%s testament=%d book=%d chapter=%d/%d verse=%d/%d text=%s\n", + navbar.module_name, key, + vkey->getTestament(), vkey->getBook(), + vkey->getChapter(), vkey->getChapterMax(), + vkey->getVerse(), vkey->getVerseMax(), + vkey->getText()); + // we need the book index to highlight "active" in the pulldown. if ((backend->module_has_testament(navbar.module_name, 1)) && (vkey->getTestament() == 2)) book = vkey->BMAX[0] + vkey->getBook(); diff --git a/src/main/navbar_versekey.h b/src/main/navbar_versekey.h index 1e0c04690..623590217 100644 --- a/src/main/navbar_versekey.h +++ b/src/main/navbar_versekey.h @@ -79,6 +79,7 @@ struct _navbar_versekey GtkWidget *verse_menu; GtkWidget *lookup_entry; + GtkWidget *button_sets; /* Sets menu button with current set name */ //GtkTooltips *tooltips; GString *key; gchar *book; diff --git a/src/main/settings.c b/src/main/settings.c index 999ade93c..68405ab45 100644 --- a/src/main/settings.c +++ b/src/main/settings.c @@ -422,7 +422,18 @@ void load_settings_structure(void) else settings.parallel_list = NULL; g_free(parallels); - + /* parallel sets */ + settings.parallel_set_names = xml_get_value("modules", "parallel_set_names"); + settings.parallel_set_current = xml_get_value("modules", "parallel_set_current"); + settings.parallel_set_current = xml_get_value("modules", "parallel_set_current"); + /* load active parallel set at startup */ + if (settings.parallel_set_current && *settings.parallel_set_current) { + char **set_modules = get_parallel_set(settings.parallel_set_current); + if (set_modules) { + g_strfreev(settings.parallel_list); + settings.parallel_list = set_modules; + } + } settings.personalcommentsmod = xml_get_value("modules", "percomm"); settings.devotionalmod = xml_get_value("modules", "devotional"); settings.book_mod = xml_get_value("modules", "book"); @@ -1199,4 +1210,73 @@ if (!settings.morph_heb_lex || strlen(settings.morph_heb_lex) == 0) { settings.browsing = 1; } #endif + } +/****************************************************************************** + * Name + * get_parallel_set + * + * Synopsis + * #include "main/settings.h" + * + * gchar **get_parallel_set(const char *name) + * + * Description + * Return the module list for a named parallel set, as a NULL-terminated + * array of strings (g_strsplit result). Caller must g_strfreev() the result. + * Returns NULL if the set does not exist. + * + * Return value + * gchar ** or NULL + */ +char **get_parallel_set(const gchar *name) +{ + char *key, *value; + + if (!name || !*name) + return NULL; + + key = g_strdup_printf("parallel_set_%s", name); + value = xml_get_value("modules", key); + g_free(key); + + if (!value || !*value) { + g_free(value); + return NULL; + } + + char **result = g_strsplit(value, ",", -1); + g_free(value); + return result; +} + +/****************************************************************************** + * Name + * save_parallel_set + * + * Synopsis + * #include "main/settings.h" + * + * void save_parallel_set(const gchar *name, char **modules) + * + * Description + * Save a named parallel set to settings.conf. + * modules is a NULL-terminated array of module name strings. + * + * Return value + * void + */ +void save_parallel_set(const gchar *name, gchar **modules) +{ + char *key, *value; + + if (!name || !*name || !modules) + return; + + key = g_strdup_printf("parallel_set_%s", name); + value = g_strjoinv(",", modules); + xml_set_or_create_value("modules", key, value); + g_free(key); + g_free(value); +} + diff --git a/src/main/settings.h b/src/main/settings.h index 124d58a7e..9541250eb 100644 --- a/src/main/settings.h +++ b/src/main/settings.h @@ -35,6 +35,8 @@ struct _settings *CommWindowModule, /* module to open at program startup */ *DictWindowModule, /* module to open at program startup */ **parallel_list, /* strsplit result from xml parallels */ + *parallel_set_names, /* comma-separated list of saved parallel set names */ + *parallel_set_current, /* name of the currently active parallel set */ *personalcommentsmod, /* module to open at program startup */ sb_search_mod[80], /* module for sidebar search */ *devotionalmod, /* module for devotional */ @@ -246,6 +248,8 @@ extern SETTINGS settings; int settings_init(int argc, char **argv, int new_configs, int new_bookmarks); void load_settings_structure(void); +char **get_parallel_set(const char *name); +void save_parallel_set(const char *name, char **modules); #ifdef __cplusplus } diff --git a/src/main/xml.c b/src/main/xml.c index ab1fce48f..75b9d8996 100644 --- a/src/main/xml.c +++ b/src/main/xml.c @@ -1544,6 +1544,35 @@ void xml_set_value(const char *type_doc, const char *section, } } +/****************************************************************************** + * Name + * xml_set_or_create_value + * + * Synopsis + * #include "main/xml.h" + * + * void xml_set_or_create_value(const char *section, const char *item, + * const char *value) + * + * Description + * Set an existing node's content (even if empty) or create it if absent. + * + * Return value + * void + */ +void xml_set_or_create_value(const char *section, const char *item, + const char *value) +{ + xmlNodePtr cur = + xml_find_prop(xml_settings_doc, "Xiphos", section, item); + if (cur) + xmlNodeSetContent(cur, (const xmlChar *)value); + else + xml_add_new_item_to_section((char *)section, + (char *)item, + (char *)value); +} + /****************************************************************************** * Name * xml_parse_settings_file diff --git a/src/main/xml.h b/src/main/xml.h index d9ccd11a9..ed486938c 100644 --- a/src/main/xml.h +++ b/src/main/xml.h @@ -79,6 +79,8 @@ void xml_remove_node(const char *section, const char *item, const char *label); void xml_remove_section(const char *section); void xml_convert_to_osisref(void); +void xml_set_or_create_value(const char *section, const char *item, + const char *value); #ifdef __cplusplus }