source: tags/arb-6.0-rc3/NTREE/NT_extern.cxx

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