source: branches/alilink/EDIT4/ed4_class.hxx

Last change on this file was 18126, checked in by westram, 5 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 88.5 KB
Line 
1#ifndef ED4_CLASS_HXX
2#define ED4_CLASS_HXX
3
4#ifndef AW_FONT_GROUP_HXX
5#include <aw_font_group.hxx>
6#endif
7#ifndef POS_RANGE_H
8#include <pos_range.h>
9#endif
10
11#define e4_assert(bed) arb_assert(bed)
12
13#define concat(a,b) a##b
14
15#ifdef DEBUG
16# define IMPLEMENT_DUMP         // comment out this line to skip compilation of the dump() methods
17#endif
18
19#ifndef ARB_ERROR_H
20#include <arb_error.h>
21#endif
22#ifndef ED4_DEFS_HXX
23#include "ed4_defs.hxx"
24#endif
25#ifndef ED4_SEARCH_HXX
26#include "ed4_search.hxx"
27#endif
28#ifndef _GLIBCXX_LIST
29#include <list>
30#endif
31#ifndef ATTRIBUTES_H
32#include <attributes.h>
33#endif
34#ifndef BI_BASEPOS_HXX
35#include <BI_basepos.hxx>
36#endif
37#ifndef DOWNCAST_H
38#include <downcast.h>
39#endif
40#ifndef CHARTABLE_H
41#include "chartable.h"
42#endif
43
44#if defined(IMPLEMENT_DUMP) // ------------------------------
45
46#if 0
47#define WARN(msg) void dummy_to_produce_a_warning(int msg) {}
48#else
49#define WARN(msg)
50#endif
51
52#define EMPTY_FUNCTION(name)         void name() const {}
53#define EMPTY_FUNCTION_VERBOSE(name) void name(int je_mappelle_##name) const {}
54
55#define DERIVABLEFROM(base) concat(prohibited_leafclass_derivation,base)
56
57#define COMMON_FOR_BASES()                      \
58    virtual void dump(size_t indent) const = 0; \
59
60#define COMMON_FOR_DERIVABLE(self)               \
61    void dump_base(size_t indent) const;         \
62    EMPTY_FUNCTION(DERIVABLEFROM(self));         \
63
64#define COMMON_FOR_DERIVED(mybase)                                              \
65    void dump_my_base(size_t indent) const { mybase::dump_base(indent); }       \
66    virtual const char *baseclassname() const { return #mybase; }               \
67
68#define COMMON_FOR_INSTANCIABLE(mybase)                 \
69    void dump(size_t indent) const OVERRIDE;            \
70
71#define DECLARE_DUMP_FOR_ROOTCLASS(self)        \
72    COMMON_FOR_BASES();                         \
73    COMMON_FOR_DERIVABLE(self);                 \
74
75#define DECLARE_DUMP_FOR_BASECLASS(self,mybase) \
76    COMMON_FOR_BASES();                         \
77    COMMON_FOR_DERIVABLE(self);                 \
78    COMMON_FOR_DERIVED(mybase);                 \
79
80#define DECLARE_DUMP_FOR_MIDCLASS(self,mybase)  \
81    WARN(midclass_is_unwanted);                 \
82    COMMON_FOR_DERIVABLE(self);                 \
83    COMMON_FOR_DERIVED(mybase);                 \
84    COMMON_FOR_INSTANCIABLE(mybase);            \
85
86#define DECLARE_DUMP_FOR_LEAFCLASS(mybase)              \
87    virtual void leaf() { DERIVABLEFROM(mybase)(); }    \
88    COMMON_FOR_DERIVED(mybase);                         \
89    COMMON_FOR_INSTANCIABLE(mybase);                    \
90
91#else
92#define DECLARE_DUMP_FOR_ROOTCLASS(self)
93#define DECLARE_DUMP_FOR_BASECLASS(self,mybase)
94#define DECLARE_DUMP_FOR_MIDCLASS(self,mybase)
95#define DECLARE_DUMP_FOR_LEAFCLASS(mybase)
96
97#endif // IMPLEMENT_DUMP ------------------------------
98
99
100
101// #define LIMIT_TOP_AREA_SPACE // if defined, top area is size-limited
102#ifdef LIMIT_TOP_AREA_SPACE
103#define MAX_TOP_AREA_SIZE 10    // size limit for top-area
104#endif
105
106#define ed4_beep() do { fputc(char(7), stdout); fflush(stdout); } while (0)
107
108enum PositionType {
109    ED4_POS_SEQUENCE,
110    ED4_POS_ECOLI,
111    ED4_POS_BASE,
112};
113
114// ****************************************
115// needed prototypes, definitions below
116// ****************************************
117
118class ED4_Edit_String;
119class ED4_area_manager;
120class ED4_abstract_group_manager;
121class ED4_base;
122class ED4_bracket_terminal;
123class BaseFrequencies;
124class ED4_columnStat_terminal;
125class ED4_consensus_sequence_terminal;
126class ED4_cursor;
127class ED4_device_manager;
128class ED4_folding_line;
129class ED4_group_manager;
130class ED4_line_terminal;
131class ED4_main_manager;
132class ED4_manager;
133class ED4_multi_name_manager;
134class ED4_multi_sequence_manager;
135class ED4_multi_species_manager;
136class ED4_name_manager;
137class ED4_pure_text_terminal;
138class ED4_reference_terminals;
139class ED4_remap;
140class ED4_root;
141class ED4_root_group_manager;
142class ED4_sequence_info_terminal;
143class ED4_sequence_manager;
144class ED4_sequence_terminal;
145class ED4_orf_terminal;
146class ED4_spacer_terminal;
147class ED4_species_manager;
148class ED4_species_name_terminal;
149class ED4_species_pointer;
150class ED4_terminal;
151class ED4_text_terminal;
152class ED4_tree_terminal;
153class ED4_flag_header_terminal;
154class ED4_flag_terminal;
155class ED4_window;
156
157class AP_tree;
158class ED4_reference;
159class ED4_seq_colors;
160class BI_ecoli_ref;
161class AW_helix;
162class arb_progress;
163class ST_ML;
164class ed_key;
165class ConsensusBuildParams;
166
167template <class T> class ED4_list;      // derived from Noncopyable
168template <class T> class ED4_list_elem; // derived from Noncopyable
169
170typedef ED4_list<ED4_base>      ED4_base_list;
171typedef ED4_list_elem<ED4_base> ED4_base_list_elem;
172
173typedef ED4_list<ED4_selection_entry>      ED4_selected_list;
174typedef ED4_list_elem<ED4_selection_entry> ED4_selected_elem;
175
176
177struct EDB_root_bact {
178    char *make_string();
179    char *make_top_bot_string();
180
181    void calc_no_of_all(const char *string_to_scan,       // group gets the number of groups in string_to_scan,
182                        long *group,                // species gets the number of species in string_to_scan
183                        long *species);
184
185    ED4_returncode fill_species(ED4_multi_species_manager *multi_species_manager,
186                                ED4_reference_terminals&   refterms,
187                                const char                *str,
188                                int                       *index,
189                                int                        group_depth,
190                                arb_progress              *progress);
191
192    ED4_returncode fill_data(ED4_multi_species_manager *multi_species_manager,
193                             ED4_reference_terminals&   refterms,
194                             char                      *str,
195                             int                        group_depth,
196                             ED4_datamode               datamode);      // flag only needed for loading a new configuration
197
198    ED4_returncode search_sequence_data_rek(ED4_multi_sequence_manager *multi_sequence_manager,
199                                            ED4_reference_terminals&    refterms,
200                                            GBDATA                     *gb_ali_xxx, // alignment-container (or any subcontainer of)
201                                            int                         count_too,
202                                            ED4_index                  *max_sequence_terminal_length,
203                                            bool                        isSAI);
204
205    void scan_string(ED4_multi_species_manager *parent,
206                     ED4_reference_terminals&   refterms,
207                     const char                *str,
208                     int                       *index,
209                     arb_progress&              progress);
210
211    void save_current_config(char *confname);
212
213    EDB_root_bact() {}
214};
215
216#define SPECIFIED_OBJECT_TYPES 23
217
218class ED4_objspec : public Noncopyable {
219    static bool object_specs_initialized;
220    static bool descendants_uptodate;
221
222    mutable ED4_level used_children;         // in any object of this type
223    mutable ED4_level possible_descendants;  // below any object of this type (depends on used_children)
224    mutable ED4_level allowed_descendants;   // below any object of this type (depends on allowed_children)
225
226    void calc_descendants() const;
227
228public:
229    ED4_properties static_prop;
230    ED4_level      level;
231    ED4_level      allowed_children;
232    ED4_level      handled_level;
233    ED4_level      restriction_level;
234
235    ED4_objspec(ED4_properties static_prop_, ED4_level level_, ED4_level allowed_children_, ED4_level handled_level_, ED4_level restriction_level_);
236
237#if defined(IMPLEMENT_DUMP)
238    void dump(size_t indent) const;
239#endif // IMPLEMENT_DUMP
240
241    static void init_object_specs();
242
243    bool is_manager() const { return static_prop & PROP_IS_MANAGER; }
244    bool is_terminal() const { return static_prop & PROP_IS_TERMINAL; }
245
246    bool allowed_to_contain(ED4_level child_level) const {
247        // e4_assert(object_specs_initialized); // @@@ cant check here.. but where
248        e4_assert(is_manager()); // terminals can't contain anything - your test is senseless
249        return allowed_children & child_level;
250    }
251
252    void announce_added(ED4_level child_level) const {
253        e4_assert(allowed_to_contain(child_level));
254        used_children          = ED4_level(used_children|child_level);
255        descendants_uptodate = false;
256    }
257
258    static void recalc_descendants();
259
260    ED4_level get_possible_descendants() const {
261        e4_assert(is_manager());
262        if (!descendants_uptodate) recalc_descendants();
263        return possible_descendants;
264    }
265    ED4_level get_allowed_descendants() const { // (allowed = possible + those allowed to add, but not added anywhere)
266        e4_assert(is_manager());
267        if (!descendants_uptodate) recalc_descendants();
268        return allowed_descendants;
269    }
270};
271
272class ED4_folding_line : virtual Noncopyable {
273    AW_pos            dimension; // amount of pixel folded away
274    AW_pos            pos;       // window position of folding line (x or y, only owner knows which coordinate is folded)
275    ED4_folding_line *next;
276
277    ED4_folding_line *insert(ED4_folding_line *fl) {
278        e4_assert(!fl->next);
279        if (pos <= fl->pos) { // insert behind
280            next = next ? next->insert(fl) : fl;
281            return this;
282        }
283
284        fl->next = this;
285        return fl;
286    }
287
288public:
289
290    ED4_folding_line(AW_pos world, AW_pos dim) : dimension(dim), next(NULp) { set_pos(world-dimension); }
291
292    ~ED4_folding_line() { delete next; }
293
294    void insertAs(ED4_folding_line*& ptr) {
295        ED4_folding_line *other = ptr;
296        e4_assert(knownNonNull(this));
297        ptr = other ? other->insert(this) : this;
298    }
299
300    ED4_folding_line *delete_member(ED4_folding_line *fl) {
301        ED4_folding_line *result = this;
302        if (this == fl) {
303            result = next;
304            next   = NULp;
305            delete this;
306        }
307        return result;
308    }
309
310    AW_pos get_dimension() const { return dimension; }
311    const ED4_folding_line *get_next() const { return next; }
312
313    void warn_illegal_dimension();
314
315    void set_dimension(AW_pos dim) { dimension = dim; warn_illegal_dimension(); }
316    void add_to_dimension(AW_pos offset) { dimension += offset; warn_illegal_dimension(); }
317
318    void set_pos(AW_pos p) { pos = p; }
319    AW_pos get_pos() const { return pos; }
320
321    AW_pos win2world(AW_pos win) const {
322        if (win<pos) return win;
323        return (next ? next->win2world(win) : win)+dimension;
324    }
325    AW_pos world2win(AW_pos world) const {
326        if (world<pos) return world;
327        world -= dimension;
328        if (!next) return world;
329        return next->world2win(world);
330    }
331};
332
333struct ED4_scroll_links {
334    ED4_base *link_for_hor_slider;
335    ED4_base *link_for_ver_slider;
336
337    ED4_scroll_links() : link_for_hor_slider(NULp), link_for_ver_slider(NULp) {}
338};
339
340class ED4_foldable : virtual Noncopyable {
341    ED4_folding_line *horizontal_fl;
342    ED4_folding_line *vertical_fl;
343protected:
344    void reset() {
345        delete horizontal_fl;
346        delete vertical_fl;
347        horizontal_fl = NULp;
348        vertical_fl   = NULp;
349    }
350    bool is_reset() const { return !horizontal_fl && !vertical_fl; }
351public:
352
353    ED4_foldable() : horizontal_fl(NULp), vertical_fl(NULp) {}
354    ~ED4_foldable() { reset(); }
355
356    const ED4_folding_line *get_horizontal_folding() { return horizontal_fl; }
357    const ED4_folding_line *get_vertical_folding() { return vertical_fl; }
358
359    void world_to_win_coords(AW_pos *xPtr, AW_pos *yPtr) const { // @@@ old style
360        // Calculates transformation from world to window coordinates in a given window.
361        // world-coordinates inside folded range result in window coordinates lower than folding line position.
362        e4_assert(!is_reset());
363        *xPtr = vertical_fl->world2win(*xPtr);
364        *yPtr = horizontal_fl->world2win(*yPtr);
365    }
366    void win_to_world_coords(AW_pos *xPtr, AW_pos *yPtr) const { // @@@ old style
367        // calculates transformation from window to world coordinates in a given window
368        e4_assert(!is_reset());
369        *xPtr = vertical_fl->win2world(*xPtr);
370        *yPtr = horizontal_fl->win2world(*yPtr);
371    }
372
373    AW::Position world_to_win_coords(const AW::Position& pos) const {
374        e4_assert(!is_reset());
375        return AW::Position(vertical_fl->world2win(pos.xpos()),
376                            horizontal_fl->world2win(pos.ypos()));
377    }
378    AW::Position win_to_world_coords(const AW::Position& pos) const {
379        e4_assert(!is_reset());
380        return AW::Position(vertical_fl->win2world(pos.xpos()),
381                            horizontal_fl->win2world(pos.ypos()));
382    }
383
384    ED4_folding_line *insert_folding_line(AW_pos pos, AW_pos dimension, ED4_properties prop);
385    void              delete_folding_line(ED4_folding_line *fl, ED4_properties prop);
386};
387
388
389class ED4_scrolled_rectangle : virtual Noncopyable {
390    ED4_folding_line *scroll_bottom;
391    ED4_folding_line *scroll_right;
392    ED4_folding_line *scroll_top;
393    ED4_folding_line *scroll_left;
394
395    ED4_base *x_link;
396    ED4_base *y_link;
397    ED4_base *width_link;
398    ED4_base *height_link;
399
400    AW::Rectangle world;
401
402    bool folding_dimensions_calculated; // flag to ensure calc_bottomRight_folding_dimensions is called before get_window_rect
403
404    void init_links() {
405        x_link      = NULp;
406        y_link      = NULp;
407        width_link  = NULp;
408        height_link = NULp;
409    }
410
411    void init_folding_lines() {
412        scroll_top    = NULp;
413        scroll_bottom = NULp;
414        scroll_left   = NULp;
415        scroll_right  = NULp;
416
417        folding_dimensions_calculated = false;
418    }
419    void init_pos_size() { world = AW::Rectangle(AW::Origin, AW::ZeroVector); }
420
421    void init() {
422        init_folding_lines();
423        init_pos_size();
424        init_links();
425    }
426
427    void update_folding_line_positions() {
428        scroll_top->set_pos(world.top());
429        scroll_left->set_pos(world.left());
430    }
431
432public:
433
434    ED4_scrolled_rectangle() { init(); }
435
436    AW_pos bottom() const { return world.bottom(); }
437    AW_pos right() const { return world.right(); }
438
439    void reset(ED4_foldable& owner) {
440        destroy_folding_lines(owner);
441        init_pos_size();
442    }
443
444    AW_pos top_dim() const { return scroll_top->get_dimension(); }
445    AW_pos left_dim() const { return scroll_left->get_dimension(); }
446
447    bool exists() const { return scroll_top && scroll_bottom && scroll_left && scroll_right; }
448    bool is_linked() const {
449        if (x_link) {
450            e4_assert(y_link);
451            e4_assert(width_link);
452            e4_assert(height_link);
453            return true;
454        }
455        e4_assert(!y_link);
456        e4_assert(!width_link);
457        e4_assert(!height_link);
458        return false;
459    }
460    void link(ED4_base *x, ED4_base *y, ED4_base *w, ED4_base *h) {
461        e4_assert(x && y && w && h);
462
463        x_link      = x;
464        y_link      = y;
465        width_link  = w;
466        height_link = h;
467    }
468
469    void replace_x_width_link_to(ED4_base *old_link, ED4_base *new_link) {
470        if (x_link == old_link)     x_link     = new_link;
471        if (width_link == old_link) width_link = new_link;
472    }
473
474    void add_to_top_left_dimension(int dx, int dy) {
475        scroll_left->add_to_dimension(dx);
476        scroll_top->add_to_dimension(dy);
477    }
478
479    void scroll(int dx, int dy) {
480        scroll_left->add_to_dimension(-dx);
481        scroll_top->add_to_dimension(-dy);
482        scroll_right->add_to_dimension(dx);
483        scroll_bottom->add_to_dimension(dy);
484    }
485
486    AW::Rectangle get_window_rect() const {
487        e4_assert(folding_dimensions_calculated);
488        return AW::Rectangle(scroll_left->get_pos(), scroll_top->get_pos(),
489                             scroll_right->get_pos(), scroll_bottom->get_pos());
490    }
491
492    AW::Rectangle get_world_rect() const;
493
494    void set_rect(const AW::Rectangle& rect) { world = rect; }
495    void set_rect_and_update_folding_line_positions(const AW::Rectangle& rect) {
496        set_rect(rect);
497        update_folding_line_positions();
498    }
499
500    void calc_bottomRight_folding_dimensions(int area_width, int area_height) {
501        area_width  -= SLIDER_OFFSET;
502        area_height -= SLIDER_OFFSET;
503
504        AW_pos dim;
505        if (bottom() > area_height) {   // our world doesn't fit vertically in our window
506            dim = bottom()-area_height; // calc dimension of both horizontal folding lines
507            scroll_top->set_dimension(std::min(dim, scroll_top->get_dimension()));
508            scroll_bottom->set_dimension(std::max(0, int(dim - scroll_top->get_dimension())));
509        }
510        else {
511            dim = 0;
512            scroll_bottom->set_dimension(0);
513            scroll_top->set_dimension(0);
514        }
515
516        e4_assert(dim == (scroll_top->get_dimension()+scroll_bottom->get_dimension()));
517        scroll_bottom->set_pos(world.bottom()-dim+SLIDER_OFFSET);
518
519        if (right()>area_width) {     // our world doesn't fit horizontally in our window
520            dim = right()-area_width; // calc dimension of both vertical folding lines
521            scroll_left->set_dimension(std::min(dim, scroll_left->get_dimension()));
522            scroll_right->set_dimension(std::max(0, int(dim - scroll_left->get_dimension())));
523        }
524        else {
525            dim = 0;
526            scroll_right->set_dimension(0);
527            scroll_left->set_dimension(0);
528        }
529
530        e4_assert(dim == (scroll_left->get_dimension()+scroll_right->get_dimension()));
531        scroll_right->set_pos(world.right()-dim+SLIDER_OFFSET);
532
533        folding_dimensions_calculated = true;
534    }
535
536    void create_folding_lines(ED4_foldable& owner, const AW::Rectangle& rect, int area_width, int area_height) {
537        scroll_top  = owner.insert_folding_line(rect.top(), 0, PROP_HORIZONTAL);
538        scroll_left = owner.insert_folding_line(rect.left(), 0, PROP_VERTICAL);
539
540        AW_pos dim = 0;
541        if (rect.bottom() > area_height) dim = rect.bottom() - area_height;
542        scroll_bottom = owner.insert_folding_line(rect.bottom(), dim, PROP_HORIZONTAL);
543
544        dim = 0;
545        if (rect.right() > area_width) dim = rect.right() - area_width;
546        scroll_right = owner.insert_folding_line(rect.right(), dim, PROP_VERTICAL);
547    }
548
549    void destroy_folding_lines(ED4_foldable& owner) {
550        if (scroll_top)    owner.delete_folding_line(scroll_top,    PROP_HORIZONTAL);
551        if (scroll_bottom) owner.delete_folding_line(scroll_bottom, PROP_HORIZONTAL);
552        if (scroll_left)   owner.delete_folding_line(scroll_left,   PROP_VERTICAL);
553        if (scroll_right)  owner.delete_folding_line(scroll_right,  PROP_VERTICAL);
554
555        init_folding_lines();
556    }
557};
558
559class ED4_base_position : private BasePosition { // derived from a Noncopyable
560    const ED4_terminal *calced4term; // if calced4term => callback is bound to its species manager
561    bool needUpdate;
562
563    void calc4term(const ED4_terminal *term);
564    void set_term(const ED4_terminal *term) {
565        if (calced4term != term || needUpdate) {
566            calc4term(term);
567        }
568    }
569    void remove_changed_cb();
570
571public:
572
573    ED4_base_position()
574        : calced4term(NULp),
575          needUpdate(true)
576    {}
577
578    ~ED4_base_position() {
579        remove_changed_cb();
580    }
581
582    void invalidate() {
583        needUpdate = true;
584    }
585
586    void announce_deletion(const ED4_terminal *term) {
587        if (term == calced4term) {
588            invalidate();
589            remove_changed_cb();
590        }
591        e4_assert(calced4term != term);
592    }
593    void prepare_shutdown() {
594        if (calced4term) announce_deletion(calced4term);
595    }
596
597    int get_base_position(const ED4_terminal *base, int sequence_position);
598    int get_sequence_position(const ED4_terminal *base, int base_position);
599
600    int get_base_count(const ED4_terminal *term) { set_term(term); return base_count(); }
601    int get_abs_len(const ED4_terminal *term) { set_term(term); return abs_count(); }
602};
603
604class ED4_CursorShape;
605
606
607enum ED4_CursorType {
608    ED4_RIGHT_ORIENTED_CURSOR,
609    ED4_RIGHT_ORIENTED_CURSOR_THIN,
610    ED4_TRADITIONAL_CURSOR,
611    ED4_TRADITIONAL_CURSOR_BOTTOM,
612    ED4_TRADITIONAL_CURSOR_CONNECTED,
613    ED4_FUCKING_BIG_CURSOR,
614
615    ED4_CURSOR_TYPES
616
617};
618
619struct ED4_TerminalPredicate {
620    virtual ~ED4_TerminalPredicate() {}
621    virtual bool fulfilled_by(const ED4_terminal *) const = 0;
622};
623
624class ED4_WinContextFree { // denies usage of the following functions in classes derived from this
625    AW_device   *current_device();
626    ED4_window  *current_ed4w();
627    AW_window   *current_aww();
628    ED4_cursor&  current_cursor();
629public:
630    void avoid_warning() {}
631};
632
633class ED4_cursor : virtual Noncopyable, virtual ED4_WinContextFree {
634    ED4_window                *win;
635    ED4_index                  cursor_abs_x;    // absolute (to terminal) x-position of cursor (absolute world coordinate of edit window)
636    int                        screen_position; // number of displayed characters leading the cursor
637    mutable ED4_base_position  base_position;   // # of bases left of cursor
638    ED4_CursorType             ctype;
639    ED4_CursorShape           *cursor_shape;
640
641    ED4_returncode  draw_cursor(AW_pos x, AW_pos y);
642    ED4_returncode  delete_cursor(AW_pos del_mark,  ED4_base *target_terminal);
643
644    void updateAwars(bool new_term_selected);
645
646public:
647
648    bool          allowed_to_draw; // needed for cursor handling
649    ED4_terminal *owner_of_cursor;
650
651    bool is_partly_visible() const;
652    bool is_completely_visible() const;
653
654    bool is_hidden_inside_group() const;
655
656    void changeType(ED4_CursorType typ);
657    ED4_CursorType  getType() const { return ctype; }
658
659    void redraw() { changeType(getType()); }
660
661    ED4_returncode HideCursor(); // deletes cursor and does refresh
662    ED4_returncode move_cursor(AW_event *event);
663    ED4_returncode show_clicked_cursor(AW_pos click_xpos, ED4_terminal *target_terminal);
664    ED4_returncode show_cursor_at(ED4_terminal *target_terminal, ED4_index what_pos);
665    ED4_returncode ShowCursor(ED4_index offset_x, ED4_cursor_move move, int move_pos = 1);
666
667    int get_sequence_pos() const;
668    int get_screen_pos() const { return screen_position; }
669
670    long get_abs_x() const   { return cursor_abs_x; }
671    void set_abs_x();
672
673    int base2sequence_position(int base_pos) const { return base_position.get_sequence_position(owner_of_cursor, base_pos); }
674    int sequence2base_position(int seq_pos) const { return base_position.get_base_position(owner_of_cursor, seq_pos); }
675
676    int get_base_position() const { return sequence2base_position(get_sequence_pos()); }
677
678    void prepare_shutdown() { base_position.prepare_shutdown(); }
679
680    void jump_screen_pos(int screen_pos, ED4_CursorJumpType jump_type);
681    void jump_sequence_pos(int sequence_pos, ED4_CursorJumpType jump_type);
682    void jump_base_pos(int base_pos, ED4_CursorJumpType jump_type);
683
684    int get_screen_relative_pos() const;
685    void set_screen_relative_pos(int scroll_to_relpos);
686
687    void set_to_terminal(ED4_terminal *terminal, int seq_pos, ED4_CursorJumpType jump_type);
688
689    inline bool in_species_seq_terminal() const;
690    inline bool in_consensus_terminal() const;
691    inline bool in_SAI_terminal() const;
692
693    void announce_deletion(ED4_terminal *object) {
694        base_position.announce_deletion(object);
695        if (object == owner_of_cursor) owner_of_cursor = NULp; // no need to delete the cursor (deletion triggers full redraw)
696    }
697
698    void init();
699
700    ED4_window *window() const { return win; }
701
702    ED4_cursor(ED4_window *win);
703    ~ED4_cursor();
704};
705
706class ED4_window : public ED4_foldable, virtual ED4_WinContextFree { // derived from Noncopyable
707    void set_scrollbar_indents();
708
709public:
710    AW_window_menu_modes   *aww;   // Points to Window
711    ED4_window             *next;
712    int                     slider_pos_horizontal;
713    int                     slider_pos_vertical;
714    ED4_scrolled_rectangle  scrolled_rect;
715    int                     id;    // unique id in window-list
716    ED4_coords              coords;
717
718    static int no_of_windows;
719
720    char awar_path_for_cursor[50];                  // position in current sequence, range = [1;len]
721    char awar_path_for_Ecoli[50];                   // position relative to ecoli
722    char awar_path_for_basePos[50];                 // base position in current sequence (# of bases left to cursor)
723    char awar_path_for_IUPAC[50];                   // IUPAC decoder content for current position
724    char awar_path_for_helixNr[50];                 // # of helix (or 0) for current position
725
726    bool       is_hidden;
727    ED4_cursor cursor;
728
729    // ED4_window controlling functions
730    static ED4_window *insert_window(AW_window_menu_modes *new_aww); // append to window list
731
732    void        delete_window(ED4_window *window);  // delete from window list
733    void        reset_all_for_new_config(); // reset structures for loading new config
734    ED4_window *get_matching_ed4w(AW_window *aww);
735
736    void announce_deletion(ED4_terminal *object) { cursor.announce_deletion(object); }
737
738    // functions concerned the scrolled area
739    void update_scrolled_rectangle();
740    ED4_returncode scroll_rectangle(int dx, int dy);
741    ED4_returncode set_scrolled_rectangle(ED4_base *x_link, ED4_base *y_link, ED4_base *width_link, ED4_base *height_link);
742
743    bool scrollbars_and_scrolledRect_inSync() const {
744        // Scrolling in EDIT4 window uses redundant data
745        // - dimension of folding lines
746        // - slider positions in AW_window and ED4_window
747        // This function checks whether they are in sync.
748
749        bool inSync                    =
750            (scrolled_rect.top_dim()  == aww->slider_pos_vertical) &&
751            (scrolled_rect.left_dim() == aww->slider_pos_horizontal);
752
753#if defined(DEBUG)
754        if (!inSync) {
755            fputs("scrollbars not in sync with scrolled_rect:\n", stderr);
756            fprintf(stderr, "    aww->slider_pos_vertical  =%i scrolled_rect->top_dim() =%f\n", aww->slider_pos_vertical,   scrolled_rect.top_dim());
757            fprintf(stderr, "    aww->slider_pos_horizontal=%i scrolled_rect->left_dim()=%f\n", aww->slider_pos_horizontal, scrolled_rect.left_dim());
758        }
759#endif
760
761        return inSync;
762    }
763
764    void check_valid_scrollbar_values() { e4_assert(scrollbars_and_scrolledRect_inSync()); }
765
766    bool shows_xpos(int x) const { return x >= coords.window_left_clip_point && x <= coords.window_right_clip_point; }
767    bool partly_shows(int x1, int y1, int x2, int y2) const;
768    bool completely_shows(int x1, int y1, int x2, int y2) const;
769
770    void update_window_coords();
771
772    AW_device *get_device() const { return aww->get_device(AW_MIDDLE_AREA); }
773
774    ED4_window(AW_window_menu_modes *window);
775    ~ED4_window();
776};
777
778class ED4_container : virtual Noncopyable {
779    // contains children of a manager
780
781    ED4_base  **memberList;
782    ED4_index   no_of_members;   // How much members are in the list
783    ED4_index   size_of_list;    // allocated size
784
785    void correct_insert_position(ED4_index& index);
786    void resize(ED4_index needed_size);
787
788    void shift_list(ED4_index start_index, int length);
789
790protected:
791
792    bool valid_index(ED4_index idx) const { return idx >= 0 && idx<size_of_list; }
793    bool existing_index(ED4_index idx) const { return idx >= 0 && idx<no_of_members; }
794
795public:
796
797    ED4_manager *owner() { return DOWNCAST(ED4_manager*, this); }
798    const ED4_manager *owner() const { return const_cast<ED4_container*>(this)->owner(); }
799
800    ED4_base* member(ED4_index i) const { e4_assert(i>=0 && i<size_of_list); return memberList[i]; }
801
802    ED4_index members() const { return no_of_members; }
803    bool empty() const { return !members(); }
804    void clear();
805
806    void insert_member(ED4_base *new_member); // only used to move members with mouse
807    void append_member(ED4_base *new_member);
808
809    // an array is chosen instead of a linked list, because destructorhandling is more comfortable in various destructors (manager-destructors)
810
811    ED4_returncode remove_member(ED4_base *member);
812    ED4_index search_member(ED4_extension *location, ED4_properties prop);       // search member
813
814    ED4_returncode search_target_species(ED4_extension *location, ED4_properties prop, ED4_base **found_member, ED4_level return_level);
815
816    ED4_returncode move_member(ED4_index old_pos, ED4_index new_pos);
817
818#if defined(IMPLEMENT_DUMP)
819    void dump_container(size_t indent) const;
820#endif // IMPLEMENT_DUMP
821
822#if defined(ASSERTION_USED)
823    bool members_ok() const;
824#endif // ASSERTION_USED
825
826    ED4_container();
827    virtual ~ED4_container();
828};
829
830// ----------------------------
831//      ED4_species_pointer
832
833class ED4_species_pointer : virtual Noncopyable {
834    // @@@ shall be renamed into ED4_gbdata_pointer to reflect general usage
835
836    GBDATA *species_pointer;    // points to database
837
838    void addCallback(ED4_base *base);
839    void removeCallback(ED4_base *base);
840
841public:
842
843    ED4_species_pointer();
844    ~ED4_species_pointer();
845
846    GBDATA *Get() const { return species_pointer; }
847    void Set(GBDATA *gbd, ED4_base *base);
848    void notify_deleted() {
849        species_pointer=NULp;
850    }
851};
852
853// ------------------------
854//      callback types
855
856template <class BASE, class BASECB>
857class ED4_cb_list {
858    std::list<BASECB> callbacks;
859public:
860#if defined(ASSERTION_USED)
861    ED4_cb_list() {}
862    ~ED4_cb_list() {
863        e4_assert(empty()); // calling ED4_root::remove_all_callbacks() did not remove all callbacks!
864    }
865#endif
866    void add_cb(BASECB cb) { callbacks.push_back(cb); }
867    void remove_cb(BASECB cb) { callbacks.remove(cb); }
868
869    void call(BASE *b) {
870        for (typename std::list<BASECB>::iterator cb = callbacks.begin(); cb != callbacks.end();) {
871            typename std::list<BASECB>::iterator curr = cb;
872            ++cb;
873            (*curr)(b); // Note: may be removed while called
874        }
875    }
876    void clear() { callbacks.clear(); }
877    bool empty() const { return callbacks.empty(); }
878};
879
880// declare callback types used in ED4_cb_list:
881DECLARE_CBTYPE_FVV_AND_BUILDERS(ED4_managerCallback,         void, ED4_manager*);         // generates makeED4_managerCallback
882DECLARE_CBTYPE_FVV_AND_BUILDERS(ED4_species_managerCallback, void, ED4_species_manager*); // generates makeED4_species_managerCallback
883
884// -----------------
885//      ED4_base
886
887class ED4_base;
888
889DECLARE_CBTYPE_FVV_AND_BUILDERS(ED4_route_cb, ARB_ERROR, ED4_base*); // generates makeED4_route_cb
890
891enum ED4_species_type {
892    ED4_SP_NONE,
893    ED4_SP_SPECIES,
894    ED4_SP_SAI,
895    ED4_SP_CONSENSUS,
896};
897
898class ED4_base : virtual Noncopyable {
899    // base object
900
901    ED4_species_pointer my_species_pointer;
902
903    // cache world coordinates:
904
905    static int           currTimestamp;
906    mutable AW::Position lastPos;
907    mutable int          timestamp;
908
909    ED4_base_list *linked_objects;                  // linked list of objects which are depending from this object
910
911    virtual bool set_dynamic_size() {
912        // default behavior: keep size
913        // (overload to implement dynamic sizing; also set static_prop!)
914        e4_assert(!(spec.static_prop & PROP_DYNA_RESIZE)); // forgot to overload set_dynamic_size?
915        return false; // = "nothing changed"
916    }
917
918public:
919    const ED4_objspec& spec;           // contains information about Objectproperties
920
921    ED4_manager *parent;                            // Points to parent
922
923
924    ED4_properties   dynamic_prop;                  // contains info about what i am, what i can do, what i should do
925    char            *id;                            // globally unique name in hierarchy
926    ED4_index        index;                         // defines the order of child objects
927    ED4_base        *width_link;                    // concerning the hierarchy
928    ED4_base        *height_link;                   // concerning the hierarchy
929    ED4_extension    extension;                     // contains relative info about graphical properties
930    ED4_update_info  update_info;                   // info about things to be done for the object, i.e. refresh; flag structure
931    struct {
932        unsigned int hidden : 1;                    // flag whether object is hidden or not
933    } flag;
934
935    void draw_bb(int color);
936
937    DECLARE_DUMP_FOR_ROOTCLASS(ED4_base);
938
939    // function for species_pointer
940    //
941    // Notes:
942    //
943    // * design is broken @@@
944    //   - my_species_pointer should be member of those derived classes, where it's used
945    //   - accessor functions should tell what we get (eg. ED4_species_name_terminal::get_name_entry() or similar)
946    //
947    // * current uses of my_species_pointer (grepped for 'set_species_pointer' to detect):
948    //   - ED4_species_manager        [holds pointer to]  species/SAI container
949    //   - ED4_species_name_terminal  [holds pointer to]  the 'name' entry of species/SAI
950    //   - ED4_sequence_info_terminal [holds pointer to]  the displayed sub-entry of the alignment-container of species/SAI (multiple may exist per species)
951    //   - ED4_text_terminal          [holds pointer to]  same as ED4_sequence_info_terminal (Caution: not true for all text terminals!)
952
953    GBDATA *get_species_pointer() const { return my_species_pointer.Get(); }
954    void set_species_pointer(GBDATA *gbd) { my_species_pointer.Set(gbd, this); }
955    bool has_callback() const { return get_species_pointer(); }
956
957    // callbacks
958
959    virtual void changed_by_database();
960    virtual void deleted_from_database();
961
962    // functions concerned with graphic output
963    int adjust_clipping_rectangle();
964    virtual void Show(bool refresh_all, bool is_cleared) = 0;
965
966    virtual bool calc_bounding_box() = 0;
967    void resize_dynamic() {
968        if (set_dynamic_size()) {
969            e4_assert(has_property(PROP_DYNA_RESIZE)); // object dynamically changed size (but isn't allowed to!)
970            request_resize();
971        }
972    }
973
974    ED4_returncode  clear_background(int color=0);
975
976    void set_links(ED4_base *width_ref, ED4_base *height_ref);
977    void set_both_links(ED4_base *ref) { set_links(ref, ref); }
978
979    // functions concerned with special initialization
980    void set_property(ED4_properties prop) { dynamic_prop = (ED4_properties) (dynamic_prop | prop); }
981    void clr_property(ED4_properties prop) { dynamic_prop = (ED4_properties) (dynamic_prop & ~prop); }
982    bool has_property(ED4_properties prop) const { return dynamic_prop & prop; }
983
984    // functions concerned with coordinate transformation
985
986    void calc_rel_coords(AW_pos *x, AW_pos *y);
987
988    void calc_world_coords(AW_pos *x, AW_pos *y) const {
989        update_world_coords_cache();
990        *x = lastPos.xpos();
991        *y = lastPos.ypos();
992    }
993    const AW::Position& calc_world_coords() const {
994        update_world_coords_cache();
995        return lastPos;
996    }
997
998    void update_world_coords_cache() const {
999        bool cache_up_to_date = timestamp == currTimestamp;
1000        if (!cache_up_to_date) {
1001            if (parent) {
1002                ED4_base *pab = (ED4_base*)parent;
1003                lastPos = pab->calc_world_coords();
1004            }
1005            else {
1006                lastPos = AW::Origin;
1007            }
1008            lastPos.move(extension.get_parent_offset());
1009            timestamp = currTimestamp;
1010        }
1011    }
1012
1013    static void touch_world_cache() {
1014        currTimestamp++;
1015    }
1016
1017    AW::Rectangle get_win_area(ED4_window *ed4w) const {
1018        AW::Position pos = ed4w->world_to_win_coords(calc_world_coords());
1019        return AW::Rectangle(pos, extension.get_size()-AW::Vector(1, 1));
1020    }
1021
1022    // functions which refer to the object as a child, i.e. travelling down the hierarchy
1023    virtual void request_refresh(int clear=1) = 0;
1024
1025    inline void request_resize();
1026    void request_resize_of_linked();
1027    void resize_requested_by_link(ED4_base *link);
1028    virtual void resize_requested_children() = 0;
1029
1030    virtual void delete_requested_children() = 0;
1031    virtual void Delete()                    = 0;
1032
1033    inline void set_update();
1034    virtual void update_requested_children() = 0;
1035
1036    virtual ED4_returncode event_sent_by_parent(AW_event *event, AW_window *aww) = 0;
1037
1038    virtual ARB_ERROR route_down_hierarchy(const ED4_route_cb& cb);
1039
1040    int calc_group_depth();
1041
1042    // general purpose functions
1043    virtual ED4_base *search_ID(const char *id) = 0;
1044
1045    void  check_all();
1046    short in_border(AW_pos abs_x, AW_pos abs_y, ED4_movemode mode);
1047    ED4_returncode set_width();
1048
1049
1050    ED4_AREA_LEVEL get_area_level(ED4_multi_species_manager **multi_species_manager=NULp) const; // returns area we belong to and the next multi species manager of the area
1051
1052    inline ED4_manager *get_parent(ED4_level lev) const;
1053    void unlink_from_parent();
1054    bool has_parent(ED4_manager *Parent);
1055    bool is_child_of(ED4_manager *Parent) { return has_parent(Parent); }
1056
1057    virtual char       *resolve_pointer_to_string_copy(int *str_len = NULp) const;
1058    virtual const char *resolve_pointer_to_char_pntr(int *str_len = NULp) const;
1059
1060    ED4_group_manager  *is_in_folded_group() const;
1061    virtual bool is_hidden() const = 0;
1062
1063    char *get_name_of_species();                      // go from terminal to name of species
1064
1065    // functions which refer to the selected object(s), i.e. across the hierarchy
1066
1067    ED4_terminal        *get_next_terminal();
1068    ED4_terminal        *get_prev_terminal();
1069
1070    void generate_configuration_string(GBS_strstruct& buffer);
1071
1072    virtual void remove_callbacks() = 0;
1073
1074    const ED4_terminal *get_consensus_relevant_terminal() const;
1075
1076    ED4_base(const ED4_objspec& spec_, GB_CSTR id, AW_pos width, AW_pos height, ED4_manager *parent);
1077    virtual ~ED4_base();
1078
1079    // use the following functions to test which derived class we have
1080
1081    int is_terminal()               const { e4_assert(knownNonNull(this)); return spec.static_prop & PROP_IS_TERMINAL; }
1082
1083    int is_text_terminal()          const { e4_assert(knownNonNull(this)); return spec.level & (LEV_SPECIES_NAME|LEV_SEQUENCE_INFO|LEV_SEQUENCE_STRING|LEV_PURE_TEXT|LEV_COL_STAT); }
1084
1085    int is_species_name_terminal()  const { e4_assert(knownNonNull(this)); return spec.level & LEV_SPECIES_NAME; }
1086
1087    int is_sequence_info_terminal() const { e4_assert(knownNonNull(this)); return spec.level & LEV_SEQUENCE_INFO; }
1088    int is_sequence_terminal()      const { e4_assert(knownNonNull(this)); return spec.level & LEV_SEQUENCE_STRING; }
1089    int is_orf_terminal()           const { e4_assert(knownNonNull(this)); return spec.level & LEV_ORF; }
1090
1091    int is_pure_text_terminal()     const { e4_assert(knownNonNull(this)); return spec.level & LEV_PURE_TEXT; }
1092    int is_columnStat_terminal()    const { e4_assert(knownNonNull(this)); return spec.level & LEV_COL_STAT; }
1093
1094    int is_bracket_terminal()       const { e4_assert(knownNonNull(this)); return spec.level & LEV_BRACKET; }
1095    int is_spacer_terminal()        const { e4_assert(knownNonNull(this)); return spec.level & LEV_SPACER; }
1096    int is_line_terminal()          const { e4_assert(knownNonNull(this)); return spec.level & LEV_LINE; }
1097
1098    int is_flag_header_terminal()   const { e4_assert(knownNonNull(this)); return spec.level & LEV_FLAG_HEADER; }
1099    int is_flag_terminal()          const { e4_assert(knownNonNull(this)); return spec.level & LEV_FLAG; }
1100
1101    int is_manager()                const { e4_assert(knownNonNull(this)); return spec.static_prop & PROP_IS_MANAGER; }
1102
1103    int is_sequence_manager()       const { e4_assert(knownNonNull(this)); return spec.level & LEV_SEQUENCE; }
1104    int is_multi_name_manager()     const { e4_assert(knownNonNull(this)); return spec.level & LEV_MULTI_NAME; }
1105    int is_name_manager()           const { e4_assert(knownNonNull(this)); return spec.level & LEV_NAME_MANAGER; }
1106    int is_multi_species_manager()  const { e4_assert(knownNonNull(this)); return spec.level & LEV_MULTI_SPECIES; }
1107    int is_multi_sequence_manager() const { e4_assert(knownNonNull(this)); return spec.level & LEV_MULTI_SEQUENCE; }
1108    int is_device_manager()         const { e4_assert(knownNonNull(this)); return spec.level & LEV_DEVICE; }
1109
1110    int is_group_manager()          const { e4_assert(knownNonNull(this)); return spec.level & LEV_GROUP; }
1111    int is_root_group_manager()     const { e4_assert(knownNonNull(this)); return spec.level & LEV_ROOTGROUP; }
1112    int is_abstract_group_manager() const { e4_assert(knownNonNull(this)); return spec.level & (LEV_GROUP|LEV_ROOTGROUP); }
1113
1114    int is_species_manager()        const { e4_assert(knownNonNull(this)); return spec.level & LEV_SPECIES; }
1115    int is_area_manager()           const { e4_assert(knownNonNull(this)); return spec.level & LEV_AREA; }
1116
1117    // use the following functions to cast ED4_base to derived classes:
1118
1119#define E4B_DECL_CASTOP_helper(Class,toName)            \
1120    inline const Class *toName() const;                 \
1121    inline Class *toName();
1122
1123#define E4B_AVOID_CAST__helper(Class,toName,isName)     \
1124    const Class *toName() const;                        \
1125    Class *toName();                                    \
1126    int isName() const;
1127
1128#define E4B_IMPL_CASTOP_helper(Class,toName,isName)                             \
1129    const Class *ED4_base::toName() const {                                     \
1130        e4_assert(isName());                                                    \
1131        return DOWNCAST(const Class*, this);                                    \
1132    }                                                                           \
1133    Class *ED4_base::toName() {                                                 \
1134        return const_cast<Class*>(const_cast<const ED4_base*>(this)->toName()); \
1135    }
1136
1137#define E4B_DECL_CASTOP(name)          E4B_DECL_CASTOP_helper(concat(ED4_,name), concat(to_,name))
1138#define E4B_AVOID_UNNEEDED_CASTS(name) E4B_AVOID_CAST__helper(concat(ED4_,name), concat(to_,name), concat(is_,name))
1139#define E4B_IMPL_CASTOP(name)          E4B_IMPL_CASTOP_helper(concat(ED4_,name), concat(to_,name), concat(is_,name))
1140
1141    E4B_DECL_CASTOP(area_manager);                // to_area_manager
1142    E4B_DECL_CASTOP(abstract_group_manager);      // to_abstract_group_manager
1143    E4B_DECL_CASTOP(bracket_terminal);            // to_bracket_terminal
1144    E4B_DECL_CASTOP(columnStat_terminal);         // to_columnStat_terminal
1145    E4B_DECL_CASTOP(consensus_sequence_terminal); // to_consensus_sequence_terminal
1146    E4B_DECL_CASTOP(device_manager);              // to_device_manager
1147    E4B_DECL_CASTOP(group_manager);               // to_group_manager
1148    E4B_DECL_CASTOP(line_terminal);               // to_line_terminal
1149    E4B_DECL_CASTOP(manager);                     // to_manager
1150    E4B_DECL_CASTOP(multi_name_manager);          // to_multi_name_manager
1151    E4B_DECL_CASTOP(multi_sequence_manager);      // to_multi_sequence_manager
1152    E4B_DECL_CASTOP(multi_species_manager);       // to_multi_species_manager
1153    E4B_DECL_CASTOP(name_manager);                // to_name_manager
1154    E4B_DECL_CASTOP(orf_terminal);                // to_orf_terminal
1155    E4B_DECL_CASTOP(pure_text_terminal);          // to_pure_text_terminal
1156    E4B_DECL_CASTOP(root_group_manager);          // to_root_group_manager
1157    E4B_DECL_CASTOP(sequence_info_terminal);      // to_sequence_info_terminal
1158    E4B_DECL_CASTOP(sequence_manager);            // to_sequence_manager
1159    E4B_DECL_CASTOP(sequence_terminal);           // to_sequence_terminal
1160    E4B_DECL_CASTOP(spacer_terminal);             // to_spacer_terminal
1161    E4B_DECL_CASTOP(species_manager);             // to_species_manager
1162    E4B_DECL_CASTOP(species_name_terminal);       // to_species_name_terminal
1163    E4B_DECL_CASTOP(terminal);                    // to_terminal
1164    E4B_DECL_CASTOP(text_terminal);               // to_text_terminal
1165    E4B_DECL_CASTOP(flag_header_terminal);        // to_flag_header_terminal
1166    E4B_DECL_CASTOP(flag_terminal);               // to_flag_terminal
1167
1168    // simple access to containing managers
1169    inline ED4_species_manager *containing_species_manager() const;
1170
1171    // discriminate between different sequence managers:
1172
1173    inline bool is_consensus_manager() const;
1174    inline bool is_SAI_manager() const;
1175    inline bool is_species_seq_manager() const;
1176
1177    inline ED4_species_type get_species_type() const; // works for all items (recursively) contained in ED4_species_manager
1178
1179    inline bool inside_consensus_manager() const;
1180    inline bool inside_SAI_manager() const;
1181    inline bool inside_species_seq_manager() const;
1182
1183    inline bool is_consensus_terminal() const;
1184    inline bool is_SAI_terminal() const;
1185    inline bool is_species_seq_terminal() const;
1186
1187    inline bool is_consensus_sequence_terminal() const { // alias for CASTOP
1188        return is_consensus_terminal();
1189    }
1190};
1191MARK_NONFINAL_FUNCTION(ED4_base,bool,set_dynamic_size,(),false);
1192
1193DECLARE_CBTYPE_FVV_AND_BUILDERS(ED4_basePredicate, bool, ED4_base*); // generates makeED4_basePredicate
1194
1195class ED4_manager : public ED4_base, public ED4_container { // derived from a Noncopyable
1196    ED4_cb_list<ED4_manager, ED4_managerCallback> delete_cbs;
1197public:
1198
1199    E4B_AVOID_UNNEEDED_CASTS(manager);
1200    DECLARE_DUMP_FOR_BASECLASS(ED4_manager, ED4_base);
1201
1202    void add_delete_callback(const ED4_managerCallback& cb) { delete_cbs.add_cb(cb); }
1203    void remove_delete_callback(const ED4_managerCallback& cb) { delete_cbs.remove_cb(cb); }
1204
1205    int refresh_flag_ok();
1206
1207    void changed_by_database() OVERRIDE;
1208    void deleted_from_database() OVERRIDE;
1209
1210    // functions concerned with graphics
1211    void Show(bool refresh_all, bool is_cleared) OVERRIDE;
1212    bool calc_bounding_box() FINAL_OVERRIDE;
1213
1214    ED4_returncode distribute_children();
1215
1216    // top-down functions, means travelling down the hierarchy
1217    ED4_returncode event_sent_by_parent(AW_event *event, AW_window *aww) FINAL_OVERRIDE;
1218
1219    void request_refresh(int clear=1) FINAL_OVERRIDE;
1220    ED4_returncode clear_refresh();
1221
1222    void resize_requested_children() OVERRIDE;
1223
1224    void update_requested_children() OVERRIDE;
1225
1226    void delete_requested_children() OVERRIDE;
1227    void Delete() FINAL_OVERRIDE;
1228
1229    ED4_returncode  move_requested_by_parent(ED4_move_info *mi);
1230
1231    void create_consensus(ED4_abstract_group_manager *upper_group_manager, arb_progress *progress);
1232
1233    ARB_ERROR route_down_hierarchy(const ED4_route_cb& cb) FINAL_OVERRIDE;
1234
1235    ED4_base *find_first_that(ED4_level level, const ED4_basePredicate& fulfills_predicate);
1236
1237     // bottom-up functions
1238    ED4_returncode  move_requested_by_child(ED4_move_info *moveinfo);
1239    inline void resize_requested_by_child();
1240    ED4_returncode  refresh_requested_by_child();
1241    void delete_requested_by_child();
1242    void update_requested_by_child();
1243
1244    ED4_base *get_defined_level(ED4_level lev) const;
1245
1246    // functions referring the consensus
1247
1248    void update_consensus(ED4_manager *old_parent, ED4_manager *new_parent, ED4_base *sequence);
1249    ED4_returncode rebuild_consensi(ED4_base *start_species, ED4_update_flag update_flag);
1250
1251    ED4_returncode  check_in_bases(ED4_base *added_base);
1252    ED4_returncode  check_out_bases(ED4_base *subbed_base);
1253
1254    ED4_returncode  update_bases(const ED4_base *old_base, const ED4_base *new_base, PosRange range = PosRange::whole());
1255    ED4_returncode  update_bases(const char *old_seq, int old_len, const char *new_seq, int new_len, PosRange range = PosRange::whole());
1256    ED4_returncode  update_bases(const char *old_seq, int old_len, const ED4_base *new_base, PosRange range = PosRange::whole());
1257    ED4_returncode  update_bases(const BaseFrequencies *old_table, const BaseFrequencies *new_table, PosRange range = PosRange::whole());
1258
1259    ED4_returncode  update_bases_and_rebuild_consensi(const char *old_seq, int old_len, ED4_base *species, ED4_update_flag update_flag, PosRange range = PosRange::whole());
1260
1261    // handle moves across the hierarchy
1262    ED4_returncode  handle_move(ED4_move_info *moveinfo);
1263
1264    ED4_base *get_competent_child(AW_pos x, AW_pos y, ED4_properties relevant_prop);
1265    ED4_base *get_competent_clicked_child(AW_pos x, AW_pos y, ED4_properties relevant_prop);
1266    ED4_base *search_spec_child_rek(ED4_level level); // recursive search for level
1267
1268    // general purpose functions
1269    ED4_base        *search_ID(const char *id) FINAL_OVERRIDE;
1270    void  remove_callbacks() OVERRIDE;
1271
1272    ED4_terminal *get_first_terminal(int start_index=0) const;
1273    ED4_terminal *get_last_terminal(int start_index=-1) const;
1274
1275    void hide_children();
1276    void unhide_children();
1277
1278    bool is_hidden() const FINAL_OVERRIDE {
1279        if (flag.hidden) return true;
1280        if (!parent) return false;
1281        return parent->is_hidden();
1282    }
1283
1284    ED4_manager(const ED4_objspec& spec_, const char *id, AW_pos width, AW_pos height, ED4_manager *parent);
1285    ~ED4_manager() OVERRIDE;
1286};
1287MARK_NONFINAL_METHOD(ED4_manager,update_requested_children,());
1288MARK_NONFINAL_METHOD(ED4_manager,delete_requested_children,());
1289
1290class ED4_terminal : public ED4_base { // derived from a Noncopyable
1291    E4B_AVOID_UNNEEDED_CASTS(terminal);
1292
1293public:
1294
1295    struct { unsigned int deleted : 1; } tflag; // @@@ go bool
1296
1297    long curr_timestamp;
1298
1299    DECLARE_DUMP_FOR_BASECLASS(ED4_terminal,ED4_base);
1300
1301    // callbacks
1302
1303    void changed_by_database() OVERRIDE;
1304    void deleted_from_database() OVERRIDE;
1305
1306    // functions concerning graphic output
1307    void Show(bool refresh_all, bool is_cleared) OVERRIDE;
1308    virtual void draw() = 0;
1309
1310    bool calc_bounding_box() FINAL_OVERRIDE;
1311
1312    ED4_returncode draw_drag_box(AW_pos x, AW_pos y, GB_CSTR text = NULp, int cursor_y=-1);
1313
1314    // functions which concern the object as a child
1315    void request_refresh(int clear=1) FINAL_OVERRIDE;
1316
1317    void resize_requested_children() OVERRIDE;
1318
1319    void update_requested_children() OVERRIDE;
1320    void delete_requested_children() OVERRIDE;
1321    void Delete() OVERRIDE;
1322
1323    ED4_returncode event_sent_by_parent(AW_event *event, AW_window *aww) OVERRIDE;
1324
1325    ED4_returncode kill_object();
1326
1327    // general purpose functions
1328    ED4_base *search_ID(const char *id) OVERRIDE;
1329    char          *resolve_pointer_to_string_copy(int *str_len = NULp) const FINAL_OVERRIDE;
1330    const char    *resolve_pointer_to_char_pntr(int *str_len = NULp) const FINAL_OVERRIDE;
1331    void remove_callbacks() FINAL_OVERRIDE;
1332
1333    GB_ERROR write_sequence(const char *seq, int seq_len);
1334
1335    void scroll_into_view(ED4_window *ed4w);
1336    inline bool setCursorTo(ED4_cursor *cursor, int seq_pos, bool unfoldGroups, ED4_CursorJumpType jump_type);
1337
1338    bool is_hidden() const FINAL_OVERRIDE { return parent && parent->is_hidden(); }
1339
1340    ED4_terminal(const ED4_objspec& spec_, GB_CSTR id, AW_pos width, AW_pos height, ED4_manager *parent);
1341    ~ED4_terminal() OVERRIDE;
1342};
1343MARK_NONFINAL_METHOD(ED4_terminal,Show,(bool,bool));
1344
1345enum ED4_species_mode {
1346    ED4_SM_MOVE,
1347    ED4_SM_KILL,
1348    ED4_SM_MARK,
1349    ED4_SM_INFO // same functionality as AWT_MODE_INFO
1350};
1351
1352class ED4_reference_terminals : virtual Noncopyable {
1353    ED4_sequence_info_terminal *ref_sequence_info;
1354    ED4_sequence_terminal      *ref_sequence;
1355    ED4_sequence_info_terminal *ref_column_stat_info;
1356    ED4_columnStat_terminal    *ref_column_stat;
1357
1358    void null() { ref_sequence_info = NULp; ref_sequence = NULp; ref_column_stat = NULp; ref_column_stat_info = NULp; }
1359public:
1360    void clear();
1361    void init(ED4_sequence_info_terminal *, ED4_sequence_terminal *, ED4_sequence_info_terminal *, ED4_columnStat_terminal *);
1362
1363    ED4_sequence_terminal      *sequence()         { return ref_sequence; }
1364    ED4_sequence_info_terminal *sequence_info()    { return ref_sequence_info; }
1365    ED4_columnStat_terminal    *column_stat()      { return ref_column_stat; }
1366    ED4_sequence_info_terminal *column_stat_info() { return ref_column_stat_info; }
1367
1368    ED4_reference_terminals()  { null(); }
1369    ~ED4_reference_terminals() { clear(); }
1370};
1371
1372class ED4_WinContext {
1373    ED4_window *ed4w;
1374    AW_device  *device;
1375
1376    bool is_set() const { return ed4w; }
1377    void init(ED4_window *ew) {
1378        e4_assert(ew);
1379        ed4w   = ew;
1380        device = ed4w->get_device();
1381    }
1382
1383    void warn_missing_context() const;
1384    void expect_context() const { if (!is_set()) warn_missing_context(); }
1385
1386protected:
1387    ED4_WinContext() : ed4w(NULp), device(NULp) {}
1388    static ED4_WinContext current_context;
1389
1390public:
1391    inline ED4_WinContext(AW_window *aww_);
1392    ED4_WinContext(ED4_window *ed4w_) { init(ed4w_); }
1393
1394    AW_device *get_device() const { expect_context(); return device; }
1395    ED4_window *get_ed4w() const { expect_context(); return ed4w; }
1396
1397    static const ED4_WinContext& get_current_context() { return current_context; }
1398    static bool have_context() { return current_context.is_set(); }
1399};
1400
1401// accessors for current context (see also ED4_WinContextFree)
1402inline AW_device *current_device() { return ED4_WinContext::get_current_context().get_device(); }
1403inline ED4_window *current_ed4w() { return ED4_WinContext::get_current_context().get_ed4w(); }
1404inline AW_window *current_aww() { return current_ed4w()->aww; }
1405inline ED4_cursor& current_cursor() { return current_ed4w()->cursor; }
1406
1407enum LoadableSaiState {
1408    LSAI_UNUSED,
1409    LSAI_UPTODATE,
1410    LSAI_OUTDATED,
1411};
1412
1413class ED4_root : virtual Noncopyable {
1414    void ED4_ROOT() const { e4_assert(0); } // avoid ED4_root-members use global ED4_ROOT
1415
1416    void refresh_window_simple(bool redraw);
1417    void handle_update_requests(bool& redraw);
1418
1419    ED4_window           *most_recently_used_window;
1420    ConsensusBuildParams *cons_param;
1421
1422public:
1423    char       *db_name;                            // name of Default Properties database (complete path)
1424    AW_root    *aw_root;                            // Points to 'AW-Window-Controller'
1425    AW_default  props_db;                           // Default Properties database
1426
1427    ED4_window              *first_window;          // Points to List of Main Windows of ED4
1428    ED4_main_manager        *main_manager;          // Points to Main manager of ED4
1429    ED4_area_manager        *middle_area_man;       // Points to middle area
1430    ED4_area_manager        *top_area_man;
1431    ED4_root_group_manager  *root_group_man;
1432    EDB_root_bact           *database;              // Points to Object which controls Data
1433    ED4_selected_list       *selected_objects;
1434    ED4_scroll_links         scroll_links;
1435    bool                     folding_action;        // flag tells whether action was folding action or not
1436    ED4_reference_terminals  ref_terminals;
1437    ED4_species_mode         species_mode;
1438    ED4_scroll_picture       scroll_picture;
1439    BI_ecoli_ref            *ecoli_ref;
1440    char                    *alignment_name;
1441    GB_alignment_type        alignment_type;
1442    ED4_reference           *reference;
1443    ED4_seq_colors          *sequence_colors;
1444    AW_gc_manager           *gc_manager;
1445    ST_ML                   *st_ml;
1446    AW_helix                *helix;
1447    int                      helix_spacing;
1448    long                     helix_add_spacing;
1449    long                     terminal_add_spacing;
1450    char                    *protstruct;            // protein structure summary
1451    long                     protstruct_len;        // protein structure summary
1452    ed_key                  *edk;
1453    ED4_Edit_String         *edit_string;
1454
1455    bool column_stat_activated;
1456    bool column_stat_initialized;
1457    bool visualizeSAI;
1458    bool visualizeSAI_allSpecies;
1459
1460    const ConsensusBuildParams& get_consensus_params();
1461    void reset_consensus_params();
1462
1463    LoadableSaiState loadable_SAIs; // maintain proper refresh of list of loadable SAIs
1464    void loadable_SAIs_may_have_changed() { if (loadable_SAIs == LSAI_UPTODATE) loadable_SAIs = LSAI_OUTDATED; }
1465
1466    int temp_gc;
1467    AW_font_group font_group;
1468
1469    void announce_useraction_in(AW_window *aww);
1470    ED4_window *get_most_recently_used_window() const {
1471        e4_assert(most_recently_used_window);
1472        return most_recently_used_window;
1473    }
1474
1475    inline ED4_device_manager *get_device_manager();
1476
1477    // Initializing functions
1478    ED4_returncode  create_hierarchy(const char *area_string_middle, const char *area_string_top);
1479    ARB_ERROR init_alignment();
1480    void recalc_font_group();
1481
1482    AW_window *create_first_window();
1483    ED4_returncode generate_window(AW_device **device, ED4_window **new_window);
1484    void copy_window_struct(ED4_window *source,   ED4_window *destination);
1485
1486    // functions concerned with global refresh and resize
1487    void resize_all_requesting_childs();
1488
1489    void special_window_refresh(bool handle_updates);
1490    ED4_returncode refresh_all_windows(bool redraw);
1491
1492    void request_refresh_for_all_terminals();
1493    void request_refresh_for_specific_terminals(ED4_level lev);
1494    void request_refresh_for_consensus_terminals();
1495    void request_refresh_for_sequence_terminals();
1496
1497    inline void announce_deletion(ED4_base *object); // before deleting an object, use this to announce
1498
1499     // functions concerned with list of selected objects
1500    ED4_returncode add_to_selected(ED4_species_name_terminal *object);
1501    void remove_from_selected(ED4_species_name_terminal *object);
1502    ED4_returncode deselect_all();
1503
1504    ED4_returncode get_area_rectangle(AW_screen_area *rect, AW_pos x, AW_pos y);
1505
1506    ED4_index pixel2pos(AW_pos click_x);
1507
1508    void remove_all_callbacks();
1509
1510    ED4_root(int *argc, char*** argv);
1511    ~ED4_root();
1512};
1513
1514ED4_WinContext::ED4_WinContext(AW_window *aww_) { init(ED4_ROOT->first_window->get_matching_ed4w(aww_)); }
1515
1516struct ED4_LocalWinContext : private ED4_WinContext {
1517    ED4_LocalWinContext(AW_window *aww) : ED4_WinContext(current_context) { current_context = ED4_WinContext(aww); }
1518    ED4_LocalWinContext(ED4_window *ew) : ED4_WinContext(current_context) { current_context = ED4_WinContext(ew); }
1519    ~ED4_LocalWinContext() { current_context = *this; }
1520};
1521
1522class ED4_MostRecentWinContext : virtual Noncopyable {
1523    ED4_LocalWinContext *most_recent;
1524public:
1525    ED4_MostRecentWinContext() : most_recent(NULp) {
1526        if (!ED4_WinContext::have_context()) {
1527            most_recent = new ED4_LocalWinContext(ED4_ROOT->get_most_recently_used_window());
1528        }
1529    }
1530    ~ED4_MostRecentWinContext() {
1531        delete most_recent;
1532    }
1533};
1534
1535inline void ED4_root::announce_deletion(ED4_base *object) {
1536    if (object->is_terminal()) {
1537        ED4_terminal *term = object->to_terminal();
1538        for (ED4_window *win = first_window; win; win = win->next) {
1539            ED4_LocalWinContext uses(win);
1540            win->announce_deletion(term);
1541        }
1542    }
1543}
1544
1545// ------------------------
1546//      manager classes
1547//
1548// All manager classes only differ in their static properties.
1549// This kind of construction was chosen for using a minimum of RAM
1550
1551class ED4_main_manager FINAL_TYPE : public ED4_manager { // derived from a Noncopyable
1552    // first in hierarchy
1553
1554    E4B_AVOID_UNNEEDED_CASTS(main_manager);
1555
1556    // these terminals are redrawn after refresh (with increase clipping area)
1557    // to revert text from middle area drawn into top area:
1558    ED4_terminal *top_middle_line;
1559    ED4_terminal *top_middle_spacer;
1560
1561public:
1562    ED4_main_manager(const char *id, AW_pos width, AW_pos height, ED4_manager *parent);
1563
1564    void set_top_middle_spacer_terminal(ED4_terminal *top_middle_spacer_) { top_middle_spacer = top_middle_spacer_; }
1565    void set_top_middle_line_terminal(ED4_terminal *top_middle_line_) { top_middle_line = top_middle_line_; }
1566
1567    ED4_terminal *get_top_middle_spacer_terminal() const { return top_middle_spacer; }
1568    ED4_terminal *get_top_middle_line_terminal() const { return top_middle_line; }
1569
1570    DECLARE_DUMP_FOR_LEAFCLASS(ED4_manager);
1571
1572    void Show(bool refresh_all, bool is_cleared) OVERRIDE;
1573    void resize_requested_children() OVERRIDE;
1574
1575    void clear_whole_background();
1576};
1577
1578struct ED4_device_manager : public ED4_manager {
1579    E4B_AVOID_UNNEEDED_CASTS(device_manager);
1580    ED4_device_manager  (const char *id, AW_pos width, AW_pos height, ED4_manager *parent);
1581    DECLARE_DUMP_FOR_LEAFCLASS(ED4_manager);
1582};
1583
1584struct ED4_area_manager : public ED4_manager {
1585    E4B_AVOID_UNNEEDED_CASTS(area_manager);
1586    ED4_area_manager(const char *id, AW_pos width, AW_pos height, ED4_manager *parent);
1587    DECLARE_DUMP_FOR_LEAFCLASS(ED4_manager);
1588
1589    ED4_multi_species_manager *get_multi_species_manager() const {
1590        return get_defined_level(LEV_MULTI_SPECIES)->to_multi_species_manager();
1591    }
1592};
1593
1594class ED4_multi_species_manager : public ED4_manager {
1595    E4B_AVOID_UNNEEDED_CASTS(multi_species_manager);
1596
1597    int species;          // # of species (-1 == unknown)
1598    int selected_species; // # of selected species (-1 == unknown)
1599
1600    void    set_species_counters(int no_of_species, int no_of_selected);
1601#ifdef DEBUG
1602    void    count_species(int *speciesPtr, int *selectedPtr) const;
1603#endif
1604    void    update_species_counters();
1605
1606public:
1607    ED4_multi_species_manager(const char *id, AW_pos width, AW_pos height, ED4_manager *parent);
1608
1609    DECLARE_DUMP_FOR_LEAFCLASS(ED4_manager);
1610
1611    void update_requested_children() OVERRIDE;
1612    void delete_requested_children() OVERRIDE;
1613
1614    int count_visible_children();           // is called by a multi_species_manager
1615
1616    ED4_species_manager       *get_consensus_manager() const;       // returns the consensus-manager or NULp
1617    ED4_species_name_terminal *get_consensus_name_terminal() const; // returns the consensus-name-terminal or NULp
1618
1619    // functions concerned with selection
1620    int get_no_of_selected_species();
1621    int get_no_of_species();
1622
1623    void update_group_id();
1624
1625    void invalidate_species_counters();
1626    int  has_valid_counters() const { return species != -1 && selected_species!=-1; }
1627    bool all_are_selected() const { e4_assert(has_valid_counters()); return species == selected_species; }
1628
1629    void select_all(bool only_species);
1630    void deselect_all_species_and_SAI();
1631    void invert_selection_of_all_species();
1632    void marked_species_select(bool select);
1633    void selected_species_mark(bool mark);
1634
1635    void toggle_selected_species();
1636};
1637
1638class ED4_abstract_group_manager : public ED4_manager {
1639    E4B_AVOID_UNNEEDED_CASTS(abstract_group_manager);
1640protected:
1641    BaseFrequencies my_table; // table concerning Consensusfunction
1642
1643public:
1644    ED4_abstract_group_manager(const ED4_objspec& spec_, const char *id, AW_pos width, AW_pos height, ED4_manager *parent);
1645
1646    DECLARE_DUMP_FOR_BASECLASS(ED4_abstract_group_manager, ED4_manager);
1647
1648    BaseFrequencies&       table()       { return my_table; }
1649    const BaseFrequencies& table() const { return my_table; }
1650
1651    ED4_multi_species_manager *get_multi_species_manager() const {
1652        return get_defined_level(LEV_MULTI_SPECIES)->to_multi_species_manager();
1653    }
1654
1655    char *build_consensus_string(PosRange range) const { return table().build_consensus_string(range, ED4_ROOT->get_consensus_params()); }
1656    char *build_consensus_string(int *cons_length = NULp) const {
1657        if (cons_length) *cons_length = table().size();
1658        return table().build_consensus_string(ED4_ROOT->get_consensus_params());
1659    }
1660};
1661
1662struct ED4_group_manager : public ED4_abstract_group_manager {
1663    E4B_AVOID_UNNEEDED_CASTS(group_manager);
1664    ED4_group_manager(const char *id, AW_pos width, AW_pos height, ED4_manager *parent);
1665    DECLARE_DUMP_FOR_LEAFCLASS(ED4_abstract_group_manager);
1666    void reinit_char_table();
1667
1668    void fold();
1669    void unfold();
1670    void toggle_folding();
1671};
1672
1673enum ED4_remap_mode {
1674    ED4_RM_NONE,                                    // no remapping (normal mode)
1675    ED4_RM_SHOW_ABOVE,                              // Show all positions, where xxx% of all edited sequences have any base
1676    ED4_RM_MAX_ALIGN,                               // ------------------------- any edited sequence has a base
1677    ED4_RM_MAX_EDIT,                                // like ED4_RM_MAX_ALIGN, but bases are pushed OVER remapped gaps (not INTO)
1678    ED4_RM_DYNAMIC_GAPS,                            // gaps shown as spaces (more gaps => more spaces)
1679
1680    ED4_RM_MODES
1681
1682};
1683
1684class ED4_remap : virtual Noncopyable {
1685
1686    ED4_remap_mode mode;
1687    int show_above_percent;     // used only for ED4_RM_SHOW_ABOVE
1688
1689    size_t sequence_table_len;      // allocated size of sequence_to_screen_tab
1690    size_t screen_table_len;        // allocated size of screen_to_sequence_tab
1691
1692    size_t sequence_len;        // size of recently compiled part of sequence_to_screen_tab
1693    size_t screen_len;          // size of recently compiled part of screen_to_sequence_tab
1694
1695    int *screen_to_sequence_tab;
1696    int *sequence_to_screen_tab;    // <0 means position is not mapped (last displayed sequence position); 0 may be mapped or not; see is_shown() below
1697
1698    int changed;            // remap-table changed at last compile
1699    int update_needed;          // remapping should be recompiled
1700
1701    inline void set_sequence_to_screen(int pos, int newVal);
1702
1703public:
1704
1705    ED4_remap();
1706    ~ED4_remap();
1707
1708    int screen_to_sequence(int screen_pos) const;
1709
1710    int sequence_to_screen_PLAIN(int sequence_pos) const {
1711        e4_assert(sequence_pos>=0 && size_t(sequence_pos)<=sequence_len);
1712        return sequence_to_screen_tab[sequence_pos];
1713    }
1714    int shown_sequence_to_screen(int sequence_pos) const {
1715        // as well works for sequence_pos == MAXSEQUENCECHARACTERLENGTH
1716        int screen_pos = sequence_to_screen_PLAIN(sequence_pos);
1717        e4_assert(screen_pos >= 0); // sequence_pos expected to be visible (i.e. not folded away)
1718        return screen_pos;
1719    }
1720
1721    int clipped_sequence_to_screen_PLAIN(int sequence_pos) const;
1722    int sequence_to_screen(int sequence_pos) const;
1723
1724    PosRange sequence_to_screen(PosRange range) const {
1725        e4_assert(!range.is_empty());
1726        return PosRange(sequence_to_screen(range.start()), sequence_to_screen(range.end()));
1727    }
1728    PosRange screen_to_sequence(PosRange range) const {
1729        e4_assert(!range.is_empty());
1730        if (range.is_unlimited()) return PosRange::from(screen_to_sequence(range.start()));
1731        return PosRange(screen_to_sequence(range.start()), screen_to_sequence(range.end()));
1732    }
1733
1734    size_t get_max_screen_pos() const { return screen_len-1; }
1735
1736    void adjacent_screen_positions(int seq_pos, int& screen_pos_left, int& screen_pos_right);
1737
1738    ED4_remap_mode get_mode() const { return mode; }
1739    void set_mode(ED4_remap_mode Mode, int above_percent) {
1740        if (Mode<0 || Mode>=ED4_RM_MODES) {
1741            Mode = ED4_RM_NONE;
1742        }
1743        if (mode!=Mode) {
1744            mode = Mode;
1745            update_needed = 1;
1746        }
1747
1748        if (show_above_percent!=above_percent) {
1749            show_above_percent = above_percent;
1750            if (mode==ED4_RM_SHOW_ABOVE) {
1751                update_needed = 1;
1752            }
1753        }
1754    }
1755
1756    void mark_compile_needed();     // recompile if mode != none
1757    void mark_compile_needed_force();   // always recompile
1758    int compile_needed() const { return update_needed; }
1759
1760    GB_ERROR compile(ED4_root_group_manager *gm);
1761    int was_changed() const { return changed; }     // mapping changed by last compile ?
1762
1763    int is_shown(int seq_pos) const {
1764        int scr_pos = sequence_to_screen_PLAIN(seq_pos);
1765        if (scr_pos<0) return false;
1766        if (scr_pos>0) return true;
1767
1768        int seq_pos2    = screen_to_sequence_tab[0];
1769        return seq_pos == seq_pos2;
1770    }
1771
1772    ExplicitRange clip_screen_range(PosRange screen_range) const { return ExplicitRange(screen_range, screen_len-1); }
1773};
1774
1775class ED4_root_group_manager : public ED4_abstract_group_manager {
1776    E4B_AVOID_UNNEEDED_CASTS(root_group_manager);
1777    ED4_remap my_remap;
1778public:
1779    ED4_root_group_manager(const char *id, AW_pos width, AW_pos height, ED4_manager *parent);
1780
1781    bool update_remap(); // 'true' if mapping has changed
1782
1783    const ED4_remap *remap() const { return &my_remap; }
1784    ED4_remap *remap() { return &my_remap; }
1785
1786    void Show(bool refresh_all, bool is_cleared) OVERRIDE;
1787    void resize_requested_children() OVERRIDE;
1788
1789    DECLARE_DUMP_FOR_LEAFCLASS(ED4_abstract_group_manager);
1790};
1791
1792class ED4_species_manager FINAL_TYPE : public ED4_manager {
1793    E4B_AVOID_UNNEEDED_CASTS(species_manager);
1794
1795    ED4_cb_list<ED4_species_manager, ED4_species_managerCallback> changed_cbs; // called when sequence changes
1796
1797    ED4_species_type type;
1798    bool selected;
1799
1800public:
1801    ED4_species_manager(ED4_species_type type_, const char *id, AW_pos width, AW_pos height, ED4_manager *parent);
1802    ~ED4_species_manager() OVERRIDE;
1803
1804    DECLARE_DUMP_FOR_LEAFCLASS(ED4_manager);
1805
1806    ED4_species_type get_type() const { return type; }
1807
1808    bool is_selected() const { return selected; }
1809    void set_selected(bool select) {
1810        // e4_assert(type != ED4_SP_CONSENSUS); // it's not allowed to select a consensus // @@@ happens atm when moving a group
1811        selected = select;
1812    }
1813
1814    bool setCursorTo(ED4_cursor *cursor, int seq_pos, bool unfold_groups, ED4_CursorJumpType jump_type);
1815
1816    void add_sequence_changed_cb(const ED4_species_managerCallback& cb) { changed_cbs.add_cb(cb); }
1817    void remove_sequence_changed_cb(const ED4_species_managerCallback& cb) { changed_cbs.remove_cb(cb); }
1818    void do_callbacks() { changed_cbs.call(this); }
1819
1820    ED4_species_name_terminal *get_name_terminal() const { return member(0)->to_species_name_terminal(); }
1821};
1822
1823inline ED4_manager *ED4_base::get_parent(ED4_level lev) const {
1824    ED4_manager *temp_parent = parent;
1825    while (temp_parent && !(temp_parent->spec.level & lev)) {
1826        temp_parent = temp_parent->parent;
1827    }
1828    return temp_parent;
1829}
1830
1831
1832inline ED4_species_manager *ED4_base::containing_species_manager() const {
1833    ED4_base *sman = get_parent(LEV_SPECIES);
1834    return sman ? sman->to_species_manager() : NULp;
1835}
1836
1837inline bool ED4_base::is_consensus_manager()    const { return is_species_manager() && to_species_manager()->get_type() == ED4_SP_CONSENSUS; }
1838inline bool ED4_base::is_SAI_manager()          const { return is_species_manager() && to_species_manager()->get_type() == ED4_SP_SAI; }
1839inline bool ED4_base::is_species_seq_manager()  const { return is_species_manager() && to_species_manager()->get_type() == ED4_SP_SPECIES; }
1840
1841inline ED4_species_type ED4_base::get_species_type() const {
1842    ED4_species_manager *sman = containing_species_manager();
1843    return sman ? sman->get_type() : ED4_SP_NONE;
1844}
1845
1846inline bool ED4_base::inside_consensus_manager()   const { return get_species_type() == ED4_SP_CONSENSUS; }
1847inline bool ED4_base::inside_SAI_manager()         const { return get_species_type() == ED4_SP_SAI; }
1848inline bool ED4_base::inside_species_seq_manager() const { return get_species_type() == ED4_SP_SPECIES; }
1849
1850inline bool ED4_base::is_consensus_terminal()   const { return is_sequence_terminal() && inside_consensus_manager(); }
1851inline bool ED4_base::is_SAI_terminal()         const { return is_sequence_terminal() && inside_SAI_manager(); }
1852inline bool ED4_base::is_species_seq_terminal() const { return is_sequence_terminal() && inside_species_seq_manager(); }
1853
1854inline bool ED4_cursor::in_species_seq_terminal() const { return owner_of_cursor && owner_of_cursor->is_species_seq_terminal(); }
1855inline bool ED4_cursor::in_consensus_terminal()   const { return owner_of_cursor && owner_of_cursor->is_consensus_terminal(); }
1856inline bool ED4_cursor::in_SAI_terminal()         const { return owner_of_cursor && owner_of_cursor->is_SAI_terminal(); }
1857
1858
1859struct ED4_multi_sequence_manager : public ED4_manager {
1860    E4B_AVOID_UNNEEDED_CASTS(multi_sequence_manager);
1861    ED4_multi_sequence_manager(const char *id, AW_pos width, AW_pos height, ED4_manager *parent);
1862    DECLARE_DUMP_FOR_LEAFCLASS(ED4_manager);
1863};
1864
1865struct ED4_sequence_manager : public ED4_manager {
1866    E4B_AVOID_UNNEEDED_CASTS(sequence_manager);
1867    ED4_sequence_manager(const char *id, AW_pos width, AW_pos height, ED4_manager *parent);
1868    DECLARE_DUMP_FOR_LEAFCLASS(ED4_manager);
1869};
1870
1871struct ED4_multi_name_manager : public ED4_manager {
1872    E4B_AVOID_UNNEEDED_CASTS(multi_name_manager);
1873    // member of ED4_species_manager (contains ED4_name_manager for name and info)
1874    ED4_multi_name_manager(const char *id, AW_pos width, AW_pos height, ED4_manager *parent);
1875    DECLARE_DUMP_FOR_LEAFCLASS(ED4_manager);
1876};
1877
1878
1879struct ED4_name_manager : public ED4_manager {
1880    E4B_AVOID_UNNEEDED_CASTS(name_manager);
1881    // member of ED4_multi_name_manager (contains speciesname or other info concerning the species)
1882    ED4_name_manager(const char *id, AW_pos width, AW_pos height, ED4_manager *parent);
1883    DECLARE_DUMP_FOR_LEAFCLASS(ED4_manager);
1884};
1885
1886
1887// -------------------------
1888//      terminal classes
1889
1890
1891struct ED4_tree_terminal FINAL_TYPE : public ED4_terminal {
1892    E4B_AVOID_UNNEEDED_CASTS(tree_terminal);
1893
1894    void draw() OVERRIDE;
1895
1896    ED4_tree_terminal(const char *id, AW_pos width, AW_pos height, ED4_manager *parent);
1897
1898    DECLARE_DUMP_FOR_LEAFCLASS(ED4_terminal);
1899};
1900
1901struct ED4_bracket_terminal : public ED4_terminal {
1902    E4B_AVOID_UNNEEDED_CASTS(bracket_terminal);
1903
1904    void draw() OVERRIDE;
1905
1906    void toggle_folding();
1907
1908    ED4_bracket_terminal(const char *id, AW_pos width, AW_pos height, ED4_manager *parent);
1909
1910    DECLARE_DUMP_FOR_LEAFCLASS(ED4_terminal);
1911};
1912
1913struct ED4_text_terminal : public ED4_terminal {
1914    E4B_AVOID_UNNEEDED_CASTS(text_terminal);
1915
1916    // functions concerning graphic output
1917    void draw() OVERRIDE;
1918
1919    virtual int get_length() const = 0;
1920    void deleted_from_database() OVERRIDE;
1921
1922    ED4_text_terminal(const ED4_objspec& spec_, GB_CSTR id, AW_pos width, AW_pos height, ED4_manager *parent);
1923    ~ED4_text_terminal() OVERRIDE {}
1924
1925    DECLARE_DUMP_FOR_BASECLASS(ED4_text_terminal, ED4_terminal);
1926};
1927
1928class ED4_abstract_sequence_terminal : public ED4_text_terminal { // derived from a Noncopyable
1929
1930    PosRange pixel2index(PosRange pixel_range);
1931
1932    E4B_AVOID_UNNEEDED_CASTS(abstract_sequence_terminal);
1933public:
1934    char *species_name; // @@@ wrong place (may be member of ED4_sequence_manager)
1935
1936
1937    ED4_abstract_sequence_terminal(const ED4_objspec& spec_, const char *id, AW_pos width, AW_pos height, ED4_manager *parent);
1938    ~ED4_abstract_sequence_terminal() OVERRIDE;
1939
1940    virtual GB_alignment_type GetAliType() = 0;
1941    int get_length() const OVERRIDE { int len; resolve_pointer_to_char_pntr(&len); return len; }
1942
1943    ED4_species_name_terminal *corresponding_species_name_terminal() const {
1944        return get_parent(LEV_SPECIES)->search_spec_child_rek(LEV_SPECIES_NAME)->to_species_name_terminal();
1945    }
1946    PosRange calc_interval_displayed_in_rectangle(AW_screen_area *area_rect);
1947    PosRange calc_update_interval();
1948
1949    DECLARE_DUMP_FOR_BASECLASS(ED4_abstract_sequence_terminal, ED4_text_terminal);
1950};
1951
1952class ED4_orf_terminal : public ED4_abstract_sequence_terminal { // derived from a Noncopyable
1953    // NOTE: ED4_orf_terminal is a separate terminal class used to display Open Reading Frames (ORFs)
1954    //       for the corresponding gene (DNA) sequence. It is used in ProteinViewer Module and should not be
1955    //       used for drawing aminoacid sequence alone as in protein alignment. Aminoacid sequences are
1956    //       handled by the standard "ED4_sequence_terminal" class.
1957
1958    char *aaSequence;
1959    size_t aaSeqLen;
1960    char *aaColor;
1961    int   aaStartPos;
1962    int   aaStrandType;
1963
1964    void draw() OVERRIDE;
1965    E4B_AVOID_UNNEEDED_CASTS(orf_terminal);
1966public:
1967    ED4_orf_terminal(const char *id, AW_pos width, AW_pos height, ED4_manager *parent);
1968    ~ED4_orf_terminal() OVERRIDE;
1969
1970    GB_alignment_type GetAliType() OVERRIDE { return GB_AT_AA; }
1971
1972    void SET_aaSeqFlags (int startPos, int strandType) { aaStartPos = startPos; aaStrandType = strandType; }
1973    void SET_aaSequence(const char *aaSeq) { freedup(aaSequence, aaSeq); aaSeqLen = strlen(aaSequence); }
1974    void SET_aaColor(const char *aaSeq) { freedup(aaColor, aaSeq); }
1975
1976    int GET_aaStartPos () { return aaStartPos; }
1977    int GET_aaStrandType () { return aaStrandType; }
1978
1979    DECLARE_DUMP_FOR_LEAFCLASS(ED4_abstract_sequence_terminal);
1980};
1981
1982class ED4_sequence_terminal : public ED4_abstract_sequence_terminal { // derived from a Noncopyable
1983    mutable ED4_SearchResults searchResults;
1984    bool shall_display_secstruct_info; // helix or protstruct
1985
1986    void draw() OVERRIDE;
1987
1988    E4B_AVOID_UNNEEDED_CASTS(sequence_terminal);
1989
1990public:
1991
1992    AP_tree *st_ml_node;
1993
1994    ED4_sequence_terminal(const char *id, AW_pos width, AW_pos height, ED4_manager *parent, bool shall_display_secstruct_info_);
1995
1996    GB_alignment_type GetAliType() FINAL_OVERRIDE { return ED4_ROOT->alignment_type; }
1997
1998    void deleted_from_database() OVERRIDE;
1999    int get_length() const OVERRIDE { return ED4_abstract_sequence_terminal::get_length(); }
2000
2001    virtual char *get_sequence_copy(int *str_len = NULp) const { return resolve_pointer_to_string_copy(str_len); }
2002
2003    void set_secstruct_display(bool show) { shall_display_secstruct_info = show; }
2004
2005    ED4_SearchResults& results() const { return searchResults; }
2006
2007    ED4_columnStat_terminal *corresponding_columnStat_terminal() const {
2008        ED4_base *col_term = get_parent(LEV_MULTI_SEQUENCE)->search_spec_child_rek(LEV_COL_STAT);
2009        return col_term ? col_term->to_columnStat_terminal() : NULp;
2010    }
2011
2012    DECLARE_DUMP_FOR_MIDCLASS(ED4_sequence_terminal,ED4_abstract_sequence_terminal);
2013    PREPARE_MARK_NONFINAL_CLASS(ED4_sequence_terminal);
2014};
2015MARK_NONFINAL_CLASS(ED4_sequence_terminal);
2016MARK_NONFINAL_FUNCTION(ED4_sequence_terminal,int,get_length,()const,0);
2017MARK_NONFINAL_FUNCTION(ED4_sequence_terminal,char*,get_sequence_copy,(int*)const,NULp);
2018
2019class ED4_columnStat_terminal FINAL_TYPE : public ED4_text_terminal { // derived from a Noncopyable
2020    char *likelihood[4];        // likelihood-array for each base (ACGU) [length of array = alignment_length]
2021    int   latest_update;
2022
2023    static double threshold;
2024
2025    int update_likelihood();
2026
2027    E4B_AVOID_UNNEEDED_CASTS(columnStat_terminal);
2028
2029public:
2030    // functions concerning graphic output
2031    void draw() OVERRIDE;
2032    int get_length() const OVERRIDE { return corresponding_sequence_terminal()->get_length(); }
2033
2034    static int threshold_is_set();
2035    static void set_threshold(double aThreshold);
2036    static double get_threshold() { return threshold; }
2037
2038    ED4_sequence_terminal *corresponding_sequence_terminal() const { return get_parent(LEV_MULTI_SEQUENCE)->search_spec_child_rek(LEV_SEQUENCE_STRING)->to_sequence_terminal(); }
2039
2040    ED4_columnStat_terminal(GB_CSTR id, AW_pos width, AW_pos height, ED4_manager *parent);
2041    ~ED4_columnStat_terminal() OVERRIDE;
2042
2043    DECLARE_DUMP_FOR_LEAFCLASS(ED4_text_terminal);
2044};
2045
2046class ED4_species_name_terminal FINAL_TYPE : public ED4_text_terminal { // derived from a Noncopyable
2047    E4B_AVOID_UNNEEDED_CASTS(species_name_terminal);
2048    bool set_dynamic_size() OVERRIDE;
2049
2050public:
2051    ED4_species_name_terminal(GB_CSTR id, AW_pos width, AW_pos height, ED4_manager *parent);
2052    ~ED4_species_name_terminal() OVERRIDE { delete selection_info; }
2053
2054
2055    ED4_selection_entry *selection_info;            // Info about i.e. Position
2056    bool dragged;
2057
2058    GB_CSTR get_displayed_text() const;
2059    int get_length() const OVERRIDE { return strlen(get_displayed_text()); }
2060
2061    ED4_sequence_terminal *corresponding_sequence_terminal() const {
2062        ED4_base *seq_term = get_parent(LEV_SPECIES)->search_spec_child_rek(LEV_SEQUENCE_STRING);
2063        return seq_term ? seq_term->to_sequence_terminal() : NULp;
2064    }
2065
2066    DECLARE_DUMP_FOR_LEAFCLASS(ED4_text_terminal);
2067};
2068
2069class ED4_flag_header_terminal FINAL_TYPE : public ED4_text_terminal { // derived from a Noncopyable
2070    // displays header of flags
2071
2072    E4B_AVOID_UNNEEDED_CASTS(flag_header_terminal);
2073    bool set_dynamic_size() OVERRIDE;
2074
2075public:
2076    ED4_flag_header_terminal(GB_CSTR id, AW_pos width, AW_pos height, ED4_manager *parent);
2077
2078    GB_CSTR get_displayed_text() const;
2079    int get_length() const OVERRIDE;
2080
2081    DECLARE_DUMP_FOR_LEAFCLASS(ED4_text_terminal);
2082};
2083
2084class ED4_sequence_info_terminal FINAL_TYPE : public ED4_text_terminal {
2085    E4B_AVOID_UNNEEDED_CASTS(sequence_info_terminal);
2086    bool set_dynamic_size() OVERRIDE;
2087
2088public:
2089    ED4_sequence_info_terminal(const char *id, AW_pos width, AW_pos height, ED4_manager *parent);
2090
2091    ED4_species_name_terminal *corresponding_species_name_terminal() const {
2092        return get_parent(LEV_SPECIES)->search_spec_child_rek(LEV_SPECIES_NAME)->to_species_name_terminal();
2093    }
2094
2095    void draw() OVERRIDE;
2096
2097    GBDATA *data() { return get_species_pointer(); } // DB-entry ("ali_xxx/data")
2098    const GBDATA *data() const { return get_species_pointer(); }
2099
2100    int get_length() const OVERRIDE { return 1+strlen(id); }
2101
2102    DECLARE_DUMP_FOR_LEAFCLASS(ED4_text_terminal);
2103};
2104
2105struct ED4_pure_text_terminal FINAL_TYPE : public ED4_text_terminal {
2106    E4B_AVOID_UNNEEDED_CASTS(pure_text_terminal);
2107
2108    ED4_pure_text_terminal(const char *id, AW_pos width, AW_pos height, ED4_manager *parent);
2109
2110    int get_length() const OVERRIDE { int len; resolve_pointer_to_char_pntr(&len); return len; }
2111
2112    DECLARE_DUMP_FOR_LEAFCLASS(ED4_text_terminal);
2113};
2114
2115class ED4_consensus_sequence_terminal : public ED4_sequence_terminal { // derived from a Noncopyable
2116    E4B_AVOID_UNNEEDED_CASTS(consensus_sequence_terminal);
2117
2118    void draw() OVERRIDE;
2119    const ED4_abstract_group_manager *get_group_manager() const  { return get_parent(LEV_GROUP)->to_group_manager(); }
2120    const BaseFrequencies& get_char_table() const { return get_group_manager()->table(); }
2121
2122public:
2123    char *temp_cons_seq; // used for editing consensus (normally NULp)
2124
2125    ED4_consensus_sequence_terminal(const char *id, AW_pos width, AW_pos height, ED4_manager *parent);
2126#if defined(ASSERTION_USED)
2127    virtual ~ED4_consensus_sequence_terminal() { e4_assert(!temp_cons_seq); }
2128#endif
2129
2130    int get_length() const OVERRIDE;
2131    char *get_sequence_copy(int *str_len = NULp) const FINAL_OVERRIDE { return get_group_manager()->build_consensus_string(str_len); }
2132
2133    DECLARE_DUMP_FOR_LEAFCLASS(ED4_sequence_terminal);
2134};
2135
2136class ED4_spacer_terminal FINAL_TYPE : public ED4_terminal {
2137    E4B_AVOID_UNNEEDED_CASTS(spacer_terminal);
2138    bool shallDraw; // true -> spacer is really drawn (otherwise it's only a placeholder)
2139
2140    bool set_dynamic_size() OVERRIDE;
2141
2142public:
2143    void Show(bool refresh_all, bool is_cleared) OVERRIDE;
2144    void draw() OVERRIDE;
2145
2146    ED4_spacer_terminal(const char *id, bool shallDraw_, AW_pos width, AW_pos height, ED4_manager *parent);
2147
2148    DECLARE_DUMP_FOR_LEAFCLASS(ED4_terminal);
2149};
2150
2151class ED4_line_terminal : public ED4_terminal {
2152    E4B_AVOID_UNNEEDED_CASTS(line_terminal);
2153    bool set_dynamic_size() OVERRIDE;
2154
2155public:
2156    void draw() OVERRIDE;
2157
2158    ED4_line_terminal(const char *id, AW_pos width, AW_pos height, ED4_manager *parent);
2159
2160    DECLARE_DUMP_FOR_LEAFCLASS(ED4_terminal);
2161};
2162
2163class ED4_flag_terminal FINAL_TYPE : public ED4_terminal {
2164    E4B_AVOID_UNNEEDED_CASTS(flag_terminal);
2165    bool set_dynamic_size() OVERRIDE;
2166
2167public:
2168    void draw() OVERRIDE;
2169
2170    ED4_flag_terminal(const char *id, AW_pos width, AW_pos height, ED4_manager *parent);
2171
2172    GBDATA *get_species() const { return get_parent(LEV_SPECIES)->get_species_pointer(); }
2173    void handle_left_click(const AW::Position& click);
2174
2175    DECLARE_DUMP_FOR_LEAFCLASS(ED4_terminal);
2176};
2177
2178
2179// ----------------------------------------------
2180//      inlines which need complete classdefs
2181
2182inline void ED4_base::set_update() { // @@@ rename into request_update
2183    if (!update_info.update_requested) {
2184        update_info.update_requested = 1;
2185        if (parent) parent->update_requested_by_child();
2186    }
2187}
2188
2189inline void ED4_base::request_resize() {
2190    update_info.set_resize(1);
2191    if (parent) parent->resize_requested_by_child();
2192}
2193
2194void ED4_manager::resize_requested_by_child() {
2195    if (!update_info.resize) request_resize();
2196}
2197
2198inline bool ED4_terminal::setCursorTo(ED4_cursor *cursor, int seq_pos, bool unfoldGroups, ED4_CursorJumpType jump_type) {
2199    ED4_species_manager *sm = get_parent(LEV_SPECIES)->to_species_manager();
2200    return sm->setCursorTo(cursor, seq_pos, unfoldGroups, jump_type);
2201}
2202
2203E4B_IMPL_CASTOP(area_manager);                // to_area_manager
2204E4B_IMPL_CASTOP(abstract_group_manager);      // to_abstract_group_manager
2205E4B_IMPL_CASTOP(bracket_terminal);            // to_bracket_terminal
2206E4B_IMPL_CASTOP(columnStat_terminal);         // to_columnStat_terminal
2207E4B_IMPL_CASTOP(consensus_sequence_terminal); // to_consensus_sequence_terminal
2208E4B_IMPL_CASTOP(device_manager);              // to_device_manager
2209E4B_IMPL_CASTOP(group_manager);               // to_group_manager
2210E4B_IMPL_CASTOP(line_terminal);               // to_line_terminal
2211E4B_IMPL_CASTOP(manager);                     // to_manager
2212E4B_IMPL_CASTOP(multi_name_manager);          // to_multi_name_manager
2213E4B_IMPL_CASTOP(multi_sequence_manager);      // to_multi_sequence_manager
2214E4B_IMPL_CASTOP(multi_species_manager);       // to_multi_species_manager
2215E4B_IMPL_CASTOP(name_manager);                // to_name_manager
2216E4B_IMPL_CASTOP(orf_terminal);                // to_orf_terminal
2217E4B_IMPL_CASTOP(pure_text_terminal);          // to_pure_text_terminal
2218E4B_IMPL_CASTOP(root_group_manager);          // to_root_group_manager
2219E4B_IMPL_CASTOP(sequence_info_terminal);      // to_sequence_info_terminal
2220E4B_IMPL_CASTOP(sequence_manager);            // to_sequence_manager
2221E4B_IMPL_CASTOP(sequence_terminal);           // to_sequence_terminal
2222E4B_IMPL_CASTOP(spacer_terminal);             // to_spacer_terminal
2223E4B_IMPL_CASTOP(species_manager);             // to_species_manager
2224E4B_IMPL_CASTOP(species_name_terminal);       // to_species_name_terminal
2225E4B_IMPL_CASTOP(terminal);                    // to_terminal
2226E4B_IMPL_CASTOP(text_terminal);               // to_text_terminal
2227E4B_IMPL_CASTOP(flag_header_terminal);        // to_flag_header_terminal
2228E4B_IMPL_CASTOP(flag_terminal);               // to_flag_terminal
2229
2230inline ED4_device_manager *ED4_root::get_device_manager() {
2231    return main_manager->search_spec_child_rek(LEV_DEVICE)->to_device_manager();
2232}
2233
2234
2235inline ED4_species_name_terminal *ED4_multi_species_manager::get_consensus_name_terminal() const {
2236    ED4_species_manager *consensus_man = get_consensus_manager();
2237    return consensus_man ? consensus_man->get_name_terminal() : NULp;
2238}
2239
2240// ----------------------------------------
2241
2242enum SpeciesCreationMode {
2243    CREATE_NEW_SPECIES,
2244    CREATE_FROM_CONSENSUS, // create new species from group consensus (of surrounding group)
2245    COPY_SPECIES,          // copy current species
2246};
2247
2248#if defined(ASSERTION_USED)
2249CONSTEXPR_INLINE bool valid(SpeciesCreationMode m) { return m>=CREATE_NEW_SPECIES && m<=COPY_SPECIES; }
2250#endif
2251
2252extern ST_ML *st_ml;
2253struct AlignDataAccess;
2254
2255// -------------------------------------------------
2256//      factory functions (hierarchy builders):
2257
2258ED4_group_manager *ED4_build_group_manager_start(ED4_manager                 *group_parent,
2259                                                 GB_CSTR                      group_name,
2260                                                 int                          group_depth,
2261                                                 bool                         is_folded,
2262                                                 ED4_reference_terminals&     refterms,
2263                                                 ED4_multi_species_manager*&  multi_species_manager);
2264
2265void ED4_build_group_manager_end(ED4_multi_species_manager *multi_species_manager);
2266
2267// -------------------------------------
2268//      hierarchy access functions:
2269
2270ED4_species_name_terminal *ED4_find_species_name_terminal(const char *species_name);
2271ED4_species_name_terminal *ED4_find_SAI_name_terminal(const char *sai_name);
2272ED4_species_name_terminal *ED4_find_species_or_SAI_name_terminal(const char *species_name);
2273
2274ED4_multi_species_manager *ED4_find_MoreSequences_manager();
2275
2276// --------------------------
2277//      other functions:
2278
2279void ED4_new_editor_window(AW_window *aww);
2280void ED4_with_all_edit_windows(void (*cb)(ED4_window *));
2281
2282void ED4_resize_all_extensions();
2283void ED4_calc_terminal_extentions();
2284
2285void ED4_input_cb(AW_window *aww);
2286void ED4_remote_event(AW_event *faked_event);
2287void ED4_motion_cb(AW_window *aww);
2288void ED4_vertical_change_cb(AW_window *aww);
2289void ED4_horizontal_change_cb(AW_window *aww);
2290void ED4_scrollbar_change_cb(AW_window *aww);
2291void ED4_trigger_instant_refresh();
2292void ED4_request_relayout();
2293void ED4_request_full_refresh();
2294void ED4_request_full_instant_refresh();
2295
2296void ED4_store_curpos(AW_window *aww);
2297void ED4_restore_curpos(AW_window *aww);
2298void ED4_clear_stored_curpos();
2299void ED4_helix_jump_opposite(AW_window *aww);
2300void ED4_jump_to_cursor_position(AW_window *aww, const char *awar_name, PositionType posType);
2301void ED4_remote_set_cursor_cb(AW_root *awr);
2302void ED4_change_cursor(AW_window *aww);
2303
2304void ED4_set_iupac(AW_window *aww, const char *awar_name);
2305void ED4_set_helixnr(AW_window *aww, const char *awar_name);
2306void ed4_changesecurity(AW_root *root);
2307void ed4_change_edit_mode(AW_root *root);
2308
2309void ED4_jump_to_current_species(AW_window *);
2310void ED4_get_and_jump_to_current(AW_window *);
2311void ED4_get_and_jump_to_species(GB_CSTR species_name);
2312
2313void ED4_get_marked_from_menu(AW_window *);
2314void ED4_selected_species_changed_cb(AW_root *aw_root);
2315
2316AW_window *ED4_create_loadSAI_window(AW_root *awr);
2317void       ED4_get_and_jump_to_selected_SAI(AW_window *aww);
2318void       ED4_selected_SAI_changed_cb(AW_root *aw_root);
2319
2320void ED4_init_notFoundMessage();
2321void ED4_finish_and_show_notFoundMessage();
2322
2323const AlignDataAccess *ED4_get_aligner_data_access();
2324
2325void ED4_popup_gc_window(AW_window *awp, AW_gc_manager *gcman);
2326void ED4_no_dangerous_modes();
2327
2328void       group_species_cb(AW_window *aww, bool use_fields);
2329AW_window *ED4_create_group_species_by_field_window(AW_root *aw_root);
2330
2331AW_window *ED4_create_loadConfiguration_window(AW_root *awr);
2332void       ED4_reloadConfiguration(AW_window *aww);
2333void       ED4_saveConfiguration(AW_window *aww, bool hide_aww);
2334AW_window *ED4_create_saveConfigurationAs_window(AW_root *awr);
2335
2336ARB_ERROR  rebuild_consensus(ED4_base *object);
2337
2338void       ED4_create_consensus_awars(AW_root *aw_root);
2339AW_window *ED4_create_consensus_definition_window(AW_root *root);
2340void       ED4_consensus_definition_changed(AW_root*);
2341void       ED4_consensus_display_changed(AW_root *root);
2342
2343AW_window *ED4_create_editor_options_window(AW_root *root);
2344void       ED4_compression_toggle_changed_cb(AW_root *root, bool hideChanged);
2345void       ED4_compression_changed_cb(AW_root *awr);
2346void       ED4_alignment_length_changed(GBDATA *gb_alignment_len, GB_CB_TYPE gbtype);
2347
2348AW_window *ED4_create_new_seq_window(AW_root *root, SpeciesCreationMode creation_mode);
2349
2350void ED4_quit_editor(AW_window *aww);
2351void ED4_exit() __ATTR__NORETURN;
2352
2353
2354#else
2355#error ed4_class included twice
2356#endif
Note: See TracBrowser for help on using the repository browser.