source: tags/arb_5.1/EDIT4/ED4_terminal.cxx

Last change on this file was 5929, checked in by westram, 15 years ago
  • added AW_awar::read_char_pntr()
  • stuffed several memory leaks
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 54.3 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <memory.h>
5// #include <malloc.h>
6#include <assert.h>
7
8#include <arbdb.h>
9#include <arbdbt.h>
10
11#include <aw_root.hxx>
12#include <aw_device.hxx>
13#include <aw_keysym.hxx>
14#include <aw_window.hxx>
15#include <aw_preset.hxx>
16
17#include <awt_seq_colors.hxx>
18#include <st_window.hxx>
19
20#include <ed4_extern.hxx>
21
22#include "ed4_class.hxx"
23#include "ed4_awars.hxx"
24#include "ed4_edit_string.hxx"
25#include "ed4_block.hxx"
26#include "ed4_nds.hxx"
27#include "ed4_ProteinViewer.hxx"
28
29//*******************************************
30//* Terminal static properties  beginning   *
31//*******************************************
32
33
34ED4_object_specification tree_terminal_spec =                       // variables which determine static default properties of predefined (sub-)classes
35{
36    ED4_P_IS_TERMINAL,  // static props
37    ED4_L_TREE,         // level
38    ED4_L_NO_LEVEL,     // allowed children level
39    ED4_L_NO_LEVEL,     // handled object
40    ED4_L_NO_LEVEL,     // restriction level
41    0                   // justification value --no meaning for a terminal
42};
43
44ED4_object_specification bracket_terminal_spec =
45{
46    ED4_P_IS_TERMINAL,  // static props
47    ED4_L_BRACKET,      // level
48    ED4_L_NO_LEVEL,     // allowed children level
49    ED4_L_NO_LEVEL,     // handled object
50    ED4_L_NO_LEVEL,     // restriction level
51    0                   // justification value --no meaning for a terminal
52};
53
54ED4_object_specification species_name_terminal_spec =
55{
56    ED4_P_IS_TERMINAL,  // static props
57    ED4_L_SPECIES_NAME, // level
58    ED4_L_NO_LEVEL,     // allowed children level
59    ED4_L_SPECIES,      // handled object
60    ED4_L_NO_LEVEL,     // restriction level
61    0                   // justification value --no meaning for a terminal
62};
63
64ED4_object_specification sequence_info_terminal_spec =
65{
66    ED4_P_IS_TERMINAL,  // static props
67    ED4_L_SEQUENCE_INFO,// level
68    ED4_L_NO_LEVEL,     // allowed children level
69    ED4_L_SEQUENCE,     // handled object
70    ED4_L_NO_LEVEL,     // restriction level
71    0                   // justification value --no meaning for a terminal
72};
73
74ED4_object_specification sequence_terminal_spec =
75{
76    ED4_P_IS_TERMINAL,     // static props
77    ED4_L_SEQUENCE_STRING, // level
78    ED4_L_NO_LEVEL,        // allowed children level
79    ED4_L_NO_LEVEL,        // handled object
80    ED4_L_NO_LEVEL,        // restriction level
81    0                      // justification value --no meaning for a terminal
82};
83
84ED4_object_specification pure_text_terminal_spec =
85{
86    ED4_P_IS_TERMINAL,     // static props
87    ED4_L_PURE_TEXT,       // level
88    ED4_L_NO_LEVEL,        // allowed children level
89    ED4_L_NO_LEVEL,        // handled object
90    ED4_L_NO_LEVEL,        // restriction level
91    0                      // justification value --no meaning for a terminal
92};
93
94ED4_object_specification spacer_terminal_spec =
95{
96    ED4_P_IS_TERMINAL,     // static props
97    ED4_L_SPACER,          // level
98    ED4_L_NO_LEVEL,        // allowed children level
99    ED4_L_NO_LEVEL,        // handled object
100    ED4_L_NO_LEVEL,        // restriction level
101    0                      // justification value --no meaning for a terminal
102};
103
104ED4_object_specification line_terminal_spec =
105{
106    ED4_P_IS_TERMINAL,     // static props
107    ED4_L_LINE,            // level
108    ED4_L_NO_LEVEL,        // allowed children level
109    ED4_L_NO_LEVEL,        // handled object
110    ED4_L_NO_LEVEL,        // restriction level
111    0                      // justification value --no meaning for a terminal
112};
113
114ED4_object_specification column_stat_terminal_spec =
115{
116    ED4_P_IS_TERMINAL,     // static props
117    ED4_L_COL_STAT,        // level
118    ED4_L_NO_LEVEL,        // allowed children level
119    ED4_L_NO_LEVEL,        // handled object
120    ED4_L_NO_LEVEL,        // restriction level
121    0                      // justification value --no meaning for a terminal
122};
123
124//*******************************************
125//* Terminal static properties      end *
126//*******************************************
127
128
129
130
131//*****************************************
132//* ED4_terminal Methods    beginning *
133//*****************************************
134
135
136char *ED4_terminal::resolve_pointer_to_string_copy(int *str_len) const {
137    int         len;
138    const char *s = resolve_pointer_to_char_pntr(&len);
139    char       *t = GB_strduplen(s, len); // space for zero byte is allocated by GB_strduplen
140
141    if (str_len) *str_len = len;
142    return t;
143}
144
145const char *ED4_terminal::resolve_pointer_to_char_pntr(int *str_len) const
146{
147    GB_TYPES    gb_type;
148    const char *db_pointer = NULL;
149    GBDATA     *gbd        = get_species_pointer();
150
151    if (!gbd) {
152        if (str_len) {
153            if (id) *str_len = strlen(id);
154            else *str_len    = 0;
155        }
156        return id; // if we don't have a link to the database we have to use our id
157    }
158
159    GB_push_transaction(GLOBAL_gb_main);
160
161    const char *copy_of = 0; // if set, return a copy of this string
162
163    gb_type = GB_read_type(gbd);
164#warning temporary workaround - gb_type GB_INT and GB_FLOAT in the switch directive must not be displayed but ignored
165    switch (gb_type)
166    {
167        case GB_STRING:
168            db_pointer = GB_read_char_pntr(gbd);
169            if (str_len) {
170                *str_len = GB_read_string_count(gbd);
171                e4_assert(*str_len == (int)strlen(db_pointer));
172            }
173            break;
174        case GB_BITS:
175            db_pointer = GB_read_bits_pntr(gbd, '.', '+');
176            if (str_len) {
177                *str_len = GB_read_bits_count(gbd);
178                e4_assert(*str_len == (int)strlen(db_pointer));
179            }
180            break;
181        case GB_BYTES:
182            db_pointer = GB_read_bytes_pntr(gbd);
183            if (str_len) {
184                *str_len = GB_read_bytes_count(gbd);
185                e4_assert(*str_len == (int)strlen(db_pointer));
186            }
187            break;
188        case GB_DB:
189            copy_of = "GB_DB";
190            break;
191        case GB_INT: // FIXME: temporary Workaround
192            copy_of = "GB_INT";
193            break;
194        case GB_INTS:
195            copy_of = "GB_INTS";
196            break;
197        case GB_FLOAT: // FIXME: temporary Workaround
198            copy_of = "GB_FLOAT";
199            break;
200        case GB_FLOATS:
201            copy_of = "GB_FLOATS";
202            break;
203        default:
204            printf("Unknown data type - Please contact administrator\n");
205            e4_assert(0);
206            break;
207    }
208
209    if (copy_of) {
210        e4_assert(db_pointer == 0);
211
212        int len    = strlen(copy_of);
213        db_pointer = GB_strduplen(copy_of, len);
214
215        if (str_len) *str_len = len;
216    }
217
218    GB_pop_transaction( GLOBAL_gb_main );
219
220    return db_pointer;
221}
222
223ED4_ERROR *ED4_terminal::write_sequence(const char *seq, int seq_len)
224{
225    ED4_ERROR *err = 0;
226    GBDATA *gbd = get_species_pointer();
227    e4_assert(gbd); // we must have a link to the database!
228
229    GB_push_transaction(GLOBAL_gb_main);
230
231    int   old_seq_len;
232    char *old_seq = resolve_pointer_to_string_copy(&old_seq_len);
233
234    bool allow_write_data = true;
235    if (ED4_ROOT->aw_root->awar(ED4_AWAR_ANNOUNCE_CHECKSUM_CHANGES)->read_int()) {
236        long old_checksum = GBS_checksum(old_seq, 1, "-.");
237        long new_checksum = GBS_checksum(seq, 1, "-.");
238
239        if (old_checksum != new_checksum) {
240            if (aw_question("Checksum changed!", "Allow, Reject") == 1) {
241                allow_write_data = false;
242                // GB_write_string(info->gb_data, old_seq);
243            }
244
245        }
246    }
247
248    if (allow_write_data) {
249        GB_TYPES gb_type = GB_read_type(gbd);
250        switch(gb_type) {
251            case GB_STRING: {
252                //             old_seq = GB_read_char_pntr(gbd);
253                err = GB_write_string(gbd, seq);
254                break;
255            }
256            case GB_BITS: {
257                err = GB_write_bits(gbd, seq, seq_len, ".-");
258                break;
259            }
260            default: {
261                e4_assert(0);
262                break;
263            }
264        }
265    }
266
267    GB_pop_transaction(GLOBAL_gb_main);
268
269    if (!err && dynamic_prop&ED4_P_CONSENSUS_RELEVANT) {
270        if (old_seq) {
271            actual_timestamp = GB_read_clock(GLOBAL_gb_main);
272
273            get_parent(ED4_L_MULTI_SPECIES)->to_multi_species_manager()
274                ->check_bases_and_rebuild_consensi(old_seq, old_seq_len, get_parent(ED4_L_SPECIES)->to_species_manager(), ED4_U_UP); // bases_check
275        }
276        else {
277            aw_message("Couldn't read old sequence data");
278        }
279
280        set_refresh();
281        parent->refresh_requested_by_child();
282    }
283
284    if (old_seq) free(old_seq);
285
286    return err;
287}
288
289
290ED4_returncode ED4_terminal::remove_callbacks()                     //removes callbacks and gb_alignment
291{
292    if (get_species_pointer()) {
293        set_species_pointer(0);
294        flag.deleted = 1;
295        dynamic_prop = (ED4_properties) (dynamic_prop & ~ED4_P_CURSOR_ALLOWED);
296
297        set_refresh();
298        parent->refresh_requested_by_child();
299    }
300    return ED4_R_OK;
301}
302
303static ED4_returncode ed4_remove_species_manager_callbacks(void **, void **, ED4_base *base) {
304    if (base->is_species_manager()) {
305        base->to_species_manager()->remove_all_callbacks();
306    }
307    return ED4_R_OK;
308}
309
310ED4_returncode ED4_terminal::kill_object()
311{
312    ED4_species_manager *species_manager = get_parent( ED4_L_SPECIES )->to_species_manager();
313    ED4_manager         *parent_manager  = species_manager->parent;
314    ED4_group_manager   *group_manager   = 0;
315
316    if (species_manager->flag.is_consensus)                         // whole group has to be killed
317    {
318        if (parent_manager->is_multi_species_manager() && ED4_new_species_multi_species_manager()==parent_manager) {
319            aw_message("This group has to exist - deleting it isn't allowed");
320            return ED4_R_IMPOSSIBLE;
321        }
322
323        parent_manager = species_manager;
324        while (!parent_manager->is_group_manager()) {
325            parent_manager = parent_manager->parent;
326        }
327        group_manager = parent_manager->to_group_manager();
328
329        parent_manager = group_manager->parent;
330        parent_manager->children->delete_member( group_manager );
331
332        GB_push_transaction ( GLOBAL_gb_main );
333        parent_manager->update_consensus( parent_manager ,NULL , group_manager );
334        parent_manager->rebuild_consensi( parent_manager , ED4_U_UP );
335        GB_pop_transaction ( GLOBAL_gb_main );
336        species_manager = NULL;
337    }
338    else
339    {
340        parent_manager->children->delete_member( species_manager );
341        GB_push_transaction (GLOBAL_gb_main );
342        parent_manager->update_consensus( parent_manager , NULL, species_manager );
343        parent_manager->rebuild_consensi( species_manager, ED4_U_UP );
344        GB_pop_transaction (GLOBAL_gb_main);
345    }
346
347    ED4_device_manager *device_manager = ED4_ROOT->main_manager
348        ->get_defined_level(ED4_L_GROUP)->to_group_manager()
349        ->get_defined_level(ED4_L_DEVICE)->to_device_manager();
350
351    for (int i=0; i<device_manager->children->members(); i++) { // when killing species numbers have to be recalculated
352        ED4_base *member = device_manager->children->member(i);
353
354        if (member->is_area_manager()) {
355            member->to_area_manager()->get_defined_level(ED4_L_MULTI_SPECIES)->to_multi_species_manager()->generate_id_for_groups();
356        }
357    }
358
359    if (species_manager) {
360        species_manager->parent = NULL;
361        species_manager->remove_all_callbacks();
362        delete species_manager;
363    }
364
365    if (group_manager) {
366        group_manager->parent = NULL;
367        group_manager->route_down_hierarchy(0, 0, ed4_remove_species_manager_callbacks);
368        delete group_manager;
369    }
370
371    return ED4_R_OK;
372}
373
374ED4_base *ED4_terminal::get_competent_clicked_child( AW_pos /*x*/, AW_pos /*y*/, ED4_properties /*relevant_prop*/)
375{
376    e4_assert(0);
377    return NULL;
378}
379
380ED4_returncode   ED4_terminal::handle_move(ED4_move_info */*moveinfo*/)
381{
382    e4_assert(0);
383    return ED4_R_IMPOSSIBLE;
384}
385
386ED4_returncode  ED4_terminal::move_requested_by_child(ED4_move_info */*moveinfo*/)
387{
388    e4_assert(0);
389    return ED4_R_IMPOSSIBLE;
390}
391
392
393ED4_base *ED4_terminal::get_competent_child( AW_pos /*x*/, AW_pos /*y*/, ED4_properties /*relevant_prop*/)
394{
395    e4_assert(0);
396    return NULL;
397}
398
399ED4_returncode ED4_terminal::resize_requested_by_child(void)
400{
401    e4_assert(0);
402    return ED4_R_IMPOSSIBLE;
403}
404
405ED4_returncode ED4_terminal::draw_drag_box( AW_pos x, AW_pos y, GB_CSTR text, int cursor_y )    // draws drag box of object at location abs_x, abs_y
406{
407    ED4_index   i;
408    AW_pos          width, height, drag_x, drag_y;
409    AW_pos      drag_line_x0[3], drag_line_y0[3];
410    AW_pos      drag_line_x1[3], drag_line_y1[3];
411    ED4_base    *drag_target = NULL;
412    AW_pos      target_x, target_y;
413    ED4_extension   location;
414
415    width = extension.size[WIDTH] - 1;
416    height = extension.size[HEIGHT] - 1;
417
418    if (cursor_y!=-1)
419    {
420        ED4_device_manager *device_manager = ED4_ROOT->main_manager->search_spec_child_rek(ED4_L_DEVICE)->to_device_manager();
421        drag_x = 0;
422        drag_y = (AW_pos)cursor_y; // cursor_y is already in world coordinates!
423        //  ED4_ROOT->win_to_world_coords( ED4_ROOT->temp_aww, &drag_x, &drag_y );
424        location.position[X_POS] = drag_x;
425        location.position[Y_POS] = drag_y;
426        //  ED4_base::touch_world_cache();
427        device_manager->children->search_target_species( &location, ED4_P_HORIZONTAL, &drag_target, ED4_L_NO_LEVEL );
428
429        if (drag_target && !is_sequence_info_terminal()) {
430            drag_target->calc_world_coords ( &target_x, &target_y );
431            ED4_ROOT->world_to_win_coords(ED4_ROOT->get_aww(), &target_x, &target_y);
432#define ARROW_LENGTH 3
433            drag_line_x0[0] = target_x + 5;                                     // horizontal
434            drag_line_y0[0] = target_y + drag_target->extension.size[HEIGHT];
435            drag_line_x1[0] = drag_line_x0[0] + 50;
436            drag_line_y1[0] = target_y + drag_target->extension.size[HEIGHT];
437
438            drag_line_x0[1] = drag_line_x0[0] -ARROW_LENGTH;                                // arrow
439            drag_line_y0[1] = drag_line_y0[0] -ARROW_LENGTH;
440            drag_line_x1[1] = drag_line_x0[0];
441            drag_line_y1[1] = drag_line_y0[0];
442
443            drag_line_x0[2] = drag_line_x0[0] -ARROW_LENGTH;                                // arrow
444            drag_line_y0[2] = drag_line_y0[0] +ARROW_LENGTH;
445            drag_line_x1[2] = drag_line_x0[0] ;
446            drag_line_y1[2] = drag_line_y0[0];
447#undef ARROW_LENGTH
448            for( i = 0; i <= 2; i++ ) {
449                ED4_ROOT->get_device()->line( ED4_G_DRAG, drag_line_x0[i], drag_line_y0[i], drag_line_x1[i], drag_line_y1[i], 1, 0, 0);
450            }
451        }
452    }
453
454    if ( text != NULL ) {
455        ED4_ROOT->get_device()->text( ED4_G_DRAG, text, (x + 20), (y + INFO_TERM_TEXT_YOFFSET), 0, 1, 0, 0);
456    }
457
458    return ( ED4_R_OK );
459}
460
461ED4_returncode  ED4_terminal::move_requested_by_parent(ED4_move_info *) { // handles a move request coming from parent
462    e4_assert(0);
463    return ( ED4_R_IMPOSSIBLE );
464}
465
466#if defined(DEBUG) && 1
467static inline void dumpEvent(const char *where, AW_event *event) {
468    printf("%s: x=%i y=%i\n", where, event->x, event->y);
469}
470#else
471#define dumpEvent(w,e)
472#endif
473
474ED4_returncode  ED4_terminal::event_sent_by_parent( AW_event *event, AW_window *aww )           // handles an input event coming from parent
475{
476    static ED4_species_name_terminal    *dragged_name_terminal = 0;
477    static int              dragged_was_selected;
478    static bool                 pressed_left_button = 0;
479    static int              other_x, other_y; // coordinates of last event
480    static bool                 right_button_started_on_sequence_term = 0;
481
482    switch ( event->type ) {
483        case AW_Mouse_Press: {
484            switch ( event->button ) {
485                case ED4_B_LEFT_BUTTON: {
486                    pressed_left_button = 0;
487                    if (is_species_name_terminal()) {
488                        switch (ED4_ROOT->species_mode) {
489                            case ED4_SM_KILL: {
490                                if (flag.selected) {
491                                    ED4_ROOT->remove_from_selected(this);
492                                }
493                                kill_object();
494                                ED4_ROOT->refresh_all_windows(0);
495                                return ED4_R_BREAK;
496                            }
497                            case ED4_SM_MOVE: {
498                                dragged_name_terminal = to_species_name_terminal();
499                                pressed_left_button = 1;
500                                other_x = event->x;
501                                other_y = event->y;
502
503                                if (!flag.selected) {
504                                    ED4_ROOT->add_to_selected(dragged_name_terminal);
505                                    dragged_was_selected = 0;
506                                    ED4_ROOT->main_manager->Show();
507                                }
508                                else {
509                                    dragged_was_selected = 1;
510                                }
511                                break;
512                            }
513                            case ED4_SM_MARK: {
514                                ED4_species_manager *species_man = get_parent(ED4_L_SPECIES)->to_species_manager();
515                                GBDATA *gbd = species_man->get_species_pointer();
516
517                                if (gbd) {
518                                    GB_write_flag(gbd, !GB_read_flag(gbd));
519                                    set_refresh();
520                                    parent->refresh_requested_by_child();
521                                    //ProtView: Refreshing AA_sequence terminals
522                                    if (ED4_ROOT->alignment_type ==  GB_AT_DNA) {
523                                        PV_RefreshWindow(aww->get_root());
524                                    }
525                                }
526                                break;
527                            }
528                            default: {
529                                e4_assert(0);
530                                break;
531                            }
532                        }
533                    }
534                    else if (is_bracket_terminal()) { // fold/unfold group
535                        if (dynamic_prop & ED4_P_IS_FOLDED) {
536                            ED4_ROOT->main_manager->unfold_group(id);
537                        }
538                        else {
539                            ED4_ROOT->main_manager->fold_group(id);
540                        }
541                        ED4_ROOT->refresh_all_windows(1);
542                    }
543                    else  {
544                        if (dynamic_prop & ED4_P_CURSOR_ALLOWED) {
545                            ED4_no_dangerous_modes();
546                            ED4_ROOT->get_ed4w()->cursor.show_clicked_cursor(event->x, this);
547                        }
548                    }
549                    break;
550                }
551                case ED4_B_RIGHT_BUTTON: {
552                    right_button_started_on_sequence_term = 0;
553                    if (is_bracket_terminal()) { // right click on bracket terminal
554                        ED4_base *group = get_parent(ED4_L_GROUP);
555                        if (group) {
556                            ED4_multi_species_manager *multi_man = group->to_group_manager()->get_defined_level(ED4_L_MULTI_SPECIES)->to_multi_species_manager();
557                            multi_man->deselect_all_species();
558                            ED4_correctBlocktypeAfterSelection();
559                            ED4_ROOT->refresh_all_windows(0);
560                        }
561                    }
562                    else if (is_species_name_terminal()) {
563                        ED4_species_manager *species_man = get_parent(ED4_L_SPECIES)->to_species_manager();
564
565                        if (parent->flag.is_consensus) { // click on consensus-name
566                            ED4_multi_species_manager *multi_man = parent->get_parent(ED4_L_MULTI_SPECIES)->to_multi_species_manager();
567                            int species = multi_man->get_no_of_species();
568                            int selected = multi_man->get_no_of_selected_species();
569
570                            if (selected==species) { // all species selected => deselect all
571                                multi_man->deselect_all_species();
572                            }
573                            else { // otherwise => select all
574                                multi_man->select_all_species();
575                            }
576
577                            ED4_correctBlocktypeAfterSelection();
578                            ED4_ROOT->refresh_all_windows(0);
579                            return ( ED4_R_BREAK );
580                        }
581                        else if (species_man->flag.is_SAI) {
582                            ; // don't mark SAIs
583                        }
584                        else { // click on species name
585                            if (!flag.selected) { // select if not selected
586                                if ( ED4_ROOT->add_to_selected( this ) == ED4_R_OK ) {
587                                    ED4_correctBlocktypeAfterSelection();
588                                    ED4_ROOT->refresh_all_windows(0);
589                                }
590                            }
591                            else { // deselect if already selected
592                                ED4_ROOT->remove_from_selected( this );
593                                ED4_correctBlocktypeAfterSelection();
594                                ED4_ROOT->refresh_all_windows(0);
595                                return ( ED4_R_BREAK ); // in case we were called by event_to selected()
596                            }
597                        }
598                    }
599                    else if (is_sequence_terminal()) {
600                        dumpEvent("Press", event);
601
602                        ED4_no_dangerous_modes();
603                        ED4_setColumnblockCorner(event, to_sequence_terminal()); // mark columnblock
604                        right_button_started_on_sequence_term = 1;
605                        ED4_ROOT->refresh_all_windows(0);
606                    }
607                    break;
608                }
609                case ED4_B_MIDDLE_BUTTON: {
610                    break;
611                }
612            }
613            break;
614        }
615        case AW_Mouse_Drag: {
616            switch ( event->button ) {
617                case ED4_B_LEFT_BUTTON: {
618                    if (dragged_name_terminal) {
619                        ED4_selection_entry *sel_info = dragged_name_terminal->selection_info;
620
621                        if (pressed_left_button) {
622                            AW_pos world_x, world_y;
623
624                            dragged_name_terminal->calc_world_coords(&world_x, &world_y);
625                            ED4_ROOT->world_to_win_coords(aww, &world_x, &world_y);
626
627                            sel_info->drag_old_x = world_x;
628                            sel_info->drag_old_y = world_y;
629                            sel_info->drag_off_x = world_x-other_x;
630                            sel_info->drag_off_y = world_y-other_y;
631                            sel_info->old_event_y = -1;
632
633                            pressed_left_button = 0;
634                        }
635
636                        //          ED4_species_manager *species_man = dragged_name_terminal->get_parent(ED4_L_SPECIES)->to_species_manager();
637                        //          char *text = ED4_get_NDS_text(species_man);
638                        GB_CSTR text = dragged_name_terminal->get_displayed_text();
639
640                        if (dragged_name_terminal->flag.dragged) {
641                            dragged_name_terminal->draw_drag_box(sel_info->drag_old_x, sel_info->drag_old_y, text, sel_info->old_event_y);
642                        }
643
644                        AW_pos new_x = sel_info->drag_off_x + event->x;
645                        AW_pos new_y = sel_info->drag_off_y + event->y;
646
647                        dragged_name_terminal->draw_drag_box(new_x, new_y, text, event->y); // @@@ event->y ist falsch, falls vertikal gescrollt ist!
648
649                        sel_info->drag_old_x = new_x;
650                        sel_info->drag_old_y = new_y;
651                        sel_info->old_event_y = event->y;
652
653                        dragged_name_terminal->flag.dragged = 1;
654                    }
655
656                    break;
657                }
658                case ED4_B_RIGHT_BUTTON: {
659                    if (is_sequence_terminal() && right_button_started_on_sequence_term) {
660                        ED4_no_dangerous_modes();
661                        ED4_setColumnblockCorner(event, to_sequence_terminal()); // mark columnblock
662                        ED4_ROOT->refresh_all_windows(0);
663                    }
664                    break;
665                }
666            }
667            break;
668        }
669        case AW_Mouse_Release: {
670            switch ( event->button ) {
671                case ED4_B_LEFT_BUTTON: {
672                    if (dragged_name_terminal) {
673                        if (dragged_name_terminal->flag.dragged) {
674                            {
675                                char                *db_pointer = dragged_name_terminal->resolve_pointer_to_string_copy();
676                                ED4_selection_entry *sel_info   = dragged_name_terminal->selection_info;
677
678                                dragged_name_terminal->draw_drag_box(sel_info->drag_old_x, sel_info->drag_old_y, db_pointer, sel_info->old_event_y);
679                                dragged_name_terminal->flag.dragged = 0;
680
681                                free(db_pointer);
682                            }
683                            {
684                                ED4_move_info mi;
685
686                                mi.object = dragged_name_terminal;
687                                mi.end_x = event->x;
688                                mi.end_y = event->y;
689                                mi.mode = ED4_M_FREE;
690                                mi.preferred_parent = ED4_L_NO_LEVEL;
691
692                                dragged_name_terminal->parent->move_requested_by_child(&mi);
693                            }
694                            {
695                                ED4_device_manager *device_manager = ED4_ROOT->main_manager
696                                    ->get_defined_level(ED4_L_GROUP)->to_group_manager()
697                                    ->get_defined_level(ED4_L_DEVICE)->to_device_manager();
698
699                                int i;
700                                for (i=0; i<device_manager->children->members(); i++) { // when moving species numbers have to be recalculated
701                                    ED4_base *member = device_manager->children->member(i);
702
703                                    if (member->is_area_manager()) {
704                                        member->to_area_manager()->get_defined_level(ED4_L_MULTI_SPECIES)->to_multi_species_manager()->generate_id_for_groups();
705                                    }
706                                }
707                            }
708                        }
709                        if (!dragged_was_selected) {
710                            ED4_ROOT->remove_from_selected(dragged_name_terminal);
711                        }
712
713                        ED4_expose_cb(ED4_ROOT->get_aww(), 0, 0);
714                        //          ED4_ROOT->refresh_all_windows(0);
715
716                        pressed_left_button = 0;
717                        dragged_name_terminal = 0;
718                    }
719                    break;
720                }
721
722                case ED4_B_RIGHT_BUTTON: {
723                    if (is_sequence_terminal() && right_button_started_on_sequence_term) {
724                        dumpEvent("Relea", event);
725                        ED4_no_dangerous_modes();
726                        ED4_setColumnblockCorner(event, to_sequence_terminal()); // mark columnblock
727                        ED4_ROOT->refresh_all_windows(0);
728                    }
729                    break;
730                }
731            }
732            break;
733        }
734        default:
735            assert(0);
736            break;
737    }
738    return ( ED4_R_OK );
739}
740
741
742ED4_returncode  ED4_terminal::calc_size_requested_by_parent( void )
743{
744    return ED4_R_OK;
745}
746
747short ED4_terminal::calc_bounding_box( void )
748{
749    short            bb_changed = 0;
750    ED4_list_elem   *current_list_elem;
751    ED4_base        *object;
752
753    if (width_link) {
754        if ( extension.size[WIDTH] != width_link->extension.size[WIDTH] ) { //all bounding Boxes have the same size !!!
755            extension.size[WIDTH] = width_link->extension.size[WIDTH];
756            bb_changed = 1;
757        }
758    }
759
760    if (height_link) {
761        if ( extension.size[HEIGHT] != height_link->extension.size[HEIGHT] ) {
762            extension.size[HEIGHT] = height_link->extension.size[HEIGHT];
763            bb_changed = 1;
764        }
765    }
766
767
768    if ( bb_changed ) {
769        //  printf("calc_bounding_box changed by terminal\n");
770        //  dump();
771
772        current_list_elem = linked_objects.first();
773        while ( current_list_elem ) {
774            object = ( ED4_base *) current_list_elem->elem();
775
776            if ( object != NULL ) {
777                object->link_changed( this );
778            }
779
780            current_list_elem = current_list_elem->next();
781        }
782
783        clear_background();
784
785        set_refresh();
786        parent->refresh_requested_by_child();
787    }
788
789    return ( bb_changed );
790}
791
792ED4_returncode ED4_terminal::Show(int /*refresh_all*/, int /*is_cleared*/)
793{
794    e4_assert(0);
795    return ED4_R_IMPOSSIBLE;
796}
797
798
799ED4_returncode ED4_terminal::draw(int /*only_text*/)
800{
801    e4_assert(0);
802    return ED4_R_IMPOSSIBLE;
803}
804
805
806ED4_returncode ED4_terminal::resize_requested_by_parent( void )
807{
808    // #ifndef NDEBUG
809    //     ED4_base *base = (ED4_base*)this;
810    //     e4_assert(!base->flag.hidden);
811    // #endif
812
813    if (update_info.resize) { // likes to resize?
814        if (calc_bounding_box()) { // size changed?
815            parent->resize_requested_by_child(); // tell parent!
816        }
817    }
818
819    return ED4_R_OK;
820}
821
822
823ED4_returncode ED4_terminal::set_refresh(int clear)                 // sets refresh flag of current object
824{
825    update_info.set_refresh(1);
826    update_info.set_clear_at_refresh(clear);
827    return ( ED4_R_OK );
828}
829
830
831ED4_base* ED4_terminal::search_ID(const char *temp_id )
832{
833    if ( id && strcmp( temp_id, id ) == 0 ) return (this);
834    return ( NULL );
835}
836
837
838int ED4_terminal::adjust_clipping_rectangle( void )                  //set scrolling area in AW_MIDDLE_AREA
839{
840    AW_pos              x, y; //, width, height;
841    AW_rectangle        area_size;
842
843    ED4_ROOT->get_device()->get_area_size(&area_size);
844
845    calc_world_coords(&x, &y);
846    ED4_ROOT->world_to_win_coords(ED4_ROOT->get_aww(), &x, &y);
847
848    return ED4_ROOT->get_device()->reduceClipBorders(int(y), int(y+extension.size[HEIGHT]-1), int(x), int(x+extension.size[WIDTH]-1));
849}
850
851
852
853ED4_terminal::ED4_terminal(GB_CSTR temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent ) :
854    ED4_base( temp_id, x, y, width, height, temp_parent )
855{
856    memset((char*)&flag, 0, sizeof(flag));
857    //    selected  = 0;
858    //    dragged   = 0;
859    //    deleted   = 0;
860    selection_info = 0;
861    actual_timestamp = 0;
862}
863
864
865ED4_terminal::~ED4_terminal()
866{
867    if (selection_info) {
868        delete selection_info;
869    }
870    ED4_cursor& cursor = ED4_ROOT->get_ed4w()->cursor;
871    if (this == cursor.owner_of_cursor) {
872        cursor.init();
873    }
874}
875
876//***********************************
877//* ED4_terminal Methods    end *
878//***********************************
879
880
881
882//*********************************************************
883//* Terminal constructors and destructor    beginning *
884//*********************************************************
885
886ED4_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 )
887    : ED4_terminal( temp_id, x, y, width, height, temp_parent )
888{
889    spec = &(tree_terminal_spec);
890}
891
892ED4_returncode ED4_tree_terminal::Show(int IF_DEBUG(refresh_all), int is_cleared)
893{
894    e4_assert(update_info.refresh || refresh_all);
895    ED4_ROOT->get_device()->push_clip_scale();
896    if (adjust_clipping_rectangle()) {
897        if (update_info.clear_at_refresh && !is_cleared) {
898            clear_background();
899        }
900        draw();
901    }
902    ED4_ROOT->get_device()->pop_clip_scale();
903
904    return ( ED4_R_OK );
905}
906
907
908
909ED4_returncode ED4_tree_terminal::draw( int /*only_text*/ )                 // draws bounding box of object
910{
911    AW_pos  x, y;
912    AW_pos  text_x, text_y;
913    char   *db_pointer;
914
915    calc_world_coords(&x, &y);
916    ED4_ROOT->world_to_win_coords(ED4_ROOT->get_aww(), &x, &y);
917
918    text_x = x + CHARACTEROFFSET;                           // don't change
919    text_y = y + SEQ_TERM_TEXT_YOFFSET;
920
921    db_pointer = resolve_pointer_to_string_copy();
922    ED4_ROOT->get_device()->text( ED4_G_STANDARD, db_pointer, text_x, text_y, 0, 1, 0, 0);
923    free(db_pointer);
924
925    return ( ED4_R_OK );
926}
927
928ED4_tree_terminal::~ED4_tree_terminal()
929{
930}
931
932ED4_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 )
933    : ED4_terminal( temp_id, x, y, width, height, temp_parent )
934{
935    spec = &(bracket_terminal_spec);
936}
937
938ED4_returncode ED4_bracket_terminal::Show(int IF_DEBUG(refresh_all), int is_cleared)
939{
940    e4_assert(update_info.refresh || refresh_all);
941    ED4_ROOT->get_device()->push_clip_scale();
942    if (adjust_clipping_rectangle()) {
943        if (update_info.clear_at_refresh && !is_cleared) {
944            clear_background();
945        }
946        draw();
947    }
948    ED4_ROOT->get_device()->pop_clip_scale();
949
950    return ED4_R_OK;
951}
952
953
954ED4_returncode ED4_bracket_terminal::draw( int /*only_text*/ )                  // draws bounding box of object
955{
956    ED4_index   i;
957    AW_pos      x, y,
958        width  = extension.size[WIDTH] - 1,
959        height = extension.size[HEIGHT] - 1,
960        margin = 0;
961    AW_pos      line_x0[3], line_y0[3];
962    AW_pos      line_x1[3], line_y1[3];
963    AW_pos      arrow_x0[6], arrow_y0[6];
964    AW_pos      arrow_x1[6], arrow_y1[6];
965
966
967    calc_world_coords(&x, &y);
968    ED4_ROOT->world_to_win_coords(ED4_ROOT->get_aww(), &x, &y);
969
970    line_x0[0] = x + margin + 2;
971    line_y0[0] = y + margin + 2;
972    line_x1[0] = x + width - margin + 2;
973    line_y1[0] = y + margin + 2;
974
975    line_x0[1] = x + width - margin + 2;
976    line_y0[1] = y + height - margin - 2;
977    line_x1[1] = x + margin + 2;
978    line_y1[1] = y + height - margin - 2;
979
980    line_x0[2] = x + margin + 2;
981    line_y0[2] = y + height - margin - 2;
982    line_x1[2] = x + margin + 2;
983    line_y1[2] = y + margin + 2;
984
985    ED4_group_manager *group_man = get_parent(ED4_L_GROUP)->to_group_manager();
986    ED4_multi_species_manager *multi_man = group_man->get_defined_level(ED4_L_MULTI_SPECIES)->to_multi_species_manager();
987    if (multi_man->get_no_of_selected_species()) {  // if multi_species_manager contains selected species
988        ED4_ROOT->get_device()->box(ED4_G_SELECTED, true, x, y, extension.size[WIDTH], extension.size[HEIGHT], (AW_bitset)-1, 0, 0);
989    }
990
991    if (dynamic_prop & ED4_P_IS_FOLDED) { // paint triangle for folded group
992        arrow_x0[0] = x + margin + 4;
993        arrow_y0[0] = y + margin + 4 + 0;
994        arrow_x1[0] = x + margin + 4;
995        arrow_y1[0] = y + margin + 4 + 10;
996
997        arrow_x0[1] = x + margin + 5;
998        arrow_y0[1] = y + margin + 4 + 1;
999        arrow_x1[1] = x + margin + 5;
1000        arrow_y1[1] = y + margin + 4 + 9;
1001
1002        arrow_x0[2] = x + margin + 6;
1003        arrow_y0[2] = y + margin + 4 + 2;
1004        arrow_x1[2] = x + margin + 6;
1005        arrow_y1[2] = y + margin + 4 + 8;
1006
1007        arrow_x0[3] = x + margin + 7;
1008        arrow_y0[3] = y + margin + 4 + 3;
1009        arrow_x1[3] = x + margin + 7;
1010        arrow_y1[3] = y + margin + 4 + 7;
1011
1012        arrow_x0[4] = x + margin + 8;
1013        arrow_y0[4] = y + margin + 4 + 4;
1014        arrow_x1[4] = x + margin + 8;
1015        arrow_y1[4] = y + margin + 4 + 6;
1016
1017        arrow_x0[5] = x + margin + 9;
1018        arrow_y0[5] = y + margin + 4 + 5;
1019        arrow_x1[5] = x + margin + 9;
1020        arrow_y1[5] = y + margin + 4 + 5;
1021
1022        for( i = 0; i < 6; i++ ) {
1023            ED4_ROOT->get_device()->line( ED4_G_STANDARD, arrow_x0[i], arrow_y0[i], arrow_x1[i], arrow_y1[i], 1, 0, 0 );
1024        }
1025    }
1026    else {
1027        arrow_x0[0] = x + margin + 4 + 0;
1028        arrow_y0[0] = y + margin + 4;
1029        arrow_x1[0] = x + margin + 4 + 4;
1030        arrow_y1[0] = y + margin + 4;
1031
1032        arrow_x0[1] = x + margin + 4 + 0;
1033        arrow_y0[1] = y + margin + 5;
1034        arrow_x1[1] = x + margin + 4 + 4;
1035        arrow_y1[1] = y + margin + 5;
1036
1037        arrow_x0[2] = x + margin + 4 + 1;
1038        arrow_y0[2] = y + margin + 6;
1039        arrow_x1[2] = x + margin + 4 + 3;
1040        arrow_y1[2] = y + margin + 6;
1041
1042        arrow_x0[3] = x + margin + 4 + 1;
1043        arrow_y0[3] = y + margin + 7;
1044        arrow_x1[3] = x + margin + 4 + 3;
1045        arrow_y1[3] = y + margin + 7;
1046
1047        arrow_x0[4] = x + margin + 4 + 2;
1048        arrow_y0[4] = y + margin + 8;
1049        arrow_x1[4] = x + margin + 4 + 2;
1050        arrow_y1[4] = y + margin + 8;
1051
1052        arrow_x0[5] = x + margin + 4 + 2;
1053        arrow_y0[5] = y + margin + 9;
1054        arrow_x1[5] = x + margin + 4 + 2;
1055        arrow_y1[5] = y + margin + 9;
1056
1057        for( i = 0; i < 6; i++ ) {
1058            ED4_ROOT->get_device()->line( ED4_G_STANDARD, arrow_x0[i], arrow_y0[i], arrow_x1[i], arrow_y1[i], 1, 0, 0 );
1059        }
1060    }
1061
1062    for( i = 0; i <= 2; i++ ) {
1063        ED4_ROOT->get_device()->line( ED4_G_STANDARD, line_x0[i], line_y0[i], line_x1[i], line_y1[i], 1, 0, 0 );
1064    }
1065
1066    return ( ED4_R_OK );
1067}
1068
1069ED4_bracket_terminal::~ED4_bracket_terminal()
1070{
1071}
1072
1073ED4_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 ) :
1074    ED4_text_terminal( temp_id, x, y, width, height, temp_parent )
1075{
1076    spec = &(species_name_terminal_spec);
1077}
1078
1079
1080ED4_species_name_terminal::~ED4_species_name_terminal()
1081{
1082}
1083
1084#define MAXNAMELEN MAXSPECIESWIDTH
1085#define BUFFERSIZE (MAXNAMELEN<<1)
1086GB_CSTR ED4_species_name_terminal::get_displayed_text() const
1087{
1088    static char *real_name;
1089    static int allocatedSize;
1090
1091    if (!real_name || allocatedSize<(BUFFERSIZE+1)) {
1092        free(real_name);
1093        allocatedSize = BUFFERSIZE+1;
1094        real_name = (char*)malloc(allocatedSize);
1095    }
1096    memset(real_name, 0, allocatedSize);
1097
1098    if (parent->flag.is_consensus) {
1099        char *db_pointer = resolve_pointer_to_string_copy();
1100        char *bracket = strchr(db_pointer, '(');
1101
1102        if (bracket) {
1103            int bracket_len = strlen(bracket);
1104            int name_len = bracket-db_pointer;
1105
1106            if (bracket[-1]==' ') {
1107                name_len--;
1108            }
1109
1110            if ((name_len+1+bracket_len)<=MAXNAMELEN) {
1111                strcpy(real_name, db_pointer);
1112            }
1113            else {
1114                int short_name_len = MAXNAMELEN-bracket_len-1;
1115
1116                memcpy(real_name, db_pointer, short_name_len);
1117                real_name[short_name_len] = ' ';
1118                strcpy(real_name+short_name_len+1, bracket);
1119            }
1120        }
1121        else {
1122            strncpy(real_name, db_pointer, BUFFERSIZE);
1123        }
1124
1125        free(db_pointer);
1126    }
1127    else if (parent->parent->parent->flag.is_SAI) { // whether species_manager has is_SAI flag
1128        char *db_pointer = resolve_pointer_to_string_copy();
1129
1130        strcpy(real_name, "SAI: ");
1131        if (strcmp(db_pointer, "ECOLI")==0) {
1132            const char *name_for_ecoli = ED4_ROOT->aw_root->awar(ED4_AWAR_NDS_ECOLI_NAME)->read_char_pntr();
1133            if (name_for_ecoli[0]==0) name_for_ecoli = db_pointer;
1134            strncpy(real_name+5, name_for_ecoli, BUFFERSIZE-5);
1135        }
1136        else {
1137            strncpy(real_name+5, db_pointer, BUFFERSIZE-5);
1138        }
1139        free(db_pointer);
1140    }
1141    else { // normal species
1142        ED4_species_manager *species_man = get_parent(ED4_L_SPECIES)->to_species_manager();
1143        char *result = ED4_get_NDS_text(species_man);
1144
1145        strncpy(real_name, result, BUFFERSIZE);
1146        free(result);
1147    }
1148
1149    return real_name;
1150}
1151#undef MAXNAMELEN
1152#undef BUFFERSIZE
1153
1154
1155ED4_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 )
1156    : ED4_text_terminal( temp_id, x, y, width, height, temp_parent )
1157{
1158    spec = &(sequence_info_terminal_spec);
1159    // gbdata = gbd;
1160}
1161
1162
1163ED4_sequence_info_terminal::~ED4_sequence_info_terminal()
1164{
1165}
1166
1167ED4_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 )
1168    : ED4_sequence_terminal( temp_id, x, y, width, height, temp_parent )
1169{
1170    spec = &(sequence_terminal_spec);
1171    species_name = NULL;
1172}
1173
1174ED4_consensus_sequence_terminal::~ED4_consensus_sequence_terminal()
1175{
1176}
1177
1178ED4_sequence_terminal_basic::ED4_sequence_terminal_basic(const char *temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent )
1179    : ED4_text_terminal( temp_id, x, y, width, height, temp_parent )
1180{
1181    spec = &(sequence_terminal_spec);
1182    species_name = NULL;
1183}
1184
1185ED4_sequence_terminal_basic::~ED4_sequence_terminal_basic() {
1186    free(species_name);
1187}
1188
1189ED4_AA_sequence_terminal::ED4_AA_sequence_terminal(const char *temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent )
1190    : ED4_sequence_terminal_basic( temp_id, x, y, width, height, temp_parent )
1191{
1192    spec = &(sequence_terminal_spec);
1193    aaSequence   = 0;
1194    aaStartPos   = 0;
1195    aaStrandType = 0;
1196}
1197
1198GB_alignment_type ED4_AA_sequence_terminal::GetAliType()
1199{
1200    return (GB_alignment_type) GB_AT_AA;
1201}
1202
1203ED4_AA_sequence_terminal::~ED4_AA_sequence_terminal()
1204{
1205    delete aaSequence;
1206}
1207
1208ED4_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 )
1209    : ED4_sequence_terminal_basic( temp_id, x, y, width, height, temp_parent )
1210{
1211    spec = &(sequence_terminal_spec);
1212    //    species_name = NULL;
1213    st_ml_node = NULL;
1214}
1215
1216GB_alignment_type ED4_sequence_terminal::GetAliType()
1217{
1218    return ED4_ROOT->alignment_type;
1219}
1220
1221ED4_sequence_terminal::~ED4_sequence_terminal()
1222{
1223}
1224
1225ED4_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 )
1226    : ED4_text_terminal( temp_id, x, y, width, height, temp_parent )
1227{
1228    spec = &pure_text_terminal_spec;
1229}
1230
1231ED4_pure_text_terminal::~ED4_pure_text_terminal()
1232{
1233}
1234
1235
1236ED4_returncode ED4_spacer_terminal::Show(int /*refresh_all*/, int is_cleared) // a spacer terminal doesn't show anything - it's just a dummy terminal
1237{
1238    if (update_info.clear_at_refresh && !is_cleared) {
1239        clear_background();
1240    }
1241    draw();
1242    return ED4_R_OK;
1243}
1244
1245
1246ED4_returncode ED4_spacer_terminal::draw( int /*only_text*/ )                   // draws bounding box of object
1247{
1248#if defined(DEBUG) && 0
1249    clear_background(ED4_G_FIRST_COLOR_GROUP); // draw colored spacers to make them visible
1250#else
1251    clear_background(0);
1252#endif // DEBUG
1253    return ( ED4_R_OK );
1254}
1255
1256ED4_spacer_terminal::ED4_spacer_terminal(const char *temp_id, AW_pos x, AW_pos y, AW_pos width, AW_pos height, ED4_manager *temp_parent )
1257    : ED4_terminal( temp_id, x, y, width, height, temp_parent )
1258{
1259    spec = &(spacer_terminal_spec);
1260}
1261
1262
1263ED4_spacer_terminal::~ED4_spacer_terminal()
1264{
1265}
1266
1267ED4_returncode ED4_line_terminal::draw( int /*only_text*/ )     // draws bounding box of object
1268{
1269    AW_pos x1, y1;
1270    calc_world_coords(&x1, &y1);
1271    ED4_ROOT->world_to_win_coords(ED4_ROOT->get_aww(), &x1, &y1);
1272
1273    AW_pos x2 = x1+extension.size[WIDTH]-1;
1274    AW_pos y2 = y1+extension.size[HEIGHT]-1;
1275
1276    AW_device *device = ED4_ROOT->get_device();
1277
1278    device->line(ED4_G_STANDARD, x1, y1, x2, y1, -1, 0, 0);
1279#if defined(DEBUG)
1280    device->box(ED4_G_MARKED, true, x1, y1+1, x2-x1+1, y2-y1-1, -1, 0, 0);
1281#else
1282    device->clear_part(x1, y1+1, x2-x1+1, y2-y1-1, -1);
1283#endif // DEBUG
1284    device->line(ED4_G_STANDARD, x1, y2, x2, y2, -1, 0, 0);
1285
1286    return ED4_R_OK;
1287}
1288
1289ED4_returncode ED4_line_terminal::Show(int /*refresh_all*/, int is_cleared)
1290{
1291    if (update_info.clear_at_refresh && !is_cleared) {
1292        clear_background();
1293    }
1294    draw();
1295    return ED4_R_OK;
1296}
1297
1298
1299ED4_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 )
1300    : ED4_terminal( temp_id, x, y, width, height, temp_parent )
1301{
1302    spec = &(line_terminal_spec);
1303}
1304
1305ED4_line_terminal::~ED4_line_terminal()
1306{
1307}
1308
1309// --------------------------------------------------------------------------------
1310//  ED4_columnStat_terminal
1311// --------------------------------------------------------------------------------
1312
1313ED4_returncode ED4_columnStat_terminal::Show(int IF_DEBUG(refresh_all), int is_cleared)
1314{
1315    e4_assert(update_info.refresh || refresh_all);
1316    ED4_ROOT->get_device()->push_clip_scale();
1317    if (adjust_clipping_rectangle()) {
1318        if (update_info.clear_at_refresh && !is_cleared) {
1319            clear_background();
1320        }
1321        draw();
1322    }
1323    ED4_ROOT->get_device()->pop_clip_scale();
1324
1325    return ED4_R_OK;
1326}
1327
1328inline char stat2display(int val, bool is_upper_digit) {
1329    if (val<0) {
1330        e4_assert(val==-1); // -1 indicates that no statistic is existing for that column
1331        return '?';
1332    }
1333    if (val==20) return ' '; // value if ACGT and - are distributed equally
1334    if (val==100) return '^'; // we have only 2 characters to display likelihood (100 cannot be displayed)
1335
1336    e4_assert(val>=0 && val<100);
1337
1338    return '0' + (is_upper_digit ? (val/10) : (val%10));
1339}
1340
1341inline int find_significant_positions(int sig, int like_A, int like_C, int like_G, int like_TU, int *sumPtr) {
1342    // result == 0      -> no base-char has a significant likelihood (>=sig)
1343    // result == 1, 2, 4, 8     -> A, C, G, T/U has a significant likelihood
1344    // else             -> the sum two of the likelihoods >= sig (bit-or-ed as in line above)
1345
1346    int like[4];
1347    like[0] = like_A;
1348    like[1] = like_C;
1349    like[2] = like_G;
1350    like[3] = like_TU;
1351
1352    int bestSum = 0;
1353    int bestResult = 0;
1354
1355    int b, c;
1356    for (b=0; b<4; b++) {
1357        int sum = like[b];
1358        if (sum>=sig && sum>=bestSum) {
1359            bestSum = sum;
1360            bestResult = 1<<b;
1361        }
1362    }
1363
1364    if (!bestResult) {
1365        for (b=0; b<4; b++) {
1366            for (c=b+1; c<4; c++) {
1367                int sum = like[b]+like[c];
1368                if (sum>=sig && sum>=bestSum) {
1369                    bestSum = sum;
1370                    bestResult = (1<<b)|(1<<c);
1371                }
1372            }
1373        }
1374    }
1375
1376    if (bestResult) {
1377        if (sumPtr) *sumPtr = bestSum;
1378        return bestResult;
1379    }
1380
1381    return 0;
1382}
1383
1384#define PROBE_MATCH_TARGET_STRING_LENGTH 32
1385
1386GB_CSTR ED4_columnStat_terminal::build_probe_match_string(int start_pos, int end_pos) const {
1387    static char            result[PROBE_MATCH_TARGET_STRING_LENGTH+1]; // see create_probe_match_window() for length
1388    int                    max_insert   = PROBE_MATCH_TARGET_STRING_LENGTH;
1389    char                  *r            = result;
1390    int                    significance = int(get_threshold());
1391    ED4_sequence_terminal *seq_term     = corresponding_sequence_terminal()->to_sequence_terminal();
1392    char                  *seq          = seq_term->resolve_pointer_to_string_copy();
1393
1394    for (int pos=start_pos; pos<=end_pos; pos++) {
1395        int found = find_significant_positions(significance, likelihood[0][pos], likelihood[1][pos], likelihood[2][pos], likelihood[3][pos], 0);
1396
1397        if (found || strchr("-=.", seq[pos])==0) {
1398            // '?' is inserted at every base position without significant bases (not at gaps!)
1399
1400            *r++ = "NACMGRSVUWYHKDBN"[found]; // this creates a string containing the full IUPAC code
1401            //*r++ = "NACNGNNNUNNNNNNN"[found]; // this creates a string containing only ACGU + N
1402
1403            if (max_insert--==0) {
1404                r--;
1405                break;
1406            }
1407        }
1408    }
1409    r[0] = 0;
1410    free(seq);
1411
1412    if (max_insert<0) {
1413        aw_message(GBS_global_string("Max. %i bases allowed in Probe Match", PROBE_MATCH_TARGET_STRING_LENGTH));
1414        result[0] = 0;
1415    }
1416    return result;
1417}
1418#undef PROBE_MATCH_TARGET_STRING_LENGTH
1419
1420ED4_returncode ED4_columnStat_terminal::draw(int /*only_text*/)
1421{
1422#warning test drawing of ED4_columnStat_terminal
1423    if (!update_likelihood()) {
1424        aw_popup_ok("Can't calculate likelihood.");
1425        return ED4_R_IMPOSSIBLE;
1426    }
1427
1428    AW_pos x, y;
1429    calc_world_coords(&x, &y);
1430    ED4_ROOT->world_to_win_coords(ED4_ROOT->get_aww(), &x, &y);
1431
1432    AW_pos term_height = extension.size[HEIGHT];
1433    AW_pos font_height = ED4_ROOT->font_group.get_height(ED4_G_SEQUENCES);
1434    AW_pos font_width  = ED4_ROOT->font_group.get_width(ED4_G_SEQUENCES);
1435
1436    AW_pos text_x = x + CHARACTEROFFSET;
1437    AW_pos text_y = y + term_height - (font_height /*+ ED4_ROOT->font_info[ED4_G_SEQUENCES].get_descent()*/ );
1438
1439    AW_device *device = ED4_ROOT->get_device();
1440    ED4_sequence_terminal *seq_term = corresponding_sequence_terminal();
1441    const ED4_remap *rm = ED4_ROOT->root_group_man->remap();
1442    long left,right;
1443    seq_term->calc_update_intervall(&left, &right );
1444    rm->clip_screen_range(&left, &right);
1445
1446    {
1447        int max_seq_len = seq_term->get_length();
1448        int max_seq_pos = rm->sequence_to_screen_clipped(max_seq_len);
1449
1450        if (right>max_seq_len) right = max_seq_pos;
1451        if (left>right) return ED4_R_OK;
1452    }
1453
1454    //int seq_start = rm->screen_to_sequence(left); // real start of sequence
1455    char *sbuffer = new char[right+1];  // used to build displayed terminal content  (values = '0'-'9')
1456    memset(sbuffer, ' ', right);
1457    sbuffer[right] = 0; // eos
1458
1459    AW_pos y2;
1460    int r;
1461
1462    // Set background:
1463    {
1464        int significance = int(get_threshold());
1465        // normal columns are colored in ED4_G_STANDARD
1466        // all columns with one (or sum of two) probability above 'significance' are back-colored in ED4_G_CBACK_0
1467        // the responsible probabilities (one or two) are back-colored in ED4_G_CBACK_1..ED4_G_CBACK_9
1468
1469        int color = ED4_G_STANDARD;
1470        int old_color = ED4_G_STANDARD;
1471        AW_pos x2 = text_x + font_width*left + 1;
1472        AW_pos old_x2 = x2;
1473        int i;
1474        int selection_col1, selection_col2;
1475        int is_selected = ED4_get_selected_range(seq_term, &selection_col1, &selection_col2);
1476
1477        for (i=left; i<=right; i++,x2+=font_width) { // colorize significant columns in ALL rows
1478            int p = rm->screen_to_sequence(i);
1479            int found = find_significant_positions(significance, likelihood[0][p], likelihood[1][p], likelihood[2][p], likelihood[3][p], 0);
1480
1481            if (found)  color = ED4_G_CBACK_0;
1482            else    color = ED4_G_STANDARD;
1483
1484            if (is_selected && p>=selection_col1 && p<=selection_col2) {
1485                color = ED4_G_SELECTED;
1486            }
1487
1488            if (color!=old_color) {
1489                if (x2>old_x2 && old_color!=ED4_G_STANDARD) {
1490                    device->box(old_color, true, old_x2, y, x2-old_x2, term_height, -1, 0, 0);
1491                }
1492                old_color = color;
1493                old_x2 = x2;
1494            }
1495        }
1496        if (x2>old_x2 && old_color!=ED4_G_STANDARD) {
1497            device->box(old_color, true, old_x2, y, x2-old_x2, term_height, -1, 0, 0);
1498        }
1499
1500        color = ED4_G_STANDARD;
1501        x2 = text_x + font_width*left + 1;
1502
1503        for (i=left; i<=right; i++,x2+=font_width) { // colorize significant columns in SINGLE rows
1504            int p = rm->screen_to_sequence(i);
1505            int sum;
1506            int found = find_significant_positions(significance, likelihood[0][p], likelihood[1][p], likelihood[2][p], likelihood[3][p], &sum);
1507
1508            if (found) {
1509                e4_assert(sum>=significance && sum<=100);
1510                color = ED4_G_CBACK_1+((sum-significance)*(ED4_G_CBACK_9-ED4_G_CBACK_1))/(100-significance);
1511                e4_assert(color>=ED4_G_CBACK_1 && color<=ED4_G_CBACK_9);
1512            }
1513            else {
1514                color = ED4_G_STANDARD;
1515            }
1516
1517            if (color!=ED4_G_STANDARD) {
1518                int bit;
1519
1520                for (r=3,y2=text_y+1,bit=1<<3;
1521                     r>=0;
1522                     r--,y2-=COLUMN_STAT_ROW_HEIGHT(font_height),bit>>=1)
1523                {
1524                    if (found&bit) {
1525                        device->box(color, true, x2, y2-2*font_height+1, font_width, 2*font_height, -1, 0, 0);
1526                    }
1527                }
1528            }
1529        }
1530    }
1531
1532    // Draw text:
1533    for (r=3, y2=text_y;
1534         r>=0;
1535         r--, y2-=COLUMN_STAT_ROW_HEIGHT(font_height)) { // 4 rows (one for T/U, G, C and A)
1536
1537        int gc = ED4_ROOT->sequence_colors->char_2_gc[(unsigned char)"ACGU"[r]];
1538        int i;
1539        for (i=left; i<=right; i++) {
1540            int p = rm->screen_to_sequence(i);
1541            int val = likelihood[r][p];
1542            sbuffer[i] = stat2display(val, 0); // calc lower digit
1543        }
1544        device->text(gc, sbuffer, text_x+font_width*0.2, y2, 0, 1, 0, 0, right); // draw lower-significant digit (shifted a bit to the right)
1545
1546        for (i=left; i<=right; i++) {
1547            int p = rm->screen_to_sequence(i);
1548            int val = likelihood[r][p];
1549            sbuffer[i] = stat2display(val, 1); // calc upper digit
1550        }
1551        device->text(gc, sbuffer, text_x, y2-font_height, 0, 1, 0, 0, right); // draw higher-significant digit
1552    }
1553
1554    free(sbuffer);
1555    return ED4_R_OK;
1556}
1557
1558int ED4_columnStat_terminal::update_likelihood() {
1559    ED4_sequence_terminal *seq_term = corresponding_sequence_terminal();
1560
1561    return st_ml_update_ml_likelihood(ED4_ROOT->st_ml, likelihood, &latest_update, 0, seq_term->st_ml_node);
1562}
1563
1564ED4_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) :
1565    ED4_text_terminal(temp_id, x, y, width, height, temp_parent)
1566{
1567    spec = &(column_stat_terminal_spec);
1568    for (int i=0; i<4; i++) likelihood[i] = 0;
1569    latest_update = 0;
1570}
1571
1572ED4_columnStat_terminal::~ED4_columnStat_terminal()
1573{
1574    for (int i=0; i<4; i++) free(likelihood[i]);
1575}
1576
1577// --------------------------------------------------------------------------------
1578//  ED4_reference_terminals
1579// --------------------------------------------------------------------------------
1580
1581void ED4_reference_terminals::clear()
1582{
1583    delete ref_sequence_info;
1584    delete ref_sequence;
1585    delete ref_column_stat;
1586    delete ref_column_stat_info;
1587    null();
1588}
1589
1590void ED4_reference_terminals::init(ED4_sequence_info_terminal *ref_sequence_info_,
1591                                   ED4_sequence_terminal *ref_sequence_,
1592                                   ED4_sequence_info_terminal *ref_column_stat_info_,
1593                                   ED4_columnStat_terminal *ref_column_stat_)
1594{
1595    clear();
1596    ref_sequence_info    = ref_sequence_info_;
1597    ref_sequence     = ref_sequence_;
1598    ref_column_stat_info = ref_column_stat_info_;
1599    ref_column_stat      = ref_column_stat_;
1600}
Note: See TracBrowser for help on using the repository browser.