source: tags/svn.1.5.4/NTREE/NT_edconf.cxx

Last change on this file was 8309, checked in by westram, 14 years ago
  • moved much code into static scope

(partly reverted by [8310])

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 24.0 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : NT_edconf.cxx                                     //
4//   Purpose   :                                                   //
5//                                                                 //
6//   Institute of Microbiology (Technical University Munich)       //
7//   http://www.arb-home.de/                                       //
8//                                                                 //
9// =============================================================== //
10
11#include "nt_cb.hxx"
12#include "nt_internal.h"
13
14#include <awt_sel_boxes.hxx>
15#include <aw_window.hxx>
16#include <aw_awars.hxx>
17#include <aw_root.hxx>
18#include <aw_msg.hxx>
19#include <ad_config.h>
20#include <arbdbt.h>
21#include <arb_strbuf.h>
22
23#define nt_assert(bed) arb_assert(bed)
24
25extern GBDATA *GLOBAL_gb_main;
26
27static void init_config_awars(AW_root *root) {
28    root->awar_string(AWAR_CONFIGURATION, "default_configuration", GLOBAL_gb_main);
29}
30
31//  ---------------------------
32//      class Store_species
33//  ---------------------------
34// stores a amount of species:
35
36class Store_species : virtual Noncopyable {
37    GBT_TREE *node;
38    Store_species *next;
39public:
40    Store_species(GBT_TREE *aNode) {
41        node = aNode;
42        next = 0;
43    }
44    ~Store_species();
45
46    Store_species* add(Store_species *list) {
47        nt_assert(next==0);
48        next = list;
49        return this;
50    }
51
52    Store_species* remove() {
53        Store_species *follower = next;
54        next = 0;
55        return follower;
56    }
57
58    GBT_TREE *getNode() const { return node; }
59
60    void call(void (*aPizza)(GBT_TREE*)) const;
61};
62
63Store_species::~Store_species() {
64    delete next;
65}
66
67void Store_species::call(void (*aPizza)(GBT_TREE*)) const {
68    aPizza(node);
69    if (next) next->call(aPizza);
70}
71
72static void unmark_species(GBT_TREE *node) {
73    nt_assert(node);
74    nt_assert(node->gb_node);
75    nt_assert(GB_read_flag(node->gb_node)!=0);
76    GB_write_flag(node->gb_node, 0);
77}
78
79static void mark_species(GBT_TREE *node, Store_species **extra_marked_species) {
80    nt_assert(node);
81    nt_assert(node->gb_node);
82    nt_assert(GB_read_flag(node->gb_node)==0);
83    GB_write_flag(node->gb_node, 1);
84
85    *extra_marked_species = (new Store_species(node))->add(*extra_marked_species);
86}
87
88
89
90static GBT_TREE *rightmost_leaf(GBT_TREE *node) {
91    nt_assert(node);
92    while (!node->is_leaf) {
93        node = node->rightson;
94        nt_assert(node);
95    }
96    return node;
97}
98
99static GBT_TREE *left_neighbour_leaf(GBT_TREE *node) {
100    if (node) {
101        GBT_TREE *father = node->father;
102        while (father) {
103            if (father->rightson==node) {
104                node = rightmost_leaf(father->leftson);
105                nt_assert(node->is_leaf);
106                if (!node->gb_node) { // Zombie
107                    node = left_neighbour_leaf(node);
108                }
109                return node;
110            }
111            node = father;
112            father = node->father;
113        }
114    }
115    return 0;
116}
117
118static int nt_build_conf_string_rek(GB_HASH *used, GBT_TREE *tree, GBS_strstruct *memfile,
119                             Store_species **extra_marked_species, int use_species_aside,
120                             int *auto_mark, int marked_at_left, int *marked_at_right)
121{
122    /*! Builds a configuration string from a tree.
123     *
124     * @param extra_marked_species      all extra marked species are inserted here
125     * @param use_species_aside         number of species to mark left and right of marked species
126     * @param auto_mark                 number species to extra-mark (if not already marked)
127     * @param marked_at_left            number of species which were marked (looking to left)
128     * @param marked_at_right           number of species which are marked (when returning from recursion)
129     *
130     * @return the number of marked species
131     *
132     * --------------------------------------------------
133     * Format of configuration string : [Part]+ \0
134     *
135     * Part : '\A' ( Group | Species | Sai )
136     *
137     * Group : ( OpenedGroup | ClosedGroup )
138     * OpenedGroup : 'G' GroupDef
139     * ClosedGroup : 'F' GroupDef
140     * GroupDef : 'groupname' [PART]* EndGroup
141     * EndGroup : '\AE'
142     *
143     * SPECIES : 'L' 'speciesname'
144     * SAI : 'S' 'sainame'
145     *
146     * \0 : ASCII 0 (eos)
147     * \A : ASCII 1
148     */
149
150    if (!tree) return 0;
151    if (tree->is_leaf) {
152        if (!tree->gb_node) {
153            *marked_at_right = marked_at_left;
154            return 0;   // Zombie
155        }
156
157        if (!GB_read_flag(tree->gb_node)) { // unmarked species
158            if (*auto_mark) {
159                (*auto_mark)--;
160                mark_species(tree, extra_marked_species);
161            }
162            else {
163                *marked_at_right = 0;
164                return 0;
165            }
166        }
167        else { // marked species
168            if (marked_at_left<use_species_aside) {
169                // on the left side there are not as many marked species as needed!
170
171                nt_assert(marked_at_left>=0);
172
173                GBT_TREE *leaf_at_left = tree;
174                int       step_over    = marked_at_left+1; // step over myself
175                int       then_mark    = use_species_aside-marked_at_left;
176
177                while (step_over--) { // step over self and over any adjacent, marked species
178                    leaf_at_left = left_neighbour_leaf(leaf_at_left);
179                }
180
181                Store_species *marked_back = 0;
182                while (leaf_at_left && then_mark--) { // then additionally mark some species
183                    if (GB_read_flag(leaf_at_left->gb_node) == 0) { // if they are not marked yet
184                        mark_species(leaf_at_left, extra_marked_species);
185                        marked_back = (new Store_species(leaf_at_left))->add(marked_back);
186                    }
187                    leaf_at_left = left_neighbour_leaf(leaf_at_left);
188                }
189
190                while (marked_back) {
191                    GBS_chrcat(memfile, 1);             // Separated by 1
192                    GBS_strcat(memfile, "L");
193                    GBS_strcat(memfile, marked_back->getNode()->name);
194                    GBS_write_hash(used, marked_back->getNode()->name, 1);      // Mark species
195
196                    Store_species *rest = marked_back->remove();
197                    delete marked_back;
198                    marked_back = rest;
199                }
200
201                marked_at_left = use_species_aside;
202            }
203            // now use_species_aside species to left are marked!
204            *auto_mark = use_species_aside;
205        }
206
207        GBS_chrcat(memfile, 1);             // Separated by 1
208        GBS_strcat(memfile, "L");
209        GBS_strcat(memfile, tree->name);
210        GBS_write_hash(used, tree->name, 1);    // Mark species
211
212        *marked_at_right = marked_at_left+1;
213        return 1;
214    }
215
216    long oldpos = GBS_memoffset(memfile);
217    if (tree->gb_node && tree->name) {      // but we are a group
218        GBDATA *gb_grouped = GB_entry(tree->gb_node, "grouped");
219        GBS_chrcat(memfile, 1);             // Separated by 1
220        if (gb_grouped && GB_read_byte(gb_grouped)) {
221            GBS_strcat(memfile, "F");
222        }
223        else {
224            GBS_strcat(memfile, "G");
225        }
226
227        GBS_strcat(memfile, tree->name);
228    }
229
230    int right_of_leftson;
231    long nspecies = nt_build_conf_string_rek(used, tree->leftson, memfile, extra_marked_species, use_species_aside, auto_mark, marked_at_left, &right_of_leftson);
232    nspecies += nt_build_conf_string_rek(used, tree->rightson, memfile, extra_marked_species, use_species_aside, auto_mark, right_of_leftson, marked_at_right);
233
234    if (tree->gb_node && tree->name) {      // but we are a group
235        GBS_chrcat(memfile, 1);         // Separated by 1
236        GBS_chrcat(memfile, 'E');        // Group end indicated by 'E'
237    }
238
239    if (!nspecies) {
240        long newpos = GBS_memoffset(memfile);
241        GBS_str_cut_tail(memfile, newpos-oldpos);   // delete group info
242    }
243    return nspecies;
244}
245
246struct SAI_string_builder {
247    GBS_strstruct *sai_middle;
248    const char    *last_group_name;
249};
250
251static long nt_build_sai_string_by_hash(const char *key, long val, void *cd_sai_builder) {
252    SAI_string_builder *sai_builder = (SAI_string_builder*)cd_sai_builder;
253
254    const char *sep = strchr(key, 1);
255    if (!sep) return val;                           // what's wrong
256
257    GBS_strstruct *sai_middle      = sai_builder->sai_middle;
258    const char    *last_group_name = sai_builder->last_group_name;
259
260    if (!last_group_name || strncmp(key, last_group_name, sep-key)) { // new group
261        if (last_group_name) {
262            GBS_chrcat(sai_middle, 1);              // Separated by 1
263            GBS_chrcat(sai_middle, 'E');             // End of old group
264        }
265        GBS_chrcat(sai_middle, 1);                  // Separated by 1
266        GBS_strcat(sai_middle, "FSAI:");
267        GBS_strncat(sai_middle, key, sep-key);
268        sai_builder->last_group_name = key;
269    }
270    GBS_chrcat(sai_middle, 1);                      // Separated by 1
271    GBS_strcat(sai_middle, "S");
272    GBS_strcat(sai_middle, sep+1);
273    return val;
274}
275
276
277static void nt_build_sai_string(GBS_strstruct *topfile, GBS_strstruct *middlefile) {
278    //! collect all Sais, place some SAI in top area, rest in middle
279
280    GBDATA *gb_sai_data = GBT_get_SAI_data(GLOBAL_gb_main);
281    if (gb_sai_data) {
282        GB_HASH *hash = GBS_create_hash(GB_number_of_subentries(gb_sai_data), GB_IGNORE_CASE);
283
284        for (GBDATA *gb_sai = GBT_first_SAI_rel_SAI_data(gb_sai_data); gb_sai; gb_sai = GBT_next_SAI(gb_sai)) {
285            GBDATA *gb_name = GB_search(gb_sai, "name", GB_FIND);
286            if (gb_name) {
287                char *name = GB_read_string(gb_name);
288
289                if (strcmp(name,  "HELIX") == 0  || strcmp(name,  "HELIX_NR") == 0 || strcmp(name,  "ECOLI") == 0) {
290                    GBS_chrcat(topfile, 1);             // Separated by 1
291                    GBS_strcat(topfile, "S");
292                    GBS_strcat(topfile, name);
293                }
294                else {
295                    GBDATA *gb_gn = GB_search(gb_sai, "sai_group", GB_FIND);
296                    char   *gn;
297
298                    if (gb_gn)  gn = GB_read_string(gb_gn);
299                    else        gn = strdup("SAI's");
300
301                    char *cn = new char[strlen(gn) + strlen(name) + 2];
302                    sprintf(cn, "%s%c%s", gn, 1, name);
303                    GBS_write_hash(hash, cn, 1);
304                    delete [] cn;
305                    free(gn);
306                }
307                free(name);
308            }
309        }
310
311        // open surrounding SAI-group:
312        GBS_chrcat(middlefile, 1);
313        GBS_strcat(middlefile, "GSAI-Maingroup");
314
315        SAI_string_builder sai_builder = { middlefile, 0 };
316        GBS_hash_do_sorted_loop(hash, nt_build_sai_string_by_hash, GBS_HCF_sortedByKey, &sai_builder);
317        if (sai_builder.last_group_name) {
318            GBS_chrcat(middlefile, 1);              // Separated by 1
319            GBS_chrcat(middlefile, 'E');             // End of old group
320        }
321
322        // close surrounding SAI-group:
323        GBS_chrcat(middlefile, 1);
324        GBS_chrcat(middlefile, 'E');
325
326        GBS_free_hash(hash);
327    }
328}
329
330static void nt_build_conf_marked(GB_HASH *used, GBS_strstruct *file) {
331    GBS_chrcat(file, 1);            // Separated by 1
332    GBS_strcat(file, "FMore Sequences");
333    GBDATA *gb_species;
334    for (gb_species = GBT_first_marked_species(GLOBAL_gb_main);
335         gb_species;
336         gb_species = GBT_next_marked_species(gb_species)) {
337        char *name = GBT_read_string(gb_species, "name");
338        if (GBS_read_hash(used, name)) {
339            free(name);
340            continue;
341        }
342        GBS_chrcat(file, 1);
343        GBS_strcat(file, "L");
344        GBS_strcat(file, name);
345        free(name);
346    }
347
348    GBS_chrcat(file, 1); // Separated by 1
349    GBS_chrcat(file, 'E');   // Group end indicated by 'E'
350}
351
352enum extractType {
353    CONF_EXTRACT,
354    CONF_MARK,
355    CONF_UNMARK,
356    CONF_INVERT,
357    CONF_COMBINE // logical AND
358};
359
360static void nt_extract_configuration(AW_window *aww, AW_CL cl_extractType) {
361    GB_transaction  dummy2(GLOBAL_gb_main);         // open close transaction
362    AW_root        *aw_root = aww->get_root();
363    char           *cn      = aw_root->awar(AWAR_CONFIGURATION)->read_string();
364   
365    GBDATA *gb_configuration = GBT_find_configuration(GLOBAL_gb_main, cn);
366    if (!gb_configuration) {
367        aw_message(GBS_global_string("Configuration '%s' not found in the database", cn));
368    }
369    else {
370        GBDATA *gb_middle_area  = GB_search(gb_configuration, "middle_area", GB_STRING);
371        char   *md              = 0;
372        size_t  unknown_species = 0;
373        bool    refresh         = false;
374
375        if (gb_middle_area) {
376            extractType ext_type = extractType(cl_extractType);
377
378            GB_HASH *was_marked = NULL;             // only used for CONF_COMBINE
379
380            switch (ext_type) {
381                case CONF_EXTRACT:
382                    GBT_mark_all(GLOBAL_gb_main, 0); // unmark all for extract
383                    refresh = true;
384                    break;
385                case CONF_COMBINE: {
386                    // store all marked species in hash and unmark them
387                    was_marked = GBS_create_hash(GBT_get_species_count(GLOBAL_gb_main), GB_IGNORE_CASE);
388                    for (GBDATA *gbd = GBT_first_marked_species(GLOBAL_gb_main); gbd; gbd = GBT_next_marked_species(gbd)) {
389                        int marked = GB_read_flag(gbd);
390                        if (marked) {
391                            GBS_write_hash(was_marked, GBT_read_name(gbd), 1);
392                            GB_write_flag(gbd, 0);
393                        }
394                    }
395
396                    refresh = refresh || GBS_hash_count_elems(was_marked);
397                    break;
398                }
399                default:
400                    break;
401            }
402
403            md = GB_read_string(gb_middle_area);
404            if (md) {
405                char *p;
406                char tokens[2];
407                tokens[0] = 1;
408                tokens[1] = 0;
409                for (p = strtok(md, tokens); p; p = strtok(NULL, tokens)) {
410                    if (p[0] == 'L') {
411                        const char *species_name = p+1;
412                        GBDATA     *gb_species   = GBT_find_species(GLOBAL_gb_main, species_name);
413
414                        if (gb_species) {
415                            int oldmark = GB_read_flag(gb_species);
416                            int newmark = oldmark;
417                            switch (ext_type) {
418                                case CONF_EXTRACT:
419                                case CONF_MARK:     newmark = 1; break;
420                                case CONF_UNMARK:   newmark = 0; break;
421                                case CONF_INVERT:   newmark = !oldmark; break;
422                                case CONF_COMBINE: {
423                                    nt_assert(!oldmark); // should have been unmarked above
424                                    newmark = GBS_read_hash(was_marked, species_name); // mark if was_marked
425                                    break;
426                                }
427                                default: nt_assert(0); break;
428                            }
429                            if (newmark != oldmark) {
430                                GB_write_flag(gb_species, newmark);
431                                refresh = true;
432                            }
433                        }
434                        else {
435                            unknown_species++;
436                        }
437                    }
438                }
439            }
440
441            if (was_marked) GBS_free_hash(was_marked);
442        }
443
444        if (unknown_species>0) {
445            aw_message(GBS_global_string("configuration '%s' contains %zu unknown species", cn, unknown_species));
446        }
447
448        if (refresh) aw_root->awar(AWAR_TREE_REFRESH)->touch();
449
450        free(md);
451    }
452    free(cn);
453}
454
455static void nt_delete_configuration(AW_window *aww) {
456    GB_transaction transaction_var(GLOBAL_gb_main);
457    char *cn = aww->get_root()->awar(AWAR_CONFIGURATION)->read_string();
458    GBDATA *gb_configuration = GBT_find_configuration(GLOBAL_gb_main, cn);
459    if (gb_configuration) {
460        GB_ERROR error = GB_delete(gb_configuration);
461        if (error) aw_message(error);
462    }
463    free(cn);
464}
465
466
467static GB_ERROR nt_create_configuration(AW_window *, GBT_TREE *tree, const char *conf_name, int use_species_aside) {
468    char     *to_free = NULL;
469    GB_ERROR  error   = NULL;
470
471    if (!conf_name) {
472        char *existing_configs = awt_create_string_on_configurations(GLOBAL_gb_main);
473        conf_name              = to_free = aw_string_selection2awar("CREATE CONFIGURATION", "Enter name of configuration:", AWAR_CONFIGURATION, existing_configs, 0, 0);
474        free(existing_configs);
475    }
476
477    if (!conf_name) error = "no config name";
478    else {
479        if (use_species_aside==-1) {
480            static int last_used_species_aside = 3;
481            {
482                const char *val                    = GBS_global_string("%i", last_used_species_aside);
483                char       *use_species            = aw_input("How many extra species to view aside marked:", val);
484                if (use_species) use_species_aside = atoi(use_species);
485                free(use_species);
486            }
487
488            if (use_species_aside<1) error = "illegal number of 'species aside'";
489            else last_used_species_aside = use_species_aside; // remember for next time
490        }
491
492        if (!error) {
493            GB_transaction  ta(GLOBAL_gb_main); // open close transaction
494            GB_HASH        *used    = GBS_create_hash(GBT_get_species_count(GLOBAL_gb_main), GB_MIND_CASE);
495            GBS_strstruct  *topfile = GBS_stropen(1000);
496            GBS_strstruct  *topmid  = GBS_stropen(10000);
497            {
498                GBS_strstruct *middlefile = GBS_stropen(10000);
499                nt_build_sai_string(topfile, topmid);
500
501                if (use_species_aside) {
502                    Store_species *extra_marked_species = 0;
503                    int            auto_mark            = 0;
504                    int            marked_at_right;
505                   
506                    nt_build_conf_string_rek(used, tree, middlefile, &extra_marked_species, use_species_aside, &auto_mark, use_species_aside, &marked_at_right);
507                    if (extra_marked_species) {
508                        extra_marked_species->call(unmark_species);
509                        delete extra_marked_species;
510                    }
511                }
512                else {
513                    int dummy_1=0, dummy_2;
514                    nt_build_conf_string_rek(used, tree, middlefile, 0, 0, &dummy_1, 0, &dummy_2);
515                }
516                nt_build_conf_marked(used, topmid);
517                char *mid = GBS_strclose(middlefile);
518                GBS_strcat(topmid, mid);
519                free(mid);
520            }
521
522            {
523                char   *middle    = GBS_strclose(topmid);
524                char   *top       = GBS_strclose(topfile);
525                GBDATA *gb_config = GBT_create_configuration(GLOBAL_gb_main, conf_name);
526
527                if (!gb_config) error = GB_await_error();
528                else {
529                    error             = GBT_write_string(gb_config, "top_area", top);
530                    if (!error) error = GBT_write_string(gb_config, "middle_area", middle);
531                }
532
533                free(middle);
534                free(top);
535            }
536            GBS_free_hash(used);
537        }
538    }
539   
540    free(to_free);
541    return error;
542}
543
544static void nt_store_configuration(AW_window *) {
545    GB_ERROR err = nt_create_configuration(0, nt_get_current_tree_root(), 0, 0);
546    aw_message_if(err);
547}
548
549static void nt_rename_configuration(AW_window *aww) {
550    AW_awar  *awar_curr_cfg = aww->get_root()->awar(AWAR_CONFIGURATION);
551    char     *old_name      = awar_curr_cfg->read_string();
552    GB_ERROR  err           = 0;
553
554    GB_transaction dummy(GLOBAL_gb_main);
555
556    char *new_name = aw_input("Rename selection", "Enter the new name of the selection", old_name);
557    if (new_name) {
558        GBDATA *gb_existing_cfg  = GBT_find_configuration(GLOBAL_gb_main, new_name);
559        if (gb_existing_cfg) err = GBS_global_string("There is already a selection named '%s'", new_name);
560        else {
561            GBDATA *gb_old_cfg = GBT_find_configuration(GLOBAL_gb_main, old_name);
562            if (gb_old_cfg) {
563                GBDATA *gb_name = GB_entry(gb_old_cfg, "name");
564                if (gb_name) {
565                    err = GB_write_string(gb_name, new_name);
566                    if (!err) awar_curr_cfg->write_string(new_name);
567                }
568                else err = "Selection has no name";
569            }
570            else err = "Can't find that selection";
571        }
572        free(new_name);
573    }
574
575    if (err) aw_message(err);
576    free(old_name);
577}
578
579static AW_window *create_configuration_admin_window(AW_root *root) {
580    static AW_window_simple *aws = 0;
581    if (!aws) {
582        init_config_awars(root);
583
584        aws = new AW_window_simple;
585        aws->init(root, "SPECIES_SELECTIONS", "Species Selections");
586        aws->load_xfig("nt_selection.fig");
587
588        aws->at("close");
589        aws->callback((AW_CB0)AW_POPDOWN);
590        aws->create_button("CLOSE", "CLOSE", "C");
591
592        aws->at("help");
593        aws->callback(AW_POPUP_HELP, (AW_CL)"configuration.hlp");
594        aws->create_button("HELP", "HELP", "H");
595
596        aws->at("list");
597        awt_create_selection_list_on_configurations(GLOBAL_gb_main, aws, AWAR_CONFIGURATION);
598
599        aws->at("store");
600        aws->callback(nt_store_configuration);
601        aws->create_button("STORE", "STORE", "S");
602
603        aws->at("extract");
604        aws->callback(nt_extract_configuration, CONF_EXTRACT);
605        aws->create_button("EXTRACT", "EXTRACT", "E");
606
607        aws->at("mark");
608        aws->callback(nt_extract_configuration, CONF_MARK);
609        aws->create_button("MARK", "MARK", "M");
610
611        aws->at("unmark");
612        aws->callback(nt_extract_configuration, CONF_UNMARK);
613        aws->create_button("UNMARK", "UNMARK", "U");
614
615        aws->at("invert");
616        aws->callback(nt_extract_configuration, CONF_INVERT);
617        aws->create_button("INVERT", "INVERT", "I");
618
619        aws->at("combine");
620        aws->callback(nt_extract_configuration, CONF_COMBINE);
621        aws->create_button("COMBINE", "COMBINE", "C");
622
623        aws->at("delete");
624        aws->callback(nt_delete_configuration);
625        aws->create_button("DELETE", "DELETE", "D");
626
627        aws->at("rename");
628        aws->callback(nt_rename_configuration);
629        aws->create_button("RENAME", "RENAME", "R");
630    }
631    return aws;
632}
633
634void NT_popup_configuration_admin(AW_window *aw_main, AW_CL, AW_CL) {
635    AW_window *aww = create_configuration_admin_window(aw_main->get_root());
636    aww->activate();
637}
638
639// -----------------------------------------
640//      various ways to start the editor
641
642#define CONFNAME "default_configuration"
643
644static void nt_start_editor_on_configuration(AW_window *aww) {
645    aww->hide();
646
647    const char *cn  = aww->get_root()->awar(AWAR_CONFIGURATION)->read_char_pntr();
648    const char *com = GBS_global_string("arb_edit4 -c '%s' &", cn);
649
650    aw_message_if(GBK_system(com));
651}
652
653AW_window *NT_start_editor_on_old_configuration(AW_root *awr) {
654    static AW_window_simple *aws = 0;
655    if (aws) return (AW_window *)aws;
656    awr->awar_string(AWAR_CONFIGURATION, "default_configuration", GLOBAL_gb_main);
657    aws = new AW_window_simple;
658    aws->init(awr, "SELECT_CONFIGURATION", "SELECT A CONFIGURATION");
659    aws->at(10, 10);
660    aws->auto_space(0, 0);
661    awt_create_selection_list_on_configurations(GLOBAL_gb_main, (AW_window *)aws, AWAR_CONFIGURATION);
662    aws->at_newline();
663
664    aws->callback((AW_CB0)nt_start_editor_on_configuration);
665    aws->create_button("START", "START");
666
667    aws->callback(AW_POPDOWN);
668    aws->create_button("CLOSE", "CLOSE", "C");
669
670    aws->window_fit();
671    return (AW_window *)aws;
672}
673
674void NT_start_editor_on_tree(AW_window *, AW_CL cl_use_species_aside, AW_CL) {
675    GB_ERROR error = nt_create_configuration(0, nt_get_current_tree_root(), CONFNAME, (int)cl_use_species_aside);
676    if (!error) error = GBK_system("arb_edit4 -c " CONFNAME " &");
677    aw_message_if(error);
678}
679
680
Note: See TracBrowser for help on using the repository browser.