source: tags/ms_r16q2/NTREE/NT_extern.cxx

Last change on this file was 14988, checked in by westram, 6 years ago
  • ItemShader_impl now knows its AW_gc_manager
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 71.0 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : NT_extern.cxx                                     //
4//   Purpose   :                                                   //
5//                                                                 //
6//   Institute of Microbiology (Technical University Munich)       //
7//   http://www.arb-home.de/                                       //
8//                                                                 //
9// =============================================================== //
10
11#include "map_viewer.h"
12#include "NT_local.h"
13#include "ad_trees.h"
14
15#include <seq_quality.h>
16#include <multi_probe.hxx>
17#include <st_window.hxx>
18#include <GEN.hxx>
19#include <EXP.hxx>
20
21#include <TreeCallbacks.hxx>
22#include <AW_rename.hxx>
23#include <probe_gui.hxx>
24#include <primer_design.hxx>
25#include <gde.hxx>
26#include <awtc_submission.hxx>
27
28#include <awti_export.hxx>
29
30#include <awt.hxx>
31#include <macros.hxx>
32#include <awt_input_mask.hxx>
33#include <awt_sel_boxes.hxx>
34#include <awt_www.hxx>
35#include <awt_TreeAwars.hxx>
36#include <awt_misc.hxx>
37#include <nds.h>
38
39#include <db_query.h>
40#include <dbui.h>
41
42#include <aw_color_groups.hxx>
43#include <aw_advice.hxx>
44#include <aw_preset.hxx>
45#include <aw_awars.hxx>
46#include <aw_global_awars.hxx>
47#include <aw_file.hxx>
48#include <aw_msg.hxx>
49#include <arb_progress.h>
50#include <aw_root.hxx>
51#include <aw_question.hxx>
52#include <arb_strbuf.h>
53#include <arb_strarray.h>
54#include <arb_file.h>
55#include <ad_cb.h>
56
57#include <arb_version.h>
58#include <refentries.h>
59#include <rootAsWin.h>
60#include <insdel.h>
61#include <awti_import.hxx>
62
63#define AWAR_EXPORT_NDS             "tmp/export_nds"
64#define AWAR_EXPORT_NDS_SEPARATOR   AWAR_EXPORT_NDS "/separator"
65#define AWAR_MARKED_SPECIES_COUNTER "tmp/disp_marked_species"
66#define AWAR_NTREE_TITLE_MODE       "tmp/title_mode"
67
68void create_probe_design_variables(AW_root *aw_root, AW_default def, AW_default global);
69
70void       create_insertDeleteColumn_variables(AW_root *root, AW_default db1);
71AW_window *create_insertDeleteColumn_window(AW_root *root);
72AW_window *create_insertDeleteBySAI_window(AW_root *root, GBDATA *gb_main);
73
74AW_window *create_tree_window(AW_root *aw_root, AWT_graphic *awd);
75
76static void nt_changesecurity(AW_root *aw_root) {
77    int level = aw_root->awar(AWAR_SECURITY_LEVEL)->read_int();
78    GB_push_transaction(GLOBAL.gb_main);
79    GB_change_my_security(GLOBAL.gb_main, level);
80    GB_pop_transaction(GLOBAL.gb_main);
81}
82
83static void export_nds_cb(AW_window *aww, bool do_print) {
84    AW_root *aw_root = aww->get_root();
85    char    *name    = aw_root->awar(AWAR_EXPORT_NDS"/file_name")->read_string();
86    FILE    *out     = fopen(name, "w");
87
88    if (!out) {
89        aw_message("Error: Cannot open and write to file");
90    }
91    else {
92        GB_transaction ta(GLOBAL.gb_main);
93
94        make_node_text_init(GLOBAL.gb_main);
95        NDS_Type  nds_type  = (NDS_Type)aw_root->awar(AWAR_EXPORT_NDS_SEPARATOR)->read_int();
96        char     *tree_name = aw_root->awar(AWAR_TREE)->read_string();
97
98        for (GBDATA *gb_species = GBT_first_marked_species(GLOBAL.gb_main);
99             gb_species;
100             gb_species = GBT_next_marked_species(gb_species))
101        {
102            const char *buf = make_node_text_nds(GLOBAL.gb_main, gb_species, nds_type, 0, tree_name);
103            fprintf(out, "%s\n", buf);
104        }
105        AW_refresh_fileselection(aw_root, AWAR_EXPORT_NDS);
106        fclose(out);
107        if (do_print) {
108            GB_ERROR error = GB_textprint(name);
109            if (error) aw_message(error);
110        }
111        free(tree_name);
112    }
113    free(name);
114}
115
116static AW_window *create_nds_export_window(AW_root *root) {
117    AW_window_simple *aws = new AW_window_simple;
118    aws->init(root, "EXPORT_NDS_OF_MARKED", "EXPORT NDS OF MARKED SPECIES");
119    aws->load_xfig("sel_box_nds.fig");
120
121    aws->callback(AW_POPDOWN);
122    aws->at("close");
123    aws->create_button("CLOSE", "CLOSE", "C");
124
125    aws->callback(makeHelpCallback("arb_export_nds.hlp"));
126    aws->at("help");
127    aws->create_button("HELP", "HELP", "H");
128
129    aws->at("save");
130    aws->callback(makeWindowCallback(export_nds_cb, false));
131    aws->create_button("SAVE", "SAVE", "S");
132
133    aws->at("print");
134    aws->callback(makeWindowCallback(export_nds_cb, true));
135    aws->create_button("PRINT", "PRINT", "P");
136
137    aws->at("toggle1");
138    aws->label("Column output");
139    aws->create_option_menu(AWAR_EXPORT_NDS_SEPARATOR, true);
140    aws->insert_default_option("Space padded",    "S", NDS_OUTPUT_SPACE_PADDED);
141    aws->insert_option        ("TAB separated",   "T", NDS_OUTPUT_TAB_SEPARATED);
142    aws->insert_option        ("Comma separated", "C", NDS_OUTPUT_COMMA_SEPARATED);
143    aws->update_option_menu();
144
145    AW_create_standard_fileselection(aws, AWAR_EXPORT_NDS);
146
147    return aws;
148}
149
150static void create_export_nds_awars(AW_root *awr, AW_default def)
151{
152    AW_create_fileselection_awars(awr, AWAR_EXPORT_NDS, "", ".nds", "export.nds");
153    awr->awar_int(AWAR_EXPORT_NDS_SEPARATOR, NDS_OUTPUT_SPACE_PADDED, def);
154}
155
156static void AWAR_INFO_BUTTON_TEXT_change_cb(AW_root *awr) {
157    char *value = awr->awar(AWAR_SPECIES_NAME)->read_string();
158    awr->awar(AWAR_INFO_BUTTON_TEXT)->write_string(value[0] ? value : "Species Info");
159    free(value);
160}
161
162static void expert_mode_changed_cb(AW_root *aw_root) {
163    aw_root->awar(AWAR_AWM_MASK)->write_int(aw_root->awar(AWAR_EXPERT)->read_int() ? AWM_ALL : AWM_BASIC); // publish expert-mode globally
164}
165
166static void NT_toggle_expert_mode(AW_window *aww) { aww->get_root()->awar(AWAR_EXPERT)->toggle_toggle(); }
167#if defined(ARB_MOTIF)
168static void NT_toggle_focus_policy(AW_window *aww) { aww->get_root()->awar(AWAR_AW_FOCUS_FOLLOWS_MOUSE)->toggle_toggle(); }
169#endif
170
171static void nt_create_all_awars(AW_root *awr) {
172    // creates awars for all modules reachable from ARB_NT main window
173
174    awr->awar_string(AWAR_FOOTER, "", AW_ROOT_DEFAULT);
175    if (GB_read_clients(GLOBAL.gb_main)>=0) {
176        awr->awar_string(AWAR_TREE, "", GLOBAL.gb_main);
177    }
178    else {
179        awr->awar_string(AWAR_TREE, "", AW_ROOT_DEFAULT);
180    }
181
182    awr->awar_string(AWAR_SPECIES_NAME, "",     GLOBAL.gb_main);
183    awr->awar_string(AWAR_SAI_NAME, "",     GLOBAL.gb_main);
184    awr->awar_string(AWAR_SAI_GLOBAL, "",     GLOBAL.gb_main);
185    awr->awar_string(AWAR_MARKED_SPECIES_COUNTER, "unknown",    GLOBAL.gb_main);
186    awr->awar_string(AWAR_INFO_BUTTON_TEXT, "Species Info",    GLOBAL.gb_main);
187    awr->awar(AWAR_SPECIES_NAME)->add_callback(AWAR_INFO_BUTTON_TEXT_change_cb);
188    awr->awar_int(AWAR_NTREE_TITLE_MODE, 1);
189
190    awr->awar_string(AWAR_SAI_COLOR_STR, "", GLOBAL.gb_main); // sai visualization in probe match
191
192    GEN_create_awars(awr, AW_ROOT_DEFAULT, GLOBAL.gb_main);
193    EXP_create_awars(awr, AW_ROOT_DEFAULT, GLOBAL.gb_main);
194#if defined(DEBUG)
195    AWT_create_db_browser_awars(awr, AW_ROOT_DEFAULT);
196#endif // DEBUG
197
198    AW_create_namesadmin_awars(awr, GLOBAL.gb_main);
199
200    awr->awar_int(AWAR_SECURITY_LEVEL, 0, AW_ROOT_DEFAULT);
201    awr->awar(AWAR_SECURITY_LEVEL)->add_callback(nt_changesecurity);
202#if defined(DEBUG) && 0
203    awr->awar(AWAR_SECURITY_LEVEL)->write_int(6); // no security for debugging..
204#endif // DEBUG
205
206    create_insertDeleteColumn_variables(awr, AW_ROOT_DEFAULT);
207    create_probe_design_variables(awr, AW_ROOT_DEFAULT, GLOBAL.gb_main);
208    create_primer_design_variables(awr, AW_ROOT_DEFAULT, GLOBAL.gb_main);
209    create_trees_var(awr, AW_ROOT_DEFAULT);
210    DBUI::create_dbui_awars(awr);
211    AP_create_consensus_var(awr, AW_ROOT_DEFAULT);
212    {
213        GB_ERROR gde_err = GDE_init(awr, AW_ROOT_DEFAULT, GLOBAL.gb_main, 0, ARB_format_alignment, GDE_WINDOWTYPE_DEFAULT);
214        if (gde_err) GBK_terminatef("Fatal: %s", gde_err);
215    }
216    NT_create_transpro_variables(awr, AW_ROOT_DEFAULT);
217    NT_create_resort_awars(awr, AW_ROOT_DEFAULT);
218    NT_create_compare_taxonomy_awars(awr, AW_ROOT_DEFAULT);
219    NT_create_trackAliChanges_Awars(awr, GLOBAL.gb_main);
220
221    NT_create_alignment_vars(awr, AW_ROOT_DEFAULT, GLOBAL.gb_main);
222    NT_create_extendeds_vars(awr, AW_ROOT_DEFAULT, GLOBAL.gb_main);
223    create_nds_vars(awr, AW_ROOT_DEFAULT, GLOBAL.gb_main, false);
224    create_export_nds_awars(awr, AW_ROOT_DEFAULT);
225    TREE_create_awars(awr, GLOBAL.gb_main);
226
227    awr->awar_string(AWAR_ERROR_MESSAGES, "", GLOBAL.gb_main);
228    awr->awar_string(AWAR_DB_COMMENT, "<no description>", GLOBAL.gb_main);
229
230    AWTC_create_submission_variables(awr, GLOBAL.gb_main);
231    NT_createConcatenationAwars(awr, AW_ROOT_DEFAULT, GLOBAL.gb_main);
232    NT_createValidNamesAwars(awr, AW_ROOT_DEFAULT); // lothar
233    SQ_create_awars(awr, AW_ROOT_DEFAULT);
234    RefEntries::create_refentries_awars(awr, AW_ROOT_DEFAULT);
235
236    NT_create_multifurcate_tree_awars(awr, AW_ROOT_DEFAULT);
237
238    GB_ERROR error = ARB_bind_global_awars(GLOBAL.gb_main);
239    if (!error) {
240        AW_awar *awar_expert = awr->awar(AWAR_EXPERT);
241        awar_expert->add_callback(expert_mode_changed_cb);
242        awar_expert->touch();
243
244        awt_create_aww_vars(awr, AW_ROOT_DEFAULT);
245    }
246
247    if (error) aw_message(error);
248}
249
250// --------------------------------------------------------------------------------
251
252bool nt_disconnect_from_db(AW_root *aw_root, GBDATA*& gb_main_ref) {
253    // ask user if DB was not saved
254    // returns true if user allows to quit
255
256    // @@@ code here could as well be applied to both merge DBs
257    // - question about saving only with target DB!
258
259    if (gb_main_ref) {
260        if (GB_read_clients(gb_main_ref)>=0) {
261            if (GB_read_clock(gb_main_ref) > GB_last_saved_clock(gb_main_ref)) {
262                long secs;
263                secs = GB_last_saved_time(gb_main_ref);
264
265#if defined(DEBUG)
266                secs =  GB_time_of_day(); // simulate "just saved"
267#endif // DEBUG
268
269                const char *quit_buttons = "Quit ARB,Do NOT quit";
270                if (secs) {
271                    secs = GB_time_of_day() - secs;
272                    if (secs>10) {
273                        char *question = GBS_global_string_copy("You last saved your data %li:%li minutes ago\nSure to quit ?", secs/60, secs%60);
274                        int   dontQuit = aw_question("quit_arb", question, quit_buttons);
275                        free(question);
276                        if (dontQuit) {
277                            return false;
278                        }
279                    }
280                }
281                else {
282                    if (aw_question("quit_arb", "You never saved any data\nSure to quit ???", quit_buttons)) {
283                        return false;
284                    }
285                }
286            }
287        }
288
289        GBCMS_shutdown(gb_main_ref);
290
291        GBDATA *gb_main = gb_main_ref;
292        gb_main_ref     = NULL;                  // avoid further usage
293
294        nt_assert(aw_root);
295#if defined(WARN_TODO)
296#warning instead of directly calling the following functions, try to add them as GB_atclose-callbacks
297#endif
298        aw_root->unlink_awars_from_DB(gb_main);
299        AWT_destroy_input_masks();
300#if defined(DEBUG)
301        AWT_browser_forget_db(gb_main);
302#endif // DEBUG
303
304        GB_close(gb_main);
305    }
306    return true;
307}
308
309static void nt_run(const char *command) {
310    GB_ERROR error = GBK_system(command);
311    if (error) {
312        fprintf(stderr, "nt_run: Failed to run '%s' (Reason: %s)\n", command, error);
313#if defined(DEBUG)
314        GBK_dump_backtrace(stderr, "nt_run-error");
315#endif
316    }
317}
318
319void NT_start(const char *arb_ntree_args, bool restart_with_new_ARB_PID) {
320    char *command = GBS_global_string_copy("arb_launcher --async %s %s", restart_with_new_ARB_PID ? "arb" : "arb_ntree", arb_ntree_args);
321    nt_run(command);
322    free(command);
323}
324
325__ATTR__NORETURN static void really_exit(int exitcode, bool kill_my_clients) {
326    if (kill_my_clients) {
327        nt_run("(arb_clean session; echo ARB done) &"); // kills all clients
328    }
329    exit(exitcode);
330}
331
332void NT_exit(AW_window *aws, int exitcode) {
333    AW_root *aw_root = aws->get_root();
334    AWTI_cleanup_importer();
335    shutdown_macro_recording(aw_root);
336    bool is_server_and_has_clients = GLOBAL.gb_main && GB_read_clients(GLOBAL.gb_main)>0;
337    if (nt_disconnect_from_db(aw_root, GLOBAL.gb_main)) {
338        really_exit(exitcode, is_server_and_has_clients);
339    }
340}
341void NT_restart(AW_root *aw_root, const char *arb_ntree_args) {
342    // restarts arb_ntree (with new ARB_PID)
343    bool is_server_and_has_clients = GLOBAL.gb_main && GB_read_clients(GLOBAL.gb_main)>0;
344    if (nt_disconnect_from_db(aw_root, GLOBAL.gb_main))  {
345        NT_start(arb_ntree_args, true);
346        really_exit(EXIT_SUCCESS, is_server_and_has_clients);
347    }
348}
349
350static void nt_start_2nd_arb(AW_window *aww, bool quit) {
351    // start 2nd arb with intro window
352    AW_root *aw_root = aww->get_root();
353    char    *dir4intro;
354    GB_split_full_path(aw_root->awar(AWAR_DB_PATH)->read_char_pntr(), &dir4intro, NULL, NULL, NULL);
355    if (!dir4intro) {
356        dir4intro = strdup(".");
357    }
358
359    if (quit) {
360        NT_restart(aw_root, dir4intro);
361    }
362    else {
363        NT_start(dir4intro, true);
364    }
365    free(dir4intro);
366}
367
368// --------------------------------------------------------------------------------
369
370static void NT_save_quick_cb(AW_window *aww) {
371    AW_root *awr      = aww->get_root();
372    char    *filename = awr->awar(AWAR_DB_PATH)->read_string();
373
374    awr->dont_save_awars_with_default_value(GLOBAL.gb_main);
375
376    GB_ERROR error = GB_save_quick(GLOBAL.gb_main, filename);
377    free( filename);
378    if (error) aw_message(error);
379    else       AW_refresh_fileselection(awr, AWAR_DBBASE);
380}
381
382
383static void NT_save_quick_as_cb(AW_window *aww) {
384    AW_root  *awr      = aww->get_root();
385    char     *filename = awr->awar(AWAR_DB_PATH)->read_string();
386    GB_ERROR  error    = GB_save_quick_as(GLOBAL.gb_main, filename);
387    if (!error) AW_refresh_fileselection(awr, AWAR_DBBASE);
388    aww->hide_or_notify(error);
389
390    free(filename);
391}
392
393#define AWAR_DB_TYPE          AWAR_DBBASE "/type"      // created by AWT_insert_DBsaveType_selector
394#define AWAR_DB_COMPRESSION   AWAR_DBBASE "/compression" // created by AWT_insert_DBcompression_selector
395#define AWAR_DB_OPTI_TREENAME AWAR_DBBASE "/optimize_tree_name"
396
397static void NT_save_as_cb(AW_window *aww) {
398    AW_root    *awr      = aww->get_root();
399    char       *filename = awr->awar(AWAR_DB_PATH)->read_string();
400    const char *atype    = awr->awar(AWAR_DB_TYPE)->read_char_pntr();
401    const char *ctype    = awr->awar(AWAR_DB_COMPRESSION)->read_char_pntr();
402    char       *savetype = GBS_global_string_copy("%s%s", atype, ctype);
403
404    awr->dont_save_awars_with_default_value(GLOBAL.gb_main);
405    GB_ERROR error = GB_save(GLOBAL.gb_main, filename, savetype);
406    if (!error) AW_refresh_fileselection(awr, AWAR_DBBASE);
407    aww->hide_or_notify(error);
408
409    free(savetype);
410    free(filename);
411}
412
413static AW_window *NT_create_save_quick_as_window(AW_root *aw_root, const char *base_name) {
414    static AW_window_simple *aws = 0;
415    if (!aws) {
416        aws = new AW_window_simple;
417        aws->init(aw_root, "SAVE_CHANGES_TO", "Quicksave changes as");
418        aws->load_xfig("save_as.fig");
419
420        aws->at("close");
421        aws->callback(AW_POPDOWN);
422        aws->create_button("CLOSE", "CLOSE", "C");
423
424        aws->callback(makeHelpCallback("save.hlp"));
425        aws->at("help");
426        aws->create_button("HELP", "HELP", "H");
427
428        AW_create_standard_fileselection(aws, base_name);
429
430        aws->at("comment");
431        aws->create_text_field(AWAR_DB_COMMENT);
432
433        aws->at("save");
434        aws->callback(NT_save_quick_as_cb);
435        aws->create_button("SAVE", "SAVE", "S");
436    }
437    return aws;
438}
439
440static void NT_database_optimization(AW_window *aww) {
441    arb_progress progress("Optimizing database compression", 2);
442
443    GB_push_my_security(GLOBAL.gb_main);
444    GB_ERROR error = GB_begin_transaction(GLOBAL.gb_main);
445    if (!error) {
446        ConstStrArray ali_names;
447        GBT_get_alignment_names(ali_names, GLOBAL.gb_main);
448
449        arb_progress ali_progress("Optimizing sequence data", ali_names.size());
450        ali_progress.allow_title_reuse();
451
452        error = GBT_check_data(GLOBAL.gb_main, 0);
453        error = GB_end_transaction(GLOBAL.gb_main, error);
454
455        if (!error) {
456            char *tree_name = aww->get_root()->awar(AWAR_DB_OPTI_TREENAME)->read_string();
457            for (int i = 0; ali_names[i]; ++i) {
458                error = GBT_compress_sequence_tree2(GLOBAL.gb_main, tree_name, ali_names[i]);
459                ali_progress.inc_and_check_user_abort(error);
460            }
461            free(tree_name);
462        }
463    }
464    progress.inc_and_check_user_abort(error);
465
466    if (!error) {
467        error = GB_optimize(GLOBAL.gb_main);
468        progress.inc_and_check_user_abort(error);
469    }
470
471    GB_pop_my_security(GLOBAL.gb_main);
472    aww->hide_or_notify(error);
473}
474
475static AW_window *NT_create_database_optimization_window(AW_root *aw_root) {
476    static AW_window_simple *aws = 0;
477    if (aws) return (AW_window *)aws;
478    GB_transaction ta(GLOBAL.gb_main);
479
480    const char *largest_tree = GBT_name_of_largest_tree(GLOBAL.gb_main);
481    aw_root->awar_string(AWAR_DB_OPTI_TREENAME, largest_tree);
482
483    aws = new AW_window_simple;
484    aws->init(aw_root, "OPTIMIZE_DATABASE", "Optimize database compression");
485    aws->load_xfig("optimize.fig");
486
487    aws->at("trees");
488    awt_create_TREE_selection_list(GLOBAL.gb_main, aws, AWAR_DB_OPTI_TREENAME, true);
489
490    aws->at("close");
491    aws->callback(AW_POPDOWN);
492    aws->create_button("CLOSE", "CLOSE", "C");
493
494    aws->callback(makeHelpCallback("optimize.hlp"));
495    aws->at("help");
496    aws->create_button("HELP", "HELP", "H");
497
498    aws->at("go");
499    aws->callback(NT_database_optimization);
500    aws->create_button("GO", "GO");
501    return aws;
502}
503
504static AW_window *NT_create_save_as(AW_root *aw_root, const char *base_name)
505{
506    static AW_window_simple *aws = 0;
507    if (aws) return (AW_window *)aws;
508
509    aws = new AW_window_simple;
510    aws->init(aw_root, "SAVE_DB", "SAVE ARB DB");
511    aws->load_xfig("save_as.fig");
512
513    aws->at("close");
514    aws->callback(AW_POPDOWN);
515    aws->create_button("CLOSE", "CLOSE", "C");
516
517    aws->at("help");
518    aws->callback(makeHelpCallback("save.hlp"));
519    aws->create_button("HELP", "HELP", "H");
520
521    AW_create_standard_fileselection(aws, base_name);
522
523    aws->at("type");
524    AWT_insert_DBsaveType_selector(aws, AWAR_DB_TYPE);
525
526    aws->at("compression");
527    AWT_insert_DBcompression_selector(aws, AWAR_DB_COMPRESSION);
528
529    aws->at("optimize");
530    aws->callback(NT_create_database_optimization_window);
531    aws->help_text("optimize.hlp");
532    aws->create_autosize_button("OPTIMIZE", "Optimize database compression");
533
534    aws->at("save");
535    aws->callback(NT_save_as_cb);
536    aws->create_button("SAVE", "SAVE", "S");
537
538    aws->at("comment");
539    aws->create_text_field(AWAR_DB_COMMENT);
540
541    return aws;
542}
543
544static void NT_undo_cb(AW_window*, GB_UNDO_TYPE undo_type, AWT_canvas *ntw) {
545    GB_ERROR error = GB_undo(GLOBAL.gb_main, undo_type);
546    if (error) aw_message(error);
547    else {
548        GB_transaction ta(GLOBAL.gb_main);
549        ntw->refresh();
550    }
551}
552
553enum streamSource { FROM_PIPE, FROM_FILE };
554static char *stream2str(streamSource source, const char *commandOrFile) {
555    char *output = 0;
556    FILE *in     = 0;
557
558    switch (source) {
559        case FROM_PIPE: in = popen(commandOrFile, "r"); break;
560        case FROM_FILE: in = fopen(commandOrFile, "rt"); break;
561    }
562
563    if (in) {
564        GBS_strstruct *out = GBS_stropen(2000);
565        int c;
566
567        while (EOF != (c = fgetc(in))) GBS_chrcat(out, c);
568
569        switch (source) {
570            case FROM_PIPE: pclose(in); break;
571            case FROM_FILE: fclose(in); break;
572        }
573
574        // skip trailing linefeeds
575        long offset = GBS_memoffset(out);
576        while (offset>0 && GBS_mempntr(out)[offset-1] == '\n') {
577            GBS_str_cut_tail(out, 1);
578            offset--;
579        }
580
581        output = GBS_strclose(out);
582    }
583    return output;
584}
585
586inline void removeTrailingNewlines(char *str) {
587    char *eos = strchr(str, 0)-1;
588    while (eos >= str && eos[0] == '\n') *eos-- = 0;
589}
590
591inline void append_named_value(GBS_strstruct *out, const char *prefix, const char *value) {
592    GBS_strcat(out, GBS_global_string("%-*s: %s\n", 12, prefix, value));
593}
594inline void append_command_output(GBS_strstruct *out, const char *prefix, const char *command) {
595    char *output = stream2str(FROM_PIPE, command);
596    if (output) {
597        removeTrailingNewlines(output);
598        if (strcmp(output, "unknown") != 0) append_named_value(out, prefix, output);
599        free(output);
600    }
601}
602
603static void NT_infomode_cb(UNFIXED, AWT_canvas *canvas, AWT_COMMAND_MODE mode) {
604    DBUI::popup_species_info_window(canvas->awr, canvas->gb_main);
605    nt_mode_event(NULL, canvas, mode);
606}
607
608static void NT_primer_cb(AW_window*) {
609    GB_ERROR error = GB_xcmd("arb_primer", true, false);
610    if (error) aw_message(error);
611}
612
613static void NT_mark_duplicates(UNFIXED, AWT_canvas *ntw) {
614    AP_tree *tree_root = AWT_TREE(ntw)->get_root_node();
615    if (tree_root) {
616        GB_transaction ta(ntw->gb_main);
617        NT_mark_all_cb(NULL, ntw, 0);
618
619        tree_root->mark_duplicates();
620        tree_root->compute_tree();
621        ntw->refresh();
622    }
623}
624
625static void NT_justify_branch_lenghs(UNFIXED, AWT_canvas *ntw) {
626    GB_transaction  ta(ntw->gb_main);
627    AP_tree        *tree_root = AWT_TREE(ntw)->get_root_node();
628
629    if (tree_root) {
630        tree_root->justify_branch_lenghs(ntw->gb_main);
631        tree_root->compute_tree();
632        GB_ERROR error = AWT_TREE(ntw)->save(ntw->gb_main, NULL);
633        if (error) aw_message(error);
634        ntw->refresh();
635    }
636}
637
638#if defined(DEBUG)
639static void NT_fix_database(AW_window *) {
640    GB_ERROR err = 0;
641    err = GB_fix_database(GLOBAL.gb_main);
642    if (err) aw_message(err);
643}
644#endif
645
646static void relink_pseudo_species_to_organisms(GBDATA *&ref_gb_node, char *&ref_name, GB_HASH *organism_hash) {
647    if (ref_gb_node) {
648        if (GEN_is_pseudo_gene_species(ref_gb_node)) {
649            GBDATA *gb_organism = GEN_find_origin_organism(ref_gb_node, organism_hash);
650
651            if (gb_organism) {
652                char *name = GBT_read_string(gb_organism, "name");
653
654                if (name) {
655                    freeset(ref_name, name);
656                    ref_gb_node = gb_organism;
657                }
658            }
659        }
660    }
661}
662
663static void NT_pseudo_species_to_organism(AW_window *, AWT_canvas *ntw) {
664    GB_transaction  ta(ntw->gb_main);
665    AP_tree        *tree_root = AWT_TREE(ntw)->get_root_node();
666
667    if (tree_root) {
668        GB_HASH *organism_hash = GBT_create_organism_hash(ntw->gb_main);
669        tree_root->relink_tree(ntw->gb_main, relink_pseudo_species_to_organisms, organism_hash);
670        tree_root->compute_tree();
671        GB_ERROR error = AWT_TREE(ntw)->save(ntw->gb_main, NULL);
672        if (error) aw_message(error);
673        ntw->refresh();
674        GBS_free_hash(organism_hash);
675    }
676}
677
678
679// #########################################
680// #########################################
681// ###                                   ###
682// ##          user mask section          ##
683// ###                                   ###
684// #########################################
685// #########################################
686
687struct nt_item_type_species_selector : public awt_item_type_selector {
688    nt_item_type_species_selector() : awt_item_type_selector(AWT_IT_SPECIES) {}
689    virtual ~nt_item_type_species_selector() OVERRIDE {}
690
691    virtual const char *get_self_awar() const OVERRIDE {
692        return AWAR_SPECIES_NAME;
693    }
694    virtual size_t get_self_awar_content_length() const OVERRIDE {
695        return 12; // should be enough for "nnaammee.999"
696    }
697    virtual GBDATA *current(AW_root *root, GBDATA *gb_main) const OVERRIDE { // give the current item
698        char           *species_name = root->awar(get_self_awar())->read_string();
699        GBDATA         *gb_species   = 0;
700
701        if (species_name[0]) {
702            GB_transaction ta(gb_main);
703            gb_species = GBT_find_species(gb_main, species_name);
704        }
705
706        free(species_name);
707        return gb_species;
708    }
709    virtual const char *getKeyPath() const OVERRIDE { // give the keypath for items
710        return CHANGE_KEY_PATH;
711    }
712};
713
714static nt_item_type_species_selector item_type_species;
715
716static void NT_open_mask_window(AW_window *aww, int id, GBDATA *gb_main) {
717    const awt_input_mask_descriptor *descriptor = AWT_look_input_mask(id);
718    nt_assert(descriptor);
719    if (descriptor) AWT_initialize_input_mask(aww->get_root(), gb_main, &item_type_species, descriptor->get_internal_maskname(), descriptor->is_local_mask());
720}
721
722static void NT_create_mask_submenu(AW_window_menu_modes *awm) {
723    AWT_create_mask_submenu(awm, AWT_IT_SPECIES, NT_open_mask_window, GLOBAL.gb_main);
724}
725static AW_window *create_colorize_species_window(AW_root *aw_root) {
726    return QUERY::create_colorize_items_window(aw_root, GLOBAL.gb_main, SPECIES_get_selector());
727}
728
729static void NT_update_marked_counter(GBDATA*, AW_window* aww) {
730    /*! Updates marked counter and issues redraw on tree if number of marked species changes.
731     * Called on any change of species_information container.
732     */
733    long        count   = GBT_count_marked_species(GLOBAL.gb_main);
734    const char *buffer  = count ? GBS_global_string("%li marked", count) : "";
735    AW_awar    *counter = aww->get_root()->awar(AWAR_MARKED_SPECIES_COUNTER);
736    char       *oldval  = counter->read_string();
737    if (strcmp(oldval, buffer)) {
738        counter->write_string(buffer);
739        aww->get_root()->awar(AWAR_TREE_REFRESH)->touch();
740    }
741    free(oldval);
742}
743
744// --------------------------------------------------------------------------------------------------
745
746static void NT_alltree_remove_leafs(AW_window *, GBT_TreeRemoveType mode, GBDATA *gb_main) {
747    GB_ERROR       error = 0;
748    GB_transaction ta(gb_main);
749
750    ConstStrArray tree_names;
751    GBT_get_tree_names(tree_names, gb_main, false);
752
753    if (!tree_names.empty()) {
754        int treeCount = tree_names.size();
755
756        const char *whats_removed = NULL;
757        switch (mode) {
758            case GBT_REMOVE_ZOMBIES: whats_removed = "zombies"; break;
759            case GBT_REMOVE_MARKED:  whats_removed = "marked";  break;
760            default: nt_assert(0); break;
761        }
762
763        const char *task = GBS_global_string("Deleting %s from %i trees", whats_removed, treeCount);
764
765        arb_progress  progress(task, treeCount);
766        GB_HASH      *species_hash = GBT_create_species_hash(gb_main);
767
768        int modified = 0;
769
770        for (int t = 0; t<treeCount && !error; t++) {
771            progress.subtitle(tree_names[t]);
772            TreeNode *tree = GBT_read_tree(gb_main, tree_names[t], new SimpleRoot);
773            if (!tree) {
774                aw_message(GBS_global_string("Can't load tree '%s' - skipped", tree_names[t]));
775            }
776            else {
777                int removed        = 0;
778                int groups_removed = 0;
779
780                tree = GBT_remove_leafs(tree, mode, species_hash, &removed, &groups_removed);
781
782                nt_assert(removed >= groups_removed);
783
784                if (!tree) {
785                    aw_message(GBS_global_string("'%s' would disappear. Please delete tree manually.", tree_names[t]));
786                }
787                else {
788                    if (removed>0) {
789                        error = GBT_write_tree(gb_main, tree_names[t], tree);
790                        if (error) {
791                            aw_message(GBS_global_string("Failed to write '%s' (Reason: %s)", tree_names[t], error));
792                        }
793                        else {
794                            if (groups_removed>0) {
795                                aw_message(GBS_global_string("Removed %i species and %i groups from '%s'", removed, groups_removed, tree_names[t]));
796                            }
797                            else {
798                                aw_message(GBS_global_string("Removed %i species from '%s'", removed, tree_names[t]));
799                            }
800                            modified++;
801                        }
802                    }
803                    UNCOVERED();
804                    destroy(tree);
805                }
806            }
807            progress.inc_and_check_user_abort(error);
808        }
809
810        if (modified) {
811            aw_message(GBS_global_string("Changed %i of %i trees.", modified, treeCount));
812        }
813        else {
814            aw_message("No tree modified");
815        }
816
817        GBS_free_hash(species_hash);
818    }
819
820    aw_message_if(ta.close(error));
821}
822
823TreeNode *NT_get_tree_root_of_canvas(AWT_canvas *ntw) {
824    AWT_graphic_tree *tree = AWT_TREE(ntw);
825    if (tree) {
826        AP_tree *root = tree->get_root_node();
827        if (root) return root;
828    }
829    return NULL;
830}
831
832// --------------------------------------------------------------------------------------------------
833
834static ARB_ERROR mark_referred_species(GBDATA *gb_main, const DBItemSet& referred) {
835    GB_transaction ta(gb_main);
836    GBT_mark_all(gb_main, 0);
837
838    DBItemSetIter end = referred.end();
839    for (DBItemSetIter s = referred.begin(); s != end; ++s) {
840        GB_write_flag(*s, 1);
841    }
842    return ARB_ERROR();
843}
844
845static AW_window *create_mark_by_refentries_window(AW_root *awr, GBDATA *gbmain) {
846    static AW_window *aws = NULL;
847    if (!aws) {
848        static RefEntries::ReferringEntriesHandler reh(gbmain, SPECIES_get_selector());
849        aws = RefEntries::create_refentries_window(awr, &reh, "markbyref", "Mark by reference", "markbyref.hlp", NULL, "Mark referenced", mark_referred_species);
850    }
851    return aws;
852}
853
854// --------------------------------------------------------------------------------------------------
855
856static void merge_from_to(AW_root *awr, const char *db_awar_name, bool merge_to) {
857    const char *db_name  = awr->awar(db_awar_name)->read_char_pntr();
858    char       *quotedDB = GBK_singlequote(db_name);
859
860    char *cmd = GBS_global_string_copy(
861        merge_to
862        ? "arb_ntree : %s &"
863        : "arb_ntree %s : &",
864        quotedDB);
865
866    aw_message_if(GBK_system(cmd));
867    free(cmd);
868    free(quotedDB);
869}
870
871static void merge_from_cb(AW_window *aww, AW_CL cl_awarNamePtr) { merge_from_to(aww->get_root(), *(const char**)cl_awarNamePtr, false); }
872static void merge_into_cb(AW_window *aww, AW_CL cl_awarNamePtr) { merge_from_to(aww->get_root(), *(const char**)cl_awarNamePtr, true); }
873
874static AW_window *NT_create_merge_from_window(AW_root *awr) {
875    static char *awar_name = NULL; // do not free, bound to callback
876    AW_window *aw_from     =
877        awt_create_load_box(awr, "Merge data from", "other ARB database",
878                            ".", ".arb", &awar_name,
879                            makeWindowCallback(merge_from_cb, AW_CL(&awar_name)));
880    return aw_from;
881}
882static AW_window *NT_create_merge_to_window(AW_root *awr) {
883    static char *awar_name = NULL; // do not free, bound to callback
884    AW_window *aw_to       =
885        awt_create_load_box(awr, "Merge data to", "other ARB database",
886                            ".", ".arb", &awar_name,
887                            makeWindowCallback(merge_into_cb, AW_CL(&awar_name)),
888                            makeWindowCallback(AW_POPDOWN), NULL);
889    return aw_to;
890}
891
892// --------------------------------------------------------------------------------------------------
893
894int NT_get_canvas_id(AWT_canvas *ntw) {
895    // return number of canvas [0..MAX_NT_WINDOWS-1]
896
897    const char *tree_awar_name = ntw->user_awar;
898
899    const unsigned LEN = 15;
900#if defined(ASSERTION_USED)
901    const char *EXPECT = "focus/tree_name";
902#endif
903
904    nt_assert(strlen(EXPECT)                      == LEN);
905    nt_assert(memcmp(tree_awar_name, EXPECT, LEN) == 0);
906
907    int id;
908    switch (tree_awar_name[LEN]) {
909        default :
910            nt_assert(0);
911            // NDEBUG: fallback to 0
912        case 0:
913            id = 0;
914            break;
915
916        case '_':
917            id = atoi(tree_awar_name+LEN+1);
918            nt_assert(id >= 1);
919            break;
920    }
921    return id;
922}
923
924static void update_main_window_title(AW_root* awr, AW_window_menu_modes* aww, int clone) {
925    const char* filename = awr->awar(AWAR_DB_NAME)->read_char_pntr();
926    if (clone) {
927        aww->set_window_title(GBS_global_string("%s - ARB (%i)",  filename, clone));
928    }
929    else {
930        aww->set_window_title(GBS_global_string("%s - ARB", filename));
931    }
932}
933
934static void canvas_tree_awar_changed_cb(AW_awar *, bool, AWT_canvas *ntw) {
935    NT_reload_tree_event(AW_root::SINGLETON, ntw, true);
936}
937
938// ##########################################
939// ##########################################
940// ###                                    ###
941// ##          create main window          ##
942// ###                                    ###
943// ##########################################
944// ##########################################
945
946static AW_window *popup_new_main_window(AW_root *awr, int clone, AWT_canvas **result_ntw) {
947    /*! create ARB_NTREE main window
948     * @param awr application root
949     * @param clone == 0 -> first window (full functionality); >0 -> additional tree views (restricted functionality)
950     * @param result_ntw is set to the created AWT_canvas (passed pointer may be NULL if result is not needed)
951     */
952    GB_push_transaction(GLOBAL.gb_main);
953
954    char        window_title[256];
955    const char *awar_tree = NULL;
956
957    if (clone) {
958        awar_tree = GB_keep_string(GBS_global_string_copy(AWAR_TREE "_%i", clone));
959        sprintf(window_title, "ARB_NT_%i", clone);
960    }
961    else {
962        awar_tree = AWAR_TREE;
963        sprintf(window_title, "ARB_NT");
964    }
965    AW_window_menu_modes *awm = new AW_window_menu_modes;
966    awm->init(awr, window_title, window_title, 0, 0);
967
968    awr->awar(AWAR_DB_NAME)
969       ->add_callback(makeRootCallback(update_main_window_title, awm, clone))
970       ->update();
971
972    awm->button_length(5);
973
974    if (!clone) AW_init_color_group_defaults("arb_ntree");
975
976    AWT_graphic_tree *tree = NT_generate_tree(awr, GLOBAL.gb_main, launch_MapViewer_cb);
977
978    AWT_canvas *ntw;
979    {
980        AP_tree_display_type old_sort_type = tree->tree_sort;
981        tree->set_tree_type(AP_LIST_SIMPLE, NULL); // avoid NDS warnings during startup
982
983        ntw = new AWT_canvas(GLOBAL.gb_main, awm, "ARB_NT", tree, awar_tree);
984        tree->set_tree_type(old_sort_type, ntw);
985        ntw->set_mode(AWT_MODE_SELECT);
986    }
987
988    if (result_ntw) *result_ntw = ntw;
989
990    {
991        AW_awar    *tree_awar          = awr->awar_string(awar_tree);
992        const char *tree_name          = tree_awar->read_char_pntr();
993        const char *existing_tree_name = GBT_existing_tree(GLOBAL.gb_main, tree_name);
994
995        if (existing_tree_name) {
996            tree_awar->write_string(existing_tree_name);
997            NT_reload_tree_event(awr, ntw, true); // load first tree
998        }
999        else {
1000            AW_advice("Your database contains no tree.", AW_ADVICE_TOGGLE_AND_HELP, 0, "no_tree.hlp");
1001            tree->set_tree_type(AP_LIST_NDS, ntw); // no tree -> show NDS list
1002        }
1003
1004        AWT_registerTreeAwarCallback(tree_awar, makeTreeAwarCallback(canvas_tree_awar_changed_cb, ntw), false);
1005    }
1006
1007    TREE_install_update_callbacks(ntw);
1008    awr->awar(AWAR_TREE_NAME)->add_callback(makeRootCallback(TREE_auto_jump_cb, ntw, true)); // NT specific (tree name never changes in parsimony!)
1009
1010    bool is_genome_db = GEN_is_genome_db(GLOBAL.gb_main, 0); //  is this a genome database ? (default = 0 = not a genom db)
1011
1012    WindowCallback popupinfo_wcb = RootAsWindowCallback::simple(DBUI::popup_species_info_window, GLOBAL.gb_main);
1013
1014    // --------------
1015    //      File
1016
1017#if defined(DEBUG)
1018    AWT_create_debug_menu(awm);
1019#endif // DEBUG
1020
1021    bool allow_new_window = (NT_get_canvas_id(ntw)+1) < MAX_NT_WINDOWS;
1022
1023    if (clone) {
1024        awm->create_menu("File", "F", AWM_ALL);
1025        if (allow_new_window) {
1026            awm->insert_menu_topic(awm->local_id("new_window"), "New window (same database)", "N", "newwindow.hlp", AWM_ALL, makeCreateWindowCallback(popup_new_main_window, clone+1, (AWT_canvas**)NULL));
1027        }
1028        awm->insert_menu_topic("close", "Close", "C", 0, AWM_ALL, AW_POPDOWN);
1029    }
1030    else {
1031#if defined(DEBUG)
1032        // add more to debug-menu
1033        awm->sep______________();
1034        awm->insert_menu_topic("fix_db",      "Fix database",            "F", 0, AWM_ALL, NT_fix_database);
1035        awm->insert_menu_topic("debug_arbdb", "Print debug information", "d", 0, AWM_ALL, makeWindowCallback(GB_print_debug_information, GLOBAL.gb_main));
1036        awm->insert_menu_topic("test_compr",  "Test compression",        "T", 0, AWM_ALL, makeWindowCallback(GBT_compression_test,       GLOBAL.gb_main));
1037#endif // DEBUG
1038
1039        awm->create_menu("File", "F", AWM_ALL);
1040        {
1041            // keep the following entries in sync with ../EDIT4/ED4_root.cxx@common_save_menu_entries
1042            awm->insert_menu_topic("save_changes", "Quicksave changes",          "s", "save.hlp",      AWM_ALL, NT_save_quick_cb);
1043            awm->insert_menu_topic("save_all_as",  "Save whole database as ...", "w", "save.hlp",      AWM_ALL, makeCreateWindowCallback(NT_create_save_as, AWAR_DBBASE));
1044            if (allow_new_window) {
1045                awm->sep______________();
1046                awm->insert_menu_topic("new_window", "New window (same database)", "N", "newwindow.hlp", AWM_ALL, makeCreateWindowCallback(popup_new_main_window, clone+1, (AWT_canvas**)NULL));
1047            }
1048            awm->sep______________();
1049            awm->insert_menu_topic("optimize_db",  "Optimize database compression", "O", "optimize.hlp",  AWM_ALL, NT_create_database_optimization_window);
1050            awm->sep______________();
1051
1052            awm->insert_sub_menu("Import",      "I");
1053            {
1054                awm->insert_menu_topic("merge_from", "Merge from other ARB database", "d", "arb_merge_into.hlp", AWM_ALL, NT_create_merge_from_window);
1055                awm->insert_menu_topic("import_seq", "Import from external format",   "I", "arb_import.hlp",     AWM_ALL, makeWindowCallback(NT_import_sequences, ntw));
1056                GDE_load_menu(awm, AWM_EXP, "Import");
1057            }
1058            awm->close_sub_menu();
1059
1060            awm->insert_sub_menu("Export",      "E");
1061            {
1062                awm->insert_menu_topic("export_to_ARB", "Merge to (new) ARB database", "A", "arb_merge_outof.hlp", AWM_ALL, NT_create_merge_to_window);
1063                awm->insert_menu_topic("export_seqs",   "Export to external format",   "f", "arb_export.hlp",      AWM_ALL, makeCreateWindowCallback(create_AWTC_export_window, GLOBAL.gb_main));
1064                GDE_load_menu(awm, AWM_ALL, "Export");
1065                awm->insert_menu_topic("export_nds",    "Export fields (to calc-sheet using NDS)", "N", "arb_export_nds.hlp",  AWM_ALL, create_nds_export_window);
1066            }
1067            awm->close_sub_menu();
1068            awm->sep______________();
1069
1070            insert_macro_menu_entry(awm, false);
1071
1072            awm->insert_sub_menu("VersionInfo/Bugreport/MailingList", "V");
1073            {
1074                awm->insert_menu_topic("version_info", "Version info (" ARB_VERSION_DETAILED ")", "V", "version.hlp", AWM_ALL, makeHelpCallback  ("version.hlp"));
1075                awm->insert_menu_topic("bug_report",   "Report bug",                              "b", NULL,          AWM_ALL, makeWindowCallback(AWT_openURL, "http://bugs.arb-home.de/wiki/BugReport"));
1076                awm->insert_menu_topic("mailing_list", "Mailing list",                            "M", NULL,          AWM_ALL, makeWindowCallback(AWT_openURL, "http://bugs.arb-home.de/wiki/ArbMailingList"));
1077            }
1078            awm->close_sub_menu();
1079            awm->sep______________();
1080
1081            awm->insert_menu_topic("new_arb",     "Start second database",      "d", "quit.hlp", AWM_ALL, makeWindowCallback(nt_start_2nd_arb, false));
1082            awm->insert_menu_topic("restart_arb", "Quit + load other database", "l", "quit.hlp", AWM_ALL, makeWindowCallback(nt_start_2nd_arb, true));
1083            awm->insert_menu_topic("quit",        "Quit",                       "Q", "quit.hlp", AWM_ALL, makeWindowCallback(NT_exit, EXIT_SUCCESS));
1084        }
1085
1086        // -----------------
1087        //      Species
1088
1089        awm->create_menu("Species", "c", AWM_ALL);
1090        {
1091            awm->insert_menu_topic("species_search", "Search and query",    "q", "sp_search.hlp", AWM_ALL, makeCreateWindowCallback(DBUI::create_species_query_window, GLOBAL.gb_main));
1092            awm->insert_menu_topic("species_info",   "Species information", "i", "sp_info.hlp",   AWM_ALL, popupinfo_wcb);
1093
1094            awm->sep______________();
1095
1096            NT_insert_mark_submenus(awm, ntw, 1);
1097            awm->insert_menu_topic("mark_by_ref",     "Mark by reference..", "r", "markbyref.hlp",       AWM_EXP, makeCreateWindowCallback(create_mark_by_refentries_window, GLOBAL.gb_main));
1098            awm->insert_menu_topic("species_colors",  "Colors ...",          "l", "colorize.hlp",        AWM_ALL, create_colorize_species_window);
1099            awm->insert_menu_topic("selection_admin", "Selections ...",      "o", "species_configs.hlp", AWM_ALL, makeWindowCallback(NT_popup_configuration_admin, ntw));
1100
1101            awm->sep______________();
1102
1103            awm->insert_sub_menu("Database fields admin", "f");
1104            DBUI::insert_field_admin_menuitems(awm, GLOBAL.gb_main);
1105            awm->close_sub_menu();
1106            NT_create_mask_submenu(awm);
1107
1108            awm->sep______________();
1109
1110            awm->insert_menu_topic("del_marked",    "Delete Marked Species",    "D", "sp_del_mrkd.hlp", AWM_ALL, makeWindowCallback(NT_delete_mark_all_cb, ntw));
1111
1112            awm->insert_sub_menu("Sort Species",         "s");
1113            {
1114                awm->insert_menu_topic("$sort_by_field", "According to Database Entries", "D", "sp_sort_fld.hlp",  AWM_ALL, NT_create_resort_window);
1115                awm->insert_menu_topic("$sort_by_tree",  "According to Phylogeny",        "P", "sp_sort_phyl.hlp", AWM_ALL, makeWindowCallback(NT_resort_data_by_phylogeny, ntw));
1116            }
1117            awm->close_sub_menu();
1118
1119            awm->insert_sub_menu("Merge Species", "g", AWM_EXP);
1120            {
1121                awm->insert_menu_topic("merge_species", "Create merged species from similar species", "m", "merge_species.hlp", AWM_EXP, NT_createMergeSimilarSpeciesWindow);
1122                awm->insert_menu_topic("join_marked",   "Join Marked Species",                        "J", "species_join.hlp",  AWM_EXP, NT_create_species_join_window);
1123            }
1124            awm->close_sub_menu();
1125
1126            awm->sep______________();
1127
1128            awm->insert_menu_topic("species_submission", "Submit Species", "b", "submission.hlp", AWM_EXP, makeCreateWindowCallback(AWTC_create_submission_window, GLOBAL.gb_main));
1129
1130            awm->sep______________();
1131
1132            awm->insert_menu_topic("new_names", "Synchronize IDs", "e", "sp_rename.hlp", AWM_ALL, makeCreateWindowCallback(AWTC_create_rename_window, GLOBAL.gb_main));
1133
1134            awm->insert_sub_menu("Valid Names ...", "V", AWM_EXP);
1135            {
1136                awm->insert_menu_topic("imp_names",    "Import names from file", "I", "vn_import.hlp",  AWM_EXP, NT_importValidNames);
1137                awm->insert_menu_topic("del_names",    "Delete names from DB",   "D", "vn_delete.hlp",  AWM_EXP, NT_deleteValidNames);
1138                awm->insert_menu_topic("sug_names",    "Suggest valid names",    "v", "vn_suggest.hlp", AWM_EXP, NT_suggestValidNames);
1139                awm->insert_menu_topic("search_names", "Search manually",        "m", "vn_search.hlp",  AWM_EXP, NT_create_searchManuallyNames_window);
1140            }
1141            awm->close_sub_menu();
1142        }
1143
1144        // ----------------------------
1145        //      Genes + Experiment
1146
1147        if (is_genome_db) GEN_create_genes_submenu(awm, GLOBAL.gb_main, true);
1148
1149        // ------------------
1150        //      Sequence
1151
1152        awm->create_menu("Sequence", "S", AWM_ALL);
1153        {
1154            awm->insert_menu_topic("seq_admin",   "Sequence/Alignment Admin", "A", "ad_align.hlp",   AWM_ALL, makeCreateWindowCallback(NT_create_alignment_admin_window, (AW_window*)0));
1155            awm->insert_sub_menu("Insert/delete", "I");
1156            {
1157                awm->insert_menu_topic("ins_del_col", ".. column",     "c", "insdel.hlp",     AWM_ALL, create_insertDeleteColumn_window);
1158                awm->insert_menu_topic("ins_del_sai", ".. using SAI",  "S", "insdel_sai.hlp", AWM_ALL, makeCreateWindowCallback(create_insertDeleteBySAI_window,  GLOBAL.gb_main));
1159            }
1160            awm->close_sub_menu();
1161            awm->sep______________();
1162
1163            awm->insert_sub_menu("Edit Sequences", "E");
1164            {
1165                awm->insert_menu_topic("new_arb_edit4",  "Using marked species and tree", "m", "arb_edit4.hlp", AWM_ALL, makeWindowCallback(NT_start_editor_on_tree,  0, ntw));
1166                awm->insert_menu_topic("new2_arb_edit4", "... plus relatives",            "r", "arb_edit4.hlp", AWM_ALL, makeWindowCallback(NT_start_editor_on_tree, -1, ntw));
1167                awm->insert_menu_topic("old_arb_edit4",  "Using earlier configuration",   "c", "arb_edit4.hlp", AWM_ALL, NT_create_startEditorOnOldConfiguration_window);
1168            }
1169            awm->close_sub_menu();
1170
1171            awm->sep______________();
1172
1173            awm->insert_sub_menu("Align Sequences",  "S");
1174            {
1175                awm->insert_menu_topic("realign_dna", "Realign DNA according to aligned protein", "R", "realign_dna.hlp", AWM_ALL, NT_create_realign_dna_window);
1176                GDE_load_menu(awm, AWM_ALL, "Align");
1177            }
1178            awm->close_sub_menu();
1179            awm->insert_menu_topic("seq_concat",    "Concatenate Sequences/Alignments", "C", "concatenate.hlp",       AWM_ALL, NT_createConcatenationWindow);
1180            awm->insert_menu_topic("track_changes", "Track alignment changes",          "k", "track_ali_changes.hlp", AWM_EXP, NT_create_trackAliChanges_window);
1181            awm->sep______________();
1182
1183            awm->insert_menu_topic("dna_2_pro", "Perform translation",      "t", "translate_dna_2_pro.hlp", AWM_ALL, NT_create_dna_2_pro_window);
1184            awm->insert_menu_topic("arb_dist",  "Distance Matrix + ARB NJ", "D", "dist.hlp",                AWM_ALL, makeWindowCallback(NT_system_cb, "arb_dist &"));
1185            awm->sep______________();
1186
1187            awm->insert_menu_topic("seq_quality",   "Check Sequence Quality", "Q", "seq_quality.hlp",   AWM_EXP, makeCreateWindowCallback(SQ_create_seq_quality_window, GLOBAL.gb_main));
1188            awm->insert_menu_topic("chimera_check", "Chimera Check",          "m", "chimera_check.hlp", AWM_EXP, makeCreateWindowCallback(STAT_create_chimera_check_window, GLOBAL.gb_main));
1189
1190            awm->sep______________();
1191
1192            GDE_load_menu(awm, AWM_ALL, "Print");
1193        }
1194
1195        // -------------
1196        //      SAI
1197
1198        awm->create_menu("SAI", "A", AWM_ALL);
1199        {
1200            awm->insert_menu_topic("sai_admin", "Manage SAIs", "S", "ad_extended.hlp", AWM_ALL, NT_create_extendeds_window);
1201            awm->insert_sub_menu("Create SAI using ...", "C");
1202            {
1203                awm->insert_menu_topic("sai_max_freq",  "Max. Frequency",                                               "M", "max_freq.hlp",     AWM_EXP, AP_create_max_freq_window);
1204                awm->insert_menu_topic("sai_consensus", "Consensus",                                                    "C", "consensus.hlp",    AWM_ALL, AP_create_con_expert_window);
1205                awm->insert_menu_topic("pos_var_pars",  "Positional variability + Column statistic (parsimony method)", "a", "pos_var_pars.hlp", AWM_ALL, AP_create_pos_var_pars_window);
1206                awm->insert_menu_topic("arb_phyl",      "Filter by base frequency",                                     "F", "phylo.hlp",        AWM_ALL, makeWindowCallback(NT_system_cb, "arb_phylo &"));
1207                awm->insert_menu_topic("sai_pfold",     "Protein secondary structure (field \"sec_struct\")",           "P", "pfold.hlp",        AWM_EXP, makeWindowCallback(NT_create_sai_from_pfold, ntw));
1208
1209                GDE_load_menu(awm, AWM_EXP, "SAI");
1210            }
1211            awm->close_sub_menu();
1212
1213            awm->insert_sub_menu("Other functions", "O");
1214            {
1215                awm->insert_menu_topic("count_different_chars", "Count different chars/column",             "C", "count_chars.hlp",    AWM_EXP, makeWindowCallback(NT_count_different_chars, GLOBAL.gb_main));
1216                awm->insert_menu_topic("corr_mutat_analysis",   "Compute clusters of correlated positions", "m", "",                   AWM_ALL, makeWindowCallback(NT_system_in_xterm_cb,    "arb_rnacma"));
1217                awm->insert_menu_topic("export_pos_var",        "Export Column Statistic (GNUPLOT format)", "E", "csp_2_gnuplot.hlp",  AWM_ALL, NT_create_colstat_2_gnuplot_window);
1218            }
1219            awm->close_sub_menu();
1220        }
1221
1222        // ----------------
1223        //      Probes
1224
1225        awm->create_menu("Probes", "P", AWM_ALL);
1226        {
1227            awm->insert_menu_topic("probe_design", "Design Probes",          "D", "probedesign.hlp", AWM_ALL, makeCreateWindowCallback(create_probe_design_window, GLOBAL.gb_main));
1228            awm->insert_menu_topic("probe_multi",  "Calculate Multi-Probes", "u", "multiprobe.hlp",  AWM_ALL, makeCreateWindowCallback(create_multiprobe_window, ntw));
1229            awm->insert_menu_topic("probe_match",  "Match Probes",           "M", "probematch.hlp",  AWM_ALL, makeCreateWindowCallback(create_probe_match_window, GLOBAL.gb_main));
1230            awm->sep______________();
1231            awm->insert_menu_topic("probe_match_sp",   "Match Probes with Specificity", "f", "probespec.hlp", AWM_ALL, makeCreateWindowCallback(create_probe_match_with_specificity_window,    ntw));
1232            awm->sep______________();
1233            awm->insert_menu_topic("primer_design_new", "Design Primers",            "P", "primer_new.hlp", AWM_EXP, makeCreateWindowCallback(create_primer_design_window, GLOBAL.gb_main));
1234            awm->insert_menu_topic("primer_design",     "Design Sequencing Primers", "S", "primer.hlp",     AWM_EXP, NT_primer_cb);
1235            awm->sep______________();
1236            awm->insert_menu_topic("pt_server_admin",   "PT_SERVER Admin",           "A", "probeadmin.hlp",  AWM_ALL, makeCreateWindowCallback(create_probe_admin_window, GLOBAL.gb_main));
1237        }
1238
1239    }
1240
1241    // --------------
1242    //      Tree
1243
1244    awm->create_menu("Tree", "T", AWM_ALL);
1245    {
1246        if (!clone) {
1247            awm->insert_sub_menu("Add Species to Existing Tree", "A");
1248            {
1249                awm->insert_menu_topic("arb_pars_quick", "ARB Parsimony (Quick add marked)", "Q", "pars.hlp", AWM_ALL, makeWindowCallback(NT_system_cb, "arb_pars -add_marked -quit &"));
1250                awm->insert_menu_topic("arb_pars",       "ARB Parsimony interactive",        "i", "pars.hlp", AWM_ALL, makeWindowCallback(NT_system_cb, "arb_pars &"));
1251                GDE_load_menu(awm, AWM_EXP, "Incremental phylogeny");
1252            }
1253            awm->close_sub_menu();
1254        }
1255
1256        awm->insert_sub_menu("Remove Species from Tree",     "R");
1257        {
1258            awm->insert_menu_topic(awm->local_id("tree_remove_deleted"), "Remove zombies", "z", "trm_del.hlp",    AWM_ALL, makeWindowCallback(NT_remove_leafs, ntw, AWT_REMOVE_ZOMBIES));
1259            awm->insert_menu_topic(awm->local_id("tree_remove_marked"),  "Remove marked",  "m", "trm_mrkd.hlp",   AWM_ALL, makeWindowCallback(NT_remove_leafs, ntw, AWT_REMOVE_MARKED));
1260            awm->insert_menu_topic(awm->local_id("tree_keep_marked"),    "Keep marked",    "K", "tkeep_mrkd.hlp", AWM_ALL, makeWindowCallback(NT_remove_leafs, ntw, AWT_KEEP_MARKED));
1261            awm->sep______________();
1262            awm->insert_menu_topic("all_tree_remove_deleted", "Remove zombies from ALL trees", "A", "trm_del.hlp",  AWM_ALL, makeWindowCallback(NT_alltree_remove_leafs, GBT_REMOVE_ZOMBIES, GLOBAL.gb_main));
1263            awm->insert_menu_topic("all_tree_remove_marked",  "Remove marked from ALL trees",  "L", "trm_mrkd.hlp", AWM_ALL, makeWindowCallback(NT_alltree_remove_leafs, GBT_REMOVE_MARKED,  GLOBAL.gb_main));
1264        }
1265        awm->close_sub_menu();
1266
1267        if (!clone) {
1268            awm->insert_sub_menu("Build tree from sequence data",    "B");
1269            {
1270                awm->insert_sub_menu("Distance matrix methods", "D");
1271                awm->insert_menu_topic("arb_dist", "Distance Matrix + ARB NJ", "J", "dist.hlp", AWM_ALL, makeWindowCallback(NT_system_cb, "arb_dist &"));
1272                GDE_load_menu(awm, AWM_ALL, "Phylogeny Distance Matrix");
1273                awm->close_sub_menu();
1274
1275                awm->insert_sub_menu("Maximum Parsimony methods", "P");
1276                GDE_load_menu(awm, AWM_ALL, "Phylogeny max. parsimony");
1277                awm->close_sub_menu();
1278
1279                awm->insert_sub_menu("Maximum Likelihood methods", "L");
1280                GDE_load_menu(awm, AWM_EXP, "Phylogeny max. Likelihood EXP");
1281                GDE_load_menu(awm, AWM_ALL, "Phylogeny max. Likelihood");
1282                awm->close_sub_menu();
1283
1284                awm->insert_sub_menu("Other methods", "O", AWM_EXP);
1285                GDE_load_menu(awm, AWM_EXP, "Phylogeny (Other)");
1286                awm->close_sub_menu();
1287            }
1288            awm->close_sub_menu();
1289        }
1290
1291        awm->insert_menu_topic(awm->local_id("consense_tree"), "Build consensus tree", "c", "consense_tree.hlp", AWM_ALL, NT_create_consense_window);
1292        awm->sep______________();
1293
1294        awm->insert_sub_menu("Reset zoom",         "z");
1295        {
1296            awm->insert_menu_topic(awm->local_id("reset_logical_zoom"),  "Logical zoom",  "L", "rst_log_zoom.hlp",  AWM_ALL, makeWindowCallback(NT_reset_lzoom_cb, ntw));
1297            awm->insert_menu_topic(awm->local_id("reset_physical_zoom"), "Physical zoom", "P", "rst_phys_zoom.hlp", AWM_ALL, makeWindowCallback(NT_reset_pzoom_cb, ntw));
1298        }
1299        awm->close_sub_menu();
1300        NT_insert_collapse_submenu(awm, ntw);
1301        awm->insert_sub_menu("Beautify tree", "e");
1302        {
1303            awm->insert_menu_topic(awm->local_id("beautifyt_tree"),  "#beautifyt.xpm",  "",  "resorttree.hlp", AWM_ALL, makeWindowCallback(NT_resort_tree_cb, ntw, BIG_BRANCHES_TO_TOP));
1304            awm->insert_menu_topic(awm->local_id("beautifyc_tree"),  "#beautifyc.xpm",  "",  "resorttree.hlp", AWM_ALL, makeWindowCallback(NT_resort_tree_cb, ntw, BIG_BRANCHES_TO_EDGE));
1305            awm->insert_menu_topic(awm->local_id("beautifyb_tree"),  "#beautifyb.xpm",  "",  "resorttree.hlp", AWM_ALL, makeWindowCallback(NT_resort_tree_cb, ntw, BIG_BRANCHES_TO_BOTTOM));
1306            awm->insert_menu_topic(awm->local_id("beautifyr_tree"),  "Radial tree (1)", "1", "resorttree.hlp", AWM_ALL, makeWindowCallback(NT_resort_tree_cb, ntw, BIG_BRANCHES_TO_CENTER));
1307            awm->insert_menu_topic(awm->local_id("beautifyr2_tree"), "Radial tree (2)", "2", "resorttree.hlp", AWM_ALL, makeWindowCallback(NT_resort_tree_cb, ntw, BIG_BRANCHES_ALTERNATING));
1308            awm->sep______________();
1309            awm->insert_menu_topic(awm->local_id("sort_by_other"),   "By other tree",   "o", "resortbyother.hlp", AWM_ALL, makeCreateWindowCallback(NT_create_sort_tree_by_other_tree_window, ntw));
1310        }
1311        awm->close_sub_menu();
1312        awm->insert_sub_menu("Modify branches", "M");
1313        {
1314            awm->insert_menu_topic(awm->local_id("tree_remove_remark"),     "Remove bootstraps",      "b", "trm_boot.hlp", AWM_ALL, makeWindowCallback(NT_remove_bootstrap,    ntw));
1315            awm->insert_menu_topic(awm->local_id("tree_toggle_bootstraps"), "Toggle 100% bootstraps", "1", "trm_boot.hlp", AWM_ALL, makeWindowCallback(NT_toggle_bootstrap100, ntw));
1316            awm->sep______________();
1317            awm->insert_menu_topic(awm->local_id("tree_reset_lengths"),     "Reset branchlengths",   "R", "tbl_reset.hlp",   AWM_ALL, makeWindowCallback(NT_reset_branchlengths,   ntw));
1318            awm->insert_menu_topic(awm->local_id("justify_branch_lengths"), "Justify branchlengths", "J", "tbl_justify.hlp", AWM_ALL, makeWindowCallback(NT_justify_branch_lenghs, ntw));
1319            awm->insert_menu_topic(awm->local_id("tree_scale_lengths"),     "Scale Branchlengths",   "S", "tbl_scale.hlp",   AWM_ALL, makeWindowCallback(NT_scale_tree,            ntw));
1320            awm->sep______________();
1321            awm->insert_menu_topic(awm->local_id("tree_multifurcate"), "Multifurcate...", "M", "multifurcate.hlp", AWM_ALL, makeCreateWindowCallback(NT_create_multifurcate_tree_window, ntw));
1322            awm->sep______________();
1323            awm->insert_menu_topic(awm->local_id("tree_boot2len"), "Bootstraps -> Branchlengths", "l", "tbl_boot2len.hlp", AWM_ALL, makeWindowCallback(NT_move_boot_branch, ntw, 0));
1324            awm->insert_menu_topic(awm->local_id("tree_len2boot"), "Bootstraps <- Branchlengths", "o", "tbl_boot2len.hlp", AWM_ALL, makeWindowCallback(NT_move_boot_branch, ntw, 1));
1325
1326        }
1327        awm->close_sub_menu();
1328
1329        awm->insert_menu_topic(awm->local_id("branch_analysis"), "Branch analysis", "s", "branch_analysis.hlp", AWM_ALL, makeCreateWindowCallback(NT_create_branch_analysis_window, ntw));
1330        awm->insert_menu_topic(awm->local_id("mark_duplicates"), "Mark duplicates", "u", "mark_duplicates.hlp", AWM_ALL, makeWindowCallback(NT_mark_duplicates, ntw));
1331
1332        awm->sep______________();
1333
1334        awm->insert_menu_topic(awm->local_id("compare_taxonomy"), "Compare taxonomy...", "x", "compare_taxonomy.hlp", AWM_ALL, makeCreateWindowCallback(NT_create_compare_taxonomy_window, ntw));
1335        awm->insert_menu_topic(awm->local_id("shade"),            "Tree shading...",     "s", "tree_shading.hlp",     AWM_ALL, makeWindowCallback(NT_configure_treeShader));
1336
1337        awm->sep______________();
1338
1339        awm->insert_menu_topic(awm->local_id("tree_select"),        "Select Tree",      "T", 0, AWM_ALL, makeCreateWindowCallback(NT_create_select_tree_window, awar_tree));
1340        awm->insert_menu_topic(awm->local_id("tree_select_latest"), "Select Last Tree", "L", 0, AWM_ALL, makeWindowCallback(NT_select_bottom_tree, awar_tree));
1341
1342        awm->sep______________();
1343
1344        if (!clone) {
1345            awm->insert_menu_topic("tree_admin", "Tree admin",               "i", "treeadm.hlp",   AWM_ALL, popup_tree_admin_window);
1346            awm->insert_menu_topic("nds",        "NDS (Node display setup)", "N", "props_nds.hlp", AWM_ALL, makeCreateWindowCallback(AWT_create_nds_window, GLOBAL.gb_main));
1347        }
1348        awm->sep______________();
1349
1350        awm->insert_menu_topic("transversion",       "Transversion analysis",   "y", "trans_anal.hlp", AWM_EXP, makeHelpCallback("trans_anal.hlp"));
1351
1352        awm->sep______________();
1353
1354        if (!clone) {
1355            awm->insert_menu_topic("print_tree",  "Print tree",          "P", "tree2prt.hlp",  AWM_ALL, makeWindowCallback(AWT_popup_print_window, ntw));
1356            awm->insert_menu_topic("tree_2_xfig", "Export tree to XFIG", "F", "tree2file.hlp", AWM_ALL, makeWindowCallback(AWT_popup_tree_export_window, ntw));
1357            awm->sep______________();
1358        }
1359
1360        if (is_genome_db) {
1361            awm->insert_sub_menu("Other..",  "O", AWM_EXP);
1362            {
1363                awm->insert_menu_topic(awm->local_id("tree_pseudo_species_to_organism"), "Relink tree to organisms", "o", "tree_pseudo.hlp", AWM_EXP, makeWindowCallback(NT_pseudo_species_to_organism, ntw));
1364            }
1365            awm->close_sub_menu();
1366        }
1367    }
1368
1369    if (!clone) {
1370        // ---------------
1371        //      Tools
1372
1373        awm->create_menu("Tools", "o", AWM_ALL);
1374        {
1375            awm->insert_menu_topic("names_admin",      "Name server admin (IDs)",    "s", "namesadmin.hlp",  AWM_ALL, makeCreateWindowCallback(AW_create_namesadmin_window, GLOBAL.gb_main));
1376            awm->insert_sub_menu("DB admin", "D", AWM_EXP);
1377            {
1378                awm->insert_menu_topic("db_admin", "Re-repair DB", "R", "rerepair.hlp", AWM_EXP, makeWindowCallback(NT_rerepair_DB, GLOBAL.gb_main));
1379            }
1380            awm->close_sub_menu();
1381            awm->insert_sub_menu("Network", "N", AWM_EXP);
1382            {
1383                GDE_load_menu(awm, AWM_EXP, "Network");
1384            }
1385            awm->close_sub_menu();
1386            awm->sep______________();
1387
1388            awm->insert_sub_menu("GDE specials", "G", AWM_EXP);
1389            {
1390                GDE_load_menu(awm, AWM_EXP, NULL);
1391            }
1392            awm->close_sub_menu();
1393
1394            awm->sep______________();
1395            awm->insert_menu_topic("xterm", "Start XTERM", "X", 0, AWM_ALL, NT_xterm);
1396            awm->sep______________();
1397            GDE_load_menu(awm, AWM_EXP, "User");
1398        }
1399        // --------------------
1400        //      Properties
1401
1402        awm->create_menu("Properties", "r", AWM_ALL);
1403        {
1404#if defined(ARB_MOTIF)
1405            awm->insert_menu_topic("props_menu",                 "Frame settings ...",          "F", "props_frame.hlp",      AWM_ALL, AW_preset_window);
1406#endif
1407            awm->insert_menu_topic(awm->local_id("props_tree2"), "Tree options",                "o", "nt_tree_settings.hlp", AWM_ALL, TREE_create_settings_window);
1408            awm->insert_menu_topic("props_tree",                 "Tree colors & fonts",         "c", "color_props.hlp",      AWM_ALL, makeCreateWindowCallback(AW_create_gc_window, ntw->gc_manager));
1409            awm->insert_menu_topic("props_www",                  "Search world wide web (WWW)", "b", "props_www.hlp",        AWM_ALL, makeCreateWindowCallback(AWT_create_www_window, GLOBAL.gb_main));
1410            awm->sep______________();
1411            awm->insert_menu_topic("!toggle_expert", "Toggle expert mode",         "x", 0, AWM_ALL, NT_toggle_expert_mode);
1412#if defined(ARB_MOTIF)
1413            awm->insert_menu_topic("!toggle_focus",  "Toggle focus follows mouse", "m", 0, AWM_ALL, NT_toggle_focus_policy);
1414#endif
1415            awm->sep______________();
1416            AW_insert_common_property_menu_entries(awm);
1417            awm->sep______________();
1418            awm->insert_menu_topic("save_props", "Save properties (ntree.arb)", "S", "savedef.hlp", AWM_ALL, AW_save_properties);
1419        }
1420    }
1421
1422    awm->insert_help_topic("ARB_NT help",     "N", "arb_ntree.hlp", AWM_ALL, makeHelpCallback("arb_ntree.hlp"));
1423
1424    // ----------------------
1425    //      mode buttons
1426    //
1427    // keep them synchronized as far as possible with those in ARB_PARSIMONY
1428    // see ../PARSIMONY/PARS_main.cxx@keepModesSynchronized
1429
1430    awm->create_mode("mode_select.xpm", "mode_select.hlp", AWM_ALL, makeWindowCallback(nt_mode_event, ntw, AWT_MODE_SELECT));
1431    awm->create_mode("mode_mark.xpm",   "mode_mark.hlp",   AWM_ALL, makeWindowCallback(nt_mode_event, ntw, AWT_MODE_MARK));
1432    awm->create_mode("mode_group.xpm",  "mode_group.hlp",  AWM_ALL, makeWindowCallback(nt_mode_event, ntw, AWT_MODE_GROUP));
1433    awm->create_mode("mode_zoom.xpm",   "mode_pzoom.hlp",  AWM_ALL, makeWindowCallback(nt_mode_event, ntw, AWT_MODE_ZOOM));
1434    awm->create_mode("mode_lzoom.xpm",  "mode_lzoom.hlp",  AWM_ALL, makeWindowCallback(nt_mode_event, ntw, AWT_MODE_LZOOM));
1435
1436    awm->create_mode("mode_info.xpm", "mode_info.hlp", AWM_ALL, makeWindowCallback(NT_infomode_cb, ntw, AWT_MODE_INFO));
1437    awm->create_mode("mode_www.xpm",  "mode_www.hlp",  AWM_ALL, makeWindowCallback(nt_mode_event,  ntw, AWT_MODE_WWW));
1438
1439    // topology-modification-modes
1440    awm->create_mode("mode_setroot.xpm",   "mode_setroot.hlp", AWM_ALL, makeWindowCallback(nt_mode_event, ntw, AWT_MODE_SETROOT));
1441    awm->create_mode("mode_swap.xpm",      "mode_swap.hlp",    AWM_ALL, makeWindowCallback(nt_mode_event, ntw, AWT_MODE_SWAP));
1442    awm->create_mode("mode_move.xpm",      "mode_move.hlp",    AWM_ALL, makeWindowCallback(nt_mode_event, ntw, AWT_MODE_MOVE));
1443    awm->create_mode("mode_length.xpm",    "mode_length.hlp",  AWM_ALL, makeWindowCallback(nt_mode_event, ntw, AWT_MODE_LENGTH));
1444    awm->create_mode("mode_multifurc.xpm", "mode_length.hlp",  AWM_ALL, makeWindowCallback(nt_mode_event, ntw, AWT_MODE_MULTIFURC));
1445
1446    // layout-modes
1447    awm->create_mode("mode_line.xpm",   "mode_width.hlp",  AWM_ALL, makeWindowCallback(nt_mode_event, ntw, AWT_MODE_LINE));
1448    awm->create_mode("mode_rotate.xpm", "mode_rotate.hlp", AWM_ALL, makeWindowCallback(nt_mode_event, ntw, AWT_MODE_ROTATE));
1449    awm->create_mode("mode_spread.xpm", "mode_spread.hlp", AWM_ALL, makeWindowCallback(nt_mode_event, ntw, AWT_MODE_SPREAD));
1450
1451    awm->set_info_area_height(250);
1452    awm->at(5, 2);
1453    awm->auto_space(-2, -2);
1454    awm->shadow_width(1);
1455
1456    // -------------------------
1457    //      create top area
1458
1459    int first_liney;
1460    int leftx;
1461    awm->get_at_position(&leftx, &first_liney);
1462
1463    // ---------------------
1464    //      quit + help
1465
1466    awm->button_length(0);
1467
1468    if (clone) {
1469        awm->callback(AW_POPDOWN);
1470        awm->create_button("CLOSE", "#close.xpm");
1471    }
1472    else {
1473        awm->callback(makeWindowCallback(NT_exit, EXIT_SUCCESS));
1474#if defined(ARB_GTK)
1475        awm->set_hide_on_close(false); //the main window should really close when closed
1476#endif
1477        awm->help_text("quit.hlp");
1478        awm->create_button("QUIT", "#quit.xpm");
1479#if defined(ARB_GTK)
1480        awm->set_close_action("QUIT");
1481#endif
1482    }
1483
1484    int db_pathx = awm->get_at_xposition();
1485
1486    // now fetch the yposition for the 2nd button line
1487    awm->at_newline();
1488    int second_liney = awm->get_at_yposition();
1489
1490    awm->callback(AW_help_entry_pressed);
1491    awm->help_text("arb_ntree.hlp");
1492    awm->create_button("?", "#help.xpm");
1493
1494    // --------------------------
1495    //      save + undo/redo
1496
1497    awm->callback(NT_save_quick_cb);
1498    awm->help_text("save.hlp");
1499    awm->create_button("SAVE", "#save.xpm");
1500
1501    awm->callback(makeCreateWindowCallback(NT_create_save_as, AWAR_DBBASE));
1502    awm->help_text("save.hlp");
1503    awm->create_button("SAVE_AS", "#saveAs.xpm");
1504
1505    // undo/redo:
1506    awm->callback(makeWindowCallback(NT_undo_cb, GB_UNDO_UNDO, ntw));
1507    awm->help_text("undo.hlp");
1508    awm->create_button("UNDO", "#undo.xpm");
1509
1510    awm->callback(makeWindowCallback(NT_undo_cb, GB_UNDO_REDO, ntw));
1511    awm->help_text("undo.hlp");
1512    awm->create_button("REDO", "#redo.xpm");
1513
1514    int db_pathx2 = awm->get_at_xposition();
1515
1516    // fetch position for mode help-line:
1517    awm->at_newline();
1518    int third_liney = awm->get_at_yposition();
1519
1520    awm->at(db_pathx, first_liney);
1521    // size of DB-name button is determined by buttons below:
1522    awm->at_set_to(false, false, db_pathx2-db_pathx-1, second_liney-first_liney+1);
1523    awm->callback(makeCreateWindowCallback(NT_create_save_quick_as_window, AWAR_DBBASE));
1524    awm->help_text("save.hlp");
1525    awm->create_button("QUICK_SAVE_AS", AWAR_DB_NAME);
1526
1527    // -----------------------------
1528    //      tree + tree display
1529
1530#define TREE_BUTTON_OVERSIZE 6
1531
1532    int db_treex      = awm->get_at_xposition();
1533    int second_uppery = second_liney-TREE_BUTTON_OVERSIZE;
1534
1535    awm->at(db_treex, second_uppery);
1536    awm->button_length(0);
1537
1538    awm->callback(makeWindowCallback(NT_set_tree_style, ntw, AP_TREE_RADIAL));
1539    awm->help_text("tr_type_radial.hlp");
1540    awm->create_button("RADIAL_TREE_TYPE", "#radial.xpm");
1541
1542    awm->callback(makeWindowCallback(NT_set_tree_style, ntw, AP_TREE_NORMAL));
1543    awm->help_text("tr_type_list.hlp");
1544    awm->create_button("LIST_TREE_TYPE", "#dendro.xpm");
1545
1546    awm->callback(makeWindowCallback(NT_set_tree_style, ntw, AP_TREE_IRS));
1547    awm->help_text("tr_type_irs.hlp");
1548    awm->create_button("FOLDED_LIST_TREE_TYPE", "#dendroIrs.xpm");
1549
1550    awm->callback(makeWindowCallback(NT_set_tree_style, ntw, AP_LIST_NDS));
1551    awm->help_text("tr_type_nds.hlp");
1552    awm->create_button("NO_TREE_TYPE", "#listdisp.xpm");
1553
1554    int db_treex2 = awm->get_at_xposition();
1555
1556    awm->at(db_treex, first_liney);
1557    // size of tree-name button is determined by buttons below:
1558    awm->at_set_to(false, false, db_treex2-db_treex-1, second_uppery-first_liney+1);
1559    awm->callback(makeCreateWindowCallback(NT_create_select_tree_window, awar_tree));
1560    awm->help_text("nt_tree_select.hlp");
1561    awm->create_button("SELECT_A_TREE", awar_tree);
1562
1563    // ---------------------------------------------------------------
1564    //      protection, alignment + editor (and maybe Genome Map)
1565
1566    int db_alignx = awm->get_at_xposition();
1567
1568    // editor and genemap buttons have to be 44x24 sized
1569#define EDIT_XSIZE 50
1570#define EDIT_YSIZE 30 // same as 'save as' buttons
1571
1572    // first draw protection:
1573    int protectx = db_alignx + 2*EDIT_XSIZE;
1574
1575    awm->at(protectx+2, first_liney+1);
1576    awm->button_length(0);
1577    awm->create_button(NULL, "#protect.xpm");
1578
1579    awm->at(protectx, second_liney+2);
1580    awm->create_option_menu(AWAR_SECURITY_LEVEL, true);
1581    awm->insert_option("0", 0, 0);
1582    awm->insert_option("1", 0, 1);
1583    awm->insert_option("2", 0, 2);
1584    awm->insert_option("3", 0, 3);
1585    awm->insert_option("4", 0, 4);
1586    awm->insert_option("5", 0, 5);
1587    awm->insert_default_option("6", 0, 6);
1588    awm->update_option_menu();
1589
1590    int db_searchx = awm->get_at_xposition() - 7;
1591
1592    // draw ali/editor buttons AFTER protect menu (to get rid of it's label)
1593    awm->at(db_alignx, second_liney);
1594
1595    awm->at_set_to(false, false, ((2-is_genome_db)*EDIT_XSIZE), EDIT_YSIZE);
1596    awm->callback(makeWindowCallback(NT_start_editor_on_tree, 0, ntw));
1597    awm->help_text("arb_edit4.hlp");
1598    if (is_genome_db) awm->create_button("EDIT_SEQUENCES", "#editor_small.xpm");
1599    else              awm->create_button("EDIT_SEQUENCES", "#editor.xpm");
1600
1601    if (is_genome_db) {
1602        awm->at_set_to(false, false, EDIT_XSIZE, EDIT_YSIZE);
1603        awm->callback(makeCreateWindowCallback(GEN_create_first_map, GLOBAL.gb_main)); // initial gene map
1604        awm->help_text("gene_map.hlp");
1605        awm->create_button("OPEN_GENE_MAP", "#gen_map.xpm");
1606    }
1607
1608    int db_alignx2 = awm->get_at_xposition();
1609
1610    awm->at(db_alignx, first_liney);
1611    awm->at_set_to(false, false, db_alignx2-db_alignx-1, second_liney-first_liney+1);
1612    awm->callback(NT_create_select_alignment_window);
1613    awm->help_text("nt_align_select.hlp");
1614    awm->create_button("SELECT_AN_ALIGNMENT", AWAR_DEFAULT_ALIGNMENT);
1615
1616    // -------------------------------
1617    //      create mode-help line
1618
1619    awm->at(leftx, third_liney);
1620    awm->button_length(AWAR_FOOTER_MAX_LEN);
1621    awm->create_button(0, AWAR_FOOTER);
1622
1623    awm->at_newline();
1624    int bottomy = awm->get_at_yposition();
1625
1626    // ---------------------------------------
1627    //      Info / marked / Search / Jump
1628
1629    awm->button_length(7);
1630
1631    awm->at(db_searchx, first_liney);
1632    awm->callback(makeCreateWindowCallback(DBUI::create_species_query_window, GLOBAL.gb_main));
1633    awm->help_text("sp_search.hlp");
1634    awm->create_button("SEARCH",  "Search");
1635
1636    awm->at(db_searchx, second_uppery);
1637    awm->callback(makeWindowCallback(NT_jump_cb, ntw, AP_JUMP_BY_BUTTON));
1638    awm->help_text("tr_jump.hlp");
1639    awm->create_button("JUMP", "Jump");
1640
1641    int db_infox = awm->get_at_xposition();
1642
1643    awm->at(db_infox, first_liney);
1644    awm->button_length(13);
1645    awm->callback(popupinfo_wcb);
1646    awm->help_text("sp_search.hlp");
1647    awm->create_button("INFO",  AWAR_INFO_BUTTON_TEXT);
1648
1649    awm->at(db_infox, second_uppery);
1650    awm->button_length(13);
1651    awm->help_text("species_configs.hlp");
1652    awm->callback(makeWindowCallback(NT_popup_configuration_admin, ntw));
1653    awm->create_button("selection_admin2", AWAR_MARKED_SPECIES_COUNTER);
1654    {
1655        GBDATA *gb_species_data = GBT_get_species_data(GLOBAL.gb_main);
1656        GB_add_callback(gb_species_data, GB_CB_CHANGED, makeDatabaseCallback(NT_update_marked_counter, static_cast<AW_window*>(awm)));
1657        NT_update_marked_counter(NULL, awm);
1658    }
1659
1660    // set height of top area:
1661    awm->set_info_area_height(bottomy+2);
1662    awm->set_bottom_area_height(0);
1663
1664    NT_activate_configMarkers_display(ntw);
1665
1666    // ------------------------------------
1667    //      Autostarts for development
1668
1669#if defined(DEVEL_RALF)
1670    // if (is_genome_db) GEN_map_first(awr)->show();
1671#endif // DEVEL_RALF
1672
1673    GB_pop_transaction(GLOBAL.gb_main);
1674
1675#if defined(DEBUG)
1676    AWT_check_action_ids(awr, is_genome_db ? "_genome" : "");
1677#endif
1678
1679    return awm;
1680}
1681
1682AWT_canvas *NT_create_main_window(AW_root *aw_root) {
1683    GB_ERROR error = GB_request_undo_type(GLOBAL.gb_main, GB_UNDO_NONE);
1684    if (error) aw_message(error);
1685
1686    nt_create_all_awars(aw_root);
1687
1688    AWT_canvas *ntw = NULL;
1689    AW_window  *aww = popup_new_main_window(aw_root, 0, &ntw);
1690    NT_install_treeShader(ntw, GLOBAL.gb_main);
1691    aww->show();
1692
1693    error = GB_request_undo_type(GLOBAL.gb_main, GB_UNDO_UNDO);
1694    if (error) aw_message(error);
1695
1696    return ntw;
1697}
Note: See TracBrowser for help on using the repository browser.