| 1 | // =============================================================== // |
|---|
| 2 | // // |
|---|
| 3 | // File : EDB_root_bact.cxx // |
|---|
| 4 | // Purpose : // |
|---|
| 5 | // // |
|---|
| 6 | // Institute of Microbiology (Technical University Munich) // |
|---|
| 7 | // http://www.arb-home.de/ // |
|---|
| 8 | // // |
|---|
| 9 | // =============================================================== // |
|---|
| 10 | |
|---|
| 11 | #include <ed4_extern.hxx> |
|---|
| 12 | #include "ed4_class.hxx" |
|---|
| 13 | |
|---|
| 14 | #include <aw_msg.hxx> |
|---|
| 15 | #include <arb_progress.h> |
|---|
| 16 | #include <arbdbt.h> |
|---|
| 17 | #include <arb_strbuf.h> |
|---|
| 18 | #include <ad_config.h> |
|---|
| 19 | |
|---|
| 20 | void EDB_root_bact::calc_no_of_all(const char *string_to_scan, long *group, long *species) { |
|---|
| 21 | *group = 0; |
|---|
| 22 | *species = 0; |
|---|
| 23 | |
|---|
| 24 | if (string_to_scan) { |
|---|
| 25 | long i = 0; |
|---|
| 26 | while (string_to_scan[i]) { |
|---|
| 27 | if (string_to_scan[i] == 1) { |
|---|
| 28 | if (string_to_scan[i+1] == 'L' || string_to_scan[i+1] == 'S') { |
|---|
| 29 | (*species)++; |
|---|
| 30 | i++; |
|---|
| 31 | } |
|---|
| 32 | else if (string_to_scan[i+1] == 'F' || string_to_scan[i+1] == 'G') { |
|---|
| 33 | (*group)++; |
|---|
| 34 | i++; |
|---|
| 35 | } |
|---|
| 36 | } |
|---|
| 37 | i++; |
|---|
| 38 | } |
|---|
| 39 | } |
|---|
| 40 | } |
|---|
| 41 | |
|---|
| 42 | ED4_returncode EDB_root_bact::fill_data(ED4_multi_species_manager *multi_species_manager, |
|---|
| 43 | ED4_reference_terminals& refterms, |
|---|
| 44 | char *str, |
|---|
| 45 | int group_depth, |
|---|
| 46 | ED4_datamode datamode) |
|---|
| 47 | { |
|---|
| 48 | GBDATA *gb_item = NULp; |
|---|
| 49 | GBDATA *gb_main = ED4_ROOT->get_gb_main(); |
|---|
| 50 | |
|---|
| 51 | switch (datamode) { |
|---|
| 52 | case ED4_D_EXTENDED: gb_item = GBT_find_SAI(gb_main, str); break; |
|---|
| 53 | case ED4_D_SPECIES: gb_item = GBT_find_species(gb_main, str); break; |
|---|
| 54 | } |
|---|
| 55 | |
|---|
| 56 | if (!gb_item) { // didn't find this species/SAI |
|---|
| 57 | not_found_counter++; |
|---|
| 58 | if (not_found_counter <= MAX_SHOWN_MISSING_SPECIES) { |
|---|
| 59 | char dummy[150]; |
|---|
| 60 | sprintf(dummy, "%zu. %s\n", not_found_counter, str); |
|---|
| 61 | e4_assert(not_found_message); |
|---|
| 62 | not_found_message->cat(dummy); |
|---|
| 63 | } |
|---|
| 64 | return ED4_R_BREAK; |
|---|
| 65 | } |
|---|
| 66 | |
|---|
| 67 | // check whether sequence has data in desired alignment |
|---|
| 68 | bool has_alignment = GB_entry(gb_item, ED4_ROOT->get_alignment_name()); |
|---|
| 69 | if (!has_alignment) { |
|---|
| 70 | if (datamode == ED4_D_SPECIES) { // only warn about species w/o data (SAIs are skipped silently) |
|---|
| 71 | not_found_counter++; |
|---|
| 72 | if (not_found_counter <= MAX_SHOWN_MISSING_SPECIES) { |
|---|
| 73 | char dummy[150]; |
|---|
| 74 | sprintf(dummy, "%zu. %s (no data in alignment)\n", not_found_counter, str); |
|---|
| 75 | not_found_message->cat(dummy); |
|---|
| 76 | } |
|---|
| 77 | } |
|---|
| 78 | return ED4_R_BREAK; |
|---|
| 79 | } |
|---|
| 80 | |
|---|
| 81 | ED4_species_type spec_type = (datamode == ED4_D_EXTENDED) ? ED4_SP_SAI : ED4_SP_SPECIES; |
|---|
| 82 | |
|---|
| 83 | |
|---|
| 84 | { |
|---|
| 85 | char namebuffer[NAME_BUFFERSIZE]; |
|---|
| 86 | int count_two = 0; |
|---|
| 87 | |
|---|
| 88 | sprintf(namebuffer, "Species_Manager.%ld.%d", ED4_counter, count_two); |
|---|
| 89 | ED4_species_manager *species_manager = new ED4_species_manager(spec_type, namebuffer, 0, 0, multi_species_manager); |
|---|
| 90 | |
|---|
| 91 | species_manager->set_property(PROP_MOVABLE); |
|---|
| 92 | if (spec_type == ED4_SP_SAI) { |
|---|
| 93 | ED4_abstract_group_manager *group_man = species_manager->get_parent(ED4_level(LEV_GROUP|LEV_ROOTGROUP))->to_abstract_group_manager(); |
|---|
| 94 | group_man->table().ignore_me(); // ignore SAI tables (does not work - instead ignore SAIs when calculating consensus) |
|---|
| 95 | } |
|---|
| 96 | species_manager->set_species_pointer(gb_item); |
|---|
| 97 | multi_species_manager->append_member(species_manager); |
|---|
| 98 | |
|---|
| 99 | sprintf(namebuffer, "MultiName_Manager.%ld.%d", ED4_counter, count_two); |
|---|
| 100 | ED4_multi_name_manager *multi_name_manager = new ED4_multi_name_manager(namebuffer, 0, 0, species_manager); |
|---|
| 101 | species_manager->append_member(multi_name_manager); |
|---|
| 102 | |
|---|
| 103 | sprintf(namebuffer, "MultiSeq_Manager.%ld.%d", ED4_counter, count_two++); |
|---|
| 104 | ED4_multi_sequence_manager *multi_sequence_manager = new ED4_multi_sequence_manager(namebuffer, 0, 0, species_manager); |
|---|
| 105 | species_manager->append_member(multi_sequence_manager); |
|---|
| 106 | |
|---|
| 107 | sprintf(namebuffer, "Name_Manager%ld.%d", ED4_counter, count_two++); |
|---|
| 108 | ED4_name_manager *name_manager = new ED4_name_manager(namebuffer, 0, 0, multi_name_manager); |
|---|
| 109 | name_manager->set_property(PROP_MOVABLE); // only Speciesname should be movable |
|---|
| 110 | multi_name_manager->append_member(name_manager); |
|---|
| 111 | |
|---|
| 112 | { |
|---|
| 113 | sprintf(namebuffer, "Species_Name_Term%ld.%d", ED4_counter, count_two++); |
|---|
| 114 | ED4_species_name_terminal *species_name_terminal = new ED4_species_name_terminal(namebuffer, MAXNAME_WIDTH-(group_depth*BRACKET_WIDTH), TERMINAL_HEIGHT, name_manager); |
|---|
| 115 | species_name_terminal->set_property((ED4_properties) (PROP_SELECTABLE | PROP_DRAGABLE | PROP_IS_HANDLE)); |
|---|
| 116 | species_name_terminal->set_links(NULp, refterms.sequence()); |
|---|
| 117 | species_name_terminal->set_species_pointer(GB_entry(gb_item, "name")); |
|---|
| 118 | name_manager->append_member(species_name_terminal); |
|---|
| 119 | } |
|---|
| 120 | |
|---|
| 121 | { |
|---|
| 122 | sprintf(namebuffer, "Flag_Term%ld.%d", ED4_counter, count_two++); |
|---|
| 123 | ED4_flag_terminal *flag_terminal = new ED4_flag_terminal(namebuffer, FLAG_WIDTH, TERMINAL_HEIGHT, name_manager); |
|---|
| 124 | flag_terminal->set_links(NULp, refterms.sequence()); |
|---|
| 125 | name_manager->append_member(flag_terminal); |
|---|
| 126 | } |
|---|
| 127 | |
|---|
| 128 | GBDATA *gb_ali_xxx = GB_entry(gb_item, ED4_ROOT->get_alignment_name()); |
|---|
| 129 | if (gb_ali_xxx) { |
|---|
| 130 | search_sequence_data_rek(multi_sequence_manager, refterms, gb_ali_xxx, count_two, &max_seq_terminal_length, datamode == ED4_D_EXTENDED); |
|---|
| 131 | } |
|---|
| 132 | } |
|---|
| 133 | |
|---|
| 134 | return ED4_R_OK; |
|---|
| 135 | } |
|---|
| 136 | |
|---|
| 137 | ED4_returncode EDB_root_bact::search_sequence_data_rek(ED4_multi_sequence_manager *multi_sequence_manager, |
|---|
| 138 | ED4_reference_terminals& refterms, |
|---|
| 139 | GBDATA *gb_ali_xxx, // alignment-container (or any subcontainer of) |
|---|
| 140 | int count_too, |
|---|
| 141 | ED4_index *max_sequence_terminal_length, |
|---|
| 142 | bool isSAI) |
|---|
| 143 | { |
|---|
| 144 | char namebuffer[NAME_BUFFERSIZE]; |
|---|
| 145 | AW_device *device = ED4_ROOT->first_window->get_device(); |
|---|
| 146 | |
|---|
| 147 | e4_assert(gb_ali_xxx); |
|---|
| 148 | |
|---|
| 149 | for (GBDATA *gb_ali_child = GB_child(gb_ali_xxx); gb_ali_child; gb_ali_child = GB_nextChild(gb_ali_child)) { |
|---|
| 150 | GB_TYPES type = GB_read_type(gb_ali_child); |
|---|
| 151 | |
|---|
| 152 | if (type == GB_INTS || type == GB_FLOATS) { |
|---|
| 153 | continue; |
|---|
| 154 | } |
|---|
| 155 | |
|---|
| 156 | if (type == GB_DB) { // we have to unpack container |
|---|
| 157 | search_sequence_data_rek(multi_sequence_manager, refterms, gb_ali_child, count_too, max_sequence_terminal_length, isSAI); |
|---|
| 158 | } |
|---|
| 159 | else { // otherwise we enter the data |
|---|
| 160 | char *key_string = GB_read_key(gb_ali_child); |
|---|
| 161 | if (key_string[0] != '_') { // don't show sequences starting with an underscore |
|---|
| 162 | sprintf(namebuffer, "Sequence_Manager.%ld.%d", ED4_counter, count_too++); |
|---|
| 163 | ED4_sequence_manager *seq_manager = new ED4_sequence_manager(namebuffer, 0, 0, multi_sequence_manager); |
|---|
| 164 | seq_manager->set_property(PROP_MOVABLE); |
|---|
| 165 | multi_sequence_manager->append_member(seq_manager); |
|---|
| 166 | |
|---|
| 167 | { |
|---|
| 168 | ED4_sequence_info_terminal *sequence_info_terminal = new ED4_sequence_info_terminal(key_string, SEQUENCE_INFO_WIDTH, TERMINAL_HEIGHT, seq_manager); |
|---|
| 169 | sequence_info_terminal->set_property((ED4_properties) (PROP_SELECTABLE | PROP_DRAGABLE | PROP_IS_HANDLE)); |
|---|
| 170 | sequence_info_terminal->set_both_links(refterms.sequence_info()); |
|---|
| 171 | sequence_info_terminal->set_species_pointer(gb_ali_child); |
|---|
| 172 | seq_manager->append_member(sequence_info_terminal); |
|---|
| 173 | } |
|---|
| 174 | |
|---|
| 175 | ED4_text_terminal *text_terminal = NULp; |
|---|
| 176 | |
|---|
| 177 | bool is_data = false; |
|---|
| 178 | bool is_data2 = false; |
|---|
| 179 | bool is_bits = false; |
|---|
| 180 | bool is_quality = false; |
|---|
| 181 | |
|---|
| 182 | if (strcmp(key_string, "data") == 0) is_data = true; // SAI or species |
|---|
| 183 | else if (strcmp(key_string, "data2") == 0) is_data2 = true; // used by SAIs with two entries (e.g. first and second digit of 2-digit-numbers) |
|---|
| 184 | else if (strcmp(key_string, "bits") == 0) is_bits = true; // used by binary SAIs (e.g. MARKERLINE) |
|---|
| 185 | else if (strcmp(key_string, "quality") == 0) is_quality = true; // used by "quality" entry written by chimera check; see ../STAT/ST_quality.cxx@chimera_check_quality_string |
|---|
| 186 | |
|---|
| 187 | bool is_aligned = is_data || is_data2 || is_bits || is_quality; |
|---|
| 188 | |
|---|
| 189 | if (is_aligned) { |
|---|
| 190 | bool shall_display_secinfo = is_data; |
|---|
| 191 | |
|---|
| 192 | if (isSAI) { |
|---|
| 193 | GBDATA *gb_sai = GB_get_grandfather(gb_ali_child); |
|---|
| 194 | GBDATA *gb_disp_sec = GB_searchOrCreate_int(gb_sai, "showsec", 0); |
|---|
| 195 | shall_display_secinfo = GB_read_int(gb_disp_sec); |
|---|
| 196 | } |
|---|
| 197 | |
|---|
| 198 | sprintf(namebuffer, "Sequence_Term%ld.%d", ED4_counter, count_too++); |
|---|
| 199 | ED4_sequence_terminal *seq_term = new ED4_sequence_terminal(namebuffer, 0, TERMINAL_HEIGHT, seq_manager, shall_display_secinfo); |
|---|
| 200 | seq_term->species_name = seq_term->get_name_of_species(); |
|---|
| 201 | |
|---|
| 202 | if (is_data) seq_term->set_property(PROP_CONSENSUS_RELEVANT); |
|---|
| 203 | seq_term->set_property(PROP_ALIGNMENT_DATA); |
|---|
| 204 | |
|---|
| 205 | text_terminal = seq_term; |
|---|
| 206 | } |
|---|
| 207 | else { |
|---|
| 208 | sprintf(namebuffer, "PureText_Term%ld.%d", ED4_counter, count_too++); |
|---|
| 209 | text_terminal = new ED4_pure_text_terminal(namebuffer, 0, TERMINAL_HEIGHT, seq_manager); |
|---|
| 210 | } |
|---|
| 211 | |
|---|
| 212 | text_terminal->set_property(PROP_CURSOR_ALLOWED); |
|---|
| 213 | text_terminal->set_both_links(refterms.sequence()); |
|---|
| 214 | seq_manager->append_member(text_terminal); |
|---|
| 215 | #if defined(DEBUG) |
|---|
| 216 | // ensure only 1 terminal is consensus-relevant! |
|---|
| 217 | if (is_data) { |
|---|
| 218 | seq_manager->get_consensus_relevant_terminal(); // does an error otherwise! |
|---|
| 219 | } |
|---|
| 220 | #endif // DEBUG |
|---|
| 221 | text_terminal->set_species_pointer(gb_ali_child); |
|---|
| 222 | |
|---|
| 223 | long string_length; |
|---|
| 224 | if (gb_ali_child) { |
|---|
| 225 | string_length = GB_read_count(gb_ali_child); |
|---|
| 226 | } |
|---|
| 227 | else { |
|---|
| 228 | string_length = 100; |
|---|
| 229 | } |
|---|
| 230 | |
|---|
| 231 | int pixel_length = device->get_string_size(ED4_G_SEQUENCES, string_length) + 100; // @@@ "+ 100" looks like a hack |
|---|
| 232 | |
|---|
| 233 | *max_sequence_terminal_length = std::max(*max_sequence_terminal_length, long(pixel_length)); |
|---|
| 234 | text_terminal->extension.size[WIDTH] = pixel_length; |
|---|
| 235 | |
|---|
| 236 | if (MAXSEQUENCECHARACTERLENGTH < string_length) { |
|---|
| 237 | MAXSEQUENCECHARACTERLENGTH = string_length; |
|---|
| 238 | refterms.sequence()->extension.size[WIDTH] = pixel_length; |
|---|
| 239 | } |
|---|
| 240 | |
|---|
| 241 | if (!ED4_ROOT->scroll_links.link_for_hor_slider) { |
|---|
| 242 | ED4_ROOT->scroll_links.link_for_hor_slider = text_terminal; |
|---|
| 243 | } |
|---|
| 244 | else if (*max_sequence_terminal_length > ED4_ROOT->scroll_links.link_for_hor_slider->extension.size[WIDTH]) { |
|---|
| 245 | ED4_ROOT->scroll_links.link_for_hor_slider = text_terminal; |
|---|
| 246 | } |
|---|
| 247 | } |
|---|
| 248 | free(key_string); |
|---|
| 249 | } |
|---|
| 250 | } |
|---|
| 251 | |
|---|
| 252 | return ED4_R_OK; |
|---|
| 253 | } |
|---|
| 254 | |
|---|
| 255 | ED4_returncode EDB_root_bact::fill_species(ED4_multi_species_manager *multi_species_manager, |
|---|
| 256 | ED4_reference_terminals& refterms, |
|---|
| 257 | const char *str, |
|---|
| 258 | int *index, |
|---|
| 259 | int group_depth, |
|---|
| 260 | arb_progress *progress) |
|---|
| 261 | { |
|---|
| 262 | const int MAXNAMELEN = 1024; |
|---|
| 263 | |
|---|
| 264 | bool expect_separator = true; |
|---|
| 265 | ED4_datamode datamode = ED4_D_SPECIES; |
|---|
| 266 | ED4_returncode retCode = ED4_R_OK; |
|---|
| 267 | |
|---|
| 268 | char *name = ARB_calloc<char>(MAXNAMELEN); |
|---|
| 269 | int npos = 0; |
|---|
| 270 | |
|---|
| 271 | do { |
|---|
| 272 | if (expect_separator) { |
|---|
| 273 | if (str[(*index)+1] == 'L') { |
|---|
| 274 | datamode = ED4_D_SPECIES; |
|---|
| 275 | } |
|---|
| 276 | else if (str[(*index)+1] == 'S') { |
|---|
| 277 | datamode = ED4_D_EXTENDED; |
|---|
| 278 | } |
|---|
| 279 | else { |
|---|
| 280 | const char *entry = str+*index+1; |
|---|
| 281 | char tag = entry[0]; |
|---|
| 282 | const char *sep = strchr(entry, 1); |
|---|
| 283 | |
|---|
| 284 | if (sep) { |
|---|
| 285 | int len = sep-entry+1; |
|---|
| 286 | char *content = ARB_strndup(entry+1, len); |
|---|
| 287 | char *message = GBS_global_string_copy("Unknown or misplaced tag-id '%c' (with content '%s'). Error in configuration-data!\nTrying to continue..", tag, content); |
|---|
| 288 | |
|---|
| 289 | fprintf(stderr, "ARB_EDIT4: %s\n", message); |
|---|
| 290 | aw_message(message); |
|---|
| 291 | |
|---|
| 292 | free(message); |
|---|
| 293 | free(content); |
|---|
| 294 | retCode = ED4_R_WARNING; |
|---|
| 295 | |
|---|
| 296 | (*index) += sep-entry+1; // set index to next separator |
|---|
| 297 | continue; |
|---|
| 298 | } |
|---|
| 299 | else { |
|---|
| 300 | fprintf(stderr, "Error reading configuration: Unexpected end of data (at '%s')\n", str+*index); |
|---|
| 301 | |
|---|
| 302 | e4_assert(0); |
|---|
| 303 | retCode = ED4_R_ERROR; |
|---|
| 304 | break; |
|---|
| 305 | } |
|---|
| 306 | e4_assert(0); // never reached! |
|---|
| 307 | } |
|---|
| 308 | |
|---|
| 309 | (*index) += 2; |
|---|
| 310 | } |
|---|
| 311 | |
|---|
| 312 | if (str[*index] != 1) { |
|---|
| 313 | name[npos++] = str[*index]; |
|---|
| 314 | expect_separator = false; |
|---|
| 315 | (*index)++; |
|---|
| 316 | } |
|---|
| 317 | |
|---|
| 318 | if (str[*index] == 1 || str[*index] == '\0') { |
|---|
| 319 | name[npos] = '\0'; // speciesname-generation finished |
|---|
| 320 | npos = 0; |
|---|
| 321 | |
|---|
| 322 | if (progress) { |
|---|
| 323 | progress->inc(); |
|---|
| 324 | if (progress->aborted()) ED4_exit(); |
|---|
| 325 | } |
|---|
| 326 | |
|---|
| 327 | fill_data(multi_species_manager, refterms, name, group_depth, datamode); |
|---|
| 328 | |
|---|
| 329 | ED4_counter++; |
|---|
| 330 | expect_separator = true; |
|---|
| 331 | } |
|---|
| 332 | } |
|---|
| 333 | while (!((str[(*index)] == 1) && (str[(*index)+1] == 'G' || str[(*index)+1]=='E' || str[(*index)+1]=='F')) && (str[*index] != '\0')); |
|---|
| 334 | |
|---|
| 335 | free(name); |
|---|
| 336 | |
|---|
| 337 | return retCode; |
|---|
| 338 | } |
|---|
| 339 | |
|---|
| 340 | void EDB_root_bact::scan_string(ED4_multi_species_manager *parent, |
|---|
| 341 | ED4_reference_terminals& refterms, |
|---|
| 342 | const char *str, |
|---|
| 343 | int *index, |
|---|
| 344 | arb_progress& progress) |
|---|
| 345 | { |
|---|
| 346 | static int group_depth = 0; |
|---|
| 347 | |
|---|
| 348 | while (str[(*index)] != '\0' && str[(*index)+1] != 'E') { // E = |
|---|
| 349 | if (str[(*index)+1] == 'L' || str[(*index)+1] == 'S') { // L = species, S = SAI |
|---|
| 350 | fill_species(parent, refterms, str, index, group_depth, &progress); |
|---|
| 351 | ED4_counter++; // counter is only needed to generate ids |
|---|
| 352 | } |
|---|
| 353 | |
|---|
| 354 | if (str[(*index)] && (str[(*index)+1] == 'G' || str[(*index)+1] == 'F')) { // Group or folded group |
|---|
| 355 | group_depth++; |
|---|
| 356 | bool is_folded = str[(*index)+1]=='F'; |
|---|
| 357 | |
|---|
| 358 | char groupname[GB_GROUP_NAME_MAX]; |
|---|
| 359 | { |
|---|
| 360 | ED4_index gpos = 0; |
|---|
| 361 | for (*index += 2, gpos = 0; str[*index] != 1; (*index)++) { // Jump over 'G' and Blank to get Groupname |
|---|
| 362 | groupname[gpos++] = str[*index]; |
|---|
| 363 | } |
|---|
| 364 | groupname[gpos] = '\0'; |
|---|
| 365 | } |
|---|
| 366 | |
|---|
| 367 | ED4_multi_species_manager *multi_species_manager; |
|---|
| 368 | ED4_build_group_manager_start(parent, groupname, group_depth, is_folded, refterms, multi_species_manager); |
|---|
| 369 | |
|---|
| 370 | ED4_counter++; |
|---|
| 371 | scan_string(multi_species_manager, refterms, str, index, progress); |
|---|
| 372 | |
|---|
| 373 | ED4_build_group_manager_end(multi_species_manager); |
|---|
| 374 | |
|---|
| 375 | if (is_folded) multi_species_manager->hide_children(); |
|---|
| 376 | } |
|---|
| 377 | } |
|---|
| 378 | |
|---|
| 379 | if (str[(*index)] && str[(*index)+1] == 'E') { |
|---|
| 380 | (*index)+=2; |
|---|
| 381 | group_depth--; |
|---|
| 382 | } |
|---|
| 383 | } |
|---|
| 384 | |
|---|
| 385 | void EDB_root_bact::save_current_config(char *confname) { // and save it in database |
|---|
| 386 | GB_ERROR error; |
|---|
| 387 | GBDATA *gb_main = ED4_ROOT->get_gb_main(); |
|---|
| 388 | GBT_config cfg(gb_main, confname, error); |
|---|
| 389 | |
|---|
| 390 | error = NULp; // ignore not-found error |
|---|
| 391 | |
|---|
| 392 | int counter = 0; |
|---|
| 393 | ED4_device_manager *device_manager = ED4_ROOT->get_device_manager(); |
|---|
| 394 | |
|---|
| 395 | for (int i=0; i<device_manager->members(); i++) { |
|---|
| 396 | ED4_base *area = device_manager->member(i); |
|---|
| 397 | if (area->is_area_manager()) { |
|---|
| 398 | GBS_strstruct area_config(10000); |
|---|
| 399 | area->generate_configuration_string(area_config); |
|---|
| 400 | cfg.set_definition(counter++, area_config.release()); |
|---|
| 401 | } |
|---|
| 402 | } |
|---|
| 403 | |
|---|
| 404 | // add/update comment |
|---|
| 405 | { |
|---|
| 406 | char *newComment = GBS_log_action_to(cfg.get_comment(), "saved from ARB_EDIT4", true); |
|---|
| 407 | cfg.set_comment(newComment); |
|---|
| 408 | free(newComment); |
|---|
| 409 | } |
|---|
| 410 | |
|---|
| 411 | error = cfg.save(gb_main, confname, true); |
|---|
| 412 | aw_message_if(error); |
|---|
| 413 | } |
|---|
| 414 | |
|---|