source: tags/old_import_filter/EDIT4/ED4_terminal.cxx

Last change on this file was 9960, checked in by epruesse, 11 years ago

GTK branch compatability fixes/preparation

  • awar→gb_var becomes private and cannot be accessed
  • GTK may pass on additional events
  • numeric fonts will be removed
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 44.8 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : ED4_terminal.cxx                                  //
4//   Purpose   :                                                   //
5//                                                                 //
6//   Institute of Microbiology (Technical University Munich)       //
7//   http://www.arb-home.de/                                       //
8//                                                                 //
9// =============================================================== //
10
11#include <arbdb.h>
12#include <ed4_extern.hxx>
13#include "ed4_class.hxx"
14#include "ed4_awars.hxx"
15#include "ed4_edit_string.hxx"
16#include "ed4_block.hxx"
17#include "ed4_nds.hxx"
18#include "ed4_ProteinViewer.hxx"
19
20#include <aw_preset.hxx>
21#include <aw_awar.hxx>
22#include <aw_msg.hxx>
23#include <aw_root.hxx>
24#include <aw_question.hxx>
25#include <awt_seq_colors.hxx>
26#include <st_window.hxx>
27
28// -----------------------------------
29//      static terminal properties
30
31static ED4_objspec tree_terminal_spec(
32    ED4_P_IS_TERMINAL,  // static props
33    ED4_L_TREE,         // level
34    ED4_L_NO_LEVEL,     // allowed children level
35    ED4_L_NO_LEVEL,     // handled object
36    ED4_L_NO_LEVEL      // restriction level
37    );
38
39static ED4_objspec bracket_terminal_spec(
40    ED4_P_IS_TERMINAL,  // static props
41    ED4_L_BRACKET,      // level
42    ED4_L_NO_LEVEL,     // allowed children level
43    ED4_L_NO_LEVEL,     // handled object
44    ED4_L_NO_LEVEL      // restriction level
45    );
46
47static ED4_objspec species_name_terminal_spec(
48    ED4_P_IS_TERMINAL,  // static props
49    ED4_L_SPECIES_NAME, // level
50    ED4_L_NO_LEVEL,     // allowed children level
51    ED4_L_SPECIES,      // handled object
52    ED4_L_NO_LEVEL      // restriction level
53    );
54
55static ED4_objspec sequence_info_terminal_spec(
56    ED4_P_IS_TERMINAL,  // static props
57    ED4_L_SEQUENCE_INFO, // level
58    ED4_L_NO_LEVEL,     // allowed children level
59    ED4_L_SEQUENCE,     // handled object
60    ED4_L_NO_LEVEL      // restriction level
61    );
62
63static ED4_objspec sequence_terminal_spec(
64    ED4_P_IS_TERMINAL,     // static props
65    ED4_L_SEQUENCE_STRING, // level
66    ED4_L_NO_LEVEL,        // allowed children level
67    ED4_L_NO_LEVEL,        // handled object
68    ED4_L_NO_LEVEL         // restriction level
69    );
70
71static ED4_objspec orf_terminal_spec(
72    ED4_P_IS_TERMINAL,     // static props
73    ED4_L_ORF,             // level
74    ED4_L_NO_LEVEL,        // allowed children level
75    ED4_L_NO_LEVEL,        // handled object
76    ED4_L_NO_LEVEL         // restriction level
77    );
78
79static ED4_objspec pure_text_terminal_spec(
80    ED4_P_IS_TERMINAL,     // static props
81    ED4_L_PURE_TEXT,       // level
82    ED4_L_NO_LEVEL,        // allowed children level
83    ED4_L_NO_LEVEL,        // handled object
84    ED4_L_NO_LEVEL         // restriction level
85    );
86
87static ED4_objspec spacer_terminal_spec(
88    ED4_P_IS_TERMINAL,     // static props
89    ED4_L_SPACER,          // level
90    ED4_L_NO_LEVEL,        // allowed children level
91    ED4_L_NO_LEVEL,        // handled object
92    ED4_L_NO_LEVEL         // restriction level
93    );
94
95static ED4_objspec line_terminal_spec(
96    ED4_P_IS_TERMINAL,     // static props
97    ED4_L_LINE,            // level
98    ED4_L_NO_LEVEL,        // allowed children level
99    ED4_L_NO_LEVEL,        // handled object
100    ED4_L_NO_LEVEL         // restriction level
101    );
102
103static ED4_objspec column_stat_terminal_spec(
104    ED4_P_IS_TERMINAL,     // static props
105    ED4_L_COL_STAT,        // level
106    ED4_L_NO_LEVEL,        // allowed children level
107    ED4_L_NO_LEVEL,        // handled object
108    ED4_L_NO_LEVEL         // restriction level
109    );
110
111
112char *ED4_terminal::resolve_pointer_to_string_copy(int *str_len) const {
113    int         len;
114    const char *s = resolve_pointer_to_char_pntr(&len);
115    char       *t = GB_strduplen(s, len); // space for zero byte is allocated by GB_strduplen
116
117    if (str_len) *str_len = len;
118    return t;
119}
120
121const char *ED4_terminal::resolve_pointer_to_char_pntr(int *str_len) const
122{
123    GB_TYPES    gb_type;
124    const char *db_pointer = NULL;
125    GBDATA     *gbd        = get_species_pointer();
126
127    if (!gbd) {
128        if (str_len) {
129            if (id) *str_len = strlen(id);
130            else *str_len    = 0;
131        }
132        return id; // if we don't have a link to the database we have to use our id
133    }
134
135    GB_push_transaction(GLOBAL_gb_main);
136
137    const char *copy_of = 0; // if set, return a copy of this string
138
139    gb_type = GB_read_type(gbd);
140#if defined(WARN_TODO)
141#warning temporary workaround - gb_type GB_INT and GB_FLOAT in the switch directive must not be displayed but ignored
142#endif
143    switch (gb_type)
144    {
145        case GB_STRING:
146            db_pointer = GB_read_char_pntr(gbd);
147            if (str_len) {
148                *str_len = GB_read_string_count(gbd);
149                e4_assert(*str_len == (int)strlen(db_pointer));
150            }
151            break;
152        case GB_BITS:
153            db_pointer = GB_read_bits_pntr(gbd, '.', '+');
154            if (str_len) {
155                *str_len = GB_read_bits_count(gbd);
156                e4_assert(*str_len == (int)strlen(db_pointer));
157            }
158            break;
159        case GB_BYTES:
160            db_pointer = GB_read_bytes_pntr(gbd);
161            if (str_len) {
162                *str_len = GB_read_bytes_count(gbd);
163                e4_assert(*str_len == (int)strlen(db_pointer));
164            }
165            break;
166        case GB_DB:
167            copy_of = "GB_DB";
168            break;
169        case GB_INT: // FIXME: temporary Workaround
170            copy_of = "GB_INT";
171            break;
172        case GB_INTS:
173            copy_of = "GB_INTS";
174            break;
175        case GB_FLOAT: // FIXME: temporary Workaround
176            copy_of = "GB_FLOAT";
177            break;
178        case GB_FLOATS:
179            copy_of = "GB_FLOATS";
180            break;
181        default:
182            printf("Unknown data type - Please contact administrator\n");
183            e4_assert(0);
184            break;
185    }
186
187    if (copy_of) {
188        e4_assert(db_pointer == 0);
189
190        int len    = strlen(copy_of);
191        db_pointer = GB_strduplen(copy_of, len);
192
193        if (str_len) *str_len = len;
194    }
195
196    GB_pop_transaction(GLOBAL_gb_main);
197
198    return db_pointer;
199}
200
201GB_ERROR ED4_terminal::write_sequence(const char *seq, int seq_len)
202{
203    GB_ERROR err = 0;
204    GBDATA *gbd = get_species_pointer();
205    e4_assert(gbd); // we must have a link to the database!
206
207    GB_push_transaction(GLOBAL_gb_main);
208
209    int   old_seq_len;
210    char *old_seq = resolve_pointer_to_string_copy(&old_seq_len);
211
212    bool allow_write_data = true;
213    if (ED4_ROOT->aw_root->awar(ED4_AWAR_ANNOUNCE_CHECKSUM_CHANGES)->read_int()) {
214        long old_checksum = GBS_checksum(old_seq, 1, "-.");
215        long new_checksum = GBS_checksum(seq, 1, "-.");
216
217        if (old_checksum != new_checksum) {
218            if (aw_question(NULL, "Checksum changed!", "Allow, Reject") == 1) {
219                allow_write_data = false;
220            }
221
222        }
223    }
224
225    if (allow_write_data) {
226        GB_TYPES gb_type = GB_read_type(gbd);
227        switch (gb_type) {
228            case GB_STRING: {
229                err = GB_write_string(gbd, seq);
230                break;
231            }
232            case GB_BITS: {
233                err = GB_write_bits(gbd, seq, seq_len, ".-");
234                break;
235            }
236            default: {
237                e4_assert(0);
238                break;
239            }
240        }
241    }
242
243    GB_pop_transaction(GLOBAL_gb_main);
244
245    if (!err && dynamic_prop&ED4_P_CONSENSUS_RELEVANT) {
246        if (old_seq) {
247            curr_timestamp = GB_read_clock(GLOBAL_gb_main);
248
249            get_parent(ED4_L_MULTI_SPECIES)->to_multi_species_manager()
250                ->update_bases_and_rebuild_consensi(old_seq, old_seq_len, get_parent(ED4_L_SPECIES)->to_species_manager(), ED4_U_UP); // bases_check
251        }
252        else {
253            aw_message("Couldn't read old sequence data");
254        }
255
256        request_refresh();
257    }
258
259    if (old_seq) free(old_seq);
260
261    return err;
262}
263
264
265ED4_returncode ED4_terminal::remove_callbacks()                     // removes callbacks and gb_alignment
266{
267    if (get_species_pointer()) {
268        set_species_pointer(0);
269        tflag.deleted = 1; // @@@ why ?
270        clr_property(ED4_P_CURSOR_ALLOWED);
271        request_refresh();
272    }
273    return ED4_R_OK;
274}
275
276static ARB_ERROR ed4_remove_species_manager_callbacks(ED4_base *base) { // @@@ unused since [8286]
277    if (base->is_species_manager()) {
278        base->to_species_manager()->remove_all_callbacks();
279    }
280    return NULL;
281}
282
283inline void remove_from_consensus(ED4_manager *group_or_species_man) {
284    GB_transaction ta(GLOBAL_gb_main);
285    ED4_manager *parent_manager = group_or_species_man->parent;
286    parent_manager->update_consensus(parent_manager, NULL, group_or_species_man);
287    parent_manager->rebuild_consensi(parent_manager, ED4_U_UP);
288}
289
290ED4_returncode ED4_terminal::kill_object() {
291    ED4_species_manager *species_manager = get_parent(ED4_L_SPECIES)->to_species_manager();
292
293    if (species_manager->is_consensus_manager()) { // kill whole group
294        if (ED4_new_species_multi_species_manager()==species_manager->parent) {
295            aw_message("This group has to exist - deleting it isn't allowed");
296            return ED4_R_IMPOSSIBLE;
297        }
298
299        ED4_manager *group_manager = species_manager->get_parent(ED4_L_GROUP)->to_group_manager();
300        remove_from_consensus(group_manager);
301        group_manager->Delete();
302    }
303    else { // kill single species/SAI
304        remove_from_consensus(species_manager);
305        species_manager->Delete();
306    }
307
308    return ED4_R_OK;
309}
310
311ED4_base *ED4_terminal::get_competent_clicked_child(AW_pos /* x */, AW_pos /* y */, ED4_properties /* relevant_prop */)
312{
313    e4_assert(0);
314    return NULL;
315}
316
317ED4_returncode   ED4_terminal::handle_move(ED4_move_info * /* moveinfo */)
318{
319    e4_assert(0);
320    return ED4_R_IMPOSSIBLE;
321}
322
323ED4_returncode  ED4_terminal::move_requested_by_child(ED4_move_info * /* moveinfo */)
324{
325    e4_assert(0);
326    return ED4_R_IMPOSSIBLE;
327}
328
329
330ED4_base *ED4_terminal::get_competent_child(AW_pos /* x */, AW_pos /* y */, ED4_properties /* relevant_prop */)
331{
332    e4_assert(0);
333    return NULL;
334}
335
336ED4_returncode ED4_terminal::draw_drag_box(AW_pos x, AW_pos y, GB_CSTR text, int cursor_y) {
337    // draws drag box of object at location abs_x, abs_y
338
339    if (cursor_y!=-1) {
340        ED4_base *drag_target = NULL;
341        {
342            ED4_extension location;
343            location.position[X_POS] = 0;
344            location.position[Y_POS] = (AW_pos)cursor_y;           // cursor_y is already in world coordinates
345
346            ED4_ROOT->get_device_manager()->children->search_target_species(&location, ED4_P_HORIZONTAL, &drag_target, ED4_L_NO_LEVEL);
347        }
348
349        if (drag_target) {
350            AW_pos target_x, target_y;
351
352            drag_target->calc_world_coords (&target_x, &target_y);
353            current_ed4w()->world_to_win_coords(&target_x, &target_y);
354
355#define ARROW_LENGTH 3
356            AW_pos drag_line_x0[3], drag_line_y0[3];
357            AW_pos drag_line_x1[3], drag_line_y1[3];
358
359            drag_line_x0[0] = target_x + 5;                                                 // horizontal
360            drag_line_y0[0] = target_y + drag_target->extension.size[HEIGHT];
361            drag_line_x1[0] = drag_line_x0[0] + 50;
362            drag_line_y1[0] = target_y + drag_target->extension.size[HEIGHT];
363
364            drag_line_x0[1] = drag_line_x0[0] -ARROW_LENGTH;                                // arrow
365            drag_line_y0[1] = drag_line_y0[0] -ARROW_LENGTH;
366            drag_line_x1[1] = drag_line_x0[0];
367            drag_line_y1[1] = drag_line_y0[0];
368
369            drag_line_x0[2] = drag_line_x0[0] -ARROW_LENGTH;                                // arrow
370            drag_line_y0[2] = drag_line_y0[0] + ARROW_LENGTH;
371            drag_line_x1[2] = drag_line_x0[0];
372            drag_line_y1[2] = drag_line_y0[0];
373#undef ARROW_LENGTH
374
375            for (ED4_index i = 0; i <= 2; i++) {
376                current_device()->line(ED4_G_DRAG, drag_line_x0[i], drag_line_y0[i], drag_line_x1[i], drag_line_y1[i], AW_SCREEN);
377            }
378        }
379    }
380
381    if (text != NULL) {
382        current_device()->text(ED4_G_DRAG, text, (x + 20), (y + INFO_TERM_TEXT_YOFFSET), 0, AW_SCREEN);
383    }
384
385    return ED4_R_OK;
386}
387
388ED4_returncode  ED4_terminal::move_requested_by_parent(ED4_move_info *) { // handles a move request coming from parent
389    e4_assert(0);
390    return (ED4_R_IMPOSSIBLE);
391}
392
393void ED4_multi_species_manager::toggle_selected_species() {
394    if (all_are_selected()) deselect_all_species_and_SAI();
395    else select_all(false); // species and SAI
396
397    ED4_correctBlocktypeAfterSelection();
398}
399
400#if defined(DEBUG) && 1
401static inline void dumpEvent(const char *where, AW_event *event) {
402    printf("%s: x=%i y=%i\n", where, event->x, event->y);
403}
404#else
405#define dumpEvent(w, e)
406#endif
407
408ED4_returncode  ED4_terminal::event_sent_by_parent(AW_event *event, AW_window *aww)             // handles an input event coming from parent
409{
410    static ED4_species_name_terminal    *dragged_name_terminal = 0;
411    static int              dragged_was_selected;
412    static bool                 pressed_left_button = 0;
413    static int              other_x, other_y; // coordinates of last event
414    static bool                 right_button_started_on_sequence_term = 0;
415
416    switch (event->type) {
417        case AW_Mouse_Press: {
418            switch (event->button) {
419                case AW_BUTTON_LEFT: {
420                    pressed_left_button = 0;
421                    if (is_species_name_terminal()) {
422                        switch (ED4_ROOT->species_mode) {
423                            case ED4_SM_KILL: {
424                                if (containing_species_manager()->is_selected()) ED4_ROOT->remove_from_selected(this->to_species_name_terminal());
425                                kill_object();
426                                return ED4_R_BREAK;
427                            }
428                            case ED4_SM_MOVE: {
429                                dragged_name_terminal = to_species_name_terminal();
430                                pressed_left_button = 1;
431                                other_x = event->x;
432                                other_y = event->y;
433
434                                if (!containing_species_manager()->is_selected()) {
435                                    ED4_ROOT->add_to_selected(dragged_name_terminal);
436                                    dragged_was_selected = 0;
437                                    ED4_trigger_instant_refresh();
438                                }
439                                else {
440                                    dragged_was_selected = 1;
441                                }
442                                break;
443                            }
444                            case ED4_SM_MARK: {
445                                ED4_species_manager *species_man = get_parent(ED4_L_SPECIES)->to_species_manager();
446                                GBDATA *gbd = species_man->get_species_pointer();
447
448                                if (gbd) {
449                                    GB_write_flag(gbd, !GB_read_flag(gbd));
450                                    request_refresh();
451                                    // ProtView: Refreshing orf terminals
452                                    if (ED4_ROOT->alignment_type ==  GB_AT_DNA) {
453                                        PV_RefreshWindow(aww->get_root());
454                                    }
455                                }
456                                break;
457                            }
458                            default: {
459                                e4_assert(0);
460                                break;
461                            }
462                        }
463                    }
464                    else if (is_bracket_terminal()) { // fold/unfold group
465                        if (dynamic_prop & ED4_P_IS_FOLDED) {
466                            to_bracket_terminal()->unfold();
467                        }
468                        else {
469                            to_bracket_terminal()->fold();
470                        }
471                    }
472                    else {
473                        if (dynamic_prop & ED4_P_CURSOR_ALLOWED) {
474                            ED4_no_dangerous_modes();
475                            current_cursor().show_clicked_cursor(event->x, this);
476                        }
477                    }
478                    break;
479                }
480                case AW_BUTTON_RIGHT: {
481                    right_button_started_on_sequence_term = 0;
482                    if (is_bracket_terminal()) { // right click on bracket terminal
483                        ED4_base *group = get_parent(ED4_L_GROUP);
484                        if (group) {
485                            group->to_group_manager()->get_multi_species_manager()->toggle_selected_species();
486                        }
487                    }
488                    else if (is_species_name_terminal()) {
489                        ED4_species_manager *species_man = get_parent(ED4_L_SPECIES)->to_species_manager();
490
491                        if (species_man->is_consensus_manager()) { // click on consensus-name
492                            ED4_multi_species_manager *multi_man = species_man->get_parent(ED4_L_MULTI_SPECIES)->to_multi_species_manager();
493                            multi_man->toggle_selected_species();
494                        }
495                        else { // click on species or SAI name
496                            if (!species_man->is_selected()) { // select if not selected
497                                if (ED4_ROOT->add_to_selected(this->to_species_name_terminal()) == ED4_R_OK) ED4_correctBlocktypeAfterSelection();
498                            }
499                            else { // deselect if already selected
500                                ED4_ROOT->remove_from_selected(this->to_species_name_terminal());
501                                ED4_correctBlocktypeAfterSelection();
502                            }
503                        }
504                    }
505                    else if (is_sequence_terminal()) {
506                        dumpEvent("Press", event);
507
508                        ED4_no_dangerous_modes();
509                        ED4_setColumnblockCorner(event, to_sequence_terminal()); // mark columnblock
510                        right_button_started_on_sequence_term = 1;
511                    }
512                    break;
513                }
514                default : break;
515            }
516            break;
517        }
518        case AW_Mouse_Drag: {
519            switch (event->button) {
520                case AW_BUTTON_LEFT: {
521                    if (dragged_name_terminal) {
522                        ED4_selection_entry *sel_info = dragged_name_terminal->selection_info;
523
524                        if (pressed_left_button) {
525                            AW_pos world_x, world_y;
526
527                            dragged_name_terminal->calc_world_coords(&world_x, &world_y);
528                            current_ed4w()->world_to_win_coords(&world_x, &world_y);
529
530                            sel_info->drag_old_x = world_x;
531                            sel_info->drag_old_y = world_y;
532                            sel_info->drag_off_x = world_x-other_x;
533                            sel_info->drag_off_y = world_y-other_y;
534                            sel_info->old_event_y = -1;
535
536                            pressed_left_button = 0;
537                        }
538
539                        GB_CSTR text = dragged_name_terminal->get_displayed_text();
540
541                        if (dragged_name_terminal->dragged) {
542                            dragged_name_terminal->draw_drag_box(sel_info->drag_old_x, sel_info->drag_old_y, text, sel_info->old_event_y);
543                        }
544
545                        AW_pos new_x = sel_info->drag_off_x + event->x;
546                        AW_pos new_y = sel_info->drag_off_y + event->y;
547
548                        dragged_name_terminal->draw_drag_box(new_x, new_y, text, event->y); // @@@ event->y ist falsch, falls vertikal gescrollt ist!
549
550                        sel_info->drag_old_x = new_x;
551                        sel_info->drag_old_y = new_y;
552                        sel_info->old_event_y = event->y;
553
554                        dragged_name_terminal->dragged = true;
555                    }
556
557                    break;
558                }
559                case AW_BUTTON_RIGHT: {
560                    if (is_sequence_terminal() && right_button_started_on_sequence_term) {
561                        ED4_no_dangerous_modes();
562                        ED4_setColumnblockCorner(event, to_sequence_terminal()); // mark columnblock
563                    }
564                    break;
565                }
566                default: break; 
567            }
568            break;
569        }
570        case AW_Mouse_Release: {
571            switch (event->button) {
572                case AW_BUTTON_LEFT: {
573                    if (dragged_name_terminal) {
574                        if (dragged_name_terminal->dragged) {
575                            {
576                                char                *db_pointer = dragged_name_terminal->resolve_pointer_to_string_copy();
577                                ED4_selection_entry *sel_info   = dragged_name_terminal->selection_info;
578
579                                dragged_name_terminal->draw_drag_box(sel_info->drag_old_x, sel_info->drag_old_y, db_pointer, sel_info->old_event_y);
580                                dragged_name_terminal->dragged = false;
581
582                                free(db_pointer);
583                            }
584                            {
585                                ED4_move_info mi;
586
587                                mi.object = dragged_name_terminal;
588                                mi.end_x = event->x;
589                                mi.end_y = event->y;
590                                mi.mode = ED4_M_FREE;
591                                mi.preferred_parent = ED4_L_NO_LEVEL;
592
593                                dragged_name_terminal->parent->move_requested_by_child(&mi);
594                            }
595                            {
596                                ED4_device_manager *device_manager = ED4_ROOT->get_device_manager();
597
598                                for (int i=0; i<device_manager->children->members(); i++) { // when moving species numbers have to be recalculated
599                                    ED4_base *member = device_manager->children->member(i);
600
601                                    if (member->is_area_manager()) {
602                                        member->to_area_manager()->get_multi_species_manager()->update_requested_by_child();
603                                    }
604                                }
605                            }
606                        }
607                        if (!dragged_was_selected) {
608                            ED4_ROOT->remove_from_selected(dragged_name_terminal);
609                        }
610
611                        pressed_left_button = 0;
612                        dragged_name_terminal = 0;
613                    }
614                    break;
615                }
616
617                case AW_BUTTON_RIGHT: {
618                    if (right_button_started_on_sequence_term && is_sequence_terminal()) {
619                        dumpEvent("Relea", event);
620                        ED4_no_dangerous_modes();
621                        ED4_setColumnblockCorner(event, to_sequence_terminal()); // mark columnblock
622                    }
623                    break;
624                }
625                default: break; 
626            }
627            break;
628        }
629        default:
630#ifdef ARB_GTK
631            // there can be many other events here...
632#else
633            e4_assert(0);
634#endif
635            break;
636    }
637    return (ED4_R_OK);
638}
639
640void ED4_terminal::update_requested_children() {}
641
642bool ED4_terminal::calc_bounding_box() {
643    // calculates the smallest rectangle containing the object.
644    // requests refresh and returns true if bounding box has changed.
645
646    bool bb_changed = false;
647
648    if (width_link) {
649        if (extension.size[WIDTH] != width_link->extension.size[WIDTH]) {   // all bounding Boxes have the same size !!!
650            extension.size[WIDTH] = width_link->extension.size[WIDTH];
651            bb_changed = true;
652        }
653    }
654
655    if (height_link) {
656        if (extension.size[HEIGHT] != height_link->extension.size[HEIGHT]) {
657            extension.size[HEIGHT] = height_link->extension.size[HEIGHT];
658            bb_changed = true;
659        }
660    }
661
662
663    if (bb_changed) {
664        request_resize_of_linked();
665        request_refresh();
666    }
667    return bb_changed;
668}
669
670void ED4_terminal::resize_requested_children() {
671    if (update_info.resize) { // likes to resize?
672        if (calc_bounding_box()) { 
673            request_resize();
674        }
675    }
676}
677
678
679void ED4_terminal::request_refresh(int clear) {
680    update_info.set_refresh(1);
681    update_info.set_clear_at_refresh(clear);
682    if (parent) parent->refresh_requested_by_child();
683}
684
685
686ED4_base* ED4_terminal::search_ID(const char *temp_id)
687{
688    if (id && strcmp(temp_id, id) == 0) return (this);
689    return (NULL);
690}
691
692ED4_terminal::ED4_terminal(const ED4_objspec& spec_, GB_CSTR temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent) :
693    ED4_base(spec_, temp_id, x, y, width, height, temp_parent)
694{
695    memset((char*)&tflag, 0, sizeof(tflag));
696    curr_timestamp = 0;
697}
698
699
700ED4_terminal::~ED4_terminal() {
701    for (ED4_window *window = ED4_ROOT->first_window; window; window=window->next) {
702        ED4_cursor& cursor = window->cursor;
703        if (this == cursor.owner_of_cursor) {
704            cursor.init();
705        }
706    }
707}
708
709ED4_tree_terminal::ED4_tree_terminal(const char *temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent)
710    : ED4_terminal(tree_terminal_spec, temp_id, x, y, width, height, temp_parent)
711{
712}
713
714ED4_returncode ED4_tree_terminal::Show(int IF_ASSERTION_USED(refresh_all), int is_cleared)
715{
716    e4_assert(update_info.refresh || refresh_all);
717    current_device()->push_clip_scale();
718    if (adjust_clipping_rectangle()) {
719        if (update_info.clear_at_refresh && !is_cleared) {
720            clear_background();
721        }
722        draw();
723    }
724    current_device()->pop_clip_scale();
725
726    return (ED4_R_OK);
727}
728
729
730
731ED4_returncode ED4_tree_terminal::draw() {
732    AW_pos  x, y;
733    AW_pos  text_x, text_y;
734    char   *db_pointer;
735
736    calc_world_coords(&x, &y);
737    current_ed4w()->world_to_win_coords(&x, &y);
738
739    text_x = x + CHARACTEROFFSET;                           // don't change
740    text_y = y + SEQ_TERM_TEXT_YOFFSET;
741
742    db_pointer = resolve_pointer_to_string_copy();
743    current_device()->text(ED4_G_STANDARD, db_pointer, text_x, text_y, 0, AW_SCREEN);
744    free(db_pointer);
745
746    return (ED4_R_OK);
747}
748
749ED4_bracket_terminal::ED4_bracket_terminal(const char *temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent)
750    : ED4_terminal(bracket_terminal_spec, temp_id, x, y, width, height, temp_parent)
751{
752}
753
754ED4_returncode ED4_bracket_terminal::Show(int IF_ASSERTION_USED(refresh_all), int is_cleared)
755{
756    e4_assert(update_info.refresh || refresh_all);
757    current_device()->push_clip_scale();
758    if (adjust_clipping_rectangle()) {
759        if (update_info.clear_at_refresh && !is_cleared) {
760            clear_background();
761        }
762        draw();
763    }
764    current_device()->pop_clip_scale();
765
766    return ED4_R_OK;
767}
768
769
770ED4_returncode ED4_bracket_terminal::draw() {
771    using namespace AW;
772
773    Rectangle  term_area = get_win_area(current_ed4w());
774    AW_device *device    = current_device();
775
776    ED4_multi_species_manager *multi_man = get_parent(ED4_L_GROUP)->to_group_manager()->get_multi_species_manager();
777    if (multi_man->get_no_of_selected_species()) {  // if multi_species_manager contains selected species
778#if defined(DEBUG) && 0
779        static bool toggle = false;
780        toggle             = !toggle;
781        device->box(toggle ? ED4_G_SELECTED : ED4_G_SELECTED+1, true, term_area);
782#else // !defined(DEBUG)
783        device->box(ED4_G_SELECTED, true, term_area);
784#endif
785    }
786
787    if (dynamic_prop & ED4_P_IS_FOLDED) { // paint triangle for folded group
788        Position t = term_area.upper_left_corner()+Vector(4,4);
789        Position b = t+Vector(0,12);
790
791        for (int i = 0; i<6; ++i) {
792            device->line(ED4_G_STANDARD, t, b, AW_SCREEN);
793            t += Vector(1,  1);
794            b += Vector(1, -1);
795        }
796        e4_assert(nearlyEqual(t, b));
797        device->line(ED4_G_STANDARD, t, b, AW_SCREEN); // arrowhead
798    }
799    else {
800        Position l = term_area.upper_left_corner()+Vector(4,5);
801        Position r = l+Vector(6,0);
802
803        for (int i = 0; i<3; ++i) {
804            device->line(ED4_G_STANDARD, l, r, AW_SCREEN);
805            l += Vector( 0, 1);
806            r += Vector( 0, 1);
807            device->line(ED4_G_STANDARD, l, r, AW_SCREEN);
808            l += Vector( 1, 1);
809            r += Vector(-1, 1);
810        }
811        e4_assert(nearlyEqual(l, r));
812        device->line(ED4_G_STANDARD, l, r+Vector(0,1), AW_SCREEN); // arrowhead
813    }
814
815    {
816        Rectangle bracket(term_area.upper_left_corner()+Vector(2,2), term_area.diagonal()+Vector(-2,-4));
817
818        device->line(ED4_G_STANDARD, bracket.upper_edge(), AW_SCREEN);
819        device->line(ED4_G_STANDARD, bracket.lower_edge(), AW_SCREEN);
820        device->line(ED4_G_STANDARD, bracket.left_edge(), AW_SCREEN);
821    }
822
823    return (ED4_R_OK);
824}
825
826ED4_species_name_terminal::ED4_species_name_terminal(GB_CSTR temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent) :
827    ED4_text_terminal(species_name_terminal_spec, temp_id, x, y, width, height, temp_parent),
828    selection_info(NULL),
829    dragged(false)
830{
831}
832
833#define MAXNAMELEN MAXSPECIESWIDTH
834#define BUFFERSIZE (MAXNAMELEN<<1)
835GB_CSTR ED4_species_name_terminal::get_displayed_text() const
836{
837    static char *real_name;
838    static int allocatedSize;
839
840    if (!real_name || allocatedSize<(BUFFERSIZE+1)) {
841        free(real_name);
842        allocatedSize = BUFFERSIZE+1;
843        real_name = (char*)malloc(allocatedSize);
844    }
845    memset(real_name, 0, allocatedSize);
846
847    ED4_species_manager *spec_man = get_parent(ED4_L_SPECIES)->to_species_manager();
848
849    if (spec_man->is_consensus_manager()) {
850        char *db_pointer = resolve_pointer_to_string_copy();
851        char *bracket = strchr(db_pointer, '(');
852
853        if (bracket) {
854            int bracket_len = strlen(bracket);
855            int name_len = bracket-db_pointer;
856
857            if (bracket[-1]==' ') {
858                name_len--;
859            }
860
861            if ((name_len+1+bracket_len)<=MAXNAMELEN) {
862                strcpy(real_name, db_pointer);
863            }
864            else {
865                int short_name_len = MAXNAMELEN-bracket_len-1;
866
867                memcpy(real_name, db_pointer, short_name_len);
868                real_name[short_name_len] = ' ';
869                strcpy(real_name+short_name_len+1, bracket);
870            }
871        }
872        else {
873            strncpy(real_name, db_pointer, BUFFERSIZE);
874        }
875
876        free(db_pointer);
877    }
878    else if (spec_man->is_SAI_manager()) {
879        char *db_pointer = resolve_pointer_to_string_copy();
880
881        strcpy(real_name, "SAI: ");
882        if (strcmp(db_pointer, "ECOLI")==0) {
883            const char *name_for_ecoli = ED4_ROOT->aw_root->awar(ED4_AWAR_NDS_ECOLI_NAME)->read_char_pntr();
884            if (name_for_ecoli[0]==0) name_for_ecoli = db_pointer;
885            strncpy(real_name+5, name_for_ecoli, BUFFERSIZE-5);
886        }
887        else {
888            strncpy(real_name+5, db_pointer, BUFFERSIZE-5);
889        }
890        free(db_pointer);
891    }
892    else { // normal species
893        char *result = ED4_get_NDS_text(spec_man);
894        strncpy(real_name, result, BUFFERSIZE);
895        free(result);
896    }
897
898    return real_name;
899}
900#undef MAXNAMELEN
901#undef BUFFERSIZE
902
903
904ED4_sequence_info_terminal::ED4_sequence_info_terminal(const char *temp_id, /* GBDATA *gbd, */ AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent)
905    : ED4_text_terminal(sequence_info_terminal_spec, temp_id, x, y, width, height, temp_parent)
906{
907}
908
909ED4_consensus_sequence_terminal::ED4_consensus_sequence_terminal(const char *temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent)
910    : ED4_sequence_terminal(temp_id, x, y, width, height, temp_parent, false)
911{
912    species_name = NULL;
913}
914
915ED4_abstract_sequence_terminal::ED4_abstract_sequence_terminal(const ED4_objspec& spec_, const char *temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent)
916    : ED4_text_terminal(spec_, temp_id, x, y, width, height, temp_parent)
917{
918    species_name = NULL;
919}
920
921ED4_abstract_sequence_terminal::~ED4_abstract_sequence_terminal() {
922    free(species_name);
923}
924
925ED4_orf_terminal::ED4_orf_terminal(const char *temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent)
926    : ED4_abstract_sequence_terminal(orf_terminal_spec, temp_id, x, y, width, height, temp_parent)
927{
928    aaSequence   = 0;
929    aaSeqLen     = 0;
930    aaColor      = 0;
931    aaStartPos   = 0;
932    aaStrandType = 0;
933}
934
935GB_alignment_type ED4_orf_terminal::GetAliType()
936{
937    return (GB_alignment_type) GB_AT_AA;
938}
939
940ED4_orf_terminal::~ED4_orf_terminal()
941{
942    free(aaSequence);
943    free(aaColor);
944}
945
946ED4_sequence_terminal::ED4_sequence_terminal(const char *temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent, bool shall_display_secstruct_info_)
947    : ED4_abstract_sequence_terminal(sequence_terminal_spec, temp_id, x, y, width, height, temp_parent),
948      shall_display_secstruct_info(shall_display_secstruct_info_)
949{
950    st_ml_node = NULL;
951}
952
953GB_alignment_type ED4_sequence_terminal::GetAliType()
954{
955    return ED4_ROOT->alignment_type;
956}
957
958ED4_pure_text_terminal::ED4_pure_text_terminal(const char *temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent)
959    : ED4_text_terminal(pure_text_terminal_spec, temp_id, x, y, width, height, temp_parent)
960{
961}
962
963ED4_returncode ED4_spacer_terminal::Show(int /* refresh_all */, int is_cleared) {
964    if (shallDraw) {
965        if (update_info.clear_at_refresh && !is_cleared) {
966            clear_background();
967        }
968        draw();
969    }
970    return ED4_R_OK;
971}
972
973
974ED4_returncode ED4_spacer_terminal::draw() { 
975#if defined(DEBUG) && 0
976    clear_background(ED4_G_FIRST_COLOR_GROUP); // draw colored spacers to make them visible
977#else
978    clear_background(0);
979#endif // DEBUG
980    return (ED4_R_OK);
981}
982
983ED4_spacer_terminal::ED4_spacer_terminal(const char *temp_id, bool shallDraw_, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent)
984    : ED4_terminal(spacer_terminal_spec, temp_id, x, y, width, height, temp_parent),
985      shallDraw(shallDraw_)
986{
987}
988
989ED4_returncode ED4_line_terminal::draw() {
990    AW_pos x1, y1;
991    calc_world_coords(&x1, &y1);
992    current_ed4w()->world_to_win_coords(&x1, &y1);
993
994    AW_pos x2 = x1+extension.size[WIDTH]-1;
995    AW_pos y2 = y1+extension.size[HEIGHT]-1;
996
997    AW_device *device = current_device();
998
999    device->line(ED4_G_STANDARD, x1, y1, x2, y1);
1000#if defined(DEBUG)
1001    device->box(ED4_G_MARKED, true, x1, y1+1, x2-x1+1, y2-y1-1);
1002#else
1003    device->clear_part(x1, y1+1, x2-x1+1, y2-y1-1, AW_ALL_DEVICES);
1004#endif // DEBUG
1005    device->line(ED4_G_STANDARD, x1, y2, x2, y2);
1006
1007    return ED4_R_OK;
1008}
1009
1010ED4_returncode ED4_line_terminal::Show(int /* refresh_all */, int is_cleared)
1011{
1012    if (update_info.clear_at_refresh && !is_cleared) {
1013        clear_background();
1014    }
1015    draw();
1016    return ED4_R_OK;
1017}
1018
1019
1020ED4_line_terminal::ED4_line_terminal(const char *temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent)
1021    : ED4_terminal(line_terminal_spec, temp_id, x, y, width, height, temp_parent)
1022{
1023}
1024
1025// ---------------------------------
1026//      ED4_columnStat_terminal
1027
1028ED4_returncode ED4_columnStat_terminal::Show(int IF_ASSERTION_USED(refresh_all), int is_cleared)
1029{
1030    e4_assert(update_info.refresh || refresh_all);
1031    current_device()->push_clip_scale();
1032    if (adjust_clipping_rectangle()) {
1033        if (update_info.clear_at_refresh && !is_cleared) {
1034            clear_background();
1035        }
1036        draw();
1037    }
1038    current_device()->pop_clip_scale();
1039
1040    return ED4_R_OK;
1041}
1042
1043inline char stat2display(int val, bool is_upper_digit) {
1044    if (val<0) {
1045        e4_assert(val==-1); // -1 indicates that no statistic is existing for that column
1046        return '?';
1047    }
1048    if (val==20) return ' '; // value if ACGT and - are distributed equally
1049    if (val==100) return '^'; // we have only 2 characters to display likelihood (100 cannot be displayed)
1050
1051    e4_assert(val>=0 && val<100);
1052
1053    return '0' + (is_upper_digit ? (val/10) : (val%10));
1054}
1055
1056inline int find_significant_positions(int sig, int like_A, int like_C, int like_G, int like_TU, int *sumPtr) {
1057    // result == 0      -> no base-char has a significant likelihood (>=sig)
1058    // result == 1, 2, 4, 8     -> A, C, G, T/U has a significant likelihood
1059    // else             -> the sum two of the likelihoods >= sig (bit-or-ed as in line above)
1060
1061    int like[4];
1062    like[0] = like_A;
1063    like[1] = like_C;
1064    like[2] = like_G;
1065    like[3] = like_TU;
1066
1067    int bestSum = 0;
1068    int bestResult = 0;
1069
1070    int b, c;
1071    for (b=0; b<4; b++) {
1072        int sum = like[b];
1073        if (sum>=sig && sum>=bestSum) {
1074            bestSum = sum;
1075            bestResult = 1<<b;
1076        }
1077    }
1078
1079    if (!bestResult) {
1080        for (b=0; b<4; b++) {
1081            for (c=b+1; c<4; c++) {
1082                int sum = like[b]+like[c];
1083                if (sum>=sig && sum>=bestSum) {
1084                    bestSum = sum;
1085                    bestResult = (1<<b)|(1<<c);
1086                }
1087            }
1088        }
1089    }
1090
1091    if (bestResult) {
1092        if (sumPtr) *sumPtr = bestSum;
1093        return bestResult;
1094    }
1095
1096    return 0;
1097}
1098
1099#define PROBE_MATCH_TARGET_STRING_LENGTH 32
1100
1101GB_CSTR ED4_columnStat_terminal::build_probe_match_string(PosRange range) const {
1102    static char            result[PROBE_MATCH_TARGET_STRING_LENGTH+1]; // see create_probe_match_window() for length
1103    int                    max_insert   = PROBE_MATCH_TARGET_STRING_LENGTH;
1104    char                  *r            = result;
1105    int                    significance = int(get_threshold());
1106    ED4_sequence_terminal *seq_term     = corresponding_sequence_terminal();
1107    char                  *seq          = seq_term->resolve_pointer_to_string_copy();
1108
1109    for (int pos=range.start(); pos<=range.end(); pos++) {
1110        int found = find_significant_positions(significance, likelihood[0][pos], likelihood[1][pos], likelihood[2][pos], likelihood[3][pos], 0);
1111
1112        if (found || strchr("-=.", seq[pos])==0) {
1113            // '?' is inserted at every base position without significant bases (not at gaps!)
1114
1115            *r++ = "NACMGRSVUWYHKDBN"[found]; // this creates a string containing the full IUPAC code
1116
1117            if (max_insert--==0) {
1118                r--;
1119                break;
1120            }
1121        }
1122    }
1123    r[0] = 0;
1124    free(seq);
1125
1126    if (max_insert<0) {
1127        aw_message(GBS_global_string("Max. %i bases allowed in Probe Match", PROBE_MATCH_TARGET_STRING_LENGTH));
1128        result[0] = 0;
1129    }
1130    return result;
1131}
1132#undef PROBE_MATCH_TARGET_STRING_LENGTH
1133
1134ED4_returncode ED4_columnStat_terminal::draw() {
1135    if (!update_likelihood()) {
1136        aw_message("Can't calculate likelihood.");
1137        return ED4_R_IMPOSSIBLE;
1138    }
1139
1140    AW_pos x, y;
1141    calc_world_coords(&x, &y);
1142    current_ed4w()->world_to_win_coords(&x, &y);
1143
1144    AW_pos term_height = extension.size[HEIGHT];
1145    AW_pos font_height = ED4_ROOT->font_group.get_height(ED4_G_SEQUENCES);
1146    AW_pos font_width  = ED4_ROOT->font_group.get_width(ED4_G_SEQUENCES);
1147
1148    AW_pos text_x = x + CHARACTEROFFSET;
1149    AW_pos text_y = y + term_height - font_height;
1150
1151    AW_device             *device   = current_device();
1152    ED4_sequence_terminal *seq_term = corresponding_sequence_terminal();
1153    const ED4_remap       *rm       = ED4_ROOT->root_group_man->remap();
1154   
1155    PosRange index_range = rm->clip_screen_range(seq_term->calc_update_interval());
1156    {
1157        int max_seq_len = seq_term->get_length();
1158        int max_seq_pos = rm->sequence_to_screen(max_seq_len);
1159
1160        index_range = ExplicitRange(index_range, max_seq_pos);
1161        if (index_range.is_empty()) return ED4_R_OK;
1162    }
1163
1164    const int left  = index_range.start();
1165    const int right = index_range.end();
1166
1167    char *sbuffer = new char[right+2];  // used to build displayed terminal content  (values = '0'-'9')
1168    memset(sbuffer, ' ', right+1);
1169    sbuffer[right+1] = 0; // eos
1170
1171    AW_pos y2;
1172    int r;
1173
1174    // Set background:
1175    {
1176        int significance = int(get_threshold());
1177        // normal columns are colored in ED4_G_STANDARD
1178        // all columns with one (or sum of two) probability above 'significance' are back-colored in ED4_G_CBACK_0
1179        // the responsible probabilities (one or two) are back-colored in ED4_G_CBACK_1..ED4_G_CBACK_9
1180
1181        int old_color = ED4_G_STANDARD;
1182
1183        AW_pos x2     = text_x + font_width*left + 1;
1184        AW_pos old_x2 = x2;
1185
1186        PosRange selection;
1187        bool     is_selected = ED4_get_selected_range(seq_term, selection);
1188
1189        for (int i=left; i<=right; i++, x2+=font_width) { // colorize significant columns in ALL rows
1190            int p = rm->screen_to_sequence(i);
1191            int found = find_significant_positions(significance, likelihood[0][p], likelihood[1][p], likelihood[2][p], likelihood[3][p], 0);
1192
1193            int color;
1194            if (is_selected && selection.contains(p)) {
1195                color = ED4_G_SELECTED;
1196            }
1197            else {
1198                color = found ? ED4_G_CBACK_0 : ED4_G_STANDARD;
1199            }
1200
1201            if (color!=old_color) {
1202                if (x2>old_x2 && old_color!=ED4_G_STANDARD) {
1203                    device->box(old_color, true, old_x2, y, x2-old_x2, term_height);
1204                }
1205                old_color = color;
1206                old_x2 = x2;
1207            }
1208        }
1209        if (x2>old_x2 && old_color!=ED4_G_STANDARD) {
1210            device->box(old_color, true, old_x2, y, x2-old_x2, term_height);
1211        }
1212
1213        x2 = text_x + font_width*left + 1;
1214
1215        for (int i=left; i<=right; i++, x2+=font_width) { // colorize significant columns in SINGLE rows
1216            int p = rm->screen_to_sequence(i);
1217            int sum;
1218            int found = find_significant_positions(significance, likelihood[0][p], likelihood[1][p], likelihood[2][p], likelihood[3][p], &sum);
1219
1220            if (found && significance<100) {
1221                e4_assert(sum>=significance && sum<=100);
1222                int color = ED4_G_CBACK_1+((sum-significance)*(ED4_G_CBACK_9-ED4_G_CBACK_1))/(100-significance);
1223                e4_assert(color>=ED4_G_CBACK_1 && color<=ED4_G_CBACK_9);
1224
1225                if (color!=ED4_G_STANDARD) {
1226                    int bit;
1227
1228                    for (r=3, y2=text_y+1, bit=1<<3;
1229                         r>=0;
1230                         r--, y2-=COLUMN_STAT_ROW_HEIGHT(font_height), bit>>=1)
1231                    {
1232                        if (found&bit) {
1233                            device->box(color, true, x2, y2-2*font_height+1, font_width, 2*font_height);
1234                        }
1235                    }
1236                }
1237            }
1238        }
1239    }
1240
1241    // Draw text:
1242    for (r=3, y2=text_y;
1243         r>=0;
1244         r--, y2-=COLUMN_STAT_ROW_HEIGHT(font_height)) { // 4 rows (one for T/U, G, C and A)
1245
1246        int gc = ED4_ROOT->sequence_colors->char_2_gc[(unsigned char)"ACGU"[r]];
1247        int i;
1248        for (i=left; i<=right; i++) {
1249            int p = rm->screen_to_sequence(i);
1250            int val = likelihood[r][p];
1251            sbuffer[i] = stat2display(val, 0); // calc lower digit
1252        }
1253        device->text(gc, sbuffer, text_x+font_width*0.2, y2, 0, AW_SCREEN, right); // draw lower-significant digit (shifted a bit to the right)
1254
1255        for (i=left; i<=right; i++) {
1256            int p = rm->screen_to_sequence(i);
1257            int val = likelihood[r][p];
1258            sbuffer[i] = stat2display(val, 1); // calc upper digit
1259        }
1260        device->text(gc, sbuffer, text_x, y2-font_height, 0, AW_SCREEN, right); // draw higher-significant digit
1261    }
1262
1263    delete [] sbuffer;
1264    return ED4_R_OK;
1265}
1266
1267int ED4_columnStat_terminal::update_likelihood() {
1268    ED4_sequence_terminal *seq_term = corresponding_sequence_terminal();
1269
1270    return STAT_update_ml_likelihood(ED4_ROOT->st_ml, likelihood, latest_update, 0, seq_term->st_ml_node);
1271}
1272
1273ED4_columnStat_terminal::ED4_columnStat_terminal(GB_CSTR temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent) :
1274    ED4_text_terminal(column_stat_terminal_spec, temp_id, x, y, width, height, temp_parent)
1275{
1276    for (int i=0; i<4; i++) likelihood[i] = 0;
1277    latest_update = 0;
1278}
1279
1280ED4_columnStat_terminal::~ED4_columnStat_terminal()
1281{
1282    for (int i=0; i<4; i++) free(likelihood[i]);
1283}
1284
1285// ---------------------------------
1286//      ED4_reference_terminals
1287
1288void ED4_reference_terminals::clear()
1289{
1290    delete ref_sequence_info;
1291    delete ref_sequence;
1292    delete ref_column_stat;
1293    delete ref_column_stat_info;
1294    null();
1295}
1296
1297void ED4_reference_terminals::init(ED4_sequence_info_terminal *ref_sequence_info_,
1298                                   ED4_sequence_terminal *ref_sequence_,
1299                                   ED4_sequence_info_terminal *ref_column_stat_info_,
1300                                   ED4_columnStat_terminal *ref_column_stat_)
1301{
1302    clear();
1303    ref_sequence_info    = ref_sequence_info_;
1304    ref_sequence     = ref_sequence_;
1305    ref_column_stat_info = ref_column_stat_info_;
1306    ref_column_stat      = ref_column_stat_;
1307}
Note: See TracBrowser for help on using the repository browser.