source: tags/arb-6.0/EDIT4/ed4_class.hxx

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