source: branches/port5/EDIT4/ED4_base.cxx

Last change on this file was 5901, checked in by westram, 16 years ago
  • AW_BOOL → bool
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 54.5 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <memory.h>
5
6#include <arbdb.h>
7#include <arbdbt.h>
8
9#include <aw_root.hxx>
10#include <aw_device.hxx>
11#include <aw_keysym.hxx>
12#include <aw_window.hxx>
13#include <aw_preset.hxx>
14
15#include <ed4_extern.hxx>
16
17#include "ed4_class.hxx"
18#include "ed4_awars.hxx"
19#include "ed4_edit_string.hxx"
20
21ED4_group_manager *ED4_base::is_in_folded_group() const
22{
23    if (!parent) return 0;
24    ED4_base *group = get_parent(ED4_L_GROUP);
25    if (!group) return 0;
26    if (group->dynamic_prop & ED4_P_IS_FOLDED) return group->to_group_manager();
27    return group->is_in_folded_group();
28}
29
30bool ED4_base::remove_deleted_childs()
31{
32    e4_assert(0);
33    return false;
34}
35
36bool ED4_terminal::remove_deleted_childs()
37{
38    if (flag.deleted) {
39        if (get_species_pointer() != 0) {
40#if defined(DEBUG)
41            printf("ED4_terminal: has non-zero species_pointer in remove_deleted_childs (resetting to zero)\n");
42#endif // DEBUG
43            set_species_pointer(0);
44        }
45        ED4_ROOT->announce_deletion(this);
46        parent->children->delete_member(this);
47        return true;
48    }
49
50    return false;
51}
52bool ED4_sequence_info_terminal::remove_deleted_childs()
53{
54    if (flag.deleted) {
55        if (get_species_pointer() != 0) {
56#if defined(DEBUG)
57            printf("ED4_sequence_info_terminal: has non-zero species_pointer in remove_deleted_childs (resetting to zero)\n");
58#endif // DEBUG
59            set_species_pointer(0);
60        }
61        ED4_ROOT->announce_deletion(this);
62        parent->children->delete_member(this);
63        return true;
64    }
65
66    return false;
67}
68
69bool ED4_manager::remove_deleted_childs()
70{
71    int  i;
72    bool deletion_occurred = false;
73
74 restart:
75
76    for (i=0; i<children->members(); i++) {
77        ED4_base *child = children->member(i);
78        if (child->remove_deleted_childs()) {
79            deletion_occurred = true;
80            goto restart;       // because order of childs may have changed
81        }
82    }
83
84    if (!children->members()) {
85        if (parent) {
86            ED4_ROOT->announce_deletion(this);
87            parent->children->delete_member(this);
88            return true;
89        }
90#if defined(DEBUG)
91        printf("ED4_manager::remove_deleted_childs: I have no parent\n");
92#endif // DEBUG
93    }
94    else if (deletion_occurred) {
95        parent->refresh_requested_by_child();
96    }
97
98    return false;
99}
100
101void ED4_base::changed_by_database(void)
102{
103    e4_assert(0);
104    // this happens if you add a new species_pointer to a ED4_base-derived type
105    // without defining changed_by_database for this type
106}
107
108void ED4_manager::changed_by_database(void) {
109    remove_deleted_childs();
110    set_refresh(1);
111    if (parent) {
112        parent->refresh_requested_by_child();
113    }
114    else {
115#if defined(DEBUG)
116        printf("ED4_manager::changed_by_database: I have no parent!\n");
117#endif // DEBUG
118    }
119    ED4_ROOT->main_manager->Show();
120}
121
122void ED4_terminal::changed_by_database(void)
123{
124    if (GB_read_clock(GLOBAL_gb_main) > actual_timestamp) { // only if timer_cb occurred after last change by EDIT4
125
126        // test if alignment length has changed:
127        {
128            GBDATA *gb_alignment = GBT_get_alignment(GLOBAL_gb_main,ED4_ROOT->alignment_name);
129            e4_assert(gb_alignment);
130            GBDATA *gb_alignment_len = GB_search(gb_alignment,"alignment_len",GB_FIND);
131            int alignment_length = GB_read_int(gb_alignment_len);
132
133            if (MAXSEQUENCECHARACTERLENGTH!=alignment_length) {
134                ED4_alignment_length_changed(gb_alignment_len, 0, GB_CB_CHANGED);
135            }
136        }
137
138        GBDATA *gb_seq = get_species_pointer();
139        int type = GB_read_type(gb_seq);
140
141        if (type==GB_STRING) {
142            char *data = (char*)GB_read_old_value();
143            int data_len = GB_read_old_size();
144
145            if (data) {
146                char *dup_data = new char[data_len+1];
147
148                memcpy(dup_data, data, data_len);
149                dup_data[data_len] = 0;
150
151#if defined(DEBUG) && 0
152                char *n = GB_read_string(gb_seq);
153                e4_assert(strcmp(n,dup_data)!=0); // not really changed
154                delete n;
155#endif
156
157                ED4_species_manager *spman = get_parent(ED4_L_SPECIES)->to_species_manager();
158                spman->do_callbacks();
159
160                if (dynamic_prop & ED4_P_CONSENSUS_RELEVANT) {
161                    ED4_multi_species_manager *multiman = get_parent(ED4_L_MULTI_SPECIES)->to_multi_species_manager();
162
163                    multiman->check_bases_and_rebuild_consensi(dup_data, data_len, spman, ED4_U_UP);
164
165                    set_refresh(1);
166                    parent->refresh_requested_by_child();
167                    //                     ED4_ROOT->main_manager->Show();
168                }
169
170                delete [] dup_data;
171            }
172        }
173    }
174}
175
176void ED4_base::deleted_from_database()
177{
178    my_species_pointer.notify_deleted();
179}
180void ED4_terminal::deleted_from_database()
181{
182    ED4_base::deleted_from_database();
183}
184void ED4_text_terminal::deleted_from_database()
185{
186#if defined(DEBUG)
187    printf("ED4_text_terminal::deleted_from_database (%p)\n", this);
188#endif // DEBUG
189    ED4_terminal::deleted_from_database();
190
191    // @@@ hide all cursors pointing to this terminal!
192
193    if (parent->is_name_manager()) {
194#if defined(DEBUG)
195        printf("- Deleting name terminal\n");
196#endif // DEBUG
197        ED4_name_manager *name_man = parent->to_name_manager();
198        flag.deleted               = 1;
199        name_man->delete_requested_by_child();
200    }
201    else if (parent->is_sequence_manager()) {
202#if defined(DEBUG)
203        printf("- Deleting sequence terminal\n");
204#endif // DEBUG
205        ED4_sequence_manager *seq_man = parent->to_sequence_manager();
206        flag.deleted                  = 1;
207        seq_man->delete_requested_by_child();
208    }
209    else {
210        e4_assert(0); // not prepated for that situation
211    }
212}
213
214void ED4_sequence_terminal::deleted_from_database()
215{
216#if defined(DEBUG)
217    printf("ED4_sequence_terminal::deleted_from_database (%p)\n", this);
218#endif // DEBUG
219
220    ED4_terminal::deleted_from_database();
221
222    bool was_consensus_relevant = dynamic_prop & ED4_P_CONSENSUS_RELEVANT;
223
224    dynamic_prop = ED4_properties(dynamic_prop&~(ED4_P_CONSENSUS_RELEVANT|ED4_P_ALIGNMENT_DATA));
225
226    // @@@ hide all cursors pointing to this terminal!
227
228    char *data = (char*)GB_read_old_value();
229    int data_len = GB_read_old_size();
230
231    ED4_multi_species_manager *multi_species_man = get_parent(ED4_L_MULTI_SPECIES)->to_multi_species_manager();
232
233    if (was_consensus_relevant) {
234        multi_species_man->check_bases(data, data_len, 0);
235        multi_species_man->rebuild_consensi(get_parent(ED4_L_SPECIES)->to_species_manager(), ED4_U_UP);
236    }
237
238    ED4_sequence_manager *seq_man = parent->to_sequence_manager();
239    flag.deleted = 1;
240    seq_man->delete_requested_by_child();
241}
242void ED4_manager::deleted_from_database()
243{
244    if (is_species_manager()) {
245        ED4_species_manager *species_man = to_species_manager();
246        ED4_multi_species_manager *multi_man = species_man->parent->to_multi_species_manager();
247
248        multi_man->children->delete_member(species_man);
249        GB_push_transaction(GLOBAL_gb_main);
250        multi_man->update_consensus(multi_man, 0, species_man);
251        multi_man->rebuild_consensi(species_man, ED4_U_UP);
252        GB_pop_transaction(GLOBAL_gb_main);
253
254        ED4_device_manager *device_manager = ED4_ROOT->main_manager
255            ->get_defined_level(ED4_L_GROUP)->to_group_manager()
256            ->get_defined_level(ED4_L_DEVICE)->to_device_manager();
257
258        int i;
259        for (i=0; i<device_manager->children->members(); i++) { // when killing species numbers have to be recalculated
260            ED4_base *member = device_manager->children->member(i);
261
262            if (member->is_area_manager()) {
263                member->to_area_manager()->get_defined_level(ED4_L_MULTI_SPECIES)->to_multi_species_manager()->generate_id_for_groups();
264            }
265        }
266
267        if (parent) parent->resize_requested_by_child();
268        ED4_ROOT->refresh_all_windows(0);
269
270        parent = 0;
271        //      delete this; // crashes when removing callback deleted_from_database()
272    }
273    else {
274        e4_assert(0);
275    }
276}
277
278void ED4_sequence_changed_cb(GBDATA *gb_seq, int *cl, GB_CB_TYPE gbtype)
279{
280    ED4_base *base = (ED4_base*)(cl);
281
282    if (base->get_species_pointer()!=gb_seq) {
283        e4_assert(0);
284        aw_message("Illegal callback (ED4_sequence_changed_cb())");
285    }
286
287    if (gbtype&GB_CB_DELETE) {
288        e4_assert(gbtype==GB_CB_DELETE);
289        base->deleted_from_database();
290    }
291
292    if (gbtype&GB_CB_CHANGED) {
293        base->changed_by_database();
294    }
295
296    if (gbtype&GB_CB_SON_CREATED) {
297        // @@@ New son for database-member was created ... what may we do now?
298    }
299}
300
301int ED4_elements_in_species_container; // # of elements in species container
302void ED4_species_container_changed_cb(GBDATA *gb_species_data, int */*cl*/, GB_CB_TYPE gbtype)
303{
304    if (gbtype==GB_CB_CHANGED) {
305        int nsons = GB_number_of_subentries(gb_species_data);
306
307        if (nsons>ED4_elements_in_species_container) { // new species was created
308#if defined(DEBUG) && 1
309            printf("# of species in species-container changed from %i to %i\n", ED4_elements_in_species_container, nsons);
310            aw_popup_ok("Species container changed!");
311#endif
312            GBDATA *gb_lastSon = GB_search_last_son(gb_species_data);
313
314            if (gb_lastSon) {
315                GBDATA *gb_name = GB_search(gb_lastSon, "name", GB_FIND);
316
317                if (gb_name) {
318                    char *name = GB_read_as_string(gb_name);
319
320                    ED4_get_and_jump_to_species(name);
321#if defined(DEBUG) && 1
322                    printf("new species = '%s'\n", name);
323#endif
324                    free(name);
325                }
326            }
327        }
328        ED4_elements_in_species_container = nsons;
329    }
330}
331
332ED4_species_pointer::ED4_species_pointer()
333{
334    species_pointer = 0;
335}
336ED4_species_pointer::~ED4_species_pointer()
337{
338    e4_assert(species_pointer==0);      // must be destroyed before
339}
340void ED4_species_pointer::add_callback(int *clientdata)
341{
342    GB_push_transaction(GLOBAL_gb_main);
343    GB_add_callback(species_pointer, (GB_CB_TYPE ) (GB_CB_CHANGED|GB_CB_DELETE), (GB_CB)ED4_sequence_changed_cb, clientdata);
344    GB_pop_transaction(GLOBAL_gb_main);
345}
346void ED4_species_pointer::remove_callback(int *clientdata)
347{
348    GB_push_transaction(GLOBAL_gb_main);
349    GB_remove_callback(species_pointer, (GB_CB_TYPE ) (GB_CB_CHANGED|GB_CB_DELETE), (GB_CB)ED4_sequence_changed_cb, clientdata);
350    GB_pop_transaction(GLOBAL_gb_main);
351}
352void ED4_species_pointer::set_species_pointer(GBDATA *gbd, int *clientdata)
353{
354    if (species_pointer) remove_callback(clientdata);
355    species_pointer = gbd;
356    if (species_pointer) add_callback(clientdata);
357}
358
359// -----------------
360//      ED4_base
361// -----------------
362
363bool ED4_base::is_visible(AW_pos x, AW_pos y, ED4_direction direction) {
364    // indicates whether x, y are in the visible scrolling area
365    // x, y are calculated by calc_world_coords
366    bool        visible = true;
367    ED4_coords& coords  = ED4_ROOT->get_ed4w()->coords;
368
369    switch (direction)
370    {
371        case ED4_D_HORIZONTAL:
372            if ((long(x)<coords.window_left_clip_point) ||
373                (long(x)>coords.window_right_clip_point)) {
374                visible = false;
375            }
376            break;
377        case ED4_D_VERTICAL:
378            if ((long(y)<coords.window_upper_clip_point) ||
379                (long(y)>coords.window_lower_clip_point)) {
380                visible = false;
381            }
382            break;
383        case ED4_D_VERTICAL_ALL: // special case for scrolling (whole object visible)
384            if ((long(y) < coords.window_upper_clip_point) ||
385                (long(y) + extension.size[HEIGHT] > coords.window_lower_clip_point)) {
386                visible = false;
387            }
388            break;
389        case ED4_D_ALL_DIRECTION:
390            if ((long(x) < coords.window_left_clip_point)  ||
391                (long(x) > coords.window_right_clip_point) ||
392                (long(y) < coords.window_upper_clip_point) ||
393                (long(y) > coords.window_lower_clip_point)) {
394                visible = false;
395            }
396            break;
397        default:
398            visible = false;
399            e4_assert(0);
400            break;
401    }
402
403    return visible;
404}
405
406inline bool ranges_overlap(AW_pos p1, AW_pos p2, int r1, int r2) {
407    // return true if ranges p1..p2 and r1..r2 overlap
408    e4_assert(p1 <= p2);
409    e4_assert(r1 <= r2);
410
411    return !((r2 <= p1) || (p2 <= r1)); // "exactly adjacent" means "not overlapping"
412}
413
414bool ED4_base::is_visible(AW_pos x1, AW_pos y1, AW_pos x2, AW_pos y2, ED4_direction IF_DEBUG(direction))
415// optimized case of function above (to avoid the need to call it 4 times)
416{
417    e4_assert(direction == ED4_D_ALL_DIRECTION);
418    e4_assert(x1 <= x2);
419    e4_assert(y1 <= y2);
420
421    ED4_coords& coords  = ED4_ROOT->get_ed4w()->coords;
422
423    bool visible = (ranges_overlap(x1, x2, coords.window_left_clip_point, coords.window_right_clip_point) &&
424                    ranges_overlap(y1, y2, coords.window_upper_clip_point, coords.window_lower_clip_point));
425
426    return visible;
427}
428
429
430char *ED4_base::resolve_pointer_to_string_copy(int *) const { return NULL; }
431const char *ED4_base::resolve_pointer_to_char_pntr(int *) const { return NULL; }
432
433ED4_ERROR *ED4_base::write_sequence(const char */*seq*/, int /*seq_len*/)
434{
435    e4_assert(0);
436    return 0;
437}
438
439
440ED4_returncode ED4_manager::create_group(ED4_group_manager **group_manager, GB_CSTR group_name)                 // creates group from user menu of AW_Window
441{
442    ED4_species_manager         *species_manager        = NULL;
443    ED4_species_name_terminal   *species_name_terminal  = NULL;
444    ED4_sequence_manager        *sequence_manager       = NULL;
445    ED4_sequence_info_terminal  *sequence_info_terminal = NULL;
446    ED4_sequence_terminal       *sequence_terminal      = NULL;
447    ED4_spacer_terminal         *group_spacer_terminal1 = NULL;
448    ED4_spacer_terminal         *group_spacer_terminal2 = NULL;
449    ED4_multi_species_manager   *multi_species_manager  = NULL;
450    ED4_bracket_terminal        *bracket_terminal       = NULL;
451
452    char buffer[35];
453
454    sprintf(buffer, "Group_Manager.%ld", ED4_counter);                                                          //create new group manager
455    *group_manager = new ED4_group_manager(buffer, 0, 0, 0, 0, NULL);
456
457    sprintf(buffer, "Bracket_Terminal.%ld", ED4_counter);
458    bracket_terminal = new ED4_bracket_terminal(buffer, 0, 0, BRACKETWIDTH, 0, *group_manager);
459    (*group_manager)->children->append_member(bracket_terminal);
460
461    sprintf(buffer, "MultiSpecies_Manager.%ld", ED4_counter);                                                   //create new multi_species_manager
462    multi_species_manager = new ED4_multi_species_manager(buffer, BRACKETWIDTH, 0, 0, 0,*group_manager);        //Objekt Gruppen name_terminal noch
463    (*group_manager)->children->append_member( multi_species_manager );                                 //auszeichnen
464
465    (*group_manager)->set_properties((ED4_properties) ( ED4_P_MOVABLE));
466    multi_species_manager->set_properties((ED4_properties) (ED4_P_IS_HANDLE));
467    bracket_terminal->set_properties((ED4_properties) ( ED4_P_IS_HANDLE));
468    bracket_terminal->set_links( NULL, multi_species_manager );
469
470    sprintf(buffer, "Group_Spacer_Terminal_Beg.%ld", ED4_counter);                                                      //Spacer at beginning of group
471    group_spacer_terminal1 = new ED4_spacer_terminal( buffer , 0, 0, 10, SPACERHEIGHT, multi_species_manager);  //For better Overview
472    multi_species_manager->children->append_member( group_spacer_terminal1 );
473
474    sprintf( buffer, "Consensus_Manager.%ld", ED4_counter );                                                    //Create competence terminal
475    species_manager = new ED4_species_manager( buffer, 0, SPACERHEIGHT, 0, 0, multi_species_manager );
476    species_manager->set_properties( ED4_P_MOVABLE );
477    species_manager->flag.is_consensus = 1;
478    multi_species_manager->children->append_member( species_manager );
479
480
481    species_name_terminal = new ED4_species_name_terminal(  group_name, 0, 0, MAXSPECIESWIDTH - BRACKETWIDTH, TERMINALHEIGHT, species_manager );
482    species_name_terminal->set_properties( (ED4_properties) (ED4_P_SELECTABLE | ED4_P_DRAGABLE | ED4_P_IS_HANDLE) );    //only some terminals
483    species_name_terminal->set_links( NULL, ED4_ROOT->ref_terminals.get_ref_sequence() );
484    species_manager->children->append_member( species_name_terminal );                                                  //properties
485
486    sprintf( buffer, "Consensus_Seq_Manager.%ld", ED4_counter);
487    sequence_manager = new ED4_sequence_manager( buffer, MAXSPECIESWIDTH, 0, 0, 0, species_manager );
488    sequence_manager->set_properties( ED4_P_MOVABLE );
489    species_manager->children->append_member( sequence_manager );
490
491    sequence_info_terminal = new ED4_sequence_info_terminal( "DATA",/*NULL,*/ 0, 0, SEQUENCEINFOSIZE, TERMINALHEIGHT, sequence_manager );       // Info fuer Gruppe
492    sequence_info_terminal->set_links( ED4_ROOT->ref_terminals.get_ref_sequence_info(), ED4_ROOT->ref_terminals.get_ref_sequence_info() );
493    sequence_info_terminal->set_properties( (ED4_properties) (ED4_P_SELECTABLE | ED4_P_DRAGABLE | ED4_P_IS_HANDLE) );
494    sequence_manager->children->append_member( sequence_info_terminal );
495
496    sequence_terminal = new ED4_consensus_sequence_terminal( "", SEQUENCEINFOSIZE, 0, 0, TERMINALHEIGHT, sequence_manager );
497    sequence_terminal->set_properties( ED4_P_CURSOR_ALLOWED );
498    sequence_terminal->set_links( ED4_ROOT->ref_terminals.get_ref_sequence() , ED4_ROOT->ref_terminals.get_ref_sequence());
499    sequence_manager->children->append_member( sequence_terminal );
500
501    sprintf(buffer, "Group_Spacer_Terminal_End.%ld", ED4_counter);                                                      //Spacer at beginning of group
502    group_spacer_terminal2 = new ED4_spacer_terminal( buffer , 0, SPACERHEIGHT + TERMINALHEIGHT, 10, SPACERHEIGHT, multi_species_manager);      //For better Overview
503    multi_species_manager->children->append_member( group_spacer_terminal2 );
504
505    ED4_counter ++;
506
507    return ED4_R_OK;
508}
509
510
511ED4_returncode ED4_base::generate_configuration_string(char **generated_string)
512{
513    ED4_multi_species_manager *multi_species_manager = NULL;
514    char sep_name[2];
515    sep_name[0] = 1;
516    sep_name[1] = 0;
517
518    char *old_string;
519    char *dummy        = NULL;
520    char *species_name = NULL;
521    int   i;
522    long  old_size;
523    long  new_size;
524
525    AW_pos old_pos = 0;
526
527    if (!(*generated_string)) {
528        *generated_string = new char[2];
529        strcpy(*generated_string,sep_name);
530    }
531    ED4_manager *consensus_manager = NULL;
532
533    if (is_species_name_terminal() &&
534        !((ED4_terminal *)this)->flag.deleted) { // wenn multi_name_manager mehrere name_terminals hat, dann muss das echte name_terminal markiert sein
535
536        old_size   = strlen(*generated_string);
537        old_string = *generated_string;
538
539        if (parent->flag.is_consensus) {
540            dummy = new char[strlen(id)+1];
541
542            for (i=0; id[i] != '(' && id[i] != '\0'; i++)
543                dummy[i] = id[i];
544
545            if (id[i] == '(')
546                dummy[i-1] = '\0';
547
548            new_size   = old_size + strlen(dummy) + 2;
549        }
550        else { // we are Species or SAI
551            int len;
552            species_name = resolve_pointer_to_string_copy(&len);
553            new_size     = old_size + len + 3; // 3 because of separator and identifier
554        }
555
556        *generated_string = new char[new_size];
557
558        for (i=0; i<old_size; ++i)
559            (*generated_string)[i] = old_string[i];
560
561        for (; i < new_size; ++i)
562            (*generated_string)[i] = 0;
563
564
565        if (parent->flag.is_consensus) { // in consensus terminals the brackets have to be eliminated
566            strcat (*generated_string, dummy);
567            delete [] dummy;
568        }
569        else if (parent->parent->parent->flag.is_SAI) { // if Species_manager has flag is_SAI
570            strcat(*generated_string, "S");
571            strcat(*generated_string, species_name);
572        }
573        else {
574            strcat(*generated_string, "L");
575            strcat(*generated_string, species_name);
576        }
577
578        strcat(*generated_string, sep_name);
579        delete [] old_string;
580    }
581    else if (is_group_manager()) {
582        old_string = *generated_string;
583        old_size   = strlen(*generated_string);
584        new_size   = old_size + 1; // 3 because of separator and identifier
585        *generated_string = new char[new_size+1];
586
587        for (i=0; i<old_size; ++i) {
588            (*generated_string)[i] = old_string[i];
589        }
590
591        for (; i < new_size; ++i) {
592            (*generated_string)[i] = 0;
593        }
594
595        delete [] old_string;
596
597        if (dynamic_prop & ED4_P_IS_FOLDED) {
598            strcat(*generated_string, "F");
599        }
600        else {
601            strcat(*generated_string, "G");
602        }
603
604        multi_species_manager = to_group_manager()->get_defined_level(ED4_L_MULTI_SPECIES)->to_multi_species_manager();
605        // moving Consensus to top of list is essentially
606
607        // for creating the string
608        if (!(multi_species_manager->children->member(1)->flag.is_consensus)) {
609            for (i=0; i < multi_species_manager->children->members(); i++) {
610                if (multi_species_manager->children->member(i)->flag.is_consensus) {
611                    consensus_manager = multi_species_manager->children->member(i)->to_manager();
612                    break;
613                }
614            }
615
616            multi_species_manager->children->delete_member( consensus_manager );
617            old_pos = consensus_manager->extension.position[Y_POS];
618            consensus_manager->extension.position[Y_POS] = SPACERHEIGHT;
619            ED4_base::touch_world_cache();
620            multi_species_manager->children->append_member( consensus_manager );
621        }
622    }
623
624    if (is_manager()) {
625        ED4_manager *this_manager = this->to_manager();
626        if (this_manager->children) {
627            for (i=0; i<this_manager->children->members(); i++) {
628                this_manager->children->member(i)->generate_configuration_string( generated_string );
629            }
630        }
631    }
632
633    if (multi_species_manager){
634        old_string = *generated_string;
635        old_size   = strlen(*generated_string);
636        new_size   = old_size + 3;                                                      // 3 because of separator and identifier
637        *generated_string = new char[new_size];
638
639        for (i=0; i<old_size; ++i)
640            (*generated_string)[i] = old_string[i];
641
642        for (; i < new_size; ++i)
643            (*generated_string)[i] = 0;
644
645        delete [] old_string;
646
647        strcat(*generated_string, "E");
648        strcat(*generated_string, sep_name);
649
650        if (consensus_manager) {
651            multi_species_manager->children->delete_member( consensus_manager );                // move Consensus back to old position
652            consensus_manager->extension.position[Y_POS] = old_pos;
653            ED4_base::touch_world_cache();
654            multi_species_manager->children->append_member( consensus_manager );
655        }
656    }
657
658    free(species_name);
659
660    return ED4_R_OK;
661}
662
663ED4_returncode ED4_base::route_down_hierarchy(void **arg1, void **arg2, ED4_returncode (*function) (void **, void **, ED4_base *))
664// executes 'function' for every element in hierarchy
665{
666    function(arg1, arg2, this);
667    return ED4_R_OK;
668}
669
670ED4_returncode ED4_manager::route_down_hierarchy(void **arg1, void **arg2, ED4_returncode (*function) (void **, void **, ED4_base *))
671{
672    int i;
673
674    function(arg1, arg2, this);
675
676    if (children) {
677        for (i=0; i < children->members(); i++) {
678            children->member(i)->route_down_hierarchy(arg1, arg2, function);
679        }
680    }
681
682    return ED4_R_OK;
683}
684
685ED4_base *ED4_manager::find_first_that(ED4_level level, int (*condition)(ED4_base *to_test, AW_CL arg), AW_CL arg)
686{
687    if ((spec->level&level) && condition(this, arg)) {
688        return this;
689    }
690
691    int i;
692
693    if (children) {
694        for (i=0; i<children->members(); i++) {
695            ED4_base *child = children->member(i);
696
697            if (child->is_manager()) {
698                ED4_base *found = child->to_manager()->find_first_that(level, condition, arg);
699                if (found) {
700                    return found;
701                }
702            }
703            else if ((child->spec->level&level) && condition(child, arg)) {
704                return child;
705            }
706        }
707    }
708
709    return 0;
710}
711
712ED4_base *ED4_manager::find_first_that(ED4_level level, int (*condition)(ED4_base *to_test))
713{
714    return find_first_that(level, (int(*)(ED4_base*,AW_CL))condition, (AW_CL)0);
715}
716
717int ED4_base::calc_group_depth()
718{
719    ED4_base *temp_parent;
720    int       cntr = 0;
721
722    temp_parent = parent;
723    while (temp_parent->parent && !(temp_parent->is_area_manager())) {
724        if (temp_parent->is_group_manager()) {
725            cntr ++;
726        }
727        temp_parent = temp_parent->parent;
728    }
729
730    return cntr; // don't count our own group
731}
732
733ED4_returncode ED4_base::remove_callbacks() //removes callbacks
734{
735    return ED4_R_IMPOSSIBLE;
736}
737
738
739ED4_base *ED4_base::search_spec_child_rek( ED4_level level ) //recursive search for level
740{
741    return spec->level&level ? this : (ED4_base*)NULL;
742}
743
744ED4_base *ED4_manager::search_spec_child_rek(ED4_level level)
745{
746    if (spec->level & level) return this;
747
748    if (children) {
749        int i;
750
751        for (i=0; i<children->members(); i++) { // first check children
752            if (children->member(i)->spec->level & level) {
753                return children->member(i);
754            }
755        }
756
757        for (i=0; i<children->members(); i++) {
758            ED4_base *result = children->member(i)->search_spec_child_rek(level);
759            if (result) {
760                return result;
761            }
762        }
763    }
764
765    return 0;
766}
767
768ED4_terminal *ED4_base::get_next_terminal()
769{
770    ED4_terminal *terminal = 0;
771
772    if (parent) {
773        terminal = parent->get_first_terminal(index+1);
774        if (!terminal) {
775            terminal = parent->get_next_terminal();
776        }
777    }
778
779    return terminal;
780}
781
782ED4_terminal *ED4_base::get_prev_terminal()
783{
784    ED4_terminal *terminal = 0;
785
786    if (parent) {
787        if (index) {
788            terminal = parent->get_last_terminal(index-1);
789        }
790        if (!terminal) {
791            terminal = parent->get_prev_terminal();
792        }
793    }
794
795    return terminal;
796}
797
798
799bool ED4_base::has_parent(ED4_manager *Parent)
800{
801    // return true if 'parent' is a perent of this
802
803    if (is_manager()) {
804        if (this == static_cast<ED4_base*>(Parent)) {
805            return true;
806        }
807    }
808
809    if (!parent) return false;
810    return parent->has_parent(Parent);
811}
812
813
814ED4_AREA_LEVEL  ED4_base::get_area_level(ED4_multi_species_manager **multi_species_manager) const
815{
816
817    ED4_base *temp_manager;
818    temp_manager = get_parent( ED4_L_AREA );
819    if (!temp_manager){
820        return ED4_A_ERROR;
821    }
822
823    ED4_area_manager    *temp_parent;
824    temp_parent = temp_manager->to_area_manager();
825
826    if (temp_parent == ED4_ROOT->top_area_man)
827    {
828        if (multi_species_manager){
829            *multi_species_manager = temp_parent->get_defined_level(ED4_L_MULTI_SPECIES)->to_multi_species_manager();
830        }
831        return ED4_A_TOP_AREA;
832    }
833
834    if (temp_parent == ED4_ROOT->middle_area_man)
835    {
836        if(multi_species_manager){
837            *multi_species_manager = temp_parent->get_defined_level(ED4_L_MULTI_SPECIES)->to_multi_species_manager();
838        }
839        return ED4_A_MIDDLE_AREA;
840    }
841
842    return ED4_A_ERROR;
843}
844
845
846void ED4_manager::generate_id_for_groups() {
847    int i;
848
849    for (i=0; i<children->members(); i++) {
850        if (children->member(i)->is_group_manager()) {
851            ED4_multi_species_manager *multi_man = children->member(i)->to_group_manager()->get_defined_level(ED4_L_MULTI_SPECIES)->to_multi_species_manager();
852
853            multi_man->count_all_children_and_set_group_id();
854        }
855    }
856}
857
858
859int ED4_multi_species_manager::count_all_children_and_set_group_id() // counts all species of a multi_species_manager
860{
861    int counter = 0,
862        i;
863    char *name;
864
865
866    //    ED4_multi_species_manager *multi_species_manager = get_defined_level(ED4_L_MULTI_SPECIES)->to_multi_species_manager();
867
868    for (i=0; i<children->members(); i++) {
869        ED4_base *member = children->member(i);
870        if (member->is_species_manager() && !member->flag.is_consensus) {
871            counter ++;
872        }
873        else if (member->is_group_manager()) {
874            counter += member->to_group_manager()->get_defined_level(ED4_L_MULTI_SPECIES)->to_multi_species_manager()->count_all_children_and_set_group_id();
875        }
876    }
877
878
879    ED4_base *consensus_name_terminal = get_consensus_terminal();
880    name = (char*)GB_calloc(strlen(consensus_name_terminal->id)+10, sizeof(*name));
881
882    for ( i=0; consensus_name_terminal->id[i] != '(' && consensus_name_terminal->id[i] != '\0' ; i++) {
883        name[i] = consensus_name_terminal->id[i];
884    }
885    if (consensus_name_terminal->id[i] != '\0') { // skip space
886        i--;
887    }
888    name[i] = '\0';
889    sprintf(name, "%s (%d)",name, counter);
890
891    freeset(consensus_name_terminal->id, name);
892
893    //    update_species_counters();
894    return counter;
895}
896
897void ED4_sequence_terminal_basic::calc_intervall_displayed_in_rectangle(AW_rectangle *rect, long *left_index, long *right_index) { // rect contains win-coords
898    AW_pos x ,y;
899    // int    length_of_char = ED4_ROOT->font_info[ED4_G_SEQUENCES].get_width();
900    int    length_of_char = ED4_ROOT->font_group.get_width(ED4_G_SEQUENCES);
901
902    calc_world_coords( &x, &y );
903    ED4_ROOT->world_to_win_coords(ED4_ROOT->get_ed4w()->aww, &x, &y);
904
905    int rel_left_x =  (int)(rect->l-x);
906    int rel_right_x = (int)(rect->r-x);
907
908    *left_index  = (int)((rel_left_x-CHARACTEROFFSET)/length_of_char); // - 1;
909    *right_index = (int)((rel_right_x-CHARACTEROFFSET)/length_of_char) + 1;
910
911    if (*right_index > MAXSEQUENCECHARACTERLENGTH) *right_index = MAXSEQUENCECHARACTERLENGTH;
912    if (*left_index < 0) *left_index = 0;
913}
914
915void ED4_sequence_terminal_basic::calc_update_intervall(long *left_index, long *right_index )
916{
917    AW_pos x ,y;
918    // int    length_of_char = ED4_ROOT->font_info[ED4_G_SEQUENCES].get_width();
919    int    length_of_char = ED4_ROOT->font_group.get_width(ED4_G_SEQUENCES);
920
921    calc_world_coords( &x, &y );
922    AW_device *dev = ED4_ROOT->get_device();
923    ED4_coords *coords = &ED4_ROOT->get_ed4w()->coords;
924
925    int rel_left_x =  (int)( (dev->clip_rect.l-x) // Abstand vom linken Terminalrand zum Anfang des Clipping rectangles
926                             + (coords->window_left_clip_point-x)); // Verschiebung der Sequenz (durch Scrollen) == slider Position
927
928    int rel_right_x = (int)( (dev->clip_rect.r-x) + (coords->window_left_clip_point-x) );
929
930    *left_index  = (int)((rel_left_x-CHARACTEROFFSET)/length_of_char); // - 1;
931    *right_index = (int)((rel_right_x-CHARACTEROFFSET)/length_of_char) + 1;
932
933    if (*right_index >= MAXSEQUENCECHARACTERLENGTH) *right_index = MAXSEQUENCECHARACTERLENGTH-1;
934    if (*left_index < 0) *left_index                             = 0;
935}
936
937void ED4_manager::create_consensus(ED4_group_manager *upper_group_manager) {
938    // creates consensus
939    // is called by group manager
940   
941    ED4_group_manager *group_manager_for_child = upper_group_manager;
942
943    if (is_group_manager()) {
944        ED4_group_manager *group_manager = to_group_manager();
945
946        group_manager->table().init(MAXSEQUENCECHARACTERLENGTH);
947        group_manager_for_child = group_manager;
948
949        if (loading) {
950            if (aw_status(++status_count_curr/double(status_count_total)) == 1) { // Kill has been Pressed
951                aw_closestatus();
952                ED4_exit();
953            }
954        }
955    }
956    int i;
957    for (i=0; i<children->members(); i++) {
958        ED4_base *member = children->member(i);
959
960        if (member->is_species_manager()){
961            ED4_species_manager *species_manager = member->to_species_manager();
962            ED4_terminal *sequence_data_terminal = species_manager->get_consensus_relevant_terminal();
963
964            if (sequence_data_terminal) {
965                int   db_pointer_len;
966                char *db_pointer = sequence_data_terminal->resolve_pointer_to_string_copy(&db_pointer_len);
967                group_manager_for_child->table().add(db_pointer, db_pointer_len);
968                e4_assert(!group_manager_for_child->table().empty());
969                free(db_pointer);
970            }
971        }else if (member->is_group_manager()){
972            ED4_group_manager *sub_group = member->to_group_manager();
973
974            sub_group->create_consensus(sub_group);
975            e4_assert(sub_group!=upper_group_manager);
976            upper_group_manager->table().add(sub_group->table());
977#if defined(TEST_CHAR_TABLE_INTEGRITY)
978            if (!sub_group->table().empty() && !sub_group->table().is_ignored()) {
979                e4_assert(!upper_group_manager->table().empty());
980            }
981#endif
982        }
983        else if (member->is_manager()) {
984            member->to_manager()->create_consensus(group_manager_for_child);
985        }
986    }
987}
988
989ED4_terminal *ED4_base::get_consensus_relevant_terminal()
990{
991    int i;
992
993    if (is_terminal()) {
994        if (dynamic_prop & ED4_P_CONSENSUS_RELEVANT) {
995            return this->to_terminal();
996        }
997        return NULL;
998    }
999
1000    ED4_manager  *manager           = this->to_manager();
1001    ED4_terminal *relevant_terminal = 0;
1002    int           members           = manager->children->members();
1003
1004    for (i=0; !relevant_terminal && i<members; ++i) {
1005        ED4_base     *member = manager->children->member(i);
1006        relevant_terminal    = member->get_consensus_relevant_terminal();
1007    }
1008
1009#if defined(DEBUG)
1010    if (relevant_terminal) {
1011        for (; i<members; ++i) {
1012            ED4_base *member = manager->children->member(i);
1013            e4_assert(!member->get_consensus_relevant_terminal()); // there shall be only 1 consensus relevant terminal, since much code assumes that
1014        }
1015    }
1016#endif // DEBUG
1017
1018    return relevant_terminal;
1019}
1020
1021int ED4_multi_species_manager::count_visible_children() // is called by a multi_species_manager
1022{
1023    int counter = 0;
1024
1025    for (int i=0; i<children->members(); i++) {
1026        ED4_base *member = children->member(i);
1027        if (member->is_species_manager()) {
1028            counter ++;
1029        }
1030        else if (member->is_group_manager()) {
1031            ED4_group_manager *group_manager = member->to_group_manager();
1032            if (group_manager->dynamic_prop & ED4_P_IS_FOLDED) {
1033                counter ++;
1034            }
1035            else {
1036                ED4_multi_species_manager *multi_species_manager = group_manager->get_defined_level(ED4_L_MULTI_SPECIES)->to_multi_species_manager();
1037                counter += multi_species_manager->count_visible_children();
1038            }
1039        }
1040    }
1041    return counter;
1042}
1043
1044
1045
1046ED4_base *ED4_base::get_parent(ED4_level lev) const
1047{
1048    ED4_base *temp_parent = this->parent;
1049
1050    while (temp_parent && !(temp_parent->spec->level & lev)) {
1051        temp_parent = temp_parent->parent;
1052    }
1053
1054    return temp_parent;
1055}
1056
1057char *ED4_base::get_name_of_species() {
1058    char                *name        = 0;
1059    ED4_species_manager *species_man = get_parent( ED4_L_SPECIES )->to_species_manager();
1060    if (species_man) {
1061        ED4_species_name_terminal *species_name = species_man->search_spec_child_rek(ED4_L_SPECIES_NAME)->to_species_name_terminal();
1062        if (species_name){
1063            GBDATA *gb_name   = species_name->get_species_pointer();
1064            if (gb_name) {
1065                GB_transaction ta(gb_name);
1066                name = GB_read_as_string(gb_name);
1067            }
1068        }
1069    }
1070    return name;
1071}
1072
1073ED4_base *ED4_manager::get_defined_level(ED4_level lev) const
1074{
1075    int i;
1076
1077    for (i=0; i<children->members(); i++) { // first make a complete search in myself
1078        if (children->member(i)->spec->level & lev) {
1079            return children->member(i);
1080        }
1081    }
1082
1083    for (i=0; i<children->members(); i++) { // then all groups
1084        ED4_base *member = children->member(i);
1085
1086        if (member->is_multi_species_manager()) {
1087            return member->to_multi_species_manager()->get_defined_level(lev);
1088        }
1089        else if (member->is_group_manager()) {
1090            return member->to_group_manager()->children->member(1)->to_multi_species_manager()->get_defined_level(lev);
1091        }
1092    }
1093    return NULL;                                                                //nothing found
1094}
1095
1096ED4_returncode ED4_base::set_width()                                            // sets object length of terminals to Consensus_Name_terminal if existing
1097{                                                                               // else to MAXSPECIESWIDTH
1098    int                 i;
1099
1100    if (is_species_manager() && !flag.is_consensus && !parent->flag.is_consensus) {
1101        ED4_species_manager *species_manager = to_species_manager();
1102        ED4_multi_name_manager *multi_name_manager = species_manager->get_defined_level(ED4_L_MULTI_NAME)->to_multi_name_manager();     // case I'm a species
1103        ED4_terminal *consensus_terminal = parent->to_multi_species_manager()->get_consensus_terminal();
1104
1105        for (i=0; i < multi_name_manager->children->members(); i++){
1106            ED4_name_manager *name_manager = multi_name_manager->children->member(i)->to_name_manager();
1107            if (consensus_terminal){
1108                name_manager->children->member(0)->extension.size[WIDTH] = consensus_terminal->extension.size[WIDTH];
1109            }
1110            else{
1111                name_manager->children->member(0)->extension.size[WIDTH] = MAXSPECIESWIDTH;
1112            }
1113
1114            name_manager->resize_requested_by_child();
1115        }
1116
1117        for (i=0; i < species_manager->children->members(); i++) { // adjust all managers as far as possible
1118            ED4_base *smember = species_manager->children->member(i);
1119            if (consensus_terminal) {
1120                ED4_base *kmember = consensus_terminal->parent->children->member(i);
1121                if (kmember) {
1122                    smember->extension.position[X_POS] = kmember->extension.position[X_POS];
1123                    ED4_base::touch_world_cache();
1124                }
1125            }
1126            else { // got no consensus
1127                ED4_species_manager *a_species = parent->get_defined_level(ED4_L_SPECIES)->to_species_manager();
1128                if (a_species) {
1129                    smember->extension.position[X_POS] = a_species->children->member(i)->extension.position[X_POS];
1130                    ED4_base::touch_world_cache();
1131                }
1132            }
1133            species_manager->children->member(i)->resize_requested_by_child();
1134        }
1135    }
1136    else if (is_group_manager()) {
1137        ED4_group_manager *group_manager = this->to_group_manager();
1138        ED4_multi_species_manager *multi_species_manager = group_manager->get_defined_level(ED4_L_MULTI_SPECIES)->to_multi_species_manager();
1139        ED4_terminal *mark_consensus_terminal = multi_species_manager->get_consensus_terminal();
1140        ED4_terminal *consensus_terminal = parent->to_multi_species_manager()->get_consensus_terminal();
1141
1142        if (consensus_terminal) { // we're a group in another group
1143            mark_consensus_terminal->extension.size[WIDTH] = consensus_terminal->extension.size[WIDTH] - BRACKETWIDTH;
1144        }
1145        else { // we're at the top (no consensus terminal)
1146            mark_consensus_terminal->extension.size[WIDTH] = MAXSPECIESWIDTH - BRACKETWIDTH;
1147        }
1148
1149        mark_consensus_terminal->parent->resize_requested_by_child();
1150
1151        for (i=0; i < multi_species_manager->children->members(); i++) {
1152            multi_species_manager->children->member(i)->set_width();
1153        }
1154
1155        for (i=0; i < group_manager->children->members(); i++) { // for all groups below from us
1156            if (group_manager->children->member(i)->is_group_manager()) {
1157                group_manager->children->member(i)->set_width();
1158            }
1159        }
1160    }
1161
1162    return ED4_R_OK;
1163}
1164
1165
1166short ED4_base::in_border( AW_pos x, AW_pos y, ED4_movemode mode )                              // determines if given world coords x and y
1167{                                                                                               // are within borders of current object according to move mode
1168    AW_pos    world_x, world_y;
1169
1170    calc_world_coords( &world_x, &world_y );                                            // calculate absolute extension of current object
1171
1172    switch ( mode )                                                                             // which direction ?
1173    {
1174        case ED4_M_HORIZONTAL:
1175            {
1176                if ( (x >= world_x) && (x < (world_x + extension.size[WIDTH])) )
1177                    return ( 1 );                                               // target location is within the borders of parent
1178                break;
1179            }
1180        case ED4_M_VERTICAL:
1181            {
1182                if ( (y >= world_y) && (y < (world_y + extension.size[HEIGHT])) )
1183                    return ( 1 );                                               // target location is within the borders of parent
1184                break;
1185            }
1186        case ED4_M_FREE:
1187            {
1188                return ( in_border( x, y, ED4_M_HORIZONTAL ) && in_border( x, y, ED4_M_VERTICAL ) );
1189            }
1190        case ED4_M_NO_MOVE:
1191            {
1192                break;
1193            }
1194    }
1195
1196    return ( 0 );
1197}
1198
1199
1200void ED4_base::calc_rel_coords(AW_pos *x, AW_pos *y) // calculates coordinates relative to current object from given world coords
1201{
1202    AW_pos   world_x, world_y;
1203
1204    calc_world_coords( &world_x, &world_y );                                            // calculate world coordinates of current object
1205
1206    *x -= world_x;                                                                              // calculate relative coordinates by substracting world
1207    *y -= world_y;                                                                              // coords of current object
1208}
1209
1210
1211ED4_returncode  ED4_base::event_sent_by_parent( AW_event */*event*/, AW_window */*aww*/)
1212{
1213    return ( ED4_R_OK );
1214}
1215
1216ED4_returncode ED4_manager::hide_children()
1217{
1218    int i;
1219
1220    for (i=0; i<children->members(); i++) {
1221        ED4_base *member = children->member(i);
1222        if (!member->is_spacer_terminal() && !member->flag.is_consensus) { // don't hide spacer and Consensus
1223            member->flag.hidden = 1;
1224        }
1225    }
1226
1227    update_info.set_resize(1);
1228    resize_requested_by_parent();
1229
1230    return ED4_R_OK;
1231}
1232
1233
1234ED4_returncode ED4_manager::make_children_visible()
1235{
1236    if (!children) {
1237        return ED4_R_WARNING;
1238    }
1239    else {
1240        for (int i=0; i < children->members(); i++) {
1241            children->member(i)->flag.hidden = 0; // make child visible
1242        }
1243
1244        update_info.set_resize(1);
1245        resize_requested_by_parent();
1246
1247        return ED4_R_OK;
1248    }
1249}
1250
1251ED4_returncode ED4_manager::unfold_group(char *bracket_ID_to_unfold)
1252{
1253    int i;
1254
1255    ED4_base *bracket_terminal = search_ID(bracket_ID_to_unfold);
1256    if (!bracket_terminal) return ED4_R_WARNING;
1257
1258    ED4_manager *temp_parent = bracket_terminal->parent;
1259    if (!temp_parent) return ED4_R_WARNING;
1260
1261    ED4_multi_species_manager *multi_species_manager = NULL;
1262
1263
1264#if defined(LIMIT_TOP_AREA_SPACE)
1265    int nr_of_visible_species   = 0;
1266    int nr_of_children_in_group = 0;
1267    ED4_AREA_LEVEL level = temp_parent->get_area_level(&multi_species_manager);
1268    if (level==ED4_A_TOP_AREA || level==ED4_A_BOTTOM_AREA) { // check if there are any unfolding restrictions
1269        nr_of_visible_species = multi_species_manager->count_visible_children();
1270
1271        if (nr_of_visible_species >= MAX_TOP_AREA_SIZE) {
1272            aw_message("Top area limited to " MAX_TOP_AREA_SIZE " species\n"
1273                       "Advice: Move group to main area and try again");
1274            return ED4_R_IMPOSSIBLE;
1275        }
1276
1277        nr_of_children_in_group = temp_parent->get_defined_level(ED4_L_MULTI_SPECIES)->to_multi_species_manager()->count_visible_children();
1278
1279        if (nr_of_children_in_group + nr_of_visible_species - 1 > MAX_TOP_AREA_SIZE) {
1280            aw_message("Top area limited to " MAX_TOP_AREA_SIZE " species\n"
1281                       "Advice: Move group to main area and try again");
1282            return ED4_R_IMPOSSIBLE;
1283        }
1284    }
1285#else // LIMIT_TOP_AREA_SPACE
1286    temp_parent->get_area_level(&multi_species_manager);
1287#endif
1288
1289    for (i=0; i < temp_parent->children->members(); i++) {
1290        ED4_base *member = temp_parent->children->member(i);
1291
1292        if (member->is_multi_species_manager()) {
1293            multi_species_manager = member->to_multi_species_manager();
1294            multi_species_manager->make_children_visible();
1295            multi_species_manager->dynamic_prop = ED4_properties(multi_species_manager->dynamic_prop & ~ED4_P_IS_FOLDED );
1296
1297            ED4_spacer_terminal *spacer = multi_species_manager->get_defined_level(ED4_L_SPACER)->to_spacer_terminal();
1298            spacer->extension.size[HEIGHT] = SPACERHEIGHT;
1299        }
1300    }
1301
1302    bracket_terminal->dynamic_prop =  ED4_properties(bracket_terminal->dynamic_prop & ~ED4_P_IS_FOLDED);
1303    temp_parent->dynamic_prop =  ED4_properties(temp_parent->dynamic_prop & ~ED4_P_IS_FOLDED);
1304
1305    ED4_ROOT->main_manager->update_info.set_resize(1);
1306    ED4_ROOT->main_manager->resize_requested_by_parent();
1307
1308    return ED4_R_OK;
1309}
1310
1311ED4_returncode ED4_manager::fold_group(char *bracket_ID_to_fold)
1312{
1313    ED4_base *bracket_terminal;
1314    ED4_manager *temp_parent;
1315
1316    bracket_terminal = search_ID(bracket_ID_to_fold);
1317
1318    if (!bracket_terminal) return ED4_R_WARNING;
1319
1320    temp_parent = bracket_terminal->parent;
1321    if (!temp_parent) return ED4_R_WARNING;
1322
1323    ED4_multi_species_manager *multi_species_manager = temp_parent->get_defined_level(ED4_L_MULTI_SPECIES)->to_multi_species_manager();
1324    ED4_manager *consensus_manager = NULL;
1325
1326    int consensus_shown = 0;
1327    if (!(multi_species_manager->children->member(1)->flag.is_consensus)) { // if consensus is not a top => move to top
1328        ED4_members *multi_children = multi_species_manager->children;
1329        int i;
1330
1331        for (i=0; i<multi_children->members(); i++) { // search for consensus
1332            if (multi_children->member(i)->flag.is_consensus) {
1333                consensus_manager = multi_children->member(i)->to_manager();
1334                break;
1335            }
1336        }
1337
1338        if (consensus_manager) {
1339            multi_children->move_member(i, 1); // move Consensus to top of list
1340            consensus_manager->extension.position[Y_POS] = SPACERHEIGHT;
1341            ED4_base::touch_world_cache();
1342            consensus_shown = 1;
1343        }
1344    }
1345    else  {
1346        consensus_shown = 1;
1347    }
1348
1349    if (consensus_shown && ED4_ROOT->aw_root->awar(ED4_AWAR_CONSENSUS_SHOW)->read_int()==0) {
1350        consensus_shown = 0;
1351    }
1352
1353    ED4_spacer_terminal *spacer = multi_species_manager->get_defined_level(ED4_L_SPACER)->to_spacer_terminal();
1354    if (spacer) {
1355        spacer->extension.size[HEIGHT] = consensus_shown ? SPACERHEIGHT : SPACERNOCONSENSUSHEIGHT;
1356    }
1357
1358    multi_species_manager->hide_children();
1359    multi_species_manager->set_properties((ED4_properties) (ED4_P_IS_FOLDED) );
1360
1361    bracket_terminal->set_properties((ED4_properties) (ED4_P_IS_FOLDED) );
1362    temp_parent->set_properties((ED4_properties) (ED4_P_IS_FOLDED) );
1363
1364    // fix scrollbars:
1365    ED4_ROOT->main_manager->update_info.set_resize(1);
1366    ED4_ROOT->main_manager->resize_requested_by_parent();
1367
1368    return ED4_R_OK;
1369}
1370
1371
1372void ED4_base::check_all()
1373{
1374    AW_pos x,y;
1375
1376    //  printf("\nName des Aufrufers von Check_All : \t%.40s\n", id);
1377    //  if (spec->level & ED4_L_MULTI_SPECIES)
1378    //  {
1379    calc_world_coords( &x, &y);
1380
1381    printf("Typ des Aufrufers :\t\t\t%s\n", is_manager() ? "Manager" : "Terminal");
1382    printf("Name des Aufrufers von Check_All : \t%.30s\n", (id) ? id : "Keine ID");
1383    printf("Linke obere Ecke x, y : \t\t%f, %f\n", extension.position[0], extension.position[1]);
1384    printf("Breite und Hoehe x, y : \t\t%f, %f\n", extension.size[0], extension.size[1]);
1385    printf("World Coords     x, y : \t\t%f, %f\n\n", x, y);
1386    //          printf("Laenge des Inhalts    : \t\t%d\n",strlen(resolve_pointer_to_string()));
1387    //  }
1388
1389    //  if ((spec->static_prop & ED4_P_IS_MANAGER) == 1)                                        //only scan further if calling object is manager and has children
1390    //  {
1391    //          for (i=0; i < children->no_of_members; i++)
1392    //                  (children->member_list[i])->check_all();
1393    //  }
1394    printf("***********************************************\n\n");
1395
1396}
1397
1398int ED4_base::adjust_clipping_rectangle( void )
1399// return 0 if clipping rectangle disappeared (nothing left to draw)
1400{
1401    AW_pos x, y;
1402
1403    calc_world_coords( &x, &y );
1404    ED4_ROOT->world_to_win_coords(ED4_ROOT->get_aww(), &x, &y);
1405    return ED4_ROOT->get_device()->reduceClipBorders(int(y), int(y+extension.size[HEIGHT]-1), int(x), int(x+extension.size[WIDTH]-1));
1406}
1407
1408
1409void ED4_base::set_properties( ED4_properties prop )
1410{
1411    dynamic_prop = (ED4_properties) (dynamic_prop | prop);
1412}
1413
1414
1415ED4_returncode ED4_base::set_links(ED4_base *temp_width_link, ED4_base *temp_height_link )      //sets links in hierarchy :
1416//width-link sets links between objects on same level
1417{                                                                                               //height-link sets links between objects on different levels
1418    if (temp_width_link)
1419    {
1420        if (width_link)                                                         //if object already has a link
1421            width_link->linked_objects.delete_elem( (void *) this );            //delete link and
1422
1423        width_link = temp_width_link;                                           //set new link to temp_width_link
1424        temp_width_link->linked_objects.append_elem( (void *) this );
1425    }
1426
1427    if (temp_height_link)
1428    {
1429        if ( height_link != NULL )
1430            height_link->linked_objects.delete_elem( (void *) this );
1431
1432        height_link = temp_height_link;
1433        temp_height_link->linked_objects.append_elem( (void *) this );
1434    }
1435
1436    return ( ED4_R_OK );
1437}
1438
1439ED4_returncode ED4_base::link_changed( ED4_base *link )
1440{
1441    if ( (width_link == link) || (height_link == link) )
1442        if ( calc_bounding_box() )
1443            if ( parent != NULL )
1444                parent->resize_requested_by_child();
1445
1446    return ( ED4_R_OK );
1447}
1448
1449int ED4_base::actualTimestamp = 1;
1450void ED4_base::update_world_coords_cache() {
1451    if (parent) {
1452        parent->calc_world_coords(&lastXpos, &lastYpos);
1453    }
1454    else {
1455        lastXpos = 0;
1456        lastYpos = 0;
1457    }
1458    lastXpos += extension.position[X_POS];
1459    lastYpos += extension.position[Y_POS];
1460    timestamp = actualTimestamp;
1461}
1462
1463
1464ED4_returncode ED4_base::clear_background(int color)
1465{
1466    AW_pos x, y;
1467
1468    if (ED4_ROOT->get_device())
1469    {
1470        calc_world_coords(&x, &y);
1471        ED4_ROOT->world_to_win_coords(ED4_ROOT->get_aww(), &x, &y);
1472
1473        ED4_ROOT->get_device()->push_clip_scale();
1474        if (adjust_clipping_rectangle()) {
1475            if (!color) {
1476                ED4_ROOT->get_device()->clear_part(x, y, extension.size[WIDTH], extension.size[HEIGHT], (AW_bitset)-1);
1477            }
1478            else {
1479                ED4_ROOT->get_device()->box(color, true, x, y, extension.size[WIDTH], extension.size[HEIGHT], (AW_bitset)-1, 0, 0); // fill range with color for debugging
1480            }
1481        }
1482        ED4_ROOT->get_device()->pop_clip_scale();
1483    }
1484    return ( ED4_R_OK );
1485}
1486
1487ED4_returncode ED4_base::clear_whole_background( void ) // clear AW_MIDDLE_AREA
1488{
1489    if (ED4_ROOT->get_device())
1490    {
1491        ED4_ROOT->get_device()->push_clip_scale();
1492        ED4_ROOT->get_device()->clear((AW_bitset)-1);
1493        ED4_ROOT->get_device()->pop_clip_scale();
1494    }
1495
1496    return ( ED4_R_OK );
1497}
1498
1499void ED4_base::draw_bb(int color)
1500{
1501    if (ED4_ROOT->get_device()) {
1502        ED4_ROOT->get_device()->push_clip_scale();
1503        if (adjust_clipping_rectangle()) {
1504            AW_pos x1, y1;
1505            calc_world_coords( &x1, &y1 );
1506            ED4_ROOT->world_to_win_coords(ED4_ROOT->get_aww(), &x1, &y1);
1507            ED4_ROOT->get_device()->box(color, false, x1, y1, extension.size[WIDTH]-1, extension.size[HEIGHT]-1, (AW_bitset)-1, 0, 0);
1508        }
1509        ED4_ROOT->get_device()->pop_clip_scale();
1510    }
1511}
1512
1513ED4_base::ED4_base(GB_CSTR temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent )
1514{
1515    index = 0;
1516    dynamic_prop = ED4_P_NO_PROP;
1517    timestamp =  0; // invalid - almost always..
1518
1519    //  id = new char[strlen(temp_id)+1];
1520
1521
1522    if (!strcmp(CONSENSUS,temp_id)) {
1523        id = NULL;
1524    }
1525    else {
1526        id = (char*)malloc(strlen(temp_id)+1);
1527        strcpy( id, temp_id);
1528    }
1529
1530
1531    extension.position[X_POS] = x;
1532    extension.position[Y_POS] = y;
1533    ED4_base::touch_world_cache();
1534    extension.size[WIDTH] = width;
1535    extension.size[HEIGHT] = height;
1536    extension.y_folded = 0;
1537    parent = temp_parent;
1538    width_link = NULL;
1539    height_link = NULL;
1540
1541    memset((char*)&update_info, 0, sizeof(update_info));
1542    memset((char*)&flag, 0, sizeof(flag));
1543}
1544
1545
1546ED4_base::~ED4_base() // before calling this function the first time, parent has to be set NULL
1547{
1548    ED4_base *object;
1549    ED4_base *sequence_terminal = NULL;
1550    ED4_list_elem *list_elem, *old_elem;
1551    ED4_window *ed4w;
1552
1553    list_elem = linked_objects.first();
1554    while (list_elem) {
1555        object = (ED4_base *) list_elem->elem();
1556        if ( object->width_link == this ) {
1557            object->width_link->linked_objects.delete_elem( (void *) this );            //delete link and
1558            object->width_link = NULL;
1559        }
1560
1561        if ( object->height_link == this ) {
1562            object->height_link->linked_objects.delete_elem( (void *) this );           //delete link and
1563            object->height_link = NULL;
1564        }
1565
1566        old_elem = list_elem;
1567        list_elem = list_elem->next();
1568        linked_objects.delete_elem( old_elem->elem() );
1569    }
1570
1571    if ( update_info.linked_to_scrolled_rectangle )
1572    {
1573        if (ED4_ROOT->main_manager)
1574        {
1575            sequence_terminal = ED4_ROOT->main_manager->search_spec_child_rek( ED4_L_SEQUENCE_STRING );
1576
1577            if (sequence_terminal)
1578                sequence_terminal->update_info.linked_to_scrolled_rectangle = 1;
1579
1580            update_info.linked_to_scrolled_rectangle = 0;
1581            ED4_ROOT->scroll_links.link_for_hor_slider = sequence_terminal;
1582
1583            ed4w = ED4_ROOT->get_ed4w();
1584            while ( ed4w != NULL )
1585            {
1586                if ( ed4w->scrolled_rect.x_link == this )
1587                    ed4w->scrolled_rect.x_link = sequence_terminal;
1588
1589                if ( ed4w->scrolled_rect.width_link == this )
1590                    ed4w->scrolled_rect.width_link = sequence_terminal;
1591
1592                ed4w = ed4w->next;
1593            }
1594        }
1595    }
1596
1597    if (width_link)
1598    {
1599        width_link->linked_objects.delete_elem( (void *) this );
1600        width_link = NULL;
1601    }
1602
1603    if (height_link)
1604    {
1605        height_link->linked_objects.delete_elem( (void *) this );
1606        height_link = NULL;
1607    }
1608
1609    set_species_pointer(0);     // clear pointer to database and remove callbacks
1610    free(id);
1611}
1612
Note: See TracBrowser for help on using the repository browser.