root/trunk/EDIT4/ED4_manager.cxx

Revision 8747, 69.7 KB (checked in by westram, 7 hours ago)
  • fixed a few more warnings
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1#include <arbdbt.h>
2
3#include <aw_preset.hxx>
4#include <aw_awar.hxx>
5#include <aw_msg.hxx>
6#include <aw_root.hxx>
7
8#include "ed4_class.hxx"
9#include "ed4_awars.hxx"
10#include "ed4_edit_string.hxx"
11#include "ed4_tools.hxx"
12#include "ed4_list.hxx"
13#include "ed4_ProteinViewer.hxx"
14#include "ed4_protein_2nd_structure.hxx"
15
16#if defined(DEBUG)
17#define TEST_REFRESH_FLAG
18#endif
19
20// -----------------------------------------------------------------
21//      Manager static properties (used by manager-constructors)
22
23static ED4_objspec main_manager_spec(
24    (ED4_properties)(ED4_P_IS_MANAGER | ED4_P_HORIZONTAL), // static props
25    ED4_L_ROOT,                                            // level
26    ED4_L_ROOTGROUP,                                       // allowed children level
27    ED4_L_NO_LEVEL,                                        // handled object
28    ED4_L_NO_LEVEL                                         // restriction level
29    );
30
31static ED4_objspec device_manager_spec(
32    (ED4_properties)(ED4_P_IS_MANAGER | ED4_P_HORIZONTAL), // static props
33    ED4_L_DEVICE,                                          // level
34    (ED4_level)(ED4_L_AREA | ED4_L_SPACER | ED4_L_LINE),   // allowed children level
35    ED4_L_NO_LEVEL,                                        // handled object
36    ED4_L_NO_LEVEL                                         // restriction level
37    );
38
39static ED4_objspec area_manager_spec(
40    (ED4_properties)(ED4_P_IS_MANAGER | ED4_P_VERTICAL),          // static props
41    ED4_L_AREA,                                                   // level
42    (ED4_level)(ED4_L_MULTI_SPECIES | ED4_L_TREE | ED4_L_SPACER), // allowed children level
43    ED4_L_NO_LEVEL,                                               // handled object
44    ED4_L_NO_LEVEL                                                // restriction level
45    );
46
47static ED4_objspec multi_species_manager_spec(
48    (ED4_properties)(ED4_P_IS_MANAGER | ED4_P_HORIZONTAL),   // static props
49    ED4_L_MULTI_SPECIES,                                     // level
50    (ED4_level)(ED4_L_SPECIES | ED4_L_GROUP | ED4_L_SPACER), // allowed children level
51    ED4_L_NO_LEVEL,                                          // handled object
52    ED4_L_NO_LEVEL                                           // restriction level
53    );
54
55static ED4_objspec species_manager_spec(
56    (ED4_properties)(ED4_P_IS_MANAGER | ED4_P_VERTICAL),  // static props
57    ED4_L_SPECIES,                                        // level
58    // (ED4_level)(ED4_L_MULTI_SEQUENCE | ED4_L_MULTI_NAME), // allowed children level
59    (ED4_level)(ED4_L_MULTI_SEQUENCE | ED4_L_MULTI_NAME | // (used by normal species)
60                ED4_L_SPECIES_NAME | ED4_L_SEQUENCE), // allowed children level (used by consensus)
61    ED4_L_NO_LEVEL,                                       // handled object
62    ED4_L_NO_LEVEL                                        // restriction level
63    );
64static ED4_objspec multi_sequence_manager_spec(
65    (ED4_properties)(ED4_P_IS_MANAGER | ED4_P_HORIZONTAL), // static props
66    ED4_L_MULTI_SEQUENCE,                                  // level
67    ED4_L_SEQUENCE,                                        // allowed children level
68    ED4_L_NO_LEVEL,                                        // handled object
69    ED4_L_NO_LEVEL                                         // restriction level
70    );
71
72static ED4_objspec sequence_manager_spec(
73    (ED4_properties)(ED4_P_IS_MANAGER | ED4_P_VERTICAL),      // static props
74    ED4_L_SEQUENCE,                                           // level
75    (ED4_level)(ED4_L_SEQUENCE_INFO | ED4_L_SEQUENCE_STRING | ED4_L_ORF | ED4_L_PURE_TEXT | ED4_L_COL_STAT), // allowed children level
76    ED4_L_NO_LEVEL,                                           // handled object
77    ED4_L_SPECIES                                             // restriction level
78    );
79
80static ED4_objspec multi_name_manager_spec(
81    (ED4_properties)(ED4_P_IS_MANAGER | ED4_P_HORIZONTAL), // static props
82    ED4_L_MULTI_NAME,                                      // level
83    ED4_L_NAME_MANAGER,                                    // allowed children level
84    ED4_L_NO_LEVEL,                                        // handled object
85    ED4_L_NO_LEVEL                                         // restriction level
86    );
87
88static ED4_objspec name_manager_spec(
89    (ED4_properties)(ED4_P_IS_MANAGER | ED4_P_VERTICAL), // static props
90    ED4_L_NAME_MANAGER,                                  // level
91    (ED4_level)(ED4_L_SPECIES_NAME),                     // allowed children level
92    ED4_L_NO_LEVEL,                                      // handled object
93    ED4_L_SPECIES                                        // restriction level
94    );
95
96static ED4_objspec group_manager_spec(
97    (ED4_properties)(ED4_P_IS_MANAGER | ED4_P_VERTICAL),             // static props
98    ED4_L_GROUP,                                                     // level
99    (ED4_level)(ED4_L_MULTI_SPECIES | ED4_L_BRACKET), // allowed children level
100    ED4_L_NO_LEVEL,                                                  // handled object
101    ED4_L_NO_LEVEL                                                   // restriction level
102    );
103
104static ED4_objspec root_group_manager_spec(
105    (ED4_properties)(ED4_P_IS_MANAGER | ED4_P_VERTICAL), // static props
106    ED4_L_ROOTGROUP,                                     // level
107    (ED4_level)(ED4_L_DEVICE),                           // allowed children level
108    ED4_L_NO_LEVEL,                                      // handled object
109    ED4_L_NO_LEVEL                                       // restriction level
110    );
111
112// ----------------------------
113//      ED4_manager methods
114
115ED4_returncode ED4_manager::rebuild_consensi(ED4_base *start_species, ED4_update_flag update_flag) {
116    int                        i;
117    ED4_base                  *temp_parent;
118    ED4_multi_species_manager *multi_species_manager = NULL;
119    ED4_group_manager         *first_group_manager   = NULL;
120
121    temp_parent = start_species;
122
123    switch (update_flag) {
124        case ED4_U_UP:          // rebuild consensus from a certain starting point upwards
125            while (temp_parent) {
126                if (temp_parent->is_group_manager()) {
127                    multi_species_manager = temp_parent->to_group_manager()->get_multi_species_manager();
128                    for (i=0; i<multi_species_manager->children->members(); i++) {
129                        if (multi_species_manager->children->member(i)->is_consensus_manager()) {
130                            rebuild_consensus(multi_species_manager->children->member(i)).expect_no_error();
131                        }
132                    }
133                }
134                temp_parent = temp_parent->parent;
135            }
136            break;
137        case ED4_U_UP_DOWN:     // only search first groupmanager and update consensi recursively downwards
138            while (temp_parent) {
139                if (temp_parent->is_group_manager()) {
140                    first_group_manager = temp_parent->to_group_manager();
141                }
142                temp_parent = temp_parent->parent;
143            }
144            if (first_group_manager)
145                first_group_manager->route_down_hierarchy(rebuild_consensus).expect_no_error();
146            break;
147    }
148    return ED4_R_OK;
149}
150
151ED4_returncode ED4_manager::check_in_bases(ED4_base *added_base) {
152    if (added_base->is_species_manager()) { // add a sequence
153        ED4_species_manager *species_manager = added_base->to_species_manager();
154        const ED4_terminal *sequence_terminal = species_manager->get_consensus_relevant_terminal();
155
156        if (sequence_terminal) {
157            int   seq_len;
158            char *seq          = sequence_terminal->resolve_pointer_to_string_copy(&seq_len);
159            ED4_returncode res = update_bases(0, 0, seq, seq_len);
160            free(seq);
161            return res;
162        }
163    }
164
165    e4_assert(!added_base->is_root_group_manager());
166    if (added_base->is_group_manager()) { // add a group
167        return update_bases(0, &added_base->to_group_manager()->table());
168    }
169
170    e4_assert(0); // wrong type
171   
172    return ED4_R_OK;
173}
174
175ED4_returncode ED4_manager::check_out_bases(ED4_base *subbed_base) {
176    if (subbed_base->is_species_manager()) { // sub a sequence
177        ED4_species_manager *species_manager = subbed_base->to_species_manager();
178        const ED4_terminal *sequence_terminal = species_manager->get_consensus_relevant_terminal();
179
180        if (sequence_terminal) {
181            int   seq_len;
182            char *seq          = sequence_terminal->resolve_pointer_to_string_copy(&seq_len);
183            ED4_returncode res = update_bases(seq, seq_len, (const char *)0, 0);
184            free(seq);
185            return res;
186        }
187    }
188    else {
189        e4_assert(!subbed_base->is_root_group_manager());
190        if (subbed_base->is_group_manager()) { // sub a group
191            return update_bases(&subbed_base->to_group_manager()->table(), 0);
192        }
193        e4_assert(0); // wrong type
194    }
195    return ED4_R_OK;
196}
197
198ED4_returncode ED4_manager::update_bases(const char *old_sequence, int old_len, const ED4_base *new_base, PosRange range) {
199    if (!new_base) {
200        return update_bases(old_sequence, old_len, 0, 0, range);
201    }
202
203    e4_assert(new_base->is_species_manager());
204
205    const ED4_species_manager *new_species_manager   = new_base->to_species_manager();
206    const ED4_terminal        *new_sequence_terminal = new_species_manager->get_consensus_relevant_terminal();
207
208    int   new_len;
209    char *new_sequence = new_sequence_terminal->resolve_pointer_to_string_copy(&new_len);
210
211    if (range.is_whole()) {
212        const PosRange *restricted = ED4_char_table::changed_range(old_sequence, new_sequence, min(old_len, new_len));
213       
214        e4_assert(restricted);
215        range = *restricted;
216    }
217
218    ED4_returncode res = update_bases(old_sequence, old_len, new_sequence, new_len, range);
219    free(new_sequence);
220    return res;
221}
222
223ED4_returncode ED4_manager::update_bases_and_rebuild_consensi(const char *old_sequence, int old_len, ED4_base *new_base, ED4_update_flag update_flag, PosRange range) {
224    e4_assert(new_base);
225    e4_assert(new_base->is_species_manager());
226
227    ED4_species_manager *new_species_manager   = new_base->to_species_manager();
228    const ED4_terminal  *new_sequence_terminal = new_species_manager->get_consensus_relevant_terminal();
229
230    int         new_len;
231    const char *new_sequence = new_sequence_terminal->resolve_pointer_to_char_pntr(&new_len);
232
233#if defined(DEBUG) && 0
234    printf("old: %s\n", old_sequence);
235    printf("new: %s\n", new_sequence);
236#endif // DEBUG
237
238    const PosRange *changedRange = 0;
239    if (range.is_whole()) {
240        changedRange = ED4_char_table::changed_range(old_sequence, new_sequence, min(old_len, new_len));
241    }
242    else {
243        changedRange = &range; // @@@ use method similar to changed_range here, which just reduces the existing range
244    }
245
246    ED4_returncode result = ED4_R_OK;
247    if (changedRange) {
248        ED4_returncode result1 = update_bases(old_sequence, old_len, new_sequence, new_len, *changedRange);
249        ED4_returncode result2 = rebuild_consensi(new_base, update_flag);
250
251        result = (result1 != ED4_R_OK) ? result1 : result2;
252
253        // Refresh aminoacid sequence terminals in Protein Viewer or protstruct // @@@ this is definitely wrong here (omg)
254        if (ED4_ROOT->alignment_type == GB_AT_DNA) {
255            PV_SequenceUpdate_CB(GB_CB_CHANGED);
256        }
257        else if (ED4_ROOT->alignment_type == GB_AT_AA) { 
258            GB_ERROR err = ED4_pfold_set_SAI(&ED4_ROOT->protstruct, GLOBAL_gb_main, ED4_ROOT->alignment_name, &ED4_ROOT->protstruct_len);
259            if (err) { aw_message(err); result = ED4_R_WARNING; }
260        }
261    }
262    return result;
263}
264
265ED4_returncode ED4_manager::update_bases(const ED4_base *old_base, const ED4_base *new_base, PosRange range) {
266    e4_assert(old_base);
267    e4_assert(new_base);
268
269    if (old_base->is_species_manager()) {
270        e4_assert(new_base->is_species_manager());
271        const ED4_species_manager *old_species_manager   = old_base->to_species_manager();
272        const ED4_species_manager *new_species_manager   = new_base->to_species_manager();
273        const ED4_terminal        *old_sequence_terminal = old_species_manager->get_consensus_relevant_terminal();
274        const ED4_terminal        *new_sequence_terminal = new_species_manager->get_consensus_relevant_terminal();
275
276        int   old_len;
277        int   new_len;
278        char *old_seq = old_sequence_terminal->resolve_pointer_to_string_copy(&old_len);
279        char *new_seq = new_sequence_terminal->resolve_pointer_to_string_copy(&new_len);
280
281        ED4_returncode res = update_bases(old_seq, old_len, new_seq, new_len, range);
282        free(new_seq);
283        free(old_seq);
284        return res;
285    }
286
287    e4_assert(!old_base->is_root_group_manager());
288    e4_assert(!new_base->is_root_group_manager());
289    if (old_base->is_group_manager()) {
290        e4_assert(new_base->is_group_manager());
291
292        return update_bases(&old_base->to_group_manager()->table(),
293                           &new_base->to_group_manager()->table(),
294                           range);
295    }
296
297    return ED4_R_OK;
298}
299
300// WITH_ALL_ABOVE_GROUP_MANAGER_TABLES performs a command with all groupmanager-tables
301// starting at walk_up (normally the current) until top (or until one table has an ignore flag)
302
303#define WITH_ALL_ABOVE_GROUP_MANAGER_TABLES(walk_up, COMMAND)                                   \
304    do {                                                                                        \
305        while (walk_up) {                                                                       \
306            if (walk_up->is_abstract_group_manager()) {                                         \
307                ED4_char_table& char_table = walk_up->to_abstract_group_manager()->table();     \
308                char_table.COMMAND;                                                             \
309                if (char_table.is_ignored()) break; /* @@@ problematic */                       \
310            }                                                                                   \
311            walk_up = walk_up->parent;                                                          \
312        }                                                                                       \
313    } while (0)
314
315ED4_returncode ED4_manager::update_bases(const char *old_sequence, int old_len, const char *new_sequence, int new_len, PosRange range) {
316    ED4_manager *walk_up = this;
317
318    if (old_sequence) {
319        if (new_sequence) {
320            if (range.is_whole()) {
321                const PosRange *restricted = ED4_char_table::changed_range(old_sequence, new_sequence, min(old_len, new_len));
322                if (!restricted) return ED4_R_OK;
323               
324                range = *restricted;
325            }
326
327#if defined(DEBUG) && 0
328            printf("update_bases(..., %i, %i)\n", start_pos, end_pos);
329#endif
330
331            WITH_ALL_ABOVE_GROUP_MANAGER_TABLES(walk_up, sub_and_add(old_sequence, new_sequence, range));
332        }
333        else {
334            e4_assert(range.is_whole());
335            WITH_ALL_ABOVE_GROUP_MANAGER_TABLES(walk_up, sub(old_sequence, old_len));
336        }
337    }
338    else {
339        if (new_sequence) {
340            e4_assert(range.is_whole());
341            WITH_ALL_ABOVE_GROUP_MANAGER_TABLES(walk_up, add(new_sequence, new_len));
342        }
343        else {
344            return ED4_R_OK;
345        }
346    }
347
348    ED4_ROOT->root_group_man->remap()->mark_compile_needed();
349    return ED4_R_OK;
350}
351
352ED4_returncode ED4_manager::update_bases(const ED4_char_table *old_table, const ED4_char_table *new_table, PosRange range) {
353    ED4_manager *walk_up = this;
354
355    if (old_table) {
356        if (new_table) {
357            if (range.is_whole()) {
358                const PosRange *restricted = old_table->changed_range(*new_table);
359                if (!restricted) return ED4_R_OK;
360
361                range = *restricted;
362            }
363            WITH_ALL_ABOVE_GROUP_MANAGER_TABLES(walk_up, sub_and_add(*old_table, *new_table, range));
364        }
365        else {
366            e4_assert(range.is_whole());
367            WITH_ALL_ABOVE_GROUP_MANAGER_TABLES(walk_up, sub(*old_table));
368        }
369    }
370    else {
371        if (new_table) {
372            e4_assert(range.is_whole());
373            WITH_ALL_ABOVE_GROUP_MANAGER_TABLES(walk_up, add(*new_table));
374        }
375        else {
376            return ED4_R_OK;
377        }
378    }
379
380    ED4_ROOT->root_group_man->remap()->mark_compile_needed();
381    return ED4_R_OK;
382}
383
384#undef WITH_ALL_ABOVE_GROUP_MANAGER_TABLES
385
386ED4_returncode ED4_manager::remove_callbacks() {
387    // removes callbacks
388    int i;
389
390    for (i=0; i < children->members(); i++) {
391        if (children->member(i)->is_terminal()) {
392            children->member(i)->to_terminal()->remove_callbacks();
393        }
394        else {
395            children->member(i)->to_manager()->remove_callbacks();
396        }
397    }
398
399    return ED4_R_OK;
400}
401
402void ED4_manager::update_consensus(ED4_manager *old_parent, ED4_manager *new_parent, ED4_base *sequence) {
403    if (old_parent) old_parent->check_out_bases(sequence);
404    if (new_parent) new_parent->check_in_bases(sequence);
405}
406
407ED4_terminal* ED4_manager::get_first_terminal(int start_index) const {
408    ED4_terminal *terminal = 0;
409
410    if (children) {
411        int i;
412        for (i=start_index; !terminal && i>=0 && i<children->members(); i++) {
413            ED4_base *base = children->member(i);
414            if (base->is_terminal()) {
415                terminal = base->to_terminal();
416            }
417            else {
418                terminal = base->to_manager()->get_first_terminal();
419            }
420        }
421    }
422
423    return terminal;
424}
425
426ED4_terminal* ED4_manager::get_last_terminal(int start_index) const {
427    ED4_terminal *terminal = 0;
428
429    if (children) {
430        int i;
431        if (start_index<0) start_index = children->members()-1;
432        for (i=start_index; !terminal && i>=0 && i<children->members(); i--) {
433            ED4_base *base = children->member(i);
434            if (base->is_terminal()) {
435                terminal = base->to_terminal();
436            }
437            else {
438                terminal = base->to_manager()->get_last_terminal();
439            }
440        }
441    }
442
443    return terminal;
444}
445
446ED4_base* ED4_manager::get_competent_child(AW_pos x, AW_pos y, ED4_properties relevant_prop) {
447    ED4_extension  ext;
448    ED4_index      temp_index;
449    ED4_base      *child;
450
451    ext.position[X_POS] = x;
452    ext.position[Y_POS] = y;
453    ED4_base::touch_world_cache();
454
455    temp_index = children->search_member(&ext, spec.static_prop);
456
457    if ((temp_index < 0) || (temp_index >= children->members())) {     // no child at given location
458        return (NULL);
459    }
460
461    child = children->member(temp_index);
462
463    return (child->spec.static_prop & relevant_prop) ? child : (ED4_base*)NULL;
464}
465
466ED4_base* ED4_manager::get_competent_clicked_child(AW_pos x, AW_pos y, ED4_properties relevant_prop) {
467    ED4_extension  ext;
468    ED4_base      *child;
469    ED4_base      *temp_parent = NULL;
470
471    ext.position[X_POS] = x;
472    ext.position[Y_POS] = y;
473    ED4_base::touch_world_cache();
474
475    children->search_target_species(&ext, spec.static_prop, &temp_parent, ED4_L_MULTI_SPECIES);
476
477    if (!temp_parent) {
478        temp_parent = this;
479    }
480
481    child = temp_parent;
482    if (child->spec.static_prop & relevant_prop) {
483        return (child);
484    }
485    else {
486        return (NULL);
487    }
488}
489
490ED4_returncode  ED4_manager::handle_move(ED4_move_info *mi) {
491    // handles a move request with target world
492    // coordinates within current object's borders
493    AW_pos               rel_x, rel_y, x_off, y_off;
494    ED4_base            *object;
495    ED4_manager         *old_parent;
496    ED4_manager         *manager;
497    ED4_level            mlevel;
498    ED4_terminal        *sel_object;
499    ED4_selection_entry *sel_info;
500    ED4_selected_elem   *list_elem;
501    bool                 i_am_consensus = 0;
502    ED4_base            *found_member   = NULL;
503    ED4_extension        loc;
504
505    if ((mi == NULL) || (mi->object->spec.level <= spec.level)) {
506        return (ED4_R_IMPOSSIBLE);
507    }
508
509    rel_x = mi->end_x; // calculate target position relative to current object
510    rel_y = mi->end_y;
511
512    calc_rel_coords(&rel_x, &rel_y);
513
514    if ((mi->preferred_parent & spec.level) ||             // desired parent or levels match = > can handle moving
515        (mi->object->spec.level & spec.allowed_children)) // object(s) myself, take info from list of selected objects
516    {
517
518        if (mi->object->dynamic_prop & ED4_P_IS_HANDLE) { // object is a handle for an object up in the hierarchy = > search it
519            mlevel = mi->object->spec.handled_level;
520            object = mi->object;
521
522            while ((object != NULL) && !(object->spec.level & mlevel)) object = object->parent;
523            if (object == NULL) return (ED4_R_IMPOSSIBLE); // no target level found
524        }
525        else {
526            object = mi->object; // selected object is no handle => take it directly
527
528            if (object->is_consensus_manager()) {
529                if (this->is_child_of(object->parent)) return ED4_R_IMPOSSIBLE; // has to pass multi_species_manager
530                i_am_consensus = 1;
531
532                if (object->parent != this) {
533                    object = object->parent->parent;
534                    mi->object = object;
535                }
536            }
537        }
538
539
540        old_parent = object->parent;
541
542        x_off = 0;
543        y_off = 0;
544
545        // now do move action => determine insertion offsets and insert object
546
547        if (ED4_ROOT->selected_objects->size()>1) {
548            list_elem = ED4_ROOT->selected_objects->head();
549            while (list_elem != NULL) {
550                sel_info   = list_elem->elem();
551                sel_object = sel_info->object;
552
553                if ((sel_object==mi->object)) break;
554                if (spec.static_prop & ED4_P_HORIZONTAL) y_off += sel_info->actual_height;
555                if (spec.static_prop & ED4_P_VERTICAL) x_off += sel_info->actual_width;
556
557                list_elem = list_elem->next();
558            }
559        }
560
561        loc.position[Y_POS] = mi->end_y;
562        loc.position[X_POS] = mi->end_x;
563        ED4_base::touch_world_cache();
564
565        {
566            ED4_manager *dummy_mark = ED4_ROOT->main_manager->search_spec_child_rek(ED4_L_DEVICE)->to_manager();
567            dummy_mark->children->search_target_species(&loc, ED4_P_HORIZONTAL, &found_member, ED4_L_NO_LEVEL);
568        }
569
570        if (found_member==object) { // if we are dropped on ourself => don't move
571            return ED4_R_BREAK;
572        }
573
574        ED4_base *parent_man = object->get_parent(ED4_L_MULTI_SPECIES);
575        object->parent->children->remove_member(object);
576        parent_man->to_multi_species_manager()->invalidate_species_counters();
577
578        object->extension.position[X_POS] = rel_x + x_off;
579        object->extension.position[Y_POS] = rel_y;
580        ED4_base::touch_world_cache();
581
582        object->parent = this;
583
584        if (old_parent != this) { // check whether consensus has to be calculated new or not
585            GB_push_transaction(GLOBAL_gb_main);
586            update_consensus(old_parent, this, object);
587            rebuild_consensi(old_parent, ED4_U_UP);
588            rebuild_consensi(this, ED4_U_UP);
589            GB_pop_transaction(GLOBAL_gb_main);
590        }
591
592        if ((i_am_consensus && object->parent != old_parent) || !i_am_consensus) {
593            object->set_width();
594
595            if (dynamic_prop & ED4_P_IS_FOLDED) { // add spacer and consensusheight
596                object->extension.position[Y_POS] = children->member(0)->extension.size[HEIGHT] + children->member(1)->extension.size[HEIGHT];
597                object->flag.hidden = 1;
598                ED4_base::touch_world_cache();
599            }
600        }
601
602        children->insert_member(object);
603        if (is_multi_species_manager()) {
604            to_multi_species_manager()->invalidate_species_counters();
605        }
606        else {
607            get_parent(ED4_L_MULTI_SPECIES)->to_multi_species_manager()->invalidate_species_counters();
608        }
609
610        return (ED4_R_OK);
611    }
612    else {
613        // levels do not match = > ask competent manager child to handle move request
614        if ((manager = (ED4_manager *) get_competent_child(rel_x, rel_y, ED4_P_IS_MANAGER)) == NULL) { // no manager child covering target
615            return (ED4_R_IMPOSSIBLE); // location = > move not possible
616        }
617
618        return (manager->move_requested_by_parent(mi)); // there is a manager child covering target location = > pass on move request
619    }
620}
621
622
623ED4_returncode  ED4_manager::move_requested_by_parent(ED4_move_info *mi) {
624    // handles a move request with target world coordinates coming from parent
625    if ((mi == NULL) || !(in_border(mi->end_x, mi->end_y, mi->mode)))
626        return (ED4_R_IMPOSSIBLE);
627
628    return (handle_move(mi));
629}
630
631
632ED4_returncode  ED4_manager::move_requested_by_child(ED4_move_info *mi) {
633    // handles a move request coming from a child,
634    // target location can be out of borders
635    ED4_base *temp_parent = NULL;
636
637    if (mi == NULL)
638        return (ED4_R_IMPOSSIBLE);
639
640    if (spec.level < mi->object->spec.restriction_level) return (ED4_R_IMPOSSIBLE); // check if there is a level restriction to the move request
641
642    if (mi->object->dynamic_prop & ED4_P_IS_HANDLE) { // determine first if we could be the moving object
643        if ((dynamic_prop & ED4_P_MOVABLE) && (spec.level & mi->object->spec.handled_level)) { // yes, we are meant to be the moving object
644            mi->object = this;
645        }
646
647        if (parent == NULL) return (ED4_R_WARNING);
648
649        return (parent->move_requested_by_child(mi));
650    }
651
652    if (!(in_border(mi->end_x, mi->end_y, mi->mode))) {
653        // determine if target location is within
654        // the borders of current object, do boundary
655        // adjustment of target coordinates if necessary
656        // target location is not within borders =>
657        // ask parent, i.e. move recursively up
658        if (parent == NULL) return (ED4_R_WARNING);
659        return (parent->move_requested_by_child(mi));
660    }
661    else { // target location within current borders = > handle move myself
662        temp_parent = get_competent_clicked_child(mi->end_x, mi->end_y, ED4_P_IS_MANAGER);
663
664        if (!temp_parent) {
665            return (handle_move(mi));
666        }
667        else {
668            if ((temp_parent->is_group_manager()) || (temp_parent->is_area_manager())) {
669                temp_parent = temp_parent->to_group_manager()->get_defined_level(ED4_L_MULTI_SPECIES);
670            }
671            else if (!(temp_parent->is_multi_species_manager())) {
672                temp_parent = temp_parent->get_parent(ED4_L_MULTI_SPECIES);
673            }
674            if (!temp_parent) {
675                return ED4_R_IMPOSSIBLE;
676            }
677            return (temp_parent->handle_move(mi));
678        }
679    }
680}
681
682ED4_returncode  ED4_manager::event_sent_by_parent(AW_event *event, AW_window *aww) {
683    // handles an input event coming from parent
684    ED4_extension  ext;
685    ED4_index      temp_index;
686    ED4_returncode returncode;
687
688    if (flag.hidden)
689        return ED4_R_BREAK;
690
691    ext.position[X_POS] = event->x;
692    ext.position[Y_POS] = event->y;
693
694    calc_rel_coords(&ext.position[X_POS], &ext.position[Y_POS]);
695
696    temp_index = children->search_member(&ext, spec.static_prop); // search child who is competent for the location of given event
697
698    if ((temp_index >= children->members()) || (temp_index < 0)) {
699        return (ED4_R_IMPOSSIBLE); // no suitable member found
700    }
701
702    returncode = children->member(temp_index)->event_sent_by_parent(event, aww);
703    return (returncode);
704}
705
706ED4_returncode  ED4_manager::refresh_requested_by_child() {
707    // handles a refresh-request from a child
708    if (!update_info.refresh) { // determine if there were more refresh requests already => no need to tell parent about it
709        update_info.set_refresh(1); // this is the first refresh request
710        if (parent) parent->refresh_requested_by_child(); // if we have a parent, tell him about the refresh request
711    }
712
713#ifdef TEST_REFRESH_FLAG
714    e4_assert(refresh_flag_ok());
715#endif
716    return ED4_R_OK;
717}
718
719int ED4_manager::refresh_flag_ok() {
720    ED4_index i;
721
722    for (i=0; i<children->members(); i++) {
723        ED4_base *child = children->member(i);
724
725        if (child->is_manager()) {
726            if (!child->to_manager()->refresh_flag_ok()) {
727                return 0;
728            }
729        }
730
731        if (child->update_info.refresh==1 && update_info.refresh==0) {
732            printf("Forgotten refresh-flag in '%s' (son of '%s')\n", child->id, id);
733            fflush(stdout);
734            return 0;
735        }
736    }
737
738    return 1;
739}
740
741inline void ED4_base::resize_requested_by_link(ED4_base *IF_DEBUG(link)) {
742    e4_assert((width_link == link) || (height_link == link)); // wrong link
743    if (calc_bounding_box()) request_resize();
744}
745
746void ED4_base::request_resize_of_linked() {
747    if (linked_objects) {
748        ED4_base_list_elem *current_list_elem = linked_objects->head();
749        while (current_list_elem) {
750            ED4_base *object = current_list_elem->elem();
751            object->resize_requested_by_link(this);
752            current_list_elem = current_list_elem->next();
753        }
754    }
755}
756
757bool ED4_manager::calc_bounding_box() {
758    // calculates the smallest rectangle containing the object.
759    // returns true if bounding box has changed.
760    AW_pos     sum_width  = 0;
761    AW_pos     sum_height = 0;
762    AW_pos     max_x      = 0;
763    AW_pos     max_y      = 0;
764    AW_pos     dummy      = 0;
765    ED4_index  i          = 0;
766    bool       bb_changed = false;
767    ED4_base  *child;
768
769    // initialize with first child
770    while ((child = children->member(i++)) != NULL) { // check all children
771        if (!child->flag.hidden) {
772            sum_width  += child->extension.size[WIDTH];
773            sum_height += child->extension.size[HEIGHT];
774
775            dummy = child->extension.position[X_POS] + child->extension.size[WIDTH];
776            if (dummy > max_x) {
777                max_x = dummy;
778            }
779
780            dummy = child->extension.position[Y_POS] + child->extension.size[HEIGHT];
781            if (dummy > max_y) {
782                max_y = dummy;
783            }
784            ED4_base::touch_world_cache();
785        }
786    }
787
788
789    if (spec.static_prop & ED4_P_HORIZONTAL) {
790        if (int(extension.size[WIDTH]) != int(max_x)) { // because compares between floats fail sometimes (AW_pos==float)
791            extension.size[WIDTH] = max_x;
792            bb_changed = true;
793        }
794
795        if (int(extension.size[HEIGHT]) != int(sum_height)) {
796            extension.size[HEIGHT] = sum_height;
797            bb_changed = true;
798        }
799    }
800
801    if (spec.static_prop & ED4_P_VERTICAL) {
802        if (int(extension.size[WIDTH]) != int(sum_width)) {
803            extension.size[WIDTH] = sum_width;
804            bb_changed = true;
805        }
806        if (int(extension.size[HEIGHT]) != int(max_y)) {
807            extension.size[HEIGHT] = max_y;
808            bb_changed = true;
809        }
810    }
811
812    if (bb_changed) request_resize_of_linked();
813    return bb_changed;
814}
815
816ED4_returncode ED4_manager::distribute_children() {
817    // distributes all children of current object according to current object's properties and
818    // justification value; a recalculation of current object's extension will take place if necessary
819
820    ED4_index  current_index;
821    ED4_index  rel_pos        = 0;
822    ED4_index  rel_size       = 0;
823    ED4_index  other_pos      = 0;
824    ED4_index  other_size     = 0;
825    AW_pos     max_rel_size   = 0;
826    AW_pos     max_other_size = 0;
827    ED4_base  *current_child;
828
829    // set extension-indexes rel_pos and rel_size according to properties
830    if (spec.static_prop & ED4_P_HORIZONTAL) {
831        rel_pos    = X_POS;
832        other_pos  = Y_POS;
833        rel_size   = WIDTH;
834        other_size = HEIGHT;
835    }
836    if (spec.static_prop & ED4_P_VERTICAL) {
837        rel_pos    = Y_POS;
838        other_pos  = X_POS;
839        rel_size   = HEIGHT;
840        other_size = WIDTH;
841    }
842
843    current_index = 0;  // get maximal relevant and other size of children, set children's other position increasingly
844    while ((current_child = children->member(current_index)) != NULL) {
845        max_rel_size = max(int(max_rel_size), int(current_child->extension.size[rel_size]));
846        if (current_child->extension.position[other_pos] != max_other_size) {
847            current_child->extension.position[other_pos] = max_other_size;
848            ED4_base::touch_world_cache();
849        }
850        max_other_size += current_child->extension.size[other_size];
851        current_index++;
852    }
853
854    // set children's relevant position according to justification value
855    // (0.0 means top- or left-justified, 1.0 means bottom- or right-justified)
856    current_index = 0;
857    while ((current_child = children->member(current_index++)) != NULL) {
858        current_child->extension.position[rel_pos] = 0.0;
859        ED4_base::touch_world_cache();
860    }
861
862    refresh_requested_by_child();
863    return (ED4_R_OK);
864}
865
866void ED4_manager::resize_requested_children() {
867    if (update_info.resize) { // object wants to resize
868        update_info.set_resize(0); // first clear the resize flag (remember it could be set again from somewhere below the hierarchy)
869
870        ED4_index i = 0;
871        while (1) {
872            ED4_base *child = children->member(i++);
873
874            if (!child) break;
875
876            child->update_info.set_resize(1);
877            child->resize_requested_children();
878        }
879
880        distribute_children();
881        if (calc_bounding_box()) request_resize();
882    }
883}
884void ED4_root_group_manager::resize_requested_children() {
885    if (update_info.resize) {
886        if (update_remap()) ED4_ROOT->request_refresh_for_specific_terminals(ED4_L_SEQUENCE_STRING);
887        ED4_manager::resize_requested_children();
888    }
889    else {
890        e4_assert(!update_remap());
891    }
892}
893
894static void update_scrolled_rectangles(ED4_window *win) { win->update_scrolled_rectangle(); }
895void ED4_main_manager::resize_requested_children() {
896    if (update_info.resize) {
897        ED4_manager::resize_requested_children();
898        ED4_with_all_edit_windows(update_scrolled_rectangles);
899    }
900}
901
902ED4_returncode ED4_main_manager::Show(int refresh_all, int is_cleared) {
903#ifdef TEST_REFRESH_FLAG
904    e4_assert(refresh_flag_ok());
905#endif
906
907    AW_device *device = current_device();
908
909    if (!flag.hidden && (refresh_all || update_info.refresh)) {
910#if defined(TRACE_REFRESH)
911        fprintf(stderr, "- really paint in ED4_main_manager::Show(refresh_all=%i, is_cleared=%i)\n", refresh_all, is_cleared); fflush(stderr);
912#endif
913        const AW_screen_area& area_rect = device->get_area_size();
914
915        // if update all -> clear_background
916
917        if (update_info.clear_at_refresh && !is_cleared) {
918            device->push_clip_scale();
919            if (device->reduceClipBorders(area_rect.t, area_rect.b, area_rect.l, area_rect.r)) {
920                clear_background();
921            }
922            is_cleared = 1;
923            device->pop_clip_scale();
924        }
925
926        // loop through all rectangles between folding lines:
927
928        int x1, y1, x2, y2;
929        ED4_window& win = *current_ed4w();
930        x1 = area_rect.l;
931        for (const ED4_folding_line *flv = win.get_vertical_folding(); ; flv = flv->get_next()) {
932            if (flv) {
933                x2 = int(flv->get_pos()); // @@@ use AW_INT ?
934            }
935            else {
936                x2 = area_rect.r;
937                if (x1==x2) break; // do not draw last range, if it's only 1 pixel width
938            }
939
940            y1 = area_rect.t;
941            for (const ED4_folding_line *flh = win.get_horizontal_folding(); ; flh = flh->get_next()) {
942                if (flh) {
943                    y2 = int(flh->get_pos()); // @@@ use AW_INT ?
944                }
945                else {
946                    y2 = area_rect.b;
947                    if (y1==y2) break; // do not draw last range, if it's only 1 pixel high
948                }
949
950                device->push_clip_scale();
951                if (device->reduceClipBorders(y1, y2-1, x1, x2-1)) {
952                    ED4_manager::Show(refresh_all, is_cleared);
953                }
954                device->pop_clip_scale();
955
956                if (!flh) break; // break out after drawing lowest range
957                y1 = y2;
958            }
959            if (!flv) break; // break out after drawing rightmost range
960
961            x1 = x2;
962        }
963
964        // to avoid text clipping problems between top and middle area we redraw the top-middle-spacer :
965        {
966            device->push_clip_scale();
967            const AW_screen_area& clip_rect = device->get_cliprect();
968            device->set_top_clip_border(clip_rect.t-TERMINALHEIGHT);
969
970            int char_width = ED4_ROOT->font_group.get_max_width();
971            device->set_left_clip_border(clip_rect.l-char_width);
972            device->set_right_clip_border(clip_rect.r+char_width);
973
974            get_top_middle_spacer_terminal()->Show(true, false);
975            get_top_middle_line_terminal()->Show(true, false);
976            device->pop_clip_scale();
977        }
978
979        // always draw cursor
980        ED4_cursor& cursor = current_cursor();
981        if (cursor.owner_of_cursor && cursor.allowed_to_draw) {
982            if (cursor.is_partly_visible()) {
983                cursor.ShowCursor(0, ED4_C_NONE, 0);
984            }
985        }
986    }
987#ifdef TEST_REFRESH_FLAG
988    e4_assert(refresh_flag_ok());
989#endif
990
991    return ED4_R_OK;
992}
993
994
995ED4_returncode ED4_root_group_manager::Show(int refresh_all, int is_cleared) {
996    if (update_remap()) { // @@@ dont call here ?
997#if defined(TRACE_REFRESH)
998        printf("map updated in ED4_root_group_manager::Show (bad?)\n");
999#endif
1000    }
1001    return ED4_manager::Show(refresh_all, is_cleared);
1002}
1003
1004ED4_returncode ED4_manager::Show(int refresh_all, int is_cleared) {
1005#ifdef TEST_REFRESH_FLAG
1006    e4_assert(refresh_flag_ok());
1007#endif
1008
1009    if (!flag.hidden && (refresh_all || update_info.refresh)) {
1010        if (update_info.clear_at_refresh && !is_cleared) {
1011            clear_background();
1012            is_cleared = 1;
1013        }
1014
1015        AW_screen_area rect; // clipped rectangle in world coordinates
1016
1017        {
1018            const AW_screen_area &clip_rect = current_device()->get_cliprect();      // clipped rectangle in win coordinates
1019           
1020            double x, y;
1021            x = clip_rect.l;
1022            y = clip_rect.t;
1023
1024            current_ed4w()->win_to_world_coords(&x, &y);
1025
1026            rect.l = int(x);
1027            rect.t = int(y);
1028
1029            e4_assert(AW::nearlyEqual(current_device()->get_scale(), 1.0)); // assumed by calculation below
1030            rect.r = rect.l+(clip_rect.r-clip_rect.l);
1031            rect.b = rect.t+(clip_rect.b-clip_rect.t);
1032        }
1033
1034        // binary search to find first visible child
1035
1036        int first_visible_child = 0;
1037
1038        {
1039            int l = 0;
1040            int h = children->members()-1;
1041
1042            while (l<h) {
1043
1044                while (children->member(l)->flag.hidden && l<h) l++;
1045                while (children->member(h)->flag.hidden && l<h) h--;
1046
1047                int m = (l+h)/2;
1048                int min_m = m;
1049                int max_m = m+1;
1050
1051                while (children->member(m)->flag.hidden) {
1052                    if (m==h) {
1053                        m = (l+h)/2-1;
1054                        while (children->member(m)->flag.hidden) {
1055                            if (m==l) {
1056                                // all children between l..h are flag.hidden
1057                                goto no_visible_child_found;
1058                            }
1059                            m--;
1060                        }
1061                        min_m = m;
1062                        break;
1063                    }
1064                    m++;
1065                    max_m = m;
1066                }
1067
1068                ED4_base *child = children->member(m);
1069                e4_assert(!child->flag.hidden);
1070
1071                AW_pos x, y;
1072                child->calc_world_coords(&x, &y);
1073
1074                if (spec.static_prop & ED4_P_HORIZONTAL) { // horizontal manager
1075                    e4_assert((spec.static_prop&ED4_P_VERTICAL)==0);   // otherwise this binary search will not work correctly
1076                    if ((x+child->extension.size[WIDTH])<=rect.l) { // left of clipping range
1077                        l = max_m;
1078                    }
1079                    else {
1080                        h = min_m;
1081                    }
1082                }
1083                else if (spec.static_prop & ED4_P_VERTICAL) { // vertical manager
1084                    if ((y+child->extension.size[HEIGHT])<=rect.t) { // above clipping range
1085                        l = max_m;
1086                    }
1087                    else {
1088                        h = min_m;
1089                    }
1090                }
1091                else {
1092                    e4_assert(0);
1093                }
1094            }
1095        }
1096
1097    no_visible_child_found :
1098
1099        ED4_index i = 0;
1100
1101        while (1) {
1102            ED4_base *child = children->member(i++);
1103            if (!child) break;
1104
1105            if (!child->flag.hidden && (refresh_all || child->update_info.refresh) && i>=first_visible_child) {
1106                AW_pos x, y;
1107                child->calc_world_coords(&x, &y);
1108
1109                AW_device *device = current_device();
1110
1111                if (!(((y-rect.b)>0.5) ||
1112                      ((rect.t-(y+child->extension.size[HEIGHT]-1))>0.5) ||
1113                      ((x-rect.r)>0.5) ||
1114                      ((rect.l-(x+child->extension.size[WIDTH]-1))>0.5)
1115                     ))
1116                {
1117                    // they overlap -> show it
1118                    device->push_clip_scale();
1119                    if (child->adjust_clipping_rectangle()) {
1120                        child->Show(refresh_all, is_cleared);
1121                    }
1122                    device->pop_clip_scale();
1123                }
1124            }
1125        }
1126    }
1127
1128#ifdef TEST_REFRESH_FLAG
1129    e4_assert(refresh_flag_ok());
1130#endif
1131
1132    return ED4_R_OK;
1133}
1134
1135ED4_returncode ED4_manager::clear_refresh() {
1136    e4_assert(update_info.refresh);
1137
1138    for (int i=0; i<children->members(); i++) {
1139        ED4_base *child = children->member(i);
1140
1141        if (child->update_info.refresh) {
1142            if (child->is_manager()) {
1143                child->to_manager()->clear_refresh();
1144            }
1145            else {
1146                child->update_info.set_refresh(0);
1147                child->update_info.set_clear_at_refresh(0);
1148            }
1149        }
1150    }
1151
1152    update_info.set_refresh(0);
1153    update_info.set_clear_at_refresh(0);
1154
1155    return ED4_R_OK;
1156}
1157
1158void ED4_manager::update_requested_by_child() { // @@@ same as set_update -> DRY
1159    if (!update_info.update_requested) {
1160        if (parent) parent->update_requested_by_child();
1161        update_info.update_requested = 1;
1162    }
1163}
1164void ED4_manager::delete_requested_by_child() {
1165    if (!update_info.delete_requested) {
1166        if (parent) parent->delete_requested_by_child();
1167        update_info.delete_requested = 1;
1168    }
1169}
1170void ED4_terminal::delete_requested_children() {
1171    e4_assert(update_info.delete_requested);
1172    e4_assert(tflag.deleted);
1173
1174    ED4_ROOT->announce_deletion(this);
1175
1176    unlink_from_parent();
1177    delete this;
1178}
1179
1180void ED4_manager::update_requested_children() {
1181    e4_assert(update_info.update_requested);
1182
1183    for (int i=0; i<children->members(); i++) {
1184        ED4_base *child = children->member(i);
1185        if (child->update_info.update_requested) {
1186            child->update_requested_children();
1187        }
1188    }
1189
1190    update_info.update_requested = 0;
1191}
1192
1193void ED4_multi_species_manager::update_requested_children() {
1194    e4_assert(update_info.update_requested);
1195    ED4_manager::update_requested_children();
1196    update_species_counters();
1197    update_group_id();
1198
1199    ED4_base *group_base = get_parent(ED4_L_GROUP);
1200    if (group_base) {
1201        e4_assert(group_base->is_group_manager());
1202        e4_assert(!group_base->is_root_group_manager());
1203
1204        ED4_group_manager *group_man    = parent->to_group_manager();
1205        ED4_base          *bracket_base = group_man->get_defined_level(ED4_L_BRACKET);
1206
1207        if (bracket_base) bracket_base->request_refresh();
1208    }
1209}
1210
1211void ED4_manager::delete_requested_children() {
1212    e4_assert(update_info.delete_requested);
1213
1214    for (int i = children->members()-1; i >= 0; --i) {
1215        ED4_base *child = children->member(i);
1216        if (child->update_info.delete_requested) {
1217            child->delete_requested_children();
1218        }
1219    }
1220
1221    update_info.delete_requested = 0;
1222
1223    if (!children->members()) {
1224        ED4_ROOT->announce_deletion(this);
1225       
1226        unlink_from_parent();
1227        delete this;
1228    }
1229}
1230
1231void ED4_multi_species_manager::delete_requested_children() {
1232    e4_assert(update_info.delete_requested);
1233    invalidate_species_counters();
1234    ED4_manager::delete_requested_children();
1235}
1236
1237void ED4_terminal::Delete() {
1238    if (!tflag.deleted) {
1239        tflag.deleted                = 1;
1240        update_info.delete_requested = 1;
1241        parent->delete_requested_by_child();
1242    }
1243}
1244
1245void ED4_manager::Delete() {
1246    for (int i=0; i<children->members(); i++) {
1247        children->member(i)->Delete();
1248    }
1249}
1250
1251void ED4_manager::request_refresh(int clear) {
1252    // sets refresh flag of current object and its children
1253    update_info.set_refresh(1);
1254    update_info.set_clear_at_refresh(clear);
1255
1256    if (parent) parent->refresh_requested_by_child();
1257
1258    ED4_index  current_index = 0;
1259    ED4_base  *current_child;
1260    while ((current_child = children->member(current_index++)) != NULL) {
1261        current_child->request_refresh(0); // do not trigger clear for childs
1262    }
1263}
1264
1265
1266ED4_base* ED4_manager::search_ID(const char *temp_id) {
1267    ED4_base  *current_child, *object;
1268    ED4_index  current_index;
1269
1270    if (strcmp(temp_id, id) == 0) { // this object is the sought one
1271        return this;
1272    }
1273    else {
1274        current_index = 0;
1275        while ((current_child = children->member(current_index))) { // search whole memberlist recursively for object with the given id
1276            if ((object = current_child->search_ID(temp_id)) != NULL) {
1277                return (object);
1278            }
1279            current_index++;
1280        }
1281    }
1282
1283    return NULL; // no object found
1284}
1285
1286
1287ED4_manager::ED4_manager(const ED4_objspec& spec_, const char *temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent) :
1288    ED4_base(spec_, temp_id, x, y, width, height, temp_parent)
1289{
1290    children = new ED4_members(this);
1291}
1292
1293ED4_manager::~ED4_manager() {
1294    ED4_base *current_child;
1295
1296    while (children->members() > 0) {
1297        current_child = children->member(0);
1298        children->remove_member(current_child);
1299        current_child->parent = NULL;
1300
1301        if (current_child->is_terminal())       delete current_child->to_terminal();
1302        else if (current_child->is_manager())   delete current_child->to_manager();
1303    }
1304
1305    delete children;
1306}
1307
1308// --------------------------
1309//      ED4_main_manager
1310
1311ED4_main_manager::ED4_main_manager(const char *temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent) :
1312    ED4_manager(main_manager_spec, temp_id, x, y, width, height, temp_parent)
1313{
1314}
1315
1316// ----------------------------
1317//      ED4_device_manager
1318
1319ED4_device_manager::ED4_device_manager(const char *temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent) :
1320    ED4_manager(device_manager_spec, temp_id, x, y, width, height, temp_parent)
1321{
1322}
1323
1324// --------------------------
1325//      ED4_area_manager
1326
1327ED4_area_manager::ED4_area_manager(const char *temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent) :
1328    ED4_manager(area_manager_spec, temp_id, x, y, width, height, temp_parent)
1329{
1330}
1331
1332// -----------------------------------
1333//      ED4_multi_species_manager
1334
1335ED4_multi_species_manager::ED4_multi_species_manager(const char *temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent) :
1336    ED4_manager(multi_species_manager_spec, temp_id, x, y, width, height, temp_parent),
1337    species(-1),
1338    selected_species(-1)
1339{
1340}
1341
1342int ED4_multi_species_manager::get_no_of_species() {
1343    if (!has_valid_counters()) {
1344        update_species_counters();
1345        e4_assert(has_valid_counters());
1346    }
1347    return species;
1348}
1349
1350int ED4_multi_species_manager::get_no_of_selected_species() {
1351    if (!has_valid_counters()) {
1352        update_species_counters();
1353        e4_assert(has_valid_counters());
1354    }
1355    return selected_species;
1356}
1357
1358void ED4_multi_species_manager::invalidate_species_counters() {
1359    if (has_valid_counters()) {
1360        species          = -1;
1361        selected_species = -1;
1362
1363        ED4_base *pms = get_parent(ED4_L_MULTI_SPECIES);
1364        if (pms) pms->to_multi_species_manager()->invalidate_species_counters();
1365       
1366        update_requested_by_child();
1367    }
1368}
1369
1370void ED4_multi_species_manager::set_species_counters(int no_of_species, int no_of_selected) {
1371
1372#if defined(DEBUG)
1373    int sp, sel;
1374
1375    count_species(&sp, &sel);
1376    e4_assert(no_of_species==sp);
1377    e4_assert(no_of_selected==sel);
1378#endif
1379
1380    e4_assert(no_of_species>=no_of_selected);
1381
1382    if (species!=no_of_species || selected_species!=no_of_selected) {
1383        int species_diff  = no_of_species-species;
1384        int selected_diff = no_of_selected-selected_species;
1385
1386        int quickSet = 1;
1387        if (species==-1 || selected_species==-1) {
1388            quickSet = 0;
1389        }
1390
1391        species          = no_of_species;
1392        selected_species = no_of_selected;
1393
1394        ED4_base *gm = get_parent(ED4_L_GROUP);
1395        if (gm) gm->to_manager()->search_spec_child_rek(ED4_L_BRACKET)->request_refresh();
1396
1397        ED4_base *ms = get_parent(ED4_L_MULTI_SPECIES);
1398        if (ms) {
1399            ED4_multi_species_manager *parent_multi_species_man = ms->to_multi_species_manager();
1400
1401            if (!quickSet) parent_multi_species_man->invalidate_species_counters();
1402
1403            if (parent_multi_species_man->has_valid_counters()) {
1404                parent_multi_species_man->set_species_counters(parent_multi_species_man->species+species_diff,
1405                                                               parent_multi_species_man->selected_species+selected_diff);
1406            }
1407        }
1408    }
1409}
1410
1411#ifdef DEBUG
1412void ED4_multi_species_manager::count_species(int *speciesPtr, int *selectedPtr) const {
1413    int m;
1414    int sp  = 0;
1415    int sel = 0;
1416
1417    for (m=0; m<children->members(); m++) {
1418        ED4_base *member = children->member(m);
1419
1420        if (member->is_group_manager()) {
1421            ED4_multi_species_manager *multi_species_man = member->to_group_manager()->get_multi_species_manager();
1422
1423            if (!multi_species_man->has_valid_counters()) {
1424                int sp1, sel1;
1425
1426                multi_species_man->count_species(&sp1, &sel1);
1427                sel += sel1;
1428                sp += sp1;
1429            }
1430            else {
1431                sel += multi_species_man->get_no_of_selected_species();
1432                sp += multi_species_man->get_no_of_species();
1433            }
1434        }
1435        else if (member->is_species_manager()) {
1436            ED4_species_manager *species_man = member->to_species_manager();
1437            if (!species_man->is_consensus_manager()) {
1438                sp++;
1439                if (species_man->is_selected()) sel++;
1440            }
1441        }
1442    }
1443
1444    *speciesPtr = sp;
1445    *selectedPtr = sel;
1446}
1447#endif
1448
1449void ED4_multi_species_manager::update_species_counters() {
1450    int m;
1451    int sp  = 0;
1452    int sel = 0;
1453
1454    for (m=0; m<children->members(); m++) {
1455        ED4_base *member = children->member(m);
1456
1457        if (member->is_group_manager()) {
1458            ED4_multi_species_manager *multi_species_man = member->to_group_manager()->get_multi_species_manager();
1459
1460            if (!multi_species_man->has_valid_counters()) {
1461                multi_species_man->update_species_counters();
1462            }
1463            sel += multi_species_man->get_no_of_selected_species();
1464            sp += multi_species_man->get_no_of_species();
1465        }
1466        else if (member->is_species_manager()) {
1467            ED4_species_manager *species_man = member->to_species_manager();
1468
1469            if (!species_man->is_consensus_manager()) {
1470                sp++;
1471                if (species_man->is_selected()) sel++;
1472            }
1473        }
1474    }
1475    set_species_counters(sp, sel);
1476}
1477
1478void ED4_multi_species_manager::select_all(bool only_species) {
1479    int m;
1480    int sp  = 0;
1481    int sel = 0;
1482
1483    for (m=0; m<children->members(); m++) {
1484        ED4_base *member = children->member(m);
1485
1486        if (member->is_group_manager()) {
1487            ED4_multi_species_manager *multi_species_man = member->to_group_manager()->get_multi_species_manager();
1488            multi_species_man->select_all(only_species);
1489            sp += multi_species_man->get_no_of_species();
1490            sel += multi_species_man->get_no_of_selected_species();
1491        }
1492        else if (member->is_species_manager()) {
1493            ED4_species_manager *species_man = member->to_species_manager();
1494
1495            if (!species_man->is_consensus_manager()) {
1496                sp++;
1497                if (!species_man->is_selected()) {
1498                    if (!only_species || !species_man->is_SAI_manager()) {
1499                        ED4_species_name_terminal *species_name = species_man->search_spec_child_rek(ED4_L_SPECIES_NAME)->to_species_name_terminal();
1500                        ED4_ROOT->add_to_selected(species_name);
1501                    }
1502                }
1503                if (species_man->is_selected()) sel++;
1504            }
1505        }
1506    }
1507    set_species_counters(sp, sel);
1508}
1509void ED4_multi_species_manager::deselect_all_species_and_SAI() {
1510    int m;
1511    int sp = 0;
1512
1513    for (m=0; m<children->members(); m++) {
1514        ED4_base *member = children->member(m);
1515
1516        if (member->is_group_manager()) {
1517            ED4_multi_species_manager *multi_species_man = member->to_group_manager()->get_multi_species_manager();
1518            multi_species_man->deselect_all_species_and_SAI();
1519            sp += multi_species_man->get_no_of_species();
1520        }
1521        else if (member->is_species_manager()) {
1522            ED4_species_manager *species_man = member->to_species_manager();
1523
1524            if (!species_man->is_consensus_manager()) {
1525                sp++;
1526                if (species_man->is_selected()) {
1527                    ED4_species_name_terminal *species_name = species_man->search_spec_child_rek(ED4_L_SPECIES_NAME)->to_species_name_terminal();
1528                    ED4_ROOT->remove_from_selected(species_name);
1529                }
1530            }
1531        }
1532        else {
1533            e4_assert(!member->is_manager());
1534        }
1535    }
1536    set_species_counters(sp, 0);
1537}
1538void ED4_multi_species_manager::invert_selection_of_all_species() {
1539    int m;
1540    int sp  = 0;
1541    int sel = 0;
1542
1543    for (m=0; m<children->members(); m++) {
1544        ED4_base *member = children->member(m);
1545
1546        if (member->is_group_manager()) {
1547            ED4_multi_species_manager *multi_species_man = member->to_group_manager()->get_multi_species_manager();
1548            multi_species_man->invert_selection_of_all_species();
1549            sp += multi_species_man->get_no_of_species();
1550            sel += multi_species_man->get_no_of_selected_species();
1551        }
1552        else if (member->is_species_manager()) {
1553            ED4_species_manager *species_man = member->to_species_manager();
1554
1555            if (!species_man->is_consensus_manager()) {
1556                sp++;
1557
1558                if (!species_man->is_SAI_manager()) {
1559                    ED4_species_name_terminal *species_name = species_man->search_spec_child_rek(ED4_L_SPECIES_NAME)->to_species_name_terminal();
1560
1561                    if (species_man->is_selected()) ED4_ROOT->remove_from_selected(species_name);
1562                    else                            ED4_ROOT->add_to_selected(species_name);
1563                }
1564                if (species_man->is_selected()) sel++;
1565            }
1566        }
1567        else {
1568            e4_assert(!member->is_manager());
1569        }
1570    }
1571
1572    e4_assert(get_no_of_selected_species()==sel);
1573    e4_assert(get_no_of_species()==sp);
1574}
1575void ED4_multi_species_manager::marked_species_select(bool select) {
1576    int m;
1577    int sp  = 0;
1578    int sel = 0;
1579
1580    for (m=0; m<children->members(); m++) {
1581        ED4_base *member = children->member(m);
1582
1583        if (member->is_group_manager()) {
1584            ED4_multi_species_manager *multi_species_man = member->to_group_manager()->get_multi_species_manager();
1585            multi_species_man->marked_species_select(select);
1586            sp += multi_species_man->get_no_of_species();
1587            sel += multi_species_man->get_no_of_selected_species();
1588        }
1589        else if (member->is_species_manager()) {
1590            ED4_species_manager *species_man = member->to_species_manager();
1591
1592            if (!species_man->is_consensus_manager()) {
1593                sp++;
1594
1595                if (species_man->is_species_seq_manager()) {
1596                    GBDATA *gbd = species_man->get_species_pointer();
1597                    e4_assert(gbd);
1598                    int is_marked = GB_read_flag(gbd);
1599
1600                    if (is_marked) {
1601                        if (select) { // select marked
1602                            if (!species_man->is_selected()) {
1603                                ED4_species_name_terminal *species_name = species_man->search_spec_child_rek(ED4_L_SPECIES_NAME)->to_species_name_terminal();
1604                                ED4_ROOT->add_to_selected(species_name);
1605                            }
1606                        }
1607                        else { // de-select marked
1608                            if (species_man->is_selected()) {
1609                                ED4_species_name_terminal *species_name = species_man->search_spec_child_rek(ED4_L_SPECIES_NAME)->to_species_name_terminal();
1610                                ED4_ROOT->remove_from_selected(species_name);
1611                            }
1612                        }
1613                    }
1614                }
1615                if (species_man->is_selected()) sel++;
1616            }
1617        }
1618        else {
1619            e4_assert(!member->is_manager());
1620        }
1621    }
1622    set_species_counters(sp, sel);
1623}
1624void ED4_multi_species_manager::selected_species_mark(bool mark) {
1625    int m;
1626    int sp  = 0;
1627    int sel = 0;
1628
1629    for (m=0; m<children->members(); m++) {
1630        ED4_base *member = children->member(m);
1631
1632        if (member->is_group_manager()) {
1633            ED4_multi_species_manager *multi_species_man = member->to_group_manager()->get_multi_species_manager();
1634            multi_species_man->selected_species_mark(mark);
1635            sp += multi_species_man->get_no_of_species();
1636            sel += multi_species_man->get_no_of_selected_species();
1637        }
1638        else if (member->is_species_manager()) {
1639            ED4_species_manager *species_man = member->to_species_manager();
1640
1641            if (!species_man->is_consensus_manager()) {
1642                sp++;
1643                if (species_man->is_selected()) {
1644                    if (species_man->is_species_seq_manager()) {
1645                        GBDATA *gbd = species_man->get_species_pointer();
1646                        e4_assert(gbd);
1647
1648                        GB_write_flag(gbd, mark ? 1 : 0);
1649                    }
1650                    sel++;
1651                }
1652            }
1653        }
1654        else {
1655            e4_assert(!member->is_manager());
1656        }
1657    }
1658    set_species_counters(sp, sel);
1659}
1660
1661ED4_species_manager *ED4_multi_species_manager::get_consensus_manager() const {
1662    ED4_species_manager *consensus_manager = 0;
1663
1664    for (int i=0; i<children->members(); i++) {
1665        ED4_base *member = children->member(i);
1666        if (member->is_consensus_manager()) {
1667            consensus_manager = member->to_species_manager();
1668            break;
1669        }
1670    }
1671
1672    return consensus_manager;
1673}
1674
1675// -----------------------------
1676//      ED4_species_manager
1677
1678ED4_species_manager::ED4_species_manager(ED4_species_type type_, const char *temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent) :
1679    ED4_manager(species_manager_spec, temp_id, x, y, width, height, temp_parent),
1680    type(type_),
1681    selected(false)
1682{
1683    e4_assert(type != ED4_SP_NONE);
1684}
1685
1686#if defined(DEBUG)
1687// #define DEBUG_SPMAN_CALLBACKS
1688#endif // DEBUG
1689
1690
1691ED4_species_manager::~ED4_species_manager() {
1692#if defined(DEBUG_SPMAN_CALLBACKS)
1693    if (!callbacks.empty()) {
1694        printf("this=%p - non-empty callbacks\n", (char*)this);
1695    }
1696#endif // DEBUG
1697
1698    e4_assert(callbacks.empty());
1699    // if assertion fails, callbacks are still bound to this manager.
1700    // You need to remove all callbacks at two places:
1701    // 1. ED4_species_manager::remove_all_callbacks
1702    // 2. ED4_quit_editor()
1703}
1704
1705void ED4_species_manager::add_sequence_changed_cb(ED4_species_manager_cb cb, AW_CL cd) {
1706#if defined(DEBUG_SPMAN_CALLBACKS)
1707    printf("this=%p - add_sequence_changed_cb\n", (char*)this);
1708#endif // DEBUG
1709    callbacks.insert(ED4_species_manager_cb_data(cb, cd));
1710}
1711
1712void ED4_species_manager::remove_sequence_changed_cb(ED4_species_manager_cb cb, AW_CL cd) {
1713    e4_assert(this);
1714#if defined(DEBUG_SPMAN_CALLBACKS)
1715    printf("this=%p - remove_sequence_changed_cb\n", (char*)this);
1716#endif // DEBUG
1717    callbacks.erase(ED4_species_manager_cb_data(cb, cd));
1718}
1719
1720void ED4_species_manager::do_callbacks() {
1721    for (std::set<ED4_species_manager_cb_data>::iterator cb = callbacks.begin(); cb != callbacks.end(); ++cb) {
1722        cb->call(this);
1723    }
1724}
1725
1726void ED4_species_manager::remove_all_callbacks() {
1727    if (!callbacks.empty()) {
1728        for (ED4_window *ew = ED4_ROOT->first_window; ew; ew = ew->next) {
1729            ED4_cursor&  cursor                  = ew->cursor;
1730            ED4_base    *cursors_species_manager = cursor.owner_of_cursor->get_parent(ED4_L_SPECIES);
1731            if (cursors_species_manager == this) {
1732                cursor.invalidate_base_position(); // removes the callback
1733            }
1734        }
1735        e4_assert(callbacks.empty());
1736    }
1737}
1738
1739static ARB_ERROR removeAllCallbacks(ED4_base *base) {
1740    if (base->is_species_manager()) {
1741        base->to_species_manager()->remove_all_callbacks();
1742    }
1743    return NULL;
1744}
1745
1746void ED4_root::remove_all_callbacks() {
1747    root_group_man->route_down_hierarchy(removeAllCallbacks).expect_no_error();
1748}
1749
1750// ------------------------
1751//      group managers
1752
1753ED4_abstract_group_manager::ED4_abstract_group_manager(const ED4_objspec& spec_, const char *temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent) :
1754    ED4_manager(spec_, temp_id, x, y, width, height, temp_parent), 
1755    my_table(0)
1756{
1757}
1758
1759ED4_group_manager::ED4_group_manager(const char *temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent) :
1760    ED4_abstract_group_manager(group_manager_spec, temp_id, x, y, width, height, temp_parent)
1761{
1762}
1763
1764// -------------------
1765//      ED4_remap
1766
1767ED4_remap::ED4_remap() {
1768    mode               = ED4_RM_NONE;
1769    show_above_percent = 0;
1770
1771    sequence_table_len = 1;
1772    screen_table_len   = 1;
1773
1774    screen_to_sequence_tab = new int[1];        screen_to_sequence_tab[0] = 0;
1775    sequence_to_screen_tab = new int[1];        sequence_to_screen_tab[0] = 0;
1776
1777    sequence_len               = 0;
1778    MAXSEQUENCECHARACTERLENGTH = screen_len = 0;
1779
1780    changed       = 0;
1781    update_needed = 1;
1782
1783}
1784ED4_remap::~ED4_remap() {
1785    delete [] screen_to_sequence_tab;
1786    delete [] sequence_to_screen_tab;
1787}
1788int ED4_remap::screen_to_sequence(int screen_pos) const {
1789    if (size_t(screen_pos) == screen_len) {
1790        return screen_to_sequence_tab[screen_len-1];
1791    }
1792    e4_assert(screen_pos>=0 && size_t(screen_pos)<screen_len);
1793    return screen_to_sequence_tab[screen_pos];
1794}
1795int ED4_remap::clipped_sequence_to_screen_PLAIN(int sequence_pos) const {
1796    if (sequence_pos<0) {
1797        sequence_pos = 0;
1798    }
1799    else if (size_t(sequence_pos)>sequence_len) {
1800        sequence_pos = sequence_len;
1801    }
1802    return sequence_to_screen_PLAIN(sequence_pos);
1803}
1804int ED4_remap::sequence_to_screen(int sequence_pos) const {
1805    int scr_pos = sequence_to_screen_PLAIN(sequence_pos);
1806    if (scr_pos<0) scr_pos = -scr_pos;
1807    return scr_pos;
1808}
1809inline void ED4_remap::set_sequence_to_screen(int pos, int newVal) {
1810    e4_assert(pos>=0 && size_t(pos)<sequence_table_len);
1811    if (sequence_to_screen_tab[pos]!=newVal) {
1812        sequence_to_screen_tab[pos] = newVal;
1813        changed = 1;
1814    }
1815}
1816void ED4_remap::mark_compile_needed_force() {
1817    if (!update_needed) {
1818        update_needed = 1;
1819        if (ED4_ROOT && ED4_ROOT->root_group_man) {                     // test if root_group_man already exists
1820            ED4_ROOT->root_group_man->resize_requested_by_child();      // remapping is recompiled while re-displaying the root_group_manager
1821        }
1822    }
1823}
1824void ED4_remap::mark_compile_needed() {
1825    if (mode!=ED4_RM_NONE) mark_compile_needed_force();
1826}
1827
1828GB_ERROR ED4_remap::compile(ED4_root_group_manager *gm)
1829{
1830    e4_assert(update_needed);
1831
1832    const ED4_char_table&  table = gm->table();
1833    size_t                 i, j;
1834
1835    changed = 0; // is changed by set_sequence_to_screen
1836    update_needed = 0;
1837
1838    sequence_len = table.table('A').size(); // take size of any table
1839    if ((sequence_len+1) > sequence_table_len) {
1840        delete [] sequence_to_screen_tab;
1841        sequence_to_screen_tab = new int[sequence_table_len = sequence_len+1];
1842        memset(sequence_to_screen_tab, 0, sequence_table_len*sizeof(int));
1843        changed = 1;
1844    }
1845
1846    int above_percent;
1847    switch (gm->remap()->get_mode()) {
1848        default: e4_assert(0);
1849        case ED4_RM_NONE: {
1850        dont_map :
1851            for (i=0; i<sequence_table_len; i++) {
1852                set_sequence_to_screen(i, i);
1853            }
1854            screen_len = sequence_len;
1855            break;
1856        }
1857        case ED4_RM_SHOW_ABOVE: {
1858            above_percent = show_above_percent;
1859            goto calc_percent;
1860        }
1861        case ED4_RM_MAX_ALIGN:
1862        case ED4_RM_MAX_EDIT: {
1863            above_percent = 0;
1864        calc_percent :
1865            for (i=0, j=0; i<(sequence_table_len-1); i++) {
1866                int bases;
1867                int gaps;
1868
1869                table.bases_and_gaps_at(i, &bases, &gaps);
1870
1871                if (bases==0 && gaps==0) {  // special case (should occur only after inserting columns)
1872                    set_sequence_to_screen(i, -j); // hide
1873                }
1874                else {
1875                    int percent = (int)((bases*100L)/table.added_sequences());
1876
1877                    e4_assert(percent==((bases*100)/(bases+gaps)));
1878
1879                    if (bases && percent>=above_percent) {
1880                        set_sequence_to_screen(i, j++);
1881                    }
1882                    else {
1883                        set_sequence_to_screen(i, -j);
1884                    }
1885                }
1886            }
1887            for (; i<sequence_table_len; i++) { // fill rest of table
1888                set_sequence_to_screen(i, j++);
1889            }
1890            screen_len = j;
1891            break;
1892        }
1893        case ED4_RM_DYNAMIC_GAPS: {
1894            for (i=0, j=0; i<(sequence_table_len-1); i++) {
1895                int bases;
1896
1897                table.bases_and_gaps_at(i, &bases, 0);
1898                if (bases) {
1899                    set_sequence_to_screen(i, j++);
1900                }
1901                else {
1902                    size_t k = i+1;
1903
1904                    while (k<(sequence_table_len-1)) {
1905                        int bases2;
1906
1907                        table.bases_and_gaps_at(k, &bases2, 0);
1908                        if (bases2) {
1909                            break;
1910                        }
1911                        k++;
1912                    }
1913
1914                    int gaps = k-i;
1915                    int shown_gapsize;
1916
1917                    if (gaps<100) {
1918                        shown_gapsize = gaps/10 + 1;
1919                    }
1920                    else if (gaps<1000) {
1921                        shown_gapsize = gaps/100 + 10;
1922                    }
1923                    else {
1924                        shown_gapsize = gaps/1000 + 19;
1925                    }
1926
1927                    for (; i<k && shown_gapsize; i++, shown_gapsize--) {
1928                        set_sequence_to_screen(i, j++);
1929                    }
1930                    for (; i<k; i++) {
1931                        set_sequence_to_screen(i, -j);
1932                    }
1933                    i--;
1934                }
1935            }
1936            for (; i<sequence_table_len; i++) {
1937                set_sequence_to_screen(i, j++); // fill rest of table
1938            }
1939            screen_len = j;
1940            break;
1941        }
1942    }
1943
1944    if (sequence_table_len) {
1945        if (!screen_len && sequence_len) {
1946            goto dont_map;
1947        }
1948        if ((screen_len+1) > screen_table_len) {
1949            delete [] screen_to_sequence_tab;
1950            screen_to_sequence_tab = new int[screen_table_len = screen_len+1];
1951        }
1952        memset(screen_to_sequence_tab, 0, sizeof(int)*screen_table_len);
1953        for (i=0; i<sequence_table_len; i++) {
1954            int screen_pos = sequence_to_screen_tab[i];
1955            if (screen_pos>=0) {
1956                screen_to_sequence_tab[screen_pos] = i;
1957            }
1958        }
1959    }
1960
1961    if (sequence_len>1) {
1962        MAXSEQUENCECHARACTERLENGTH = sequence_len;
1963    }
1964
1965    return NULL;
1966}
1967
1968// --------------------------------
1969//      ED4_root_group_manager
1970
1971ED4_root_group_manager::ED4_root_group_manager(const char *temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent)
1972    : ED4_abstract_group_manager(root_group_manager_spec, temp_id, x, y, width, height, temp_parent),
1973      my_remap()
1974{
1975    AW_root *awr = ED4_ROOT->aw_root;
1976    my_remap.set_mode((ED4_remap_mode)awr->awar(ED4_AWAR_COMPRESS_SEQUENCE_TYPE)->read_int(),
1977                      awr->awar(ED4_AWAR_COMPRESS_SEQUENCE_PERCENT)->read_int());
1978    my_remap.mark_compile_needed_force();
1979}
1980
1981bool ED4_root_group_manager::update_remap() {
1982    bool remapped = false;
1983
1984    if (my_remap.compile_needed()) {
1985        my_remap.compile(this);
1986        if (my_remap.was_changed()) remapped = true;
1987    }
1988
1989    return remapped;
1990}
1991
1992// -----------------------------------
1993//      ED4_multi_species_manager
1994
1995ED4_multi_sequence_manager::ED4_multi_sequence_manager(const char *temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent)
1996    : ED4_manager(multi_sequence_manager_spec, temp_id, x, y, width, height, temp_parent)
1997{
1998}
1999
2000ED4_sequence_manager::ED4_sequence_manager(const char *temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent)
2001    : ED4_manager(sequence_manager_spec, temp_id, x, y, width, height, temp_parent)
2002{
2003}
2004
2005ED4_multi_name_manager::ED4_multi_name_manager(const char *temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent)
2006    : ED4_manager(multi_name_manager_spec, temp_id, x, y, width, height, temp_parent)
2007{
2008}
2009
2010ED4_name_manager::ED4_name_manager(const char *temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent)
2011    : ED4_manager(name_manager_spec, temp_id, x, y, width, height, temp_parent)
2012{
2013}
2014
Note: See TracBrowser for help on using the browser.