source: branches/port5/AWT/AWT_tree_cb.cxx

Last change on this file was 6072, checked in by westram, 16 years ago
  • added missing and fixed broken hotkeys
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 30.6 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <ctype.h>
5
6#include <arbdb.h>
7#include <arbdbt.h>
8
9#include <aw_root.hxx>
10#include <aw_device.hxx>
11#include <aw_window.hxx>
12#include <aw_awars.hxx>
13#include <awt_canvas.hxx>
14#include <awt_tree.hxx>
15#include <awt_dtree.hxx>
16#include <awt_tree_cb.hxx>
17#include <awt_advice.hxx>
18#include <awt.hxx>
19
20
21void
22nt_mode_event( AW_window *aws, AWT_canvas *ntw, AWT_COMMAND_MODE mode)
23{
24    AWUSE(aws);
25    const char *text;
26
27    switch(mode){
28        case AWT_MODE_SELECT:
29            text = "SELECT MODE    LEFT: select species and open/close group";
30            break;
31        case AWT_MODE_MARK:
32            text = "MARK MODE    LEFT: mark subtree   RIGHT: unmark subtree";
33            break;
34        case AWT_MODE_GROUP:
35            text = "GROUP MODE   LEFT: fold/unfold group  RIGHT: create/rename/destroy group";
36            break;
37        case AWT_MODE_ZOOM:
38            text = "ZOOM MODE    LEFT: press and drag to zoom   RIGHT: zoom out one step";
39            break;
40        case AWT_MODE_LZOOM:
41            text = "LOGICAL ZOOM MODE   LEFT: show subtree  RIGHT: go up one step";
42            break;
43        case AWT_MODE_MOD:
44            text = "MODIFY MODE   LEFT: select node M: assign info to internal node";
45            break;
46        case AWT_MODE_WWW:
47            text = "CLICK NODE TO SEARCH WEB (See <PROPS/WWW...> also";
48            break;
49        case AWT_MODE_LINE:
50            text = "LINE MODE    LEFT: reduce linewidth  RIGHT: increase linewidth";
51            break;
52        case AWT_MODE_ROT:
53            text = "ROTATE MODE   LEFT: Select branch and drag to rotate";
54            break;
55        case AWT_MODE_SPREAD:
56            text = "SPREAD MODE   LEFT: decrease angles  RIGHT: increase angles";
57            break;
58        case AWT_MODE_SWAP:
59            text = "SWAP MODE    LEFT: swap branches";
60            break;
61        case AWT_MODE_LENGTH:
62            text = "BRANCH LENGTH MODE   LEFT: Drag branch/ruler to change length  RIGHT: use discrete lengths";
63            break;
64        case AWT_MODE_MOVE:
65            text = "MOVE MODE   LEFT: move subtree/ruler to new destination RIGHT: move group info only";
66            break;
67        case AWT_MODE_NNI:
68            text = "NEAREST NEIGHBOUR INTERCHANGE OPTIMIZER  L: select subtree R: whole tree";
69            break;
70        case AWT_MODE_KERNINGHAN:
71            text = "KERNIGHAN LIN OPTIMIZER   L: select subtree R: whole tree";
72            break;
73        case AWT_MODE_OPTIMIZE:
74            text = "NNI & KL OPTIMIZER   L: select subtree R: whole tree";
75            break;
76        case AWT_MODE_SETROOT:
77            text = "SET ROOT MODE   LEFT: set root";
78            break;
79        case AWT_MODE_RESET:
80            text = "RESET MODE   LEFT: reset rotation  MIDDLE: reset angles  RIGHT: reset linewidth";
81            break;
82
83        default:
84            text="No help for this mode available";
85            break;
86    }
87
88    awt_assert(strlen(text) < AWAR_FOOTER_MAX_LEN); // text too long!
89
90    ntw->awr->awar(AWAR_FOOTER)->write_string( text);
91    ntw->set_mode(mode);
92}
93
94// ---------------------------------------
95//      Basic mark/unmark callbacks :
96// ---------------------------------------
97
98void NT_count_mark_all_cb(void *dummy, AW_CL cl_ntw)
99{
100    AWUSE(dummy);
101    AWT_canvas *ntw = (AWT_canvas*)cl_ntw;
102    GB_push_transaction(ntw->gb_main);
103
104    GBDATA *gb_species_data = GB_search(ntw->gb_main,"species_data",GB_CREATE_CONTAINER);
105    long    count           = GB_number_of_marked_subentries(gb_species_data);
106
107    GB_pop_transaction(ntw->gb_main);
108
109    char buf[256];
110    switch (count) {
111        case 0: strcpy(buf, "There are NO marked species"); break;
112        case 1: strcpy(buf, "There is 1 marked species"); break;
113        default: sprintf(buf, "There are %li marked species", count); break;
114    }
115    strcat(buf, ". (The number of species is displayed in the top area as well)");
116    aw_message(buf);
117}
118
119static int nt_species_has_alignment(GBDATA *gb_species, void *cd_use) {
120    return GBT_read_sequence(gb_species, (const char*)cd_use) != 0;
121}
122
123static int nt_sequence_is_partial(GBDATA *gb_species, void *cd_partial) {
124    long wanted  = (long)cd_partial;
125    awt_assert(wanted == 0 || wanted == 1);
126    int partial = GBT_is_partial(gb_species, 1-wanted, 0);
127
128    return partial == wanted;
129}
130
131#define MARK_MODE_LOWER_BITS (1|2)
132#define MARK_MODE_UPPER_BITS (4|8|16)
133
134void NT_mark_all_cb(AW_window *, AW_CL cl_ntw, AW_CL cl_mark_mode)
135    // Bits 0 and 1 of mark_mode:
136    //
137    // mark_mode&3 == 0 -> unmark
138    // mark_mode&3 == 1 -> mark
139    // mark_mode&3 == 2 -> toggle mark
140    //
141    // Bits 2 .. 4 of mark_mode:
142    //
143    // mark_mode&12 == 4 -> affect only full sequences
144    // mark_mode&12 == 8 -> affect only partial sequences
145    // mark_mode&12 == 16 -> affect only species with data in current alignment
146    // else -> affect all sequences
147{
148    AWT_canvas *ntw       = (AWT_canvas*)cl_ntw;
149    int         mark_mode = (int)cl_mark_mode;
150
151    GB_transaction gb_dummy(ntw->gb_main);
152
153    switch (mark_mode&MARK_MODE_UPPER_BITS) {
154        case 0:                 // all sequences
155            GBT_mark_all(ntw->gb_main,mark_mode&MARK_MODE_LOWER_BITS);
156            break;
157        case 4:                 // full sequences only
158            GBT_mark_all_that(ntw->gb_main,mark_mode&MARK_MODE_LOWER_BITS, nt_sequence_is_partial, (void*)0);
159            break;
160        case 8:                 // partial sequences only
161            GBT_mark_all_that(ntw->gb_main,mark_mode&MARK_MODE_LOWER_BITS, nt_sequence_is_partial, (void*)1);
162            break;
163        case 16: {               // species with data in alignment only
164            char *ali = GBT_get_default_alignment(ntw->gb_main);
165            if (ali) GBT_mark_all_that(ntw->gb_main, mark_mode&MARK_MODE_LOWER_BITS, nt_species_has_alignment, (void*)ali);
166            free(ali);
167            break;
168        }
169        default :
170            awt_assert(0); // illegal mode
171            break;
172    }
173
174    ntw->refresh();
175}
176
177void NT_mark_tree_cb(AW_window *, AW_CL cl_ntw, AW_CL cl_mark_mode)
178{
179    AWT_canvas       *ntw       = (AWT_canvas*)cl_ntw;
180    int               mark_mode = (int)cl_mark_mode;
181    AWT_graphic_tree *gtree     = AWT_TREE(ntw);
182    GB_transaction    gb_dummy(ntw->gb_main);
183
184    gtree->check_update(ntw->gb_main);
185    switch (mark_mode&MARK_MODE_UPPER_BITS) {
186        case 0:                 // all sequences
187            gtree->mark_species_in_tree(gtree->tree_root, mark_mode&MARK_MODE_LOWER_BITS);
188            break;
189        case 4:                 // full sequences only
190            gtree->mark_species_in_tree_that(gtree->tree_root, mark_mode&MARK_MODE_LOWER_BITS, nt_sequence_is_partial, (void*)0);
191            break;
192        case 8:                 // partial sequences only
193            gtree->mark_species_in_tree_that(gtree->tree_root, mark_mode&MARK_MODE_LOWER_BITS, nt_sequence_is_partial, (void*)1);
194            break;
195        case 16: {               // species with data in alignment only
196            char *ali = GBT_get_default_alignment(ntw->gb_main);
197            if (ali) gtree->mark_species_in_tree_that(gtree->tree_root, mark_mode&MARK_MODE_LOWER_BITS, nt_species_has_alignment, (void*)ali);
198            free(ali);
199            break;
200        }
201        default :
202            awt_assert(0); // illegal mode
203            break;
204    }
205    ntw->refresh();
206}
207
208struct mark_nontree_cb_data {
209    int      mark_mode_upper_bits;
210    char    *ali;               // current alignment (only if mark_mode_upper_bits == 16)
211    GB_HASH *hash;
212};
213
214static int mark_nontree_cb(GBDATA *gb_species, void *cb_data) {
215    struct mark_nontree_cb_data *data    = (mark_nontree_cb_data*)cb_data;
216    const char                  *name    = GBT_read_name(gb_species);
217    bool                         mark_me = false;
218
219    if (GBS_read_hash(data->hash, name) == (long)gb_species) { // species is not in tree!
220        switch (data->mark_mode_upper_bits) {
221            case 0:             // all sequences
222                mark_me = true;
223                break;
224            case 4:             // full sequences only
225                mark_me = nt_sequence_is_partial(gb_species, (void*)0);
226                break;
227            case 8:             // partial sequences only
228                mark_me = nt_sequence_is_partial(gb_species, (void*)1);
229                break;
230            case 16:            // species with data in alignment only
231                mark_me = nt_species_has_alignment(gb_species, data->ali);
232                break;
233            default :
234                awt_assert(0); // illegal mode
235                break;
236        }
237    }
238
239    return mark_me;
240}
241
242void NT_mark_nontree_cb(AW_window *, AW_CL cl_ntw, AW_CL cl_mark_mode)
243{
244    AWT_canvas                  *ntw       = (AWT_canvas*)cl_ntw;
245    int                          mark_mode = (int)cl_mark_mode;
246    AWT_graphic_tree            *gtree     = AWT_TREE(ntw);
247    GB_transaction               gb_dummy(ntw->gb_main);
248    struct mark_nontree_cb_data  cd;
249
250    if ((mark_mode&MARK_MODE_LOWER_BITS) == 0) {   // unmark is much faster
251        cd.hash = GBT_create_marked_species_hash(ntw->gb_main); // because it only hashes marked species
252    }
253    else {
254        cd.hash = GBT_create_species_hash(ntw->gb_main/*, 1*/); // otherwise we have to hash ALL species
255        // Note: changed to ignore case (ralf 2007-07-06)
256    }
257
258    NT_remove_species_in_tree_from_hash(gtree->tree_root, cd.hash);
259
260    cd.mark_mode_upper_bits = mark_mode&MARK_MODE_UPPER_BITS;
261    cd.ali                  = cd.mark_mode_upper_bits == 16 ? GBT_get_default_alignment(ntw->gb_main) : 0;
262
263    GBT_mark_all_that(ntw->gb_main, mark_mode&MARK_MODE_LOWER_BITS, mark_nontree_cb, (void*)&cd);
264
265    free(cd.ali);
266
267    ntw->refresh();
268}
269
270void NT_mark_color_cb(AW_window *, AW_CL cl_ntw, AW_CL cl_mark_mode)
271{
272    AWT_canvas *ntw       = (AWT_canvas*)cl_ntw;
273    int         mark_mode = (int)cl_mark_mode;
274
275    GB_transaction gb_dummy(ntw->gb_main);
276
277    int color_group = mark_mode>>4;
278    awt_assert(mark_mode&(4|8)); // either 4 or 8 has to be set
279    bool mark_matching = (mark_mode&4) == 4;
280    mark_mode    = mark_mode&3;
281
282    for (GBDATA *gb_species = GBT_first_species(ntw->gb_main); gb_species; gb_species = GBT_next_species(gb_species)) {
283        int my_color_group = AW_find_color_group(gb_species, true);
284
285        if (mark_matching == (color_group == my_color_group)) {
286            switch (mark_mode) {
287                case 0: GB_write_flag(gb_species, 0); break;
288                case 1: GB_write_flag(gb_species, 1); break;
289                case 2: GB_write_flag(gb_species, !GB_read_flag(gb_species)); break;
290                default : awt_assert(0); break;
291            }
292        }
293    }
294
295    ntw->refresh();
296}
297
298
299void NT_insert_color_mark_submenu(AW_window_menu_modes *awm, AWT_canvas *ntree_canvas, const char *menuname, int mark_basemode) {
300#define MAXLABEL 40
301#define MAXENTRY 20
302    awm->insert_sub_menu(menuname, "");
303
304    char        label_buf[MAXLABEL+1];
305    char        entry_buf[MAXENTRY+1];
306    char hotkey[]       = "x";
307    const char *hotkeys = "N1234567890  ";
308
309    const char *label_base = 0;
310    switch (mark_basemode) {
311        case 0: label_base = "all_unmark_color"; break;
312        case 1: label_base = "all_mark_color"; break;
313        case 2: label_base = "all_invert_mark_color"; break;
314        default : awt_assert(0); break;
315    }
316
317    for (int all_but = 0; all_but <= 1; ++all_but) {
318        const char *entry_prefix;
319        if (all_but) entry_prefix = "all but";
320        else        entry_prefix  = "all of";
321
322        for (int i = 0; i <= AW_COLOR_GROUPS; ++i) {
323            sprintf(label_buf, "%s_%i", label_base, i);
324
325            if (i) {
326                char *color_group_name = AW_get_color_group_name(awm->get_root(), i);
327                sprintf(entry_buf, "%s '%s'", entry_prefix, color_group_name);
328                free(color_group_name);
329            }
330            else {
331                sprintf(entry_buf, "%s no color group", entry_prefix);
332            }
333
334            hotkey[0] = hotkeys[i];
335            if (hotkey[0] == ' ' || all_but) hotkey[0] = 0;
336
337            awm->insert_menu_topic(label_buf, entry_buf, hotkey, "markcolor.hlp", AWM_ALL,
338                                   NT_mark_color_cb,
339                                   (AW_CL)ntree_canvas,
340                                   (AW_CL)mark_basemode|((all_but == 0) ? 4 : 8)|(i*16));
341        }
342        if (!all_but) awm->insert_separator();
343    }
344
345    awm->close_sub_menu();
346#undef MAXLABEL
347#undef MAXENTRY
348}
349
350static char *create_mark_menu_entry(const char *attrib, const char *entry_template) {
351    char *entry = 0;
352    if (attrib) {
353        bool append = attrib[0] == '-'; // if attrib starts with '-' then append (otherwise prepend)
354        if (append) ++attrib; // skip '-'
355
356        if (append) {
357            char *spaced_attrib = GBS_global_string_copy(" %s", attrib);
358            entry               = GBS_global_string_copy(entry_template, "", spaced_attrib);
359            free(spaced_attrib);
360        }
361        else {
362            char *spaced_attrib = GBS_global_string_copy("%s ", attrib);
363            entry               = GBS_global_string_copy(entry_template, spaced_attrib, "");
364
365            if (islower(entry[0])) entry[0] = toupper(entry[0]); // Caps prepended lowercase 'attrib'
366
367            free(spaced_attrib);
368        }
369    }
370    else {
371        entry = GBS_global_string_copy(entry_template, "", "");
372    }
373    return entry;
374}
375static char *create_mark_menu_id(const char *attrib, const char *id_suffix) {
376    char *id = 0;
377    if (attrib) {
378        id = GBS_global_string_copy("%s_%s", attrib[0] == '-' ? attrib+1 : attrib, id_suffix);
379    }
380    else {
381        id = strdup(id_suffix);
382    }
383    return id;
384}
385
386static void nt_insert_mark_topic(AW_window_menu_modes *awm, AW_active mask, const char *attrib, const char *id_suffix, const char *entry_template,
387                                 const char *hotkey, const char *helpfile,
388                                 AW_CB cb, AW_CL cl1, AW_CL cl2)
389{
390    char *entry = create_mark_menu_entry(attrib, entry_template);
391    char *id    = create_mark_menu_id(attrib, id_suffix);
392
393    awm->insert_menu_topic(id, entry, hotkey, helpfile, mask, cb, cl1, cl2);
394
395    free(id);
396    free(entry);
397}
398
399static void nt_insert_mark_topics(AW_window_menu_modes *awm, AW_active mask, AWT_canvas *ntw, int affect, const char *attrib)
400{
401    awt_assert(affect == (affect&MARK_MODE_UPPER_BITS)); // only bits 2 .. 4 are allowed
402
403    nt_insert_mark_topic(awm, mask, attrib, "mark_all",            "Mark all %sSpecies%s",                    "M", "sp_mrk_all.hlp",    (AW_CB)NT_mark_all_cb,     (AW_CL)ntw, (AW_CL)(1+affect));
404    nt_insert_mark_topic(awm, mask, attrib, "unmark_all",          "Unmark all %sSpecies%s",                  "U", "sp_umrk_all.hlp",   (AW_CB)NT_mark_all_cb,     (AW_CL)ntw, (AW_CL)(0+affect));
405    nt_insert_mark_topic(awm, mask, attrib, "swap_marked",         "Invert marks of all %sSpecies%s",         "I", "sp_invert_mrk.hlp", (AW_CB)NT_mark_all_cb,     (AW_CL)ntw, (AW_CL)(2+affect));
406    awm->insert_separator();
407
408    char *label = create_mark_menu_entry(attrib, "%sSpecies%s in Tree");
409   
410    awm->insert_sub_menu(label, "T");
411    nt_insert_mark_topic(awm, mask, attrib, "mark_tree",           "Mark %sSpecies%s in Tree",                "M", "sp_mrk_tree.hlp",   (AW_CB)NT_mark_tree_cb,    (AW_CL)ntw, (AW_CL)(1+affect));
412    nt_insert_mark_topic(awm, mask, attrib, "unmark_tree",         "Unmark %sSpecies%s in Tree",              "U", "sp_umrk_tree.hlp",  (AW_CB)NT_mark_tree_cb,    (AW_CL)ntw, (AW_CL)(0+affect));
413    nt_insert_mark_topic(awm, mask, attrib, "swap_marked_tree",    "Invert marks of %sSpecies%s in Tree",     "I", "sp_invert_mrk.hlp", (AW_CB)NT_mark_tree_cb,    (AW_CL)ntw, (AW_CL)(2+affect));
414    awm->close_sub_menu();
415
416    freeset(label, create_mark_menu_entry(attrib, "%sSpecies%s NOT in Tree"));
417
418    awm->insert_sub_menu(label, "N");
419    nt_insert_mark_topic(awm, mask, attrib, "mark_nontree",        "Mark %sSpecies%s NOT in Tree",            "M", "sp_mrk_tree.hlp",   (AW_CB)NT_mark_nontree_cb, (AW_CL)ntw, (AW_CL)(1+affect));
420    nt_insert_mark_topic(awm, mask, attrib, "unmark_nontree",      "Unmark %sSpecies%s NOT in Tree",          "U", "sp_umrk_tree.hlp",  (AW_CB)NT_mark_nontree_cb, (AW_CL)ntw, (AW_CL)(0+affect));
421    nt_insert_mark_topic(awm, mask, attrib, "swap_marked_nontree", "Invert marks of %sSpecies%s NOT in Tree", "I", "sp_invert_mrk.hlp", (AW_CB)NT_mark_nontree_cb, (AW_CL)ntw, (AW_CL)(2+affect));
422    awm->close_sub_menu();
423   
424    free(label);
425}
426
427void NT_insert_mark_submenus(AW_window_menu_modes *awm, AWT_canvas *ntw, int insert_as_submenu) {
428    if (insert_as_submenu) {
429        awm->insert_sub_menu("Mark species", "M");
430    }
431
432    {
433        awm->insert_menu_topic("count_marked",  "Count Marked Species",     "C","sp_count_mrk.hlp", AWM_ALL, (AW_CB)NT_count_mark_all_cb,       (AW_CL)ntw, 0 );
434        awm->insert_separator();
435        nt_insert_mark_topics(awm, AWM_ALL, ntw, 0, 0);
436        awm->insert_separator();
437
438        awm->insert_sub_menu("Complete sequences", "o");
439        nt_insert_mark_topics(awm, AWM_EXP, ntw, 4, "complete");
440        awm->close_sub_menu();
441
442        awm->insert_sub_menu("Partial sequences", "P");
443        nt_insert_mark_topics(awm, AWM_EXP, ntw, 8, "partial");
444        awm->close_sub_menu();
445
446        awm->insert_sub_menu("Current Alignment", "A");
447        nt_insert_mark_topics(awm, AWM_EXP, ntw, 16, "-with data");
448        awm->close_sub_menu();
449    }
450
451    if (insert_as_submenu) {
452        awm->close_sub_menu();
453    }
454}
455
456static void nt_save_changed_tree(AWT_canvas *ntw) {
457    GB_ERROR error = AWT_TREE(ntw)->save(ntw->gb_main,0,0,0);
458    if (error) aw_message(error);
459    ntw->zoom_reset();
460    ntw->refresh();
461}
462
463// ---------------------------------------
464//      Automated collapse/expand tree
465// ---------------------------------------
466
467static void nt_group_tree(AWT_canvas *ntw, int mode, int color_group) {
468    GB_transaction gb_dummy(ntw->gb_main);
469
470    AWT_TREE(ntw)->check_update(ntw->gb_main);
471    AWT_TREE(ntw)->group_tree(AWT_TREE(ntw)->tree_root, mode, color_group);
472    nt_save_changed_tree(ntw);
473}
474
475void NT_group_tree_cb      (void *, AWT_canvas *ntw){ nt_group_tree(ntw, 0, 0); }
476void NT_group_not_marked_cb(void *, AWT_canvas *ntw){ nt_group_tree(ntw, 1, 0); }
477void NT_group_terminal_cb  (void *, AWT_canvas *ntw){ nt_group_tree(ntw, 2, 0); }
478void NT_ungroup_all_cb     (void *, AWT_canvas *ntw){ nt_group_tree(ntw, 4, 0); }
479
480void NT_group_not_color_cb(AW_window *, AW_CL cl_ntw, AW_CL cl_colornum) {
481    AWT_canvas     *ntw      = (AWT_canvas*)cl_ntw;
482    int             colornum = (int)cl_colornum;
483
484    nt_group_tree(ntw, 8, colornum);
485}
486
487// ----------------------------------------------------------------------------------------------------
488//      void NT_insert_color_collapse_submenu(AW_window_menu_modes *awm, AWT_canvas *ntree_canvas)
489// ----------------------------------------------------------------------------------------------------
490void NT_insert_color_collapse_submenu(AW_window_menu_modes *awm, AWT_canvas *ntree_canvas) {
491#define MAXLABEL 30
492#define MAXENTRY (AW_COLOR_GROUP_NAME_LEN+10)
493
494    awt_assert(ntree_canvas != 0);
495
496    awm->insert_sub_menu("Group all except Color ...", "C");
497
498    char        label_buf[MAXLABEL+1];
499    char        entry_buf[MAXENTRY+1];
500    char hotkey[]       = "x";
501    const char *hotkeys = "N1234567890  ";
502
503    for (int i = 0; i <= AW_COLOR_GROUPS; ++i) {
504        sprintf(label_buf, "tree_group_not_color_%i", i);
505
506        hotkey[0]                       = hotkeys[i];
507        if (hotkey[0] == ' ') hotkey[0] = 0;
508
509        if (i) {
510            char *color_group_name = AW_get_color_group_name(awm->get_root(), i);
511            sprintf(entry_buf, "%s group '%s'", hotkey, color_group_name);
512            free(color_group_name);
513        }
514        else {
515            strcpy(entry_buf, "No color group");
516        }
517
518        awm->insert_menu_topic(awm->local_id(label_buf), entry_buf, hotkey, "tgroupcolor.hlp", AWM_ALL, NT_group_not_color_cb, (AW_CL)ntree_canvas, (AW_CL)i);
519    }
520
521    awm->close_sub_menu();
522
523#undef MAXLABEL
524#undef MAXENTRY
525}
526
527// ------------------------
528//      tree sorting :
529// ------------------------
530
531void NT_resort_tree_cb(void *dummy, AWT_canvas *ntw,int type)
532{
533    AWUSE(dummy);
534    GB_transaction gb_dummy(ntw->gb_main);
535    AWT_TREE(ntw)->check_update(ntw->gb_main);
536    int stype;
537    switch(type){
538        case 0: stype = 0; break;
539        case 1: stype = 2; break;
540        default:stype = 1; break;
541    }
542    AWT_TREE(ntw)->resort_tree(stype);
543    nt_save_changed_tree(ntw);
544}
545
546void NT_reset_lzoom_cb(void *dummy, AWT_canvas *ntw)
547{
548    AWUSE(dummy);
549    GB_transaction gb_dummy(ntw->gb_main);
550    AWT_TREE(ntw)->check_update(ntw->gb_main);
551    AWT_TREE(ntw)->tree_root_display = AWT_TREE(ntw)->tree_root;
552    ntw->zoom_reset();
553    ntw->refresh();
554}
555
556void NT_reset_pzoom_cb(void *dummy, AWT_canvas *ntw)
557{
558    AWUSE(dummy);
559    GB_transaction gb_dummy(ntw->gb_main);
560    AWT_TREE(ntw)->check_update(ntw->gb_main);
561    ntw->zoom_reset();
562    ntw->refresh();
563}
564
565void NT_set_tree_style(void *dummy, AWT_canvas *ntw, AP_tree_sort type)
566{
567    AWUSE(dummy);
568    GB_transaction gb_dummy(ntw->gb_main);
569    AWT_TREE(ntw)->check_update(ntw->gb_main);
570    AWT_TREE(ntw)->set_tree_type(type);
571    ntw->zoom_reset();
572    ntw->refresh();
573}
574
575void NT_remove_leafs(void *, AWT_canvas *ntw, long mode) {
576    GB_transaction ta(ntw->gb_main);
577
578    AWT_TREE(ntw)->check_update(ntw->gb_main);
579    if (AWT_TREE(ntw)->tree_root) {
580        AWT_TREE(ntw)->tree_root->remove_leafs(ntw->gb_main, (int)mode);
581        if (AWT_TREE(ntw)->tree_root) AWT_TREE(ntw)->tree_root->compute_tree(ntw->gb_main);
582        nt_save_changed_tree(ntw);
583    }
584    else {
585        aw_message("Got no tree");
586    }
587}
588
589void NT_remove_bootstrap(AW_window*, AW_CL cl_ntw, AW_CL) // delete all bootstrap values
590{
591    AWT_canvas     *ntw = (AWT_canvas*)cl_ntw;
592    GB_transaction  gb_dummy(ntw->gb_main);
593   
594    AWT_TREE(ntw)->check_update(ntw->gb_main);
595
596    AP_tree *tree_root = AWT_TREE(ntw)->tree_root;
597    if (tree_root) {
598        tree_root->remove_bootstrap(ntw->gb_main);
599        tree_root->compute_tree(ntw->gb_main);
600        nt_save_changed_tree(ntw);
601    }
602}
603
604void NT_reset_branchlengths(AW_window*, AW_CL cl_ntw, AW_CL) // set all branchlengths to 0.1
605{
606    AWT_canvas     *ntw = (AWT_canvas*)cl_ntw;
607    GB_transaction  gb_dummy(ntw->gb_main);
608    AWT_TREE(ntw)->check_update(ntw->gb_main);
609
610    AP_tree *tree_root = AWT_TREE(ntw)->tree_root;
611    if (tree_root){
612        tree_root->reset_branchlengths(ntw->gb_main);
613        tree_root->compute_tree(ntw->gb_main);
614        nt_save_changed_tree(ntw);
615    }
616}
617
618void NT_move_boot_branch(AW_window*, AW_CL cl_ntw, AW_CL cl_direction) // copy branchlengths to bootstraps (or vice versa)
619{
620    AWT_canvas     *ntw       = (AWT_canvas*)cl_ntw;
621    int             direction = (int)cl_direction;
622    GB_transaction  gb_dummy(ntw->gb_main);
623
624    AWT_TREE(ntw)->check_update(ntw->gb_main);
625
626    AP_tree *tree_root = AWT_TREE(ntw)->tree_root;
627    if (tree_root) {
628        if (direction == 0) tree_root->bootstrap2branchlen(ntw->gb_main);
629        else                tree_root->branchlen2bootstrap(ntw->gb_main);
630
631        tree_root->compute_tree(ntw->gb_main);
632        nt_save_changed_tree(ntw);
633
634        char *adviceText = GBS_global_string_copy("Please note, that you just overwrote your existing %s.",
635                                                  direction ? "bootstrap values" : "branchlengths");
636        AWT_advice(adviceText, AWT_ADVICE_TOGGLE|AWT_ADVICE_HELP, 0, "tbl_boot2len.hlp");
637        free(adviceText);
638    }
639}
640
641void NT_scale_tree(AW_window*, AW_CL cl_ntw, AW_CL) // scale branchlengths
642{
643    char *answer = aw_input("Enter scale factor", "Scale branchlengths by factor:", "100");
644    if (answer) {
645        AWT_canvas *ntw    = (AWT_canvas*)cl_ntw;
646        double      factor = atof(answer);
647        GB_transaction ta(ntw->gb_main);
648
649        AP_tree *tree_root = AWT_TREE(ntw)->tree_root;
650        if (tree_root){
651            tree_root->scale_branchlengths(ntw->gb_main, factor);
652            tree_root->compute_tree(ntw->gb_main);
653            nt_save_changed_tree(ntw);
654        }
655        free(answer);
656    }
657}
658
659void NT_jump_cb(AW_window *dummy, AWT_canvas *ntw, AW_CL auto_expand_groups)
660{
661    AWUSE(dummy);
662    AW_window *aww = ntw->aww;
663    if (!AWT_TREE(ntw)) return;
664    GB_transaction gb_dummy(ntw->gb_main);
665    AWT_TREE(ntw)->check_update(ntw->gb_main);
666    char *name = aww->get_root()->awar(AWAR_SPECIES_NAME)->read_string();
667    if (name[0]){
668        AP_tree * found = AWT_TREE(ntw)->search(AWT_TREE(ntw)->tree_root_display,name);
669        if (!found && AWT_TREE(ntw)->tree_root_display != AWT_TREE(ntw)->tree_root){
670            found = AWT_TREE(ntw)->search(AWT_TREE(ntw)->tree_root,name);
671            if (found) {
672                // now i found a species outside logical zoomed tree
673                aw_message("Species found outside displayed subtree: zoom reset done");
674                AWT_TREE(ntw)->tree_root_display = AWT_TREE(ntw)->tree_root;
675                ntw->zoom_reset();
676            }
677        }
678        switch (AWT_TREE(ntw)->tree_sort) {
679            case AP_TREE_IRS:
680            case AP_TREE_NORMAL:{
681                if (auto_expand_groups) {
682                    bool changed = false;
683                    while (found) {
684                        if (found->gr.grouped) {
685                            found->gr.grouped = 0;
686                            changed = true;
687                        }
688                        found = found->father;
689                    }
690                    if (changed) {
691                        AWT_TREE(ntw)->tree_root->compute_tree(ntw->gb_main);
692                        GB_ERROR error = AWT_TREE(ntw)->save(ntw->gb_main, 0, 0, 0);
693                        if (error) aw_message(error);
694                        ntw->zoom_reset();
695                    }
696                }
697                AW_device      *device = aww->get_size_device(AW_MIDDLE_AREA);
698                device->set_filter(AW_SIZE);
699                device->reset();
700                ntw->init_device(device);
701                ntw->tree_disp->show(device);
702                AW_rectangle    screen;
703                device->get_area_size(&screen);
704                AW_pos          ys = AWT_TREE(ntw)->y_cursor;
705                AW_pos          xs = 0;
706                if (AWT_TREE(ntw)->x_cursor != 0.0 || ys != 0.0) {
707                    AW_pos          x, y;
708                    device->transform(xs, ys, x, y);
709                    if (y < 0.0) {
710                        ntw->scroll(aww, 0, (int) (y - screen.b * .5));
711                    } else if (y > screen.b) {
712                        ntw->scroll(aww, 0, (int) (y - screen.b * .5));
713                    }
714                }else{
715                    if (auto_expand_groups){
716                        aw_message(GBS_global_string("Sorry, I didn't find the species '%s' in this tree", name));
717                    }
718                }
719                ntw->refresh();
720                break;
721            }
722            case AP_LIST_NDS:
723                {
724                    AW_device      *device = aww->get_size_device(AW_MIDDLE_AREA);
725                    device->set_filter(AW_SIZE);
726                    device->reset();
727                    ntw->init_device(device);
728                    ntw->tree_disp->show(device);
729                    AW_rectangle    screen;
730                    device->get_area_size(&screen);
731                    AW_pos          ys = AWT_TREE(ntw)->y_cursor;
732                    AW_pos          xs = 0;
733                    if (AWT_TREE(ntw)->x_cursor != 0.0 || ys != 0.0) {
734                        AW_pos          x, y;
735                        device->transform(xs, ys, x, y);
736                        if (y < 0.0) {
737                            ntw->scroll(aww, 0, (int) (y - screen.b * .5));
738                        } else if (y > screen.b) {
739                            ntw->scroll(aww, 0, (int) (y - screen.b * .5));
740                        }
741                    }else{
742                        if (auto_expand_groups){
743                            aw_message(GBS_global_string("Sorry, your species '%s' is not marked and therefore not in this list", name));
744                        }
745                    }
746                    ntw->refresh();
747                    break;
748                }
749            case AP_TREE_RADIAL:{
750                AWT_TREE(ntw)->tree_root_display = 0;
751                AWT_TREE(ntw)->jump(AWT_TREE(ntw)->tree_root, name);
752                if (!AWT_TREE(ntw)->tree_root_display) {
753                    aw_message(GBS_global_string("Sorry, I didn't find the species '%s' in this tree", name));
754                    AWT_TREE(ntw)->tree_root_display = AWT_TREE(ntw)->tree_root;
755                }
756                ntw->zoom_reset();
757                ntw->refresh();
758                break;
759            }
760            default : awt_assert(0); break;
761        }
762    }
763    free(name);
764}
765
766void NT_jump_cb_auto(AW_window *dummy, AWT_canvas *ntw){    // jump only if auto jump is set
767    if (AWT_TREE(ntw)->tree_sort == AP_TREE_NORMAL || AWT_TREE(ntw)->tree_sort == AP_LIST_NDS) {
768        if (ntw->aww->get_root()->awar(AWAR_DTREE_AUTO_JUMP)->read_int()) {
769            NT_jump_cb(dummy,ntw,0);
770            return;
771        }
772    }
773    ntw->refresh();
774}
775
776inline const char *plural(int val) {
777    return "s"+(val == 1);
778}
779
780void NT_reload_tree_event(AW_root *awr, AWT_canvas *ntw, GB_BOOL set_delete_cbs)
781{
782    GB_push_transaction(ntw->gb_main);
783    char *tree_name = awr->awar(ntw->user_awar)->read_string();
784
785    GB_ERROR error = ntw->tree_disp->load(ntw->gb_main, tree_name,1,set_delete_cbs);    // linked
786    if (error) {
787        aw_message(error);
788    }
789    else {
790        int zombies, duplicates;
791        ((AWT_graphic_tree*)ntw->tree_disp)->get_zombies_and_duplicates(zombies, duplicates);
792
793        if (zombies || duplicates) {
794            const char *msg = 0;
795            if (duplicates) {
796                if (zombies) msg = GBS_global_string("%i zombie%s and %i duplicate%s", zombies, plural(zombies), duplicates, plural(duplicates));
797                else msg         = GBS_global_string("%i duplicate%s", duplicates, plural(duplicates));
798            }
799            else {
800                awt_assert(zombies);
801                msg = GBS_global_string("%i zombie%s", zombies, plural(zombies));
802            }
803            aw_message(GBS_global_string("%s in '%s'", msg, tree_name));
804        }
805    }
806    free(tree_name);
807    ntw->zoom_reset();
808    AWT_expose_cb(0,ntw,0);
809    GB_pop_transaction(ntw->gb_main);
810}
811
812void NT_recompute_cb(AW_window *,AWT_canvas *ntw, AW_CL cl2) {
813    AWT_graphic_tree *gt = dynamic_cast<AWT_graphic_tree*>(ntw->tree_disp);
814    awt_assert(gt);
815
816    gt->tree_root->compute_tree(ntw->gb_main);
817    AWT_expose_cb (ntw->aww, ntw, cl2 );
818}
819
820void NT_remove_species_in_tree_from_hash(AP_tree *tree,GB_HASH *hash) {
821    if (!tree) return;
822    if (tree->is_leaf && tree->name) {
823        GBS_write_hash(hash,tree->name,0);  // delete species in hash table
824    }else{
825        NT_remove_species_in_tree_from_hash(tree->leftson,hash);
826        NT_remove_species_in_tree_from_hash(tree->rightson,hash);
827    }
828}
829
Note: See TracBrowser for help on using the repository browser.