void XI_g_string_printf(const char *filename, int linenumber, GString *string, const gchar *format, ...) { gchar *s; va_list args; va_start(args, format); for (s = strchr(format, '%'); s; s = strchr(++s, '%')) { gchar *next = va_arg(args, gchar *); if ((next == (gchar *)NULL) && (*(s + 1) == 's')) { gchar *msg = g_strdup_printf("%s\n%s\n\n%s:%d \"%s\"", _("BUG! Xiphos is about to crash due to a \"STRING\" error."), _("Please report this error to the Xiphos team with:"), filename, linenumber, format); gui_generic_warning_modal(msg); g_free(msg); abort(); } } va_end(args); /* real g_string_printf content */ g_string_truncate(string, 0); va_start(args, format); g_string_append_vprintf(string, format, args); va_end(args); }
G_MODULE_EXPORT void on_rename_perscomm_activate(GtkMenuItem *menuitem, gpointer user_data) { if (is_dialog) return; #if defined(WIN32) gui_generic_warning(_("Renaming is not available in Windows.\n\n" "Xiphos is limited by Windows' filesystem,\n" "because it disallows the renaming of filename\n" "components of currently-open files,\n" "such as the contents of this commentary.\n" "Therefore, personal commentary renaming is\n" "not available in the Windows environment.")); #else GS_DIALOG *info; GString *workstr; char *s; char *datapath_old, *datapath_new; const char *conf_old; char *conf_new; char *sworddir, *modsdir; FILE *result; // get a new name for the module. info = gui_new_dialog(); info->title = _("Rename Commentary"); workstr = g_string_new(""); g_string_printf(workstr, "<span weight=\"bold\">%s</span>", _("Choose Commentary Name")); info->label_top = workstr->str; info->text1 = g_strdup(_("New Name")); info->label1 = N_("Name: "); info->ok = TRUE; info->cancel = TRUE; if (gui_gs_dialog(info) != GS_OK) goto out1; for (s = info->text1; *s; ++s) { if (!isalnum(*s) && (*s != '_')) { gui_generic_warning_modal(_("Module names must contain [A-Za-z0-9_] only.")); goto out1; } } if (main_is_module(info->text1)) { gui_generic_warning_modal(_("Xiphos already knows a module by that name.")); goto out1; } sworddir = g_strdup_printf("%s/" DOTSWORD, settings.homedir); modsdir = g_strdup_printf("%s/mods.d", sworddir); conf_old = main_get_mod_config_file(settings.CommWindowModule, sworddir); conf_new = g_strdup(info->text1); // dirname is lowercase. for (s = conf_new; *s; ++s) if (isupper(*s)) *s = tolower(*s); datapath_old = main_get_mod_config_entry(settings.CommWindowModule, "DataPath"); datapath_new = g_strdup(datapath_old); if ((s = strstr(datapath_new, "rawfiles/")) == NULL) { gui_generic_warning_modal("Malformed datapath in old configuration!"); goto out2; } *(s + 9) = '\0'; // skip past "rawfiles/". s = g_strdup_printf("%s%s", datapath_new, conf_new); g_free(datapath_new); // out with the old... datapath_new = s; // ..and in with the new. // move old data directory to new. if ((g_chdir(sworddir) != 0) || (rename(datapath_old, datapath_new) != 0)) { gui_generic_warning_modal("Failed to rename directory."); goto out2; } // manufacture new .conf from old. g_string_printf(workstr, "( cd \"%s\" && sed -e '/^\\[/s|^.*$|[%s]|' -e '/^DataPath=/s|rawfiles/.*$|rawfiles/%s/|' < \"%s\" > \"%s.conf\" ) 2>&1", modsdir, info->text1, conf_new, conf_old, conf_new); if ((result = popen(workstr->str, "r")) == NULL) { g_string_printf(workstr, _("Failed to create new configuration:\n%s"), strerror(errno)); gui_generic_warning_modal(workstr->str); goto out2; } else { gchar output[258]; if (fgets(output, 256, result) != NULL) { g_string_truncate(workstr, 0); g_string_append(workstr, _("Configuration build error:\n\n")); g_string_append(workstr, output); gui_generic_warning_modal(workstr->str); goto out2; // necessary? advisable? } pclose(result); } // unlink old conf. g_string_printf(workstr, "%s/%s", modsdir, conf_old); if (unlink(workstr->str) != 0) { g_string_printf(workstr, "Unlink of old configuration failed:\n%s", strerror(errno)); gui_generic_warning_modal(workstr->str); goto out2; } main_update_module_lists(); settings.CommWindowModule = g_strdup(info->text1); main_display_commentary(info->text1, settings.currentverse); out2: g_free(conf_new); g_free((char *)conf_old); g_free(datapath_old); g_free(datapath_new); g_free(modsdir); g_free(sworddir); out1: g_free(info->text1); g_free(info); g_string_free(workstr, TRUE); #endif /* !WIN32 */ }
static void _save_off_tab(const gchar *filename) { xmlDocPtr xml_doc; xmlNodePtr root_node; xmlNodePtr cur_node; xmlNodePtr section_node; //xmlAttrPtr xml_attr; gchar *tabs_dir; gchar *file; if (NULL == filename) filename = no_tab_filename; tabs_dir = g_strdup_printf("%s/tabs/", settings.gSwordDir); if (g_access(tabs_dir, F_OK) == -1) { if ((g_mkdir(tabs_dir, S_IRWXU)) == -1) { gui_generic_warning_modal("Can't create tabs dir."); return; } } file = g_strdup_printf("%s%s", tabs_dir, filename); g_free(tabs_dir); xml_doc = xmlNewDoc((const xmlChar *)"1.0"); if (xml_doc == NULL) { gui_generic_warning_modal("Tabs document not created successfully."); return; } root_node = xmlNewNode(NULL, (const xmlChar *)"Xiphos_Tabs"); //xml_attr = xmlNewProp(root_node, (const xmlChar *)"Version", (const xmlChar *)VERSION); xmlDocSetRootElement(xml_doc, root_node); section_node = xmlNewChild(root_node, NULL, (const xmlChar *)"tabs", NULL); cur_node = xmlNewChild(section_node, NULL, (const xmlChar *)"tab", NULL); xmlNewProp(cur_node, (const xmlChar *)"text_mod", (const xmlChar *)settings.MainWindowModule); xmlNewProp(cur_node, (const xmlChar *)"commentary_mod", (const xmlChar *)settings.CommWindowModule); xmlNewProp(cur_node, (const xmlChar *)"dictlex_mod", (const xmlChar *)settings.DictWindowModule); xmlNewProp(cur_node, (const xmlChar *)"book_mod", (const xmlChar *)settings.book_mod); xmlNewProp(cur_node, (const xmlChar *)"text_commentary_key", (const xmlChar *)settings.currentverse); xmlNewProp(cur_node, (const xmlChar *)"dictlex_key", (const xmlChar *)settings.dictkey); xmlNewProp(cur_node, (const xmlChar *)"book_offset", (const xmlChar *)settings.book_key); xmlNewProp(cur_node, (const xmlChar *)"comm_showing", (const xmlChar *) true_false2yes_no(settings.comm_showing)); xmlNewProp(cur_node, (const xmlChar *)"showtexts", (const xmlChar *) true_false2yes_no(settings.showtexts)); xmlNewProp(cur_node, (const xmlChar *)"showpreview", (const xmlChar *) true_false2yes_no(settings.showpreview)); xmlNewProp(cur_node, (const xmlChar *)"showcomms", (const xmlChar *) true_false2yes_no(settings.showcomms)); xmlNewProp(cur_node, (const xmlChar *)"showdicts", (const xmlChar *) true_false2yes_no(settings.showdicts)); xmlNewProp(cur_node, (const xmlChar *)"showparallel", (const xmlChar *)"no"); xmlSaveFormatFile(file, xml_doc, 1); g_free(file); xmlFreeDoc(xml_doc); }
void gui_load_tabs(const gchar *filename) { xmlDocPtr xml_doc; xmlNodePtr tmp_node, childnode; //const xmlChar *xml_filename; gboolean error = FALSE; gboolean back_compat_need_save = FALSE; settings.showparatab = FALSE; PASSAGE_TAB_INFO *pt = NULL, *pt_first = NULL; stop_refresh = TRUE; if (filename == NULL) { error = TRUE; } else { gchar *file; if (g_access(filename, F_OK) == 0) { /* we're done, just copy for local use that can be free'd */ file = g_strdup(filename); } else { gchar *tabs_dir = g_strdup_printf("%s/tabs/", settings.gSwordDir); if (g_access(tabs_dir, F_OK) == -1) { XI_message(("Creating new tabs directory\n")); gui_save_tabs(filename); } file = g_strdup_printf("%s%s", tabs_dir, filename); g_free(tabs_dir); } /* we need this for first time non tabbed browsing */ if (!settings.browsing && g_access(file, F_OK) == -1) { _save_off_tab(filename); } //xml_filename = (const xmlChar *) file; xml_doc = xmlParseFile(file); g_free(file); if (xml_doc == NULL) { gui_generic_warning_modal("Tabs document not parsed successfully."); error = TRUE; } else { tmp_node = xmlDocGetRootElement(xml_doc); if (tmp_node == NULL) { gui_generic_warning_modal("Tabs document is empty."); xmlFreeDoc(xml_doc); error = TRUE; } else if (xmlStrcmp(tmp_node->name, (const xmlChar *)"Xiphos_Tabs")) { gui_generic_warning_modal("Tabs document has wrong type, root node != Xiphos_Tabs"); xmlFreeDoc(xml_doc); error = TRUE; } } if (error == FALSE) { for (childnode = tmp_node->children; childnode != NULL; childnode = childnode->next) { if (!xmlStrcmp(childnode->name, (const xmlChar *)"tabs")) { tmp_node = childnode; for (tmp_node = tmp_node->children; tmp_node != NULL; tmp_node = tmp_node->next) { if (!xmlStrcmp(tmp_node->name, (const xmlChar *)"tab")) { gchar *val; pt = g_new0(PASSAGE_TAB_INFO, 1); if (pt_first == NULL) pt_first = pt; /* load per-tab module information. */ val = (gchar *) xmlGetProp(tmp_node, (const xmlChar *)"text_mod"); pt->text_mod = g_strdup(val); xmlFree(val); val = (gchar *) xmlGetProp(tmp_node, (const xmlChar *)"commentary_mod"); pt->commentary_mod = g_strdup(val); xmlFree(val); val = (gchar *) xmlGetProp(tmp_node, (const xmlChar *)"dictlex_mod"); pt->dictlex_mod = g_strdup(val); xmlFree(val); val = (gchar *) xmlGetProp(tmp_node, (const xmlChar *)"book_mod"); pt->book_mod = g_strdup(val); xmlFree(val); val = (gchar *) xmlGetProp(tmp_node, (const xmlChar *)"text_commentary_key"); pt->text_commentary_key = g_strdup(val); xmlFree(val); val = (gchar *) xmlGetProp(tmp_node, (const xmlChar *)"dictlex_key"); pt->dictlex_key = g_strdup(val); xmlFree(val); val = (gchar *) xmlGetProp(tmp_node, (const xmlChar *)"book_offset"); pt->book_offset = g_strdup(val); xmlFree(val); val = (gchar *) xmlGetProp(tmp_node, (const xmlChar *)"comm_showing"); pt->comm_showing = yes_no2true_false(val); xmlFree(val); val = (gchar *) xmlGetProp(tmp_node, (const xmlChar *)"showparallel"); pt->showparallel = yes_no2true_false(val); xmlFree(val); if (pt->showparallel) { settings.showparatab = TRUE; pt->paratab = gui_create_parallel_tab(); gtk_box_pack_start(GTK_BOX(widgets.page), pt->paratab, TRUE, TRUE, 0); gtk_widget_hide(pt->paratab); gui_parallel_tab_sync((gchar *) settings.currentverse); settings.showparatab = TRUE; sync_on = TRUE; } else pt->paratab = NULL; /* * load per-tab "show" state. * includes backward compatibility: * if there is no per-tab state, * take tab state from global state. */ if ((val = (gchar *) xmlGetProp(tmp_node, (const xmlChar *)"showtexts"))) { pt->showtexts = yes_no2true_false(val); xmlFree(val); val = (gchar *) xmlGetProp(tmp_node, (const xmlChar *)"showpreview"); pt->showpreview = yes_no2true_false(val); xmlFree(val); val = (gchar *) xmlGetProp(tmp_node, (const xmlChar *)"showcomms"); pt->showcomms = yes_no2true_false(val); xmlFree(val); val = (gchar *) xmlGetProp(tmp_node, (const xmlChar *)"showdicts"); pt->showdicts = yes_no2true_false(val); xmlFree(val); } else { pt->showtexts = settings.showtexts; pt->showpreview = settings.showpreview; pt->showcomms = settings.showcomms; pt->showdicts = settings.showdicts; back_compat_need_save = TRUE; } pt->history_items = 0; pt->current_history_item = 0; pt->first_back_click = TRUE; main_add_tab_history_item((PASSAGE_TAB_INFO *)pt); gui_reassign_strdup(&settings.currentverse, pt->text_commentary_key); passage_list = g_list_append(passage_list, (PASSAGE_TAB_INFO *)pt); notebook_main_add_page(pt); } } } } } xmlFreeDoc(xml_doc); /* backward compatibility completion. */ if (back_compat_need_save) gui_save_tabs(filename); if (error == TRUE || pt == NULL) { pt = g_new0(PASSAGE_TAB_INFO, 1); pt->text_mod = g_strdup(settings.MainWindowModule); pt->commentary_mod = g_strdup(settings.CommWindowModule); pt->dictlex_mod = g_strdup(settings.DictWindowModule); pt->book_mod = g_strdup(settings.book_mod); //NULL; pt->text_commentary_key = g_strdup(settings.currentverse); pt->dictlex_key = g_strdup(settings.dictkey); pt->book_offset = NULL; //settings.book_offset = atol(xml_get_value( "keys", "offset")); pt->paratab = NULL; pt->showtexts = settings.showtexts; pt->showpreview = settings.showpreview; pt->showcomms = settings.showcomms; pt->showdicts = settings.showdicts; pt->history_items = 0; pt->current_history_item = 0; pt->first_back_click = TRUE; // main_add_tab_history_item((PASSAGE_TAB_INFO*)pt); passage_list = g_list_append(passage_list, (PASSAGE_TAB_INFO *)pt); notebook_main_add_page(pt); } else { // first passage is current/displayed. pt = pt_first; pt->paratab = NULL; // This is a hack to keep gs from loading the settings // from the last session into the last tab loaded here. gui_reassign_strdup(&settings.MainWindowModule, pt->text_mod); gui_reassign_strdup(&settings.CommWindowModule, pt->commentary_mod); gui_reassign_strdup(&settings.DictWindowModule, pt->dictlex_mod); gui_reassign_strdup(&settings.book_mod, pt->book_mod); gui_reassign_strdup(&settings.currentverse, pt->text_commentary_key); gui_reassign_strdup(&settings.dictkey, pt->dictlex_key); settings.book_offset = atol(pt->book_offset); } } stop_refresh = FALSE; set_current_tab(pt); gui_recompute_view_menu_choices(); }
void gui_save_tabs(const gchar *filename) { xmlDocPtr xml_doc; xmlNodePtr root_node; xmlNodePtr cur_node; xmlNodePtr section_node; // xmlAttrPtr xml_attr; //const xmlChar *xml_filename; gchar *file; GList *tmp = NULL; if (NULL == filename) filename = default_tab_filename; if (g_access(filename, F_OK) == 0) { /* we're done, just copy for local use that can be free'd */ file = g_strdup(filename); } else { gchar *tabs_dir = g_strdup_printf("%s/tabs/", settings.gSwordDir); if (g_access(tabs_dir, F_OK) == -1) { if ((g_mkdir(tabs_dir, S_IRWXU)) == -1) { gui_generic_warning_modal(_("Can't create tabs dir.")); return; } } file = g_strdup_printf("%s%s", tabs_dir, filename); g_free(tabs_dir); } //xml_filename = (const xmlChar *) file; xml_doc = xmlNewDoc((const xmlChar *)"1.0"); if (xml_doc == NULL) { gui_generic_warning_modal("Tabs document not created successfully."); return; } root_node = xmlNewNode(NULL, (const xmlChar *)"Xiphos_Tabs"); //xml_attr = xmlNewProp(root_node, (const xmlChar *)"Version", (const xmlChar *)VERSION); xmlDocSetRootElement(xml_doc, root_node); section_node = xmlNewChild(root_node, NULL, (const xmlChar *)"tabs", NULL); for (tmp = g_list_first(passage_list); tmp != NULL; tmp = g_list_next(tmp)) { PASSAGE_TAB_INFO *pt = (PASSAGE_TAB_INFO *)tmp->data; cur_node = xmlNewChild(section_node, NULL, (const xmlChar *)"tab", NULL); xmlNewProp(cur_node, (const xmlChar *)"text_mod", (const xmlChar *)pt->text_mod); xmlNewProp(cur_node, (const xmlChar *)"commentary_mod", (const xmlChar *)pt->commentary_mod); xmlNewProp(cur_node, (const xmlChar *)"dictlex_mod", (const xmlChar *)pt->dictlex_mod); xmlNewProp(cur_node, (const xmlChar *)"book_mod", (const xmlChar *)pt->book_mod); xmlNewProp(cur_node, (const xmlChar *)"text_commentary_key", (const xmlChar *)pt->text_commentary_key); xmlNewProp(cur_node, (const xmlChar *)"dictlex_key", (const xmlChar *)pt->dictlex_key); xmlNewProp(cur_node, (const xmlChar *)"book_offset", (const xmlChar *)pt->book_offset); xmlNewProp(cur_node, (const xmlChar *)"comm_showing", (const xmlChar *) true_false2yes_no(pt->comm_showing)); xmlNewProp(cur_node, (const xmlChar *)"showtexts", (const xmlChar *) true_false2yes_no(pt->showtexts)); xmlNewProp(cur_node, (const xmlChar *)"showpreview", (const xmlChar *) true_false2yes_no(pt->showpreview)); xmlNewProp(cur_node, (const xmlChar *)"showcomms", (const xmlChar *) true_false2yes_no(pt->showcomms)); xmlNewProp(cur_node, (const xmlChar *)"showdicts", (const xmlChar *) true_false2yes_no(pt->showdicts)); xmlNewProp(cur_node, (const xmlChar *)"showparallel", (const xmlChar *) true_false2yes_no(pt->showparallel)); } xmlSaveFormatFile(file, xml_doc, 1); g_free(file); xmlFreeDoc(xml_doc); }