source: tags/initial/EDIT4/ED4_base.cxx

Last change on this file was 2, checked in by oldcode, 24 years ago

Initial revision

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