ARB
ED4_cursor.cxx
Go to the documentation of this file.
1 #include <cctype>
2 #include <climits>
3 
4 #include <arbdbt.h>
5 #include <aw_awars.hxx>
6 #include <AW_helix.hxx>
7 #include <BI_basepos.hxx>
8 #include <aw_msg.hxx>
9 #include <arb_progress.h>
10 #include <aw_root.hxx>
11 #include <iupac.h>
12 
13 #include <ed4_extern.hxx>
14 
15 #include "ed4_class.hxx"
16 #include "ed4_edit_string.hxx"
17 #include "ed4_tools.hxx"
18 #include "ed4_awars.hxx"
19 #include "ed4_ProteinViewer.hxx"
20 #include "ed4_seq_colors.hxx"
21 
22 #include <arb_strbuf.h>
23 #include <arb_defs.h>
24 
25 /* --------------------------------------------------------------------------------
26  CursorShape
27  -------------------------------------------------------------------------------- */
28 
29 #define MAXLINES 30
30 #define MAXPOINTS (2*MAXLINES)
31 
33  int points;
34  int xpos[MAXPOINTS];
35  int ypos[MAXPOINTS];
36 
37  int lines;
38  int start[MAXLINES];
39  int end[MAXLINES];
40 
41  int char_width;
42 
43  bool reverse;
44 
45  int point(int x, int y) {
46  e4_assert(points<MAXPOINTS);
47  if (reverse) {
48  xpos[points] = char_width-x;
49  }
50  else {
51  xpos[points] = x;
52  }
53  ypos[points] = y;
54  return points++;
55  }
56  int line(int p1, int p2) {
57  e4_assert(p1>=0 && p1<points);
58  e4_assert(p2>=0 && p2<points);
59 
60  e4_assert(lines<MAXLINES);
61  start[lines] = p1;
62  end[lines] = p2;
63 
64  return lines++;
65  }
66  int horizontal_line(int x, int y, int half_width) {
67  return line(point(x-half_width, y), point(x+half_width, y));
68  }
69 
70 public:
71 
72  ED4_CursorShape(ED4_CursorType type, int term_height, int character_width, bool reverse_cursor);
74 
75  void draw(AW_device *device, int x, int y) const {
76  e4_assert(lines);
77  for (int l=0; l<lines; l++) {
78  int p1 = start[l];
79  int p2 = end[l];
80  device->line(ED4_G_CURSOR, xpos[p1]+x, ypos[p1]+y, xpos[p2]+x, ypos[p2]+y, AW_SCREEN);
81  }
82  device->flush();
83  }
84 
85  void get_bounding_box(int x, int y, int &xmin, int &ymin, int &xmax, int &ymax) const {
86  e4_assert(points);
87  xmin = ymin = INT_MAX;
88  xmax = ymax = INT_MIN;
89  for (int p=0; p<points; p++) {
90  if (xpos[p]<xmin) { xmin = xpos[p]; }
91  else if (xpos[p]>xmax) { xmax = xpos[p]; }
92  if (ypos[p]<ymin) { ymin = ypos[p]; }
93  else if (ypos[p]>ymax) { ymax = ypos[p]; }
94  }
95 
96  xmin += x; xmax += x;
97  ymin += y; ymax += y;
98  }
99 
100 
101 };
102 
103 ED4_CursorShape::ED4_CursorShape(ED4_CursorType typ, /* int x, int y, */ int term_height, int character_width, bool reverse_cursor) {
104  lines = 0;
105  points = 0;
106  reverse = reverse_cursor;
107  char_width = character_width;
108 
109  int x = 0;
110  int y = 0;
111 
112  switch (typ) {
113 #define UPPER_OFFSET (-1)
114 #define LOWER_OFFSET (term_height-1)
115 #define CWIDTH (character_width)
116 
119  // --CWIDTH--
120  //
121  // 0--------1 UPPER_OFFSET (from top)
122  // |3-------4
123  // ||
124  // ||
125  // ||
126  // ||
127  // ||
128  // ||
129  // 25 LOWER_OFFSET (from top)
130  //
131  //
132  // x
133 
134  if (typ == ED4_RIGHT_ORIENTED_CURSOR) { // non-thin version
135  int p0 = point(x-1, y+UPPER_OFFSET);
136 
137  line(p0, point(x+CWIDTH-1, y+UPPER_OFFSET)); // 0->1
138  line(p0, point(x-1, y+LOWER_OFFSET)); // 0->2
139  }
140 
141  int p3 = point(x, y+UPPER_OFFSET+1);
142 
143  line(p3, point(x+CWIDTH-1, y+UPPER_OFFSET+1)); // 3->4
144  line(p3, point(x, y+LOWER_OFFSET)); // 3->5
145 
146  break;
147 
148 #undef UPPER_OFFSET
149 #undef LOWER_OFFSET
150 #undef CWIDTH
151 
152  }
155  case ED4_TRADITIONAL_CURSOR: {
156  int small_version = (term_height <= 10) ? 1 : 0;
157 
158 
159 #define UPPER_OFFSET 0
160 #define LOWER_OFFSET (term_height-1)
161 #define CWIDTH 3
162 
163  // -----2*CWIDTH----
164  //
165  // 0---------------1 UPPER_OFFSET (from top)
166  // 4---------5
167  // 8---9
168  // C/C
169  //
170  // D/D
171  // A---B
172  // 6---------7
173  // 2---------------3 LOWER_OFFSET (from top)
174 
175  bool draw_upper = typ != ED4_TRADITIONAL_CURSOR_BOTTOM;
176 
177  if (draw_upper) horizontal_line(x, y+UPPER_OFFSET, CWIDTH-small_version); // 0/1
178  horizontal_line(x, y+LOWER_OFFSET, CWIDTH-small_version); // 2/3
179 
180  if (draw_upper) horizontal_line(x, y+UPPER_OFFSET+1, (CWIDTH*2)/3-small_version); // 4/5
181  horizontal_line(x, y+LOWER_OFFSET-1, (CWIDTH*2)/3-small_version); // 6/7
182 
183  if (!small_version) {
184  if (draw_upper) horizontal_line(x, y+UPPER_OFFSET+2, CWIDTH/3); // 8/9
185  horizontal_line(x, y+LOWER_OFFSET-2, CWIDTH/3); // A/B
186  }
187 
188  int pu = point(x, y+UPPER_OFFSET+3-small_version);
189  int pl = point(x, y+LOWER_OFFSET-3+small_version);
190 
191  if (draw_upper) line(pu, pu); // C/C
192  line(pl, pl); // D/D
193 
195  int pu2 = point(x, y+UPPER_OFFSET+5-small_version);
196  int pl2 = point(x, y+LOWER_OFFSET-5+small_version);
197  line(pu2, pl2);
198  }
199 
200  break;
201 
202 #undef UPPER_OFFSET
203 #undef LOWER_OFFSET
204 #undef CWIDTH
205 
206  }
207  case ED4_FUCKING_BIG_CURSOR: {
208 
209 #define OUTER_HEIGHT (term_height/4)
210 #define INNER_HEIGHT (term_height-1)
211 #define CWIDTH 12
212 #define STEPS 6
213 #define THICKNESS 2
214 
215 #if (2*STEPS+THICKNESS > MAXLINES)
216 #error Bad definitions!
217 #endif
218 
219  // 2 3 |
220  // \ / | OUTER_HEIGHT
221  // \ / |
222  // 0 | |
223  // | | INNER_HEIGHT
224  // | |
225  // 1 |
226  // / \ --
227  // / \ --
228  // 4 5
229  //
230  // -----------------
231  // 2*WIDTH
232 
233  int s;
234  for (s=0; s<STEPS; s++) {
235  int size = ((STEPS-s)*CWIDTH)/STEPS;
236 
237  horizontal_line(x, y-OUTER_HEIGHT+s, size);
238  horizontal_line(x, y+INNER_HEIGHT+OUTER_HEIGHT-s, size);
239  }
240 
241  int y_upper = ypos[s-4];
242  int y_lower = ypos[s-2];
243 
244  int t;
245  for (t=0; t<THICKNESS; t++) {
246  int xp = x-(THICKNESS/2)+t+1;
247  line(point(xp, y_upper), point(xp, y_lower));
248  }
249 
250  break;
251 
252 #undef OUTER_HEIGHT
253 #undef INNER_HEIGHT
254 #undef CWIDTH
255 #undef STEPS
256 #undef THICKNESS
257 
258  }
259  default: {
260  e4_assert(0);
261  break;
262  }
263  }
264 }
265 
266 /* --------------------------------------------------------------------------------
267  ED4_cursor
268  -------------------------------------------------------------------------------- */
269 
270 static bool allow_update_global_cursorpos = true;
271 
272 ED4_returncode ED4_cursor::draw_cursor(AW_pos x, AW_pos y) { // @@@ remove return value
273  if (cursor_shape) {
274  delete cursor_shape;
275  cursor_shape = NULp;
276  }
277 
278  cursor_shape = new ED4_CursorShape(ctype,
282 
283  cursor_shape->draw(window()->get_device(), int(x), int(y));
284 
285 #if defined(TRACE_REFRESH)
286  printf("draw_cursor(%i, %i)\n", int(x), int(y));
287 #endif // TRACE_REFRESH
288 
289  return ED4_R_OK;
290 }
291 
292 ED4_returncode ED4_cursor::delete_cursor(AW_pos del_mark, ED4_base *target_terminal) {
293  AW_pos x, y;
294  target_terminal->calc_world_coords(&x, &y);
295  ED4_base *temp_parent = target_terminal->get_parent(LEV_SPECIES);
296  if (!temp_parent || temp_parent->flag.hidden || !is_partly_visible()) {
297  return ED4_R_BREAK;
298  }
299 
300  x = del_mark;
301  win->world_to_win_coords(&x, &y);
302 
303  // refresh own terminal + terminal above + terminal below
304 
305  const int MAX_AFFECTED = 3;
306  int affected = 0;
307  ED4_terminal *affected_terminal[MAX_AFFECTED];
308 
309  affected_terminal[affected++] = target_terminal->to_terminal();
310 
311  {
312  ED4_terminal *term = target_terminal->to_terminal();
313  bool backward = true;
314 
315  while (1) {
316  int done = 0;
317 
318  term = backward ? term->get_prev_terminal() : term->get_next_terminal();
319  if (!term) done = 1;
320  else if ((term->is_sequence_terminal()) && !term->is_in_folded_group()) {
321  affected_terminal[affected++] = term;
322  done = 1;
323  }
324 
325  if (done) {
326  if (!backward) break;
327  backward = false;
328  term = target_terminal->to_terminal();
329  }
330  }
331  }
332 
333  bool refresh_was_requested[MAX_AFFECTED];
334  e4_assert(affected >= 1 && affected <= MAX_AFFECTED);
335  for (int a = 0; a<affected; ++a) {
336  ED4_terminal *term = affected_terminal[a];
337  refresh_was_requested[a] = term->update_info.refresh;
338  term->request_refresh();
339  }
340 
341  // clear rectangle where cursor is displayed
342 
343  AW_device *dev = win->get_device();
344  dev->push_clip_scale();
345 
346  int xmin, xmax, ymin, ymax;
347 
348  e4_assert(cursor_shape);
349  cursor_shape->get_bounding_box(int(x), int(y), xmin, ymin, xmax, ymax);
350 
351 #if defined(TRACE_REFRESH)
352  printf("delete_cursor(%i, %i)\n", int(x), int(y));
353 #endif // TRACE_REFRESH
354 
355  dev->set_font_overlap(true);
356 
357 #define EXPAND_SIZE 0
358  if (dev->reduceClipBorders(ymin-EXPAND_SIZE, ymax+EXPAND_SIZE, xmin-EXPAND_SIZE, xmax+EXPAND_SIZE)) {
359  dev->clear_part(xmin, ymin, xmax-xmin+1, ymax-ymin+1, AW_ALL_DEVICES);
360  // refresh terminal to hide cursor
361  ED4_LocalWinContext uses(window());
364  }
365  dev->pop_clip_scale();
366 
367  // restore old refresh flags (to avoid refresh of 3 complete terminals when cursor changes)
368  for (int a = 0; a<affected; ++a) {
369  affected_terminal[a]->update_info.refresh = refresh_was_requested[a];
370  }
371 
372  return ED4_R_OK;
373 }
374 
375 
377  init();
378  allowed_to_draw = true;
379  cursor_shape = NULp;
380 
382 }
384  // used by ED4_terminal-d-tor
386  cursor_abs_x = 0;
387  screen_position = 0;
388 }
390  delete cursor_shape;
391 }
392 
394  ED4_remap *remap = ED4_ROOT->root_group_man->remap();
395  size_t max_scrpos = remap->get_max_screen_pos();
396 
397  return remap->screen_to_sequence(size_t(screen_position)<=max_scrpos ? screen_position : max_scrpos);
398 }
399 
400 bool ED4_species_manager::setCursorTo(ED4_cursor *cursor, int seq_pos, bool unfold_groups, ED4_CursorJumpType jump_type) {
401  ED4_group_manager *group_manager_to_unfold = is_in_folded_group();
402 
403  if (unfold_groups) {
404  bool did_unfold = false;
405 
406  while (group_manager_to_unfold && unfold_groups) {
407  group_manager_to_unfold->unfold();
408  did_unfold = true;
409  group_manager_to_unfold = is_in_folded_group();
410  }
411 
412  if (did_unfold) ED4_ROOT->refresh_all_windows(1); // needed to recalculate world cache of target terminal
413  }
414 
415  if (!group_manager_to_unfold) { // species manager is visible (now)
416  ED4_terminal *terminal = search_spec_child_rek(LEV_SEQUENCE_STRING)->to_terminal();
417  if (terminal) {
418  if (seq_pos == -1) seq_pos = cursor->get_sequence_pos();
419  cursor->set_to_terminal(terminal, seq_pos, jump_type);
420  return true;
421  }
422  }
423 
424  return false;
425 }
426 
427 static void jump_to_corresponding_seq_terminal(ED4_species_name_terminal *name_term, bool unfold_groups) {
428  ED4_species_manager *species_manager = name_term->get_parent(LEV_SPECIES)->to_species_manager();
429  ED4_cursor *cursor = &current_cursor();
430  bool jumped = false;
431 
432  if (species_manager) jumped = species_manager->setCursorTo(cursor, -1, unfold_groups, ED4_JUMP_KEEP_POSITION);
433  if (!jumped) cursor->HideCursor();
434 }
435 
437 static bool ignore_selected_SAI_changes_cb = false;
438 
439 static void select_named_sequence_terminal(const char *name) {
441  ED4_species_name_terminal *name_term = ED4_find_species_or_SAI_name_terminal(name);
442  if (name_term) {
443  ED4_MostRecentWinContext context; // use the last used window for selection
444 
445  // lookup current name term
446  ED4_species_name_terminal *cursor_name_term = NULp;
447  {
448  ED4_cursor *cursor = &current_cursor();
449  if (cursor) {
450  ED4_sequence_terminal *cursor_seq_term = NULp;
451 
452  if (cursor->owner_of_cursor) {
453  ED4_terminal *cursor_term = cursor->owner_of_cursor->to_text_terminal();
454  if (cursor_term->is_sequence_terminal()) {
455  cursor_seq_term = cursor_term->to_sequence_terminal();
456  }
457  else { // cursor is in a non-sequence text terminal -> search for corresponding sequence terminal
458  ED4_multi_sequence_manager *seq_man = cursor_term->get_parent(LEV_MULTI_SEQUENCE)->to_multi_sequence_manager();
459  if (seq_man) {
460  cursor_seq_term = seq_man->search_spec_child_rek(LEV_SEQUENCE_STRING)->to_sequence_terminal();
461  }
462  }
463  }
464  if (cursor_seq_term) {
465  cursor_name_term = cursor_seq_term->corresponding_species_name_terminal();
466  }
467  }
468  }
469 
470  if (name_term!=cursor_name_term) { // do not change if already there!
471 #if defined(TRACE_JUMPS)
472  printf("Jumping to species/SAI '%s'\n", name);
473 #endif
474  jump_to_corresponding_seq_terminal(name_term, false);
475  }
476  else {
477 #if defined(TRACE_JUMPS)
478  printf("Change ignored because same name term!\n");
479 #endif
480  }
481  }
482 }
483 
484 void ED4_selected_SAI_changed_cb(AW_root * /* aw_root */) {
485  if (!ignore_selected_SAI_changes_cb) {
487 
488  if (name && name[0]) {
489 #if defined(TRACE_JUMPS)
490  printf("Selected SAI is '%s'\n", name);
491 #endif // DEBUG
494  free(name);
495  }
496  }
497 }
498 
500  if (!ignore_selected_species_changes_cb) {
502  if (name && name[0]) {
503 #if defined(TRACE_JUMPS)
504  printf("Selected species is '%s'\n", name);
505 #endif
508  }
509  free(name);
510  }
511  else {
512 #if defined(TRACE_JUMPS)
513  printf("Change ignored because ignore_selected_species_changes_cb!\n");
514 #endif
515  }
516 }
517 
519  ED4_LocalWinContext uses(aww);
520 
522  char *name = GBT_read_string(gb_main, AWAR_SPECIES_NAME);
523  if (name && name[0]) {
524  GB_transaction ta(gb_main);
525 #if defined(TRACE_JUMPS)
526  printf("Jump to selected species (%s)\n", name);
527 #endif
528  ED4_species_name_terminal *name_term = ED4_find_species_name_terminal(name);
529 
530  if (name_term) {
531  jump_to_corresponding_seq_terminal(name_term, true);
532  }
533  else {
534  aw_message(GBS_global_string("Species '%s' is not loaded - use GET to load it.", name));
535  }
536  }
537  else {
538  aw_message("Please select a species");
539  }
540 }
541 
542 static bool multi_species_man_consensus_id_starts_with(ED4_base *base, const char *start) { // TRUE if consensus id starts with 'start'
543  ED4_multi_species_manager *ms_man = base->to_multi_species_manager();
544  ED4_base *consensus = ms_man->search_spec_child_rek(LEV_SPECIES);
545 
546  if (consensus) {
547  ED4_base *consensus_name = consensus->to_manager()->search_spec_child_rek(LEV_SPECIES_NAME);
548 
549  if (consensus_name) {
550  if (strncmp(consensus_name->id, start, strlen(start))==0) {
551  ED4_multi_species_manager *cons_ms_man = consensus_name->get_parent(LEV_MULTI_SPECIES)->to_multi_species_manager();
552  return cons_ms_man==ms_man;
553  }
554  }
555  }
556 
557  return false;
558 }
559 
561  // returns manager into which new species should be inserted
563  return manager ? manager->to_multi_species_manager() : NULp;
564 }
565 
567  not_found_counter = 0;
569  // GBS_strcat(not_found_message,"Species not found: ");
570 }
572  if (not_found_counter != 0) {
574  GBS_strcat(not_found_message, GBS_global_string("(skipped display of %zu more species)\n", not_found_counter-MAX_SHOWN_MISSING_SPECIES));
575  }
577  aw_message(GBS_global_string("Couldn't load %zu species:", not_found_counter));
578  }
581 }
582 
583 static ED4_species_name_terminal *insert_new_species_terminal(GB_CSTR species_name, bool is_SAI) {
585  ED4_group_manager *group_man = insert_into_manager->get_parent(LEV_GROUP)->to_group_manager();
586 
588  {
589  char *buffer = ARB_alloc<char>(strlen(species_name)+3);
590  sprintf(buffer, "-%c%s", is_SAI ? 'S' : 'L', species_name);
591 
592  int index = 0;
593  EDB_root_bact::fill_species(insert_into_manager, ED4_ROOT->ref_terminals, buffer, &index, insert_into_manager->calc_group_depth(), NULp);
594  free(buffer);
595  }
597 
598  {
600  GBDATA *gb_item = is_SAI ? GBT_find_SAI(gb_main, species_name) : GBT_find_species(gb_main, species_name);
601 
602  if (gb_item) {
604  if (gbd) {
605  char *data = GB_read_string(gbd); // @@@ NOT_ALL_SAI_HAVE_DATA
606  int len = GB_read_string_count(gbd);
607 
608  group_man->update_bases(NULp, 0, data, len);
609  }
610  }
611  }
612 
613  ED4_species_name_terminal *name_term = is_SAI
614  ? ED4_find_SAI_name_terminal(species_name)
615  : ED4_find_species_name_terminal(species_name);
616 
617  if (name_term) {
618  // new AAseqTerminals should be created if it is in ProtView mode
619  if (ED4_ROOT->alignment_type == GB_AT_DNA && !is_SAI) {
621  }
622  ED4_ROOT->main_manager->request_resize(); // @@@ instead needs to be called whenever adding or deleting PV-terminals
623  // it should create new AA Sequence terminals if the protein viewer is enabled
624  }
625  insert_into_manager->invalidate_species_counters();
626 
627  return name_term;
628 }
629 
631  const char *sai_name = aww->get_root()->awar(AWAR_SAI_NAME)->read_char_pntr();
632 
633  if (sai_name && sai_name[0]) {
634  ED4_MostRecentWinContext context;
636  ED4_species_name_terminal *name_term = ED4_find_SAI_name_terminal(sai_name);
637  bool loaded = false;
638 
639  if (!name_term) {
640  name_term = insert_new_species_terminal(sai_name, true);
641  loaded = true;
642  }
643  if (name_term) {
644  jump_to_corresponding_seq_terminal(name_term, true);
645  if (!loaded) aw_message(GBS_global_string("SAI '%s' is already loaded.", sai_name));
646  }
647  else {
648  aw_message(GBS_global_string("Failed to load SAI '%s'", sai_name));
649  }
650  }
651 }
652 
654  e4_assert(species_name && species_name[0]);
655 
657  ED4_species_name_terminal *name_term = ED4_find_species_name_terminal(species_name);
658  bool loaded = false;
659 
660  if (!name_term) { // insert new species
661  name_term = insert_new_species_terminal(species_name, false);
662  loaded = true;
663  }
664  if (name_term) {
665  jump_to_corresponding_seq_terminal(name_term, true);
666  if (!loaded) aw_message(GBS_global_string("Species '%s' is already loaded.", species_name));
667  }
668  else {
669  aw_message(GBS_global_string("Failed to get species '%s'", species_name));
670  }
671 }
672 
674  ED4_LocalWinContext uses(aww);
676  if (name && name[0]) {
678  }
679  else {
680  aw_message("Please select a species");
681  }
682 }
683 
685 #define BUFFERSIZE 1000
687  GB_transaction ta(gb_main);
688  long marked = GBT_count_marked_species(gb_main);
689 
690  if (marked) {
691  GBDATA *gb_species = GBT_first_marked_species(gb_main);
692  char *buffer = new char[BUFFERSIZE+1];
693  char *bp = buffer;
694 
696  ED4_group_manager *group_man = insert_into_manager->get_parent(LEV_GROUP)->to_group_manager();
697 
698  int group_depth = insert_into_manager->calc_group_depth();
699  int index = 0;
700  int inserted = 0;
701  char *default_alignment = GBT_get_default_alignment(gb_main);
702 
703  arb_progress progress("Loading species", marked);
704 
706 
707  while (gb_species) {
708  const char *name = GBT_get_name_or_description(gb_species);
709  ED4_species_name_terminal *name_term = ED4_find_species_name_terminal(name);
710 
711  if (!name_term) { // species not found -> insert
712  {
713  int namelen = strlen(name);
714  int buffree = BUFFERSIZE-int(bp-buffer);
715 
716  if ((namelen+2)>buffree) {
717  *bp = 0;
718  EDB_root_bact::fill_species(insert_into_manager, ED4_ROOT->ref_terminals, buffer, &index, group_depth, NULp);
719  bp = buffer;
720  index = 0;
721  }
722 
723  *bp++ = 1;
724  *bp++ = 'L';
725  memcpy(bp, name, namelen);
726  bp += namelen;
727  }
728 
729  {
730  GBDATA *gbd = GBT_find_sequence(gb_species, default_alignment);
731 
732  if (gbd) {
733  char *data = GB_read_string(gbd);
734  int len = GB_read_string_count(gbd);
735  group_man->table().add(data, len);
736  }
737  }
738 
739  inserted++;
740  }
741  gb_species = GBT_next_marked_species(gb_species);
742  progress.inc();
743  }
744 
745  if (bp>buffer) {
746  *bp++ = 0;
747  EDB_root_bact::fill_species(insert_into_manager, ED4_ROOT->ref_terminals, buffer, &index, group_depth, NULp);
748  }
749 
750  aw_message(GBS_global_string("Loaded %i of %li marked species.", inserted, marked));
751 
753 
754  if (inserted) {
755  // new AAseqTerminals should be created if it is in ProtView mode
758  }
759  ED4_ROOT->main_manager->request_resize(); // @@@ instead needs to be called whenever adding or deleting PV-terminals
760  }
761 
762  delete [] buffer;
763  free(default_alignment);
764  }
765  else {
766  aw_message("No species marked.");
767  }
768 
769 #undef BUFFERSIZE
770 }
771 
773  if (owner_of_cursor) {
774  if (is_partly_visible()) {
775  delete_cursor(cursor_abs_x, owner_of_cursor);
776  }
778  }
779 
780  return ED4_R_OK;
781 }
782 
784  if (owner_of_cursor) {
785  ED4_terminal *old_owner_of_cursor = owner_of_cursor;
786 
787  HideCursor();
788  ctype = typ;
790  owner_of_cursor = old_owner_of_cursor;
791  ShowCursor(0, ED4_C_NONE, 0);
792  }
793  else {
794  ctype = typ;
795  }
796 }
797 
798 static void trace_termChange_in_global_awar(ED4_terminal *term, char*& last_value, bool& ignore_flag, const char *awar_name) {
799  char *species_name = term->get_name_of_species();
800 
801  if (!last_value || strcmp(last_value, species_name) != 0) {
802  freeset(last_value, species_name);
803  LocallyModify<bool> raise(ignore_flag, true);
804 #if defined(TRACE_JUMPS)
805  fprintf(stderr, "Writing '%s' to awar '%s'\n", species_name, awar_name);
806 #endif
807  GBT_write_string(ED4_ROOT->get_gb_main(), awar_name, species_name);
808  }
809  else {
810  free(species_name);
811  }
812 }
813 
814 void ED4_cursor::updateAwars(bool new_term_selected) {
815  AW_root *aw_root = ED4_ROOT->aw_root;
816  int seq_pos = get_sequence_pos();
817 
818  if (allow_update_global_cursorpos && new_term_selected) {
819  // @@@ last_set_XXX has to be window-specific (or better cursor specific)
820  if (in_SAI_terminal()) {
821  static char *last_set_SAI = NULp;
822  trace_termChange_in_global_awar(owner_of_cursor, last_set_SAI, ignore_selected_SAI_changes_cb, AWAR_SAI_NAME);
823  }
824  else if (in_species_seq_terminal()) {
825  static char *last_set_species = NULp;
826  trace_termChange_in_global_awar(owner_of_cursor, last_set_species, ignore_selected_species_changes_cb, AWAR_SPECIES_NAME);
827  }
828  }
829  if (new_term_selected) ED4_viewDifferences_announceTerminalChange();
830 
831  // update awars for cursor position:
832  aw_root->awar(win->awar_path_for_cursor)->write_int(info2bio(seq_pos));
834  aw_root->awar(AWAR_CURSOR_POSITION)->write_int(info2bio(seq_pos)); // update ARB-global cursor position
835  }
836 
837  // look if we have a commented search result under the cursor:
838 
840  ED4_sequence_terminal *seq_term = owner_of_cursor->to_sequence_terminal();
841  ED4_SearchResults &results = seq_term->results();
842  ED4_SearchPosition *pos = results.get_shown_at(seq_pos);
843 
844  if (pos) {
845  GB_CSTR comment = pos->get_comment();
846 
847  if (comment) {
848  char *buffer = GB_give_buffer(strlen(comment)+30);
849 
850  sprintf(buffer, "%s: %s", ED4_SearchPositionTypeId[pos->get_whatsFound()], comment);
851  aw_message(buffer);
852  }
853  }
854  }
855 
856  // update awar for ecoli position:
857  BI_ecoli_ref *ecoli = ED4_ROOT->ecoli_ref;
858  if (ecoli->gotData()) {
859  int ecoli_pos = ecoli->abs_2_rel(seq_pos+1); // inclusive position behind cursor
860  aw_root->awar(win->awar_path_for_Ecoli)->write_int(ecoli_pos);
861  }
862 
863  // update awar for base position:
864  int base_pos = base_position.get_base_position(owner_of_cursor, seq_pos+1); // inclusive position behind cursor
865  aw_root->awar(win->awar_path_for_basePos)->write_int(base_pos);
866 
867  // update awar for IUPAC:
868 
869 #define MAXIUPAC 6
870 
871  char iupac[MAXIUPAC+1];
872  strcpy(iupac, ED4_IUPAC_EMPTY);
873 
874  {
875  char at[2] = "\0";
876 
877  if (in_consensus_terminal()) {
878  ED4_group_manager *group_manager = owner_of_cursor->get_parent(LEV_GROUP)->to_group_manager();
879  BaseFrequencies& groupTab = group_manager->table();
880  if (seq_pos<groupTab.size()) {
881  groupTab.build_consensus_string_to(at, ExplicitRange(seq_pos, seq_pos), ED4_ROOT->get_consensus_params());
882  }
883  }
884  else if (in_species_seq_terminal() || in_SAI_terminal()) {
885  int len;
886  const char *seq = owner_of_cursor->resolve_pointer_to_char_pntr(&len);
887 
888  if (seq_pos<len) at[0] = seq[seq_pos];
889  }
890 
891  if (at[0]) {
892  char base = at[0];
893  const char *i = iupac::decode(base, ED4_ROOT->alignment_type, aw_root->awar(ED4_AWAR_CONSENSUS_GROUP)->read_int());
894 
895  e4_assert(strlen(i)<=MAXIUPAC);
896  strcpy(iupac, i);
897  }
898  }
899 
900 #undef MAXIUPAC
901 
902  aw_root->awar(win->awar_path_for_IUPAC)->write_string(iupac);
903 
904  // update awar for helix#:
905  const char *helixNr = ED4_ROOT->helix->helixNr(seq_pos);
906  aw_root->awar(win->awar_path_for_helixNr)->write_string(null2empty(helixNr));
907 }
908 
910  const ED4_coords& coords = window()->coords;
911  return cursor_abs_x - coords.window_left_clip_point;
912 }
913 void ED4_cursor::set_screen_relative_pos(int scroll_to_relpos) {
914  int curr_rel_pos = get_screen_relative_pos();
915  int scroll_amount = curr_rel_pos-scroll_to_relpos;
916 
917  int length_of_char = ED4_ROOT->font_group.get_width(ED4_G_SEQUENCES);
918  scroll_amount = (scroll_amount/length_of_char)*length_of_char; // align to char-size
919 
920  if (scroll_amount != 0) {
921  AW_window *aww = window()->aww;
922  aww->set_horizontal_scrollbar_position(aww->slider_pos_horizontal + scroll_amount);
923 #if defined(TRACE_JUMPS)
924  printf("set_screen_relative_pos(%i) auto-scrolls %i\n", scroll_to_relpos, scroll_amount);
925 #endif
927  }
928 }
929 
930 
931 void ED4_cursor::jump_screen_pos(int screen_pos, ED4_CursorJumpType jump_type) {
932  if (!owner_of_cursor) {
933  aw_message("First you have to place the cursor");
934  return;
935  }
936 
937  if (owner_of_cursor->is_hidden()) return; // do not jump if cursor terminal is hidden
938 
939  AW_pos terminal_x, terminal_y;
940  owner_of_cursor->calc_world_coords(&terminal_x, &terminal_y);
941 
942 #if defined(TRACE_JUMPS)
943  printf("jump_screen_pos(%i)\n", screen_pos);
944 #endif
945 
947  ED4_window *ed4w = window();
948 
949  term->scroll_into_view(ed4w); // correct y-position of terminal
950 
951  int cursor_diff = screen_pos-screen_position;
952  if (cursor_diff == 0) { // cursor position did not change
953  if (jump_type == ED4_JUMP_KEEP_VISIBLE) return; // nothing special -> done
954  }
955 
956  int terminal_pixel_length = ed4w->get_device()->get_string_size(ED4_G_SEQUENCES, owner_of_cursor->to_text_terminal()->get_length());
957  int length_of_char = ED4_ROOT->font_group.get_width(ED4_G_SEQUENCES);
958  int abs_x_new = cursor_abs_x+cursor_diff*length_of_char; // position in terminal
959 
960  if (abs_x_new > terminal_x+terminal_pixel_length+CHARACTEROFFSET || abs_x_new < terminal_x+CHARACTEROFFSET) {
961  return; // don`t move out of terminal
962  }
963 
964  ED4_coords *coords = &ed4w->coords;
965 
966  int screen_width = coords->window_right_clip_point-coords->window_left_clip_point;
967  int scroll_new_to = -1; // if >0 -> scroll abs_x_new to this screen-relative position
968 
969  if (jump_type != ED4_JUMP_KEEP_VISIBLE) {
970  int rel_x = cursor_abs_x-coords->window_left_clip_point;
971 
972  if (jump_type == ED4_JUMP_KEEP_POSITION) {
973  bool was_in_screen = rel_x >= 0 && rel_x <= screen_width;
974  if (!was_in_screen) {
975  jump_type = ED4_JUMP_KEEP_VISIBLE; // // don't have useful relative position -> scroll
976  }
977  }
978 
979  switch (jump_type) {
980  case ED4_JUMP_CENTERED: scroll_new_to = screen_width/2; break;
981  case ED4_JUMP_KEEP_POSITION: scroll_new_to = rel_x; break;
982  case ED4_JUMP_KEEP_VISIBLE: break; // handled below
983  default: e4_assert(0); break;
984  }
985  }
986 
987  if (jump_type == ED4_JUMP_KEEP_VISIBLE) {
988  int margin = length_of_char * ED4_ROOT->aw_root->awar(ED4_AWAR_SCROLL_MARGIN)->read_int();
989 
990  int right_margin = coords->window_right_clip_point - margin;
991  int left_margin = coords->window_left_clip_point + margin;
992 
993  if (left_margin >= right_margin) scroll_new_to = screen_width/2; // margins too big -> center
994  else if (abs_x_new > right_margin) scroll_new_to = screen_width-margin;
995  else if (abs_x_new < left_margin) scroll_new_to = margin;
996  }
997 
998  delete_cursor(cursor_abs_x, owner_of_cursor);
999 
1000  if (scroll_new_to >= 0) { // scroll
1001  int rel_x_new = abs_x_new-coords->window_left_clip_point;
1002  int scroll_amount = rel_x_new-scroll_new_to;
1003 
1004  if (scroll_amount>0) scroll_amount += length_of_char/2;
1005  else if (scroll_amount<0) scroll_amount -= length_of_char/2;
1006 
1007  scroll_amount = (scroll_amount/length_of_char)*length_of_char; // align to char-size
1008  if (scroll_amount != 0) {
1009  AW_window *aww = ed4w->aww;
1010  aww->set_horizontal_scrollbar_position(aww->slider_pos_horizontal + scroll_amount);
1011 #if defined(TRACE_JUMPS)
1012  printf("jump_screen_pos auto-scrolls %i\n", scroll_amount);
1013 #endif
1016  }
1017  }
1018 
1020  if (cursor_diff >= 0) {
1021  ShowCursor(cursor_diff*length_of_char, ED4_C_RIGHT, abs(cursor_diff));
1022  }
1023  else {
1024  ShowCursor(cursor_diff*length_of_char, ED4_C_LEFT, abs(cursor_diff));
1025  }
1026 #if defined(ASSERTION_USED)
1027  {
1028  int sp = get_screen_pos();
1029  e4_assert(sp == screen_pos);
1030  }
1031 #endif
1032 }
1033 
1035  ED4_remap *remap = ED4_ROOT->root_group_man->remap();
1036 
1037  if (remap->is_shown(seq_pos)) {
1038  int screen_pos = remap->sequence_to_screen(seq_pos);
1039  jump_screen_pos(screen_pos, jump_type);
1040 #if defined(ASSERTION_USED)
1041  if (owner_of_cursor) {
1042  int res_seq_pos = get_sequence_pos();
1043  e4_assert(res_seq_pos == seq_pos);
1044  }
1045 #endif
1046  }
1047  else {
1048  int scr_left, scr_right;
1049  remap->adjacent_screen_positions(seq_pos, scr_left, scr_right);
1050  jump_screen_pos(scr_right>=0 ? scr_right : scr_left, jump_type);
1051  }
1052 }
1053 
1054 void ED4_cursor::jump_base_pos(int base_pos, ED4_CursorJumpType jump_type) {
1055  int seq_pos = base2sequence_position(base_pos);
1056  jump_sequence_pos(seq_pos, jump_type);
1057 
1058 #if defined(ASSERTION_USED)
1059  if (owner_of_cursor) {
1060  int bp = get_base_position();
1061  e4_assert(bp == base_pos);
1062  }
1063 #endif
1064 }
1065 
1067  int seq_pos;
1068  bool want_base;
1069 public:
1070  has_base_at(int seq_pos_, bool want_base_) : seq_pos(seq_pos_), want_base(want_base_) {}
1071  bool fulfilled_by(const ED4_terminal *terminal) const OVERRIDE {
1072  bool test_succeeded = false;
1073 
1074  if (terminal->is_sequence_terminal()) {
1075  const ED4_sequence_terminal *seqTerm = terminal->to_sequence_terminal();
1076  int len;
1077  char *seq = seqTerm->resolve_pointer_to_string_copy(&len);
1078  if (seq) {
1079  test_succeeded = len>seq_pos && bool(ED4_is_gap_character(seq[seq_pos]))!=want_base;
1080  }
1081  free(seq);
1082  }
1083 
1084  return test_succeeded;
1085  }
1086 };
1087 
1089  bool fulfilled_by(const ED4_terminal *) const OVERRIDE { return true; }
1090 };
1091 
1092 static ED4_terminal *get_upper_lower_cursor_pos(ED4_manager *starting_point, ED4_cursor_move cursor_move, AW_pos current_y, bool isScreen, const ED4_TerminalPredicate& predicate) {
1093  // current_y is y-position of terminal at which search starts.
1094  // It may be in world or screen coordinates (isScreen marks which is used)
1095  // This is needed to move the cursor from top- to middle-area w/o scrolling middle-area to top-position.
1096 
1098 
1099  int m = 0;
1100  int last_m = starting_point->members()-1;
1101  int incr = 1;
1102 
1103  if (cursor_move == ED4_C_UP) {
1104  std::swap(m, last_m); incr = -1; // revert search direction
1105  e4_assert(!isScreen); // use screen coordinates for ED4_C_DOWN only!
1106  }
1107 
1108  while (!result) {
1109  ED4_base *member = starting_point->member(m);
1110 
1111  if (member->is_manager()) {
1112  if (!member->flag.hidden) { // step over hidden managers (e.g. folded groups)
1113  result = get_upper_lower_cursor_pos(member->to_manager(), cursor_move, current_y, isScreen, predicate);
1114  }
1115  }
1116  else {
1117  if (member->has_property(PROP_CURSOR_ALLOWED)) {
1118  AW_pos x, y;
1119  member->calc_world_coords(&x, &y);
1120  if (isScreen) current_ed4w()->world_to_win_coords(&x, &y); // if current_y is screen, convert x/y to screen-coordinates as well
1121 
1122  bool pos_beyond = (cursor_move == ED4_C_UP) ? y<current_y : y>current_y;
1123  if (pos_beyond) {
1124  bool skip_top_scrolled = false;
1125  if (isScreen) {
1126  ED4_multi_species_manager *marea_man = NULp;
1127  if (member->get_area_level(&marea_man) == ED4_A_MIDDLE_AREA) {
1128  // previous position was in top-area -> avoid selecting scrolled-out terminals
1129  AW_pos y_area = marea_man->parent->extension.position[Y_POS];
1130  skip_top_scrolled = y<y_area;
1131  }
1132  }
1133 
1134  if (!skip_top_scrolled) {
1135  ED4_terminal *term = member->to_terminal();
1136  if (predicate.fulfilled_by(term)) result = term;
1137  }
1138  }
1139  }
1140  }
1141 
1142  if (m == last_m) break;
1143  m += incr;
1144  }
1145 
1146  return result;
1147 }
1148 
1150  bool fulfilled_by(const ED4_terminal *term) const OVERRIDE { return term->is_consensus_terminal(); }
1151 };
1152 
1154  // move cursor up down
1157  bool endHome = false;
1158 
1159  switch (event->keycode) {
1160  case AW_KEY_UP: dir = ED4_C_UP; break;
1161  case AW_KEY_DOWN: dir = ED4_C_DOWN; break;
1162  case AW_KEY_HOME: dir = ED4_C_UP; endHome = true; break;
1163  case AW_KEY_END: dir = ED4_C_DOWN; endHome = true; break;
1164  default: e4_assert(0); break; // illegal call of move_cursor()
1165  }
1166 
1167  if (dir != ED4_C_NONE) {
1168  if (owner_of_cursor->is_hidden()) result = ED4_R_IMPOSSIBLE; // don't move cursor if terminal is hidden
1169 
1170  if (result == ED4_R_OK) {
1171  AW_pos x_dummy, y_world;
1172 
1173  owner_of_cursor->calc_world_coords(&x_dummy, &y_world);
1174 
1175  int seq_pos = get_sequence_pos();
1176  ED4_terminal *target_terminal = NULp;
1177 
1178  // stay in current area
1179  ED4_multi_species_manager *start_at_manager = NULp;
1180  ED4_AREA_LEVEL area_level = owner_of_cursor->get_area_level(&start_at_manager);
1181 
1182  if (event->keymodifier & AW_KEYMODE_CONTROL) {
1183  bool has_base = has_base_at(seq_pos, true).fulfilled_by(owner_of_cursor);
1184 
1185  if (!endHome) { // not End or Home
1186  target_terminal = get_upper_lower_cursor_pos(start_at_manager, dir, y_world, false, has_base_at(seq_pos, !has_base));
1187  if (target_terminal && !has_base && ED4_ROOT->aw_root->awar(ED4_AWAR_FAST_CURSOR_JUMP)->read_int()) { // if jump_over group
1188  target_terminal->calc_world_coords(&x_dummy, &y_world);
1189  target_terminal = get_upper_lower_cursor_pos(start_at_manager, dir, y_world, false, has_base_at(seq_pos, false));
1190  }
1191  }
1192 
1193  if (!target_terminal) {
1194  // either already in last group (or no space behind last group) -> jump to end (or start)
1195  target_terminal = get_upper_lower_cursor_pos(start_at_manager,
1196  dir == ED4_C_UP ? ED4_C_DOWN : ED4_C_UP, // use opposite movement direction
1197  dir == ED4_C_UP ? 0 : INT_MAX, false, // search for top-/bottom-most terminal
1198  acceptAnyTerminal());
1199  }
1200  }
1201  else {
1202  e4_assert(!endHome); // END and HOME w/o Ctrl should not call move_cursor()
1203  if (event->keymodifier & AW_KEYMODE_ALT) {
1204  target_terminal = get_upper_lower_cursor_pos(start_at_manager, dir, y_world, false, acceptConsensusTerminal());
1205  }
1206  else {
1207  bool isScreen = false;
1208  if (dir == ED4_C_DOWN) {
1209  if (area_level == ED4_A_TOP_AREA) {
1210  window()->world_to_win_coords(&x_dummy, &y_world); // special handling to move cursor from top to bottom area
1211  isScreen = true;
1212  }
1213  }
1214  target_terminal = get_upper_lower_cursor_pos(ED4_ROOT->main_manager, dir, y_world, isScreen, acceptAnyTerminal());
1215  }
1216  }
1217 
1218  if (target_terminal) {
1219  set_to_terminal(target_terminal, seq_pos, ED4_JUMP_KEEP_VISIBLE);
1220  }
1221  }
1222  }
1223 
1224  return result;
1225 }
1226 
1228  AW_pos x, y;
1231 }
1232 
1233 
1235  AW_pos x=0, y=0, x_help = 0, y_help;
1236 
1238 
1239  switch (move) {
1240  case ED4_C_RIGHT: screen_position += move_pos; break;
1241  case ED4_C_LEFT: screen_position -= move_pos; break;
1242  case ED4_C_NONE: break; // no move - only redisplay
1243  default: e4_assert(0); break;
1244  }
1245 
1246  {
1248  updateAwars(false);
1249  }
1250 
1251  x_help = cursor_abs_x + offset_x;
1252  y_help = y;
1253 
1254  window()->world_to_win_coords(&x_help, &y_help);
1255 
1256  if (allowed_to_draw) draw_cursor(x_help, y_help);
1257 #if defined(DEBUG) && 0
1258  else printf("Skip draw_cursor (allowed_to_draw=false)\n");
1259 #endif // DEBUG
1260 
1261  cursor_abs_x += offset_x;
1262 
1263  return ED4_R_OK;
1264 }
1265 
1267  if (!owner_of_cursor) return false;
1268  if (!owner_of_cursor->is_in_folded_group()) return false;
1269  if (in_consensus_terminal()) {
1271  e4_assert(group_man);
1272  return group_man->is_in_folded_group();
1273  }
1274  return true;
1275 }
1276 
1279  e4_assert(cursor_shape); // cursor is not drawn, cannot test visibility
1280 
1281  if (is_hidden_inside_group()) {
1282  printf("is_hidden_inside_group=true\n");
1283  return false;
1284  }
1285 
1286  AW_pos x, y;
1288 
1289  int x1, y1, x2, y2;
1290  cursor_shape->get_bounding_box(cursor_abs_x, int(y), x1, y1, x2, y2);
1291 
1292  bool visible = false;
1293 
1294  switch (owner_of_cursor->get_area_level(NULp)) {
1295  case ED4_A_TOP_AREA: visible = win->shows_xpos(x1) || win->shows_xpos(x2); break;
1296  case ED4_A_MIDDLE_AREA: visible = win->partly_shows(x1, y1, x2, y2); break;
1297  default: break;
1298  }
1299 
1300  return visible;
1301 }
1302 
1305  e4_assert(cursor_shape); // cursor is not drawn, cannot test visibility
1306 
1307  if (is_hidden_inside_group()) return false;
1308 
1309  AW_pos x, y;
1311 
1312  int x1, y1, x2, y2;
1313  cursor_shape->get_bounding_box(cursor_abs_x, int(y), x1, y1, x2, y2);
1314 
1315  bool visible = false;
1316 
1317  switch (owner_of_cursor->get_area_level(NULp)) {
1318  case ED4_A_TOP_AREA: visible = win->shows_xpos(x1) && win->shows_xpos(x2); break;
1319  case ED4_A_MIDDLE_AREA: visible = win->completely_shows(x1, y1, x2, y2); break;
1320  default: break;
1321  }
1322 
1323  return visible;
1324 }
1325 
1326 #if defined(DEBUG) && 0
1327 #define DUMP_SCROLL_INTO_VIEW
1328 #endif
1329 
1330 void ED4_terminal::scroll_into_view(ED4_window *ed4w) { // scroll y-position only
1331  ED4_LocalWinContext uses(ed4w);
1332 
1333  AW_pos termw_x, termw_y;
1334  calc_world_coords(&termw_x, &termw_y);
1335 
1336  ED4_coords *coords = &current_ed4w()->coords;
1337 
1338  int term_height = int(extension.size[1]);
1339  int win_ysize = coords->window_lower_clip_point - coords->window_upper_clip_point + 1;
1340 
1341  bool scroll = false;
1342  int slider_pos_y;
1343 
1344  ED4_cursor_move direction = ED4_C_NONE;
1345 
1346  AW_pos termw_y_upper = termw_y; // upper border of terminal
1347  AW_pos termw_y_lower = termw_y + term_height; // lower border of terminal
1348 
1349  if (termw_y_upper > coords->top_area_height) { // don't scroll if terminal is in top area (always visible)
1350  if (termw_y_upper < coords->window_upper_clip_point) { // scroll up
1351 #ifdef DUMP_SCROLL_INTO_VIEW
1352  printf("termw_y_upper(%i) < window_upper_clip_point(%i)\n",
1353  int(termw_y_upper), int(coords->window_upper_clip_point));
1354 #endif // DEBUG
1355  slider_pos_y = int(termw_y_upper - coords->top_area_height - term_height);
1356  scroll = true;
1357  direction = ED4_C_UP;
1358  }
1359  else if (termw_y_lower > coords->window_lower_clip_point) { // scroll down
1360 #ifdef DUMP_SCROLL_INTO_VIEW
1361  printf("termw_y_lower(%i) > window_lower_clip_point(%i)\n",
1362  int(termw_y_lower), int(coords->window_lower_clip_point));
1363 #endif // DEBUG
1364  slider_pos_y = int(termw_y_upper - coords->top_area_height - win_ysize);
1365  scroll = true;
1366  direction = ED4_C_DOWN;
1367  }
1368  }
1369 
1370 #ifdef DUMP_SCROLL_INTO_VIEW
1371  if (!scroll) {
1372  printf("No scroll needed (termw_y_upper=%i termw_y_lower=%i term_height=%i window_upper_clip_point=%i window_lower_clip_point=%i)\n",
1373  int(termw_y_upper), int(termw_y_lower), term_height,
1374  int(coords->window_upper_clip_point), int(coords->window_lower_clip_point));
1375  }
1376 #endif // DEBUG
1377 
1378  if (scroll) {
1379  AW_window *aww = ed4w->aww;
1380 
1381  int pic_ysize = int(aww->get_scrolled_picture_height());
1382  int slider_pos_yrange = pic_ysize - win_ysize;
1383 
1384  if (slider_pos_yrange<0) { // win_ysize > pic_ysize
1385  slider_pos_y = 0;
1386  }
1387  else {
1388  ED4_multi_species_manager *start_at_manager = NULp;
1389  get_area_level(&start_at_manager);
1390 
1391  ED4_terminal *nextTerm = get_upper_lower_cursor_pos(start_at_manager, direction, termw_y, false, acceptAnyTerminal());
1392  if (!nextTerm) { // no next term in this area
1393  slider_pos_y = direction == ED4_C_UP ? 0 : slider_pos_yrange; // scroll to limit
1394  }
1395  }
1396 
1397  if (slider_pos_y>slider_pos_yrange) slider_pos_y = slider_pos_yrange;
1398  if (slider_pos_y<0) slider_pos_y = 0;
1399 
1400  aww->set_vertical_scrollbar_position(slider_pos_y);
1402  }
1403 }
1404 
1405 void ED4_cursor::set_to_terminal(ED4_terminal *terminal, int seq_pos, ED4_CursorJumpType jump_type) {
1406  if (seq_pos == -1) seq_pos = get_sequence_pos();
1407 
1408  bool new_term_selected = owner_of_cursor != terminal;
1409  if (new_term_selected) {
1410  if (owner_of_cursor) {
1411  if (get_sequence_pos() != seq_pos) {
1412  jump_sequence_pos(seq_pos, jump_type); // position to wanted column -- scrolls horizontally
1413  }
1414  }
1415 
1416  int scr_pos = ED4_ROOT->root_group_man->remap()->sequence_to_screen(seq_pos);
1417  show_cursor_at(terminal, scr_pos);
1418 
1419  if (!is_completely_visible()) {
1420  jump_sequence_pos(seq_pos, jump_type);
1421  }
1422  }
1423  else {
1424  jump_sequence_pos(seq_pos, jump_type);
1425  }
1426 
1428  updateAwars(new_term_selected);
1429 }
1430 
1432  bool new_term_selected = owner_of_cursor != target_terminal;
1433 
1434  if (owner_of_cursor) {
1435  if (is_partly_visible()) {
1436  delete_cursor(cursor_abs_x, owner_of_cursor);
1437  }
1439  DRAW = 1;
1440  }
1441 
1442  target_terminal->scroll_into_view(window());
1443 
1444  AW_pos termw_x, termw_y;
1445  target_terminal->calc_world_coords(&termw_x, &termw_y);
1446 
1447  screen_position = scr_pos;
1448 
1449  int length_of_char = ED4_ROOT->font_group.get_width(ED4_G_SEQUENCES);
1450 
1451  AW_pos world_x = termw_x + length_of_char*screen_position + CHARACTEROFFSET;
1452  AW_pos world_y = termw_y;
1453 
1454  AW_pos win_x = world_x;
1455  AW_pos win_y = world_y;
1456  window()->world_to_win_coords(&win_x, &win_y);
1457 
1458  cursor_abs_x = (long int)world_x;
1459  owner_of_cursor = target_terminal;
1460 
1461  draw_cursor(win_x, win_y);
1462 
1464  updateAwars(new_term_selected);
1465 
1466  return ED4_R_OK;
1467 }
1468 
1470  AW_pos termw_x, termw_y;
1471  target_terminal->calc_world_coords(&termw_x, &termw_y);
1472 
1473  ED4_index scr_pos = ED4_ROOT->pixel2pos(click_xpos - termw_x);
1474  return show_cursor_at(target_terminal, scr_pos);
1475 }
1476 
1477 
1478 /* --------------------------------------------------------------------------------
1479  ED4_base_position
1480  -------------------------------------------------------------------------------- */
1481 
1482 static void ed4_bp_sequence_changed_cb(ED4_species_manager*, ED4_base_position *base_pos) {
1483  base_pos->invalidate();
1484 }
1485 
1486 void ED4_base_position::remove_changed_cb() {
1487  if (calced4term) {
1488  ED4_species_manager *species_manager = calced4term->get_parent(LEV_SPECIES)->to_species_manager();
1489  species_manager->remove_sequence_changed_cb(makeED4_species_managerCallback(ed4_bp_sequence_changed_cb, this));
1490 
1491  calced4term = NULp;
1492  }
1493 }
1494 
1495 static bool is_consensus_gap(char c) { return ED4_is_gap_character(c) || c == '='; }
1496 
1497 void ED4_base_position::calc4term(const ED4_terminal *base) {
1498  e4_assert(base);
1499 
1500  ED4_species_manager *species_manager = base->get_parent(LEV_SPECIES)->to_species_manager();
1501 
1502  int len;
1503  char *seq;
1504 
1505  if (base != calced4term) { // terminal changes => rebind callback to new manager
1506  remove_changed_cb();
1507  species_manager->add_sequence_changed_cb(makeED4_species_managerCallback(ed4_bp_sequence_changed_cb, this));
1508  }
1509 
1510  bool (*isGap_fun)(char);
1511  if (species_manager->is_consensus_manager()) {
1512  ED4_group_manager *group_manager = base->get_parent(LEV_GROUP)->to_group_manager();
1513 
1514  seq = group_manager->build_consensus_string();
1515  len = strlen(seq);
1516  isGap_fun = is_consensus_gap;
1517  }
1518  else {
1519  seq = base->resolve_pointer_to_string_copy(&len);
1520  e4_assert((int)strlen(seq) == len);
1521  isGap_fun = ED4_is_gap_character;
1522  }
1523 
1524  e4_assert(seq);
1525 
1526  CharPredicate pred_is_gap(isGap_fun);
1527  initialize(seq, len, pred_is_gap);
1528  calced4term = base;
1529 
1530  free(seq);
1531 }
1532 int ED4_base_position::get_base_position(const ED4_terminal *term, int sequence_position) {
1533  if (!term) return 0;
1534  set_term(term);
1535  return abs_2_rel(sequence_position);
1536 }
1538  if (!term) return 0;
1539  set_term(term);
1540  return rel_2_abs(base_pos);
1541 }
1542 
1543 /* --------------------------------------------------------------------------------
1544  Store/Restore Cursorpositions
1545  -------------------------------------------------------------------------------- */
1546 
1547 class CursorPos : virtual Noncopyable {
1548  ED4_terminal *terminal;
1549  int seq_pos;
1550 
1551  CursorPos *next;
1552 
1553  static CursorPos *head;
1554 
1555 public:
1556 
1557  static void clear() {
1558  while (head) {
1559  CursorPos *p = head->next;
1560 
1561  delete head;
1562  head = p;
1563  }
1564  }
1565  static CursorPos *get_head() { return head; }
1566 
1568  terminal = t;
1569  seq_pos = p;
1570  next = head;
1571  head = this;
1572  }
1574 
1575  ED4_terminal *get_terminal() const { return terminal; }
1576  int get_seq_pos() const { return seq_pos; }
1577 
1578  void moveToEnd() {
1579  e4_assert(this==head);
1580 
1581  if (next) {
1582  CursorPos *p = head = next;
1583 
1584  while (p->next) {
1585  p = p->next;
1586  }
1587 
1588  p->next = this;
1589  this->next = NULp;
1590  }
1591  }
1592 };
1593 
1594 CursorPos *CursorPos::head = NULp;
1595 
1598  ED4_LocalWinContext uses(aww);
1599  ED4_cursor *cursor = &current_cursor();
1600 
1601  if (!cursor->owner_of_cursor) {
1602  aw_message("First you have to place the cursor.");
1603  }
1604  else {
1605  new CursorPos(cursor->owner_of_cursor, cursor->get_sequence_pos());
1606  }
1607 }
1608 
1611  ED4_LocalWinContext uses(aww);
1612  ED4_cursor *cursor = &current_cursor();
1613 
1614  CursorPos *pos = CursorPos::get_head();
1615  if (!pos) {
1616  aw_message("No cursor position stored.");
1617  return;
1618  }
1619 
1620  pos->get_terminal()->setCursorTo(cursor, pos->get_seq_pos(), true, ED4_JUMP_KEEP_VISIBLE);
1621  pos->moveToEnd();
1622 }
1623 
1625  CursorPos::clear();
1626 }
1627 
1628 /* --------------------------------------------------------------------------------
1629  Other stuff
1630  -------------------------------------------------------------------------------- */
1631 
1634  ED4_LocalWinContext uses(aww);
1635  ED4_cursor *cursor = &current_cursor();
1636 
1637  if (!cursor->owner_of_cursor) {
1638  aw_message("First you have to place the cursor.");
1639  return;
1640  }
1641 
1642  int seq_pos = cursor->get_sequence_pos();
1643  AW_helix *helix = ED4_ROOT->helix;
1644  BI_PAIR_TYPE pairType = helix->pairtype(seq_pos);
1645 
1646  if (pairType != HELIX_NONE) {
1647  int pairing_pos = helix->opposite_position(seq_pos);
1648  cursor->jump_sequence_pos(pairing_pos, ED4_JUMP_KEEP_POSITION);
1649  }
1650  else {
1651  aw_message("Not at helix position");
1652  }
1653 }
1654 
1656  ED4_LocalWinContext uses(aww);
1657  ED4_cursor *cursor = &current_cursor();
1658  ED4_CursorType typ = cursor->getType();
1659 
1660  cursor->changeType((ED4_CursorType)((typ+1)%ED4_CURSOR_TYPES));
1661 }
1662 
1663 // --------------------------------------------------------------------------------
1664 
1665 #ifdef UNIT_TESTS
1666 #include <test_unit.h>
1667 #include <test_helpers.h>
1668 
1669 struct test_absrel {
1670  bool torel;
1671  test_absrel(bool r) : torel(r) {}
1672  virtual ~test_absrel() {}
1673 
1674  virtual int a2r(int a) const = 0;
1675  virtual int r2a(int r) const = 0;
1676 
1677  virtual int abs_size() const = 0;
1678  virtual int rel_size() const = 0;
1679 
1680  int gen(int i) const { return torel ? a2r(i) : r2a(i); }
1681  int get_size() const { return torel ? abs_size()+1 : rel_size(); }
1682 
1683  char *genResult() const;
1684 };
1685 
1686 struct membind {
1687  const test_absrel& me;
1688  membind(const test_absrel& ta) : me(ta) {}
1689  int operator()(int i) const { return me.gen(i); }
1690 };
1691 
1692 char *test_absrel::genResult() const {
1693  return collectIntFunResults(membind(*this), 0, get_size()-1, 3, 1, 1);
1694 }
1695 
1696 struct test_ecoli : public test_absrel {
1697  BI_ecoli_ref& eref;
1698  test_ecoli(BI_ecoli_ref& b, bool to_rel) : test_absrel(to_rel), eref(b) {}
1699  int a2r(int a) const OVERRIDE { return eref.abs_2_rel(a); }
1700  int r2a(int r) const OVERRIDE { return eref.rel_2_abs(r); }
1701  int abs_size() const OVERRIDE { return eref.abs_count(); }
1702  int rel_size() const OVERRIDE { return eref.base_count(); }
1703 };
1704 
1705 struct test_basepos : public test_absrel {
1706  BasePosition& bpos;
1707  test_basepos(BasePosition& bpos_, bool to_rel)
1708  : test_absrel(to_rel), bpos(bpos_) {}
1709  int a2r(int a) const OVERRIDE { return bpos.abs_2_rel(a); }
1710  int r2a(int r) const OVERRIDE { return bpos.rel_2_abs(r); }
1711  int abs_size() const OVERRIDE { return bpos.abs_count(); }
1712  int rel_size() const OVERRIDE { return bpos.base_count(); }
1713 };
1714 
1715 #define TEST_ABSREL_EQUALS(tester,expected) do { \
1716  char *res = tester.genResult(); \
1717  TEST_EXPECT_EQUAL(res,expected); \
1718  free(res); \
1719  } while(0)
1720 
1721 #define TEST_ECOLIREF_EQUALS(data,alen,a2r,r2a) do { \
1722  BI_ecoli_ref eref; \
1723  eref.init(data,alen); \
1724  TEST_ABSREL_EQUALS(test_ecoli(eref, true), a2r); \
1725  TEST_ABSREL_EQUALS(test_ecoli(eref, false), r2a); \
1726  } while(0)
1727 
1728 
1729 #define TEST_BASE_POS_EQUALS(data,a2r,r2a) do { \
1730  { \
1731  BasePosition bpos(data, strlen(data), CharPredicate(ED4_is_gap_character)); \
1732  TEST_ABSREL_EQUALS(test_basepos(bpos, true), a2r); \
1733  TEST_ABSREL_EQUALS(test_basepos(bpos, false), r2a); \
1734  } \
1735  } while(0)
1736 
1737 void TEST_BI_ecoli_ref() {
1738  TEST_ECOLIREF_EQUALS("-.AC-G-T-.", 10,
1739  " [0] 0 0 0 1 2 2 3 3 4 4 4 [4]", // abs -> rel
1740  " [0] 2 3 5 7 [7]"); // rel -> abs
1741 
1742  TEST_ECOLIREF_EQUALS("-", 1, " [0] 0 0 [0]", " [0] [0]");
1743  TEST_ECOLIREF_EQUALS("--A", 1, " [0] 0 0 [0]", " [0] [0]"); // part of sequence
1744  TEST_ECOLIREF_EQUALS("--", 2, " [0] 0 0 0 [0]", " [0] [0]");
1745  TEST_ECOLIREF_EQUALS("---", 3, " [0] 0 0 0 0 [0]", " [0] [0]");
1746 
1747  TEST_ECOLIREF_EQUALS("A", 1, " [0] 0 1 [1]", " [0] 0 [0]");
1748  TEST_ECOLIREF_EQUALS("A", 2, " [0] 0 1 1 [1]", " [0] 0 [0]");
1749 
1750  TEST_ECOLIREF_EQUALS("A-", 2, " [0] 0 1 1 [1]", " [0] 0 [0]");
1751  TEST_ECOLIREF_EQUALS("-A", 2, " [0] 0 0 1 [1]", " [0] 1 [1]");
1752 
1753  TEST_ECOLIREF_EQUALS("A", 3, " [0] 0 1 1 1 [1]", " [0] 0 [0]"); // more than sequence
1754  TEST_ECOLIREF_EQUALS("A--", 3, " [0] 0 1 1 1 [1]", " [0] 0 [0]");
1755  TEST_ECOLIREF_EQUALS("-A-", 3, " [0] 0 0 1 1 [1]", " [0] 1 [1]");
1756  TEST_ECOLIREF_EQUALS("--A", 3, " [0] 0 0 0 1 [1]", " [0] 2 [2]");
1757 }
1758 
1759 void TEST_base_position() {
1760  ED4_setup_gaps_and_alitype("-", GB_AT_RNA); // count '.' as base
1761 
1762  TEST_BASE_POS_EQUALS("-.AC-G-T-.",
1763  " [0] 0 0 1 2 3 3 4 4 5 5 6 [6]", // abs -> rel
1764  " [0] 1 2 3 5 7 9 [9]"); // rel -> abs
1765 
1766  // ------------------------------
1767  ED4_setup_gaps_and_alitype(".-", GB_AT_RNA); // count '.' as gap
1768 
1769  TEST_BASE_POS_EQUALS("-.AC-G-T-.",
1770  " [0] 0 0 0 1 2 2 3 3 4 4 4 [4]", // abs -> rel
1771  " [0] 2 3 5 7 [7]"); // rel -> abs
1772 
1773  TEST_BASE_POS_EQUALS("-", " [0] 0 0 [0]", " [0] [0]");
1774  TEST_BASE_POS_EQUALS("--", " [0] 0 0 0 [0]", " [0] [0]");
1775  TEST_BASE_POS_EQUALS("---", " [0] 0 0 0 0 [0]", " [0] [0]");
1776 
1777  TEST_BASE_POS_EQUALS("A", " [0] 0 1 [1]", " [0] 0 [0]");
1778 
1779  TEST_BASE_POS_EQUALS("A-", " [0] 0 1 1 [1]", " [0] 0 [0]");
1780  TEST_BASE_POS_EQUALS("-A", " [0] 0 0 1 [1]", " [0] 1 [1]");
1781 
1782  TEST_BASE_POS_EQUALS("A--", " [0] 0 1 1 1 [1]", " [0] 0 [0]");
1783  TEST_BASE_POS_EQUALS("-A-", " [0] 0 0 1 1 [1]", " [0] 1 [1]");
1784  TEST_BASE_POS_EQUALS("--A", " [0] 0 0 0 1 [1]", " [0] 2 [2]");
1785 }
1786 
1787 #endif // UNIT_TESTS
1788 
1789 
virtual bool fulfilled_by(const ED4_terminal *) const =0
ED4_species_name_terminal * ED4_find_SAI_name_terminal(const char *sai_name)
Definition: ED4_root.cxx:895
char * collectIntFunResults(FUN fun, int start, int end, int width, int try_underflow, int try_overflow)
Definition: test_helpers.h:37
void ED4_get_and_jump_to_current(AW_window *aww)
Definition: ED4_cursor.cxx:673
string result
AW_device * get_device() const
Definition: ed4_class.hxx:766
GB_TYPES type
const char * resolve_pointer_to_char_pntr(int *str_len=NULp) const FINAL_OVERRIDE
AW_helix * helix
Definition: ed4_class.hxx:1444
int screen_to_sequence(int screen_pos) const
size_t not_found_counter
Definition: ED4_main.cxx:62
GBDATA * GBT_first_marked_species(GBDATA *gb_main)
Definition: aditem.cxx:113
ED4_returncode move_cursor(AW_event *event)
void special_window_refresh(bool handle_updates)
Definition: ED4_root.cxx:158
const AW_bitset AW_SCREEN
Definition: aw_device.hxx:34
AW_pos get_scrolled_picture_height() const
Definition: AW_window.cxx:838
AW_font_group font_group
Definition: ed4_class.hxx:1464
void set_to_terminal(ED4_terminal *terminal, int seq_pos, ED4_CursorJumpType jump_type)
AW_pos size[2]
Definition: ed4_defs.hxx:261
int rel_2_abs(int rel) const
Definition: BI_basepos.hxx:87
ED4_returncode ShowCursor(ED4_index offset_x, ED4_cursor_move move, int move_pos=1)
#define ED4_AWAR_CONSENSUS_GROUP
Definition: ed4_awars.hxx:47
static char * y[maxsp+1]
ED4_window * window() const
Definition: ed4_class.hxx:694
bool DRAW
Definition: ED4_main.cxx:69
void ED4_store_curpos(AW_window *aww)
int reduceClipBorders(int top, int bottom, int left, int right)
void scroll_into_view(ED4_window *ed4w)
bool fulfilled_by(const ED4_terminal *) const OVERRIDE
void moveToEnd()
void ED4_helix_jump_opposite(AW_window *aww)
ED4_base * member(ED4_index i) const
Definition: ed4_class.hxx:794
void ED4_horizontal_change_cb(AW_window *aww)
bool is_hidden() const FINAL_OVERRIDE
Definition: ed4_class.hxx:1332
#define BUFFERSIZE
ED4_group_manager * is_in_folded_group() const
Definition: ED4_base.cxx:20
#define INNER_HEIGHT
#define ED4_AWAR_FAST_CURSOR_JUMP
Definition: ed4_awars.hxx:28
ED4_SearchResults & results() const
Definition: ed4_class.hxx:2002
void ED4_selected_SAI_changed_cb(AW_root *)
Definition: ED4_cursor.cxx:484
GB_CSTR get_comment() const
Definition: ED4_search.cxx:856
virtual void clear_part(const AW::Rectangle &rect, AW_bitset filteri)
Definition: AW_device.cxx:317
#define AWAR_CURSOR_POSITION
char * id
Definition: ed4_class.hxx:919
bool fulfilled_by(const ED4_terminal *terminal) const OVERRIDE
bool in_species_seq_terminal() const
Definition: ed4_class.hxx:1851
static bool multi_species_man_consensus_id_starts_with(ED4_base *base, const char *start)
Definition: ED4_cursor.cxx:542
BI_PAIR_TYPE
Definition: BI_helix.hxx:18
BaseFrequencies & table()
Definition: ed4_class.hxx:1645
Definition: iupac.cxx:21
#define UPPER_OFFSET
int is_shown(int seq_pos) const
Definition: ed4_class.hxx:1760
bool shows_xpos(int x) const
Definition: ed4_class.hxx:760
long read_int() const
Definition: AW_awar.cxx:187
static CursorPos * get_head()
void initialize(const char *seq, int size)
Definition: BI_basepos.cxx:22
#define Y_POS
Definition: ed4_defs.hxx:73
#define EXPAND_SIZE
int base2sequence_position(int base_pos) const
Definition: ed4_class.hxx:667
#define THICKNESS
const char * GBS_global_string(const char *templat,...)
Definition: arb_msg.cxx:204
#define STEPS
long top_area_height
Definition: ed4_defs.hxx:323
ED4_root * ED4_ROOT
Definition: ED4_main.cxx:48
size_t opposite_position(size_t pos) const
Definition: BI_helix.hxx:96
char awar_path_for_IUPAC[50]
Definition: ed4_class.hxx:717
void draw(AW_device *device, int x, int y) const
Definition: ED4_cursor.cxx:75
int base_count() const
Definition: BI_basepos.hxx:100
ED4_update_info update_info
Definition: ed4_class.hxx:924
static void trace_termChange_in_global_awar(ED4_terminal *term, char *&last_value, bool &ignore_flag, const char *awar_name)
Definition: ED4_cursor.cxx:798
size_t get_max_screen_pos() const
Definition: ed4_class.hxx:1731
int get_sequence_position(const ED4_terminal *base, int base_position)
const AW_bitset AW_ALL_DEVICES
Definition: aw_device.hxx:44
ED4_AREA_LEVEL
Definition: ed4_defs.hxx:168
ED4_terminal * owner_of_cursor
Definition: ed4_class.hxx:643
int slider_pos_horizontal
current position of the vertical slider
Definition: aw_window.hxx:339
static bool is_consensus_gap(char c)
int get_base_position() const
Definition: ed4_class.hxx:670
int get_width(int gc) const
ED4_manager * parent
Definition: ed4_class.hxx:915
bool in_SAI_terminal() const
Definition: ed4_class.hxx:1853
ED4_reference_terminals ref_terminals
Definition: ed4_class.hxx:1434
static void ed4_bp_sequence_changed_cb(ED4_species_manager *, ED4_base_position *base_pos)
char awar_path_for_basePos[50]
Definition: ed4_class.hxx:716
char buffer[MESSAGE_BUFFERSIZE]
Definition: seq_search.cxx:34
FILE * seq
Definition: rns.c:46
ED4_CursorShape(ED4_CursorType type, int term_height, int character_width, bool reverse_cursor)
Definition: ED4_cursor.cxx:103
ED4_base * find_first_that(ED4_level level, const ED4_basePredicate &fulfills_predicate)
Definition: ED4_base.cxx:402
#define MAXIUPAC
ED4_coords coords
Definition: ed4_class.hxx:710
int get_screen_pos() const
Definition: ed4_class.hxx:662
#define e4_assert(bed)
Definition: ed4_class.hxx:11
static void jump_to_corresponding_seq_terminal(ED4_species_name_terminal *name_term, bool unfold_groups)
Definition: ED4_cursor.cxx:427
void ED4_get_and_jump_to_species(GB_CSTR species_name)
Definition: ED4_cursor.cxx:653
void jump_screen_pos(int screen_pos, ED4_CursorJumpType jump_type)
Definition: ED4_cursor.cxx:931
bool has_property(ED4_properties prop) const
Definition: ed4_class.hxx:976
static HelixNrInfo * start
void world_to_win_coords(AW_pos *xPtr, AW_pos *yPtr) const
Definition: ed4_class.hxx:353
const AW::Position & calc_world_coords() const
Definition: ed4_class.hxx:987
int get_seq_pos() const
GBDATA * GBT_find_SAI(GBDATA *gb_main, const char *name)
Definition: aditem.cxx:177
const char * read_char_pntr() const
Definition: AW_awar.cxx:171
char * build_consensus_string(PosRange range) const
Definition: ed4_class.hxx:1652
GBS_strstruct * GBS_stropen(long init_size)
Definition: arb_strbuf.cxx:39
bool is_hidden_inside_group() const
size_t GB_read_string_count(GBDATA *gbd)
Definition: arbdb.cxx:910
#define ED4_AWAR_CURSOR_TYPE
Definition: ed4_awars.hxx:29
double AW_pos
Definition: aw_base.hxx:29
void get_bounding_box(int x, int y, int &xmin, int &ymin, int &xmax, int &ymax) const
Definition: ED4_cursor.cxx:85
char * get_name_of_species()
Definition: ED4_base.cxx:680
char * GBT_read_string(GBDATA *gb_container, const char *fieldpath)
Definition: adtools.cxx:267
int abs_2_rel(int abs) const
Definition: BI_basepos.hxx:76
const char * decode(char iupac, GB_alignment_type aliType, bool decode_amino_iupac_groups)
Definition: iupac.cxx:239
int is_manager() const
Definition: ed4_class.hxx:1095
int SEQ_TERM_TEXT_YOFFSET
Definition: ED4_main.cxx:53
ED4_index members() const
Definition: ed4_class.hxx:796
#define MAX_SHOWN_MISSING_SPECIES
Definition: ed4_defs.hxx:55
int get_string_size(int gc, long textlen) const
Definition: AW_device.cxx:443
ED4_returncode
Definition: ed4_defs.hxx:160
void push_clip_scale()
Definition: AW_device.cxx:91
long window_upper_clip_point
Definition: ed4_defs.hxx:323
void ED4_viewDifferences_announceTerminalChange()
void jump_base_pos(int base_pos, ED4_CursorJumpType jump_type)
long window_lower_clip_point
Definition: ed4_defs.hxx:323
GBDATA * get_gb_main() const
Definition: ed4_class.hxx:1420
int sequence_to_screen(int sequence_pos) const
char * alignment_name
Definition: ed4_class.hxx:1438
GB_BUFFER GB_give_buffer(size_t size)
Definition: arbdb.cxx:305
void init()
Definition: ED4_cursor.cxx:383
ED4_species_name_terminal * ED4_find_species_name_terminal(const char *species_name)
Definition: ED4_root.cxx:891
ED4_species_name_terminal * ED4_find_species_or_SAI_name_terminal(const char *species_name)
Definition: ED4_root.cxx:887
ED4_SearchPositionType get_whatsFound() const
Definition: ed4_search.hxx:90
bool in_consensus_terminal() const
Definition: ed4_class.hxx:1852
bool line(int gc, const AW::LineVector &Line, AW_bitset filteri=AW_ALL_DEVICES_SCALED)
Definition: aw_device.hxx:430
void pop_clip_scale()
Definition: AW_device.cxx:62
ED4_terminal * get_next_terminal()
Definition: ED4_base.cxx:454
static bool allow_update_global_cursorpos
Definition: ED4_cursor.cxx:270
void GBS_strcat(GBS_strstruct *strstr, const char *ptr)
Definition: arb_strbuf.cxx:108
void PV_AddOrfTerminalsToLoadedSpecies()
ED4_returncode show_clicked_cursor(AW_pos click_xpos, ED4_terminal *target_terminal)
void ED4_get_marked_from_menu(AW_window *)
Definition: ED4_cursor.cxx:684
GBDATA * GBT_next_marked_species(GBDATA *gb_species)
Definition: aditem.cxx:116
CONSTEXPR_INLINE_Cxx14 void swap(unsigned char &c1, unsigned char &c2)
Definition: ad_io_inline.h:19
ASSERTING_CONSTEXPR_INLINE int info2bio(int infopos)
Definition: arb_defs.h:27
CursorPos(ED4_terminal *t, int p)
ED4_root_group_manager * root_group_man
Definition: ed4_class.hxx:1430
void ED4_jump_to_current_species(AW_window *aww)
Definition: ED4_cursor.cxx:518
void set_screen_relative_pos(int scroll_to_relpos)
Definition: ED4_cursor.cxx:913
int abs_count() const
Definition: BI_basepos.hxx:101
#define CHARACTEROFFSET
Definition: ed4_defs.hxx:110
char awar_path_for_cursor[50]
Definition: ed4_class.hxx:714
#define AWAR_SPECIES_NAME
ED4_main_manager * main_manager
Definition: ed4_class.hxx:1427
#define AWAR_SAI_NAME
void set_font_overlap(bool allow)
Definition: aw_device.hxx:260
const char * helixNr(size_t pos) const
Definition: BI_helix.hxx:102
static void select_named_sequence_terminal(const char *name)
Definition: ED4_cursor.cxx:439
void calc_world_coords(AW_pos *x, AW_pos *y) const
Definition: ed4_class.hxx:982
#define MAXPOINTS
Definition: ED4_cursor.cxx:30
ED4_returncode HideCursor()
Definition: ED4_cursor.cxx:772
GBS_strstruct * not_found_message
Definition: ED4_main.cxx:63
AW_awar * awar(const char *awar)
Definition: AW_root.cxx:554
void GBS_strforget(GBS_strstruct *strstr)
Definition: arb_strbuf.cxx:76
AW_key_code keycode
Definition: aw_window.hxx:90
AW_key_mod keymodifier
Definition: aw_window.hxx:83
void ED4_clear_stored_curpos()
GBDATA * GBT_find_sequence(GBDATA *gb_species, const char *aliname)
Definition: adali.cxx:670
GB_alignment_type alignment_type
Definition: ed4_class.hxx:1439
bool setCursorTo(ED4_cursor *cursor, int seq_pos, bool unfoldGroups, ED4_CursorJumpType jump_type)
Definition: ed4_class.hxx:2195
#define MAXLINES
Definition: ED4_cursor.cxx:29
const ConsensusBuildParams & get_consensus_params()
ED4_extension extension
Definition: ed4_class.hxx:923
long GBT_count_marked_species(GBDATA *gb_main)
Definition: aditem.cxx:353
void changeType(ED4_CursorType typ)
Definition: ED4_cursor.cxx:783
bool fulfilled_by(const ED4_terminal *term) const OVERRIDE
int calc_group_depth()
Definition: ED4_base.cxx:424
int size() const
Definition: chartable.h:242
long int flag
Definition: f2c.h:39
void PV_AddCorrespondingOrfTerminals(ED4_species_name_terminal *spNameTerm)
bool is_consensus_terminal() const
Definition: ed4_class.hxx:1847
ED4_returncode fill_species(ED4_multi_species_manager *multi_species_manager, ED4_reference_terminals &refterms, const char *str, int *index, int group_depth, arb_progress *progress)
ED4_CursorJumpType
Definition: ed4_defs.hxx:290
ED4_multi_species_manager * ED4_find_MoreSequences_manager()
Definition: ED4_cursor.cxx:560
void ED4_selected_species_changed_cb(AW_root *)
Definition: ED4_cursor.cxx:499
ED4_base * search_spec_child_rek(ED4_level level)
Definition: ED4_base.cxx:434
bool is_completely_visible() const
void ED4_change_cursor(AW_window *aww)
ED4_cursor & current_cursor()
Definition: ed4_class.hxx:1399
#define ED4_IUPAC_EMPTY
Definition: ed4_tools.hxx:14
ED4_species_name_terminal * corresponding_species_name_terminal() const
Definition: ed4_class.hxx:1940
AW_pos position[2]
Definition: ed4_defs.hxx:258
unsigned int refresh
Definition: ed4_defs.hxx:298
BI_PAIR_TYPE pairtype(size_t pos) const
Definition: BI_helix.hxx:101
void ED4_restore_curpos(AW_window *aww)
ED4_CursorType getType() const
Definition: ed4_class.hxx:651
char awar_path_for_Ecoli[50]
Definition: ed4_class.hxx:715
ED4_SearchPosition * get_shown_at(int pos) const
char * GBS_mempntr(GBS_strstruct *strstr)
Definition: arb_strbuf.cxx:86
GB_ERROR GBT_write_string(GBDATA *gb_container, const char *fieldpath, const char *content)
Definition: adtools.cxx:451
ED4_cursor(ED4_window *win)
Definition: ED4_cursor.cxx:376
#define OVERRIDE
Definition: cxxforward.h:93
ED4_AREA_LEVEL get_area_level(ED4_multi_species_manager **multi_species_manager=NULp) const
Definition: ED4_base.cxx:497
#define ED4_AWAR_SCROLL_MARGIN
Definition: ed4_awars.hxx:33
char awar_path_for_helixNr[50]
Definition: ed4_class.hxx:718
ED4_returncode update_bases(const ED4_base *old_base, const ED4_base *new_base, PosRange range=PosRange::whole())
ED4_returncode show_cursor_at(ED4_terminal *target_terminal, ED4_index what_pos)
long awar_edit_rightward
Definition: ED4_main.cxx:67
void jump_sequence_pos(int sequence_pos, ED4_CursorJumpType jump_type)
char * GB_read_string(GBDATA *gbd)
Definition: arbdb.cxx:903
ED4_window * current_ed4w()
Definition: ed4_class.hxx:1397
BI_ecoli_ref * ecoli_ref
Definition: ed4_class.hxx:1437
AW_root * aw_root
Definition: ed4_class.hxx:1423
void set_abs_x()
void set_horizontal_scrollbar_position(int position)
Definition: AW_window.cxx:995
#define abs(x)
Definition: f2c.h:151
unsigned int hidden
Definition: ed4_class.hxx:926
long window_right_clip_point
Definition: ed4_defs.hxx:323
bool ED4_is_gap_character(char chr)
void request_refresh(int clear=1) FINAL_OVERRIDE
void aw_message(const char *msg)
Definition: AW_status.cxx:932
void ED4_init_notFoundMessage()
Definition: ED4_cursor.cxx:566
ED4_index pixel2pos(AW_pos click_x)
Definition: ED4_root.cxx:1927
AW_root * get_root()
Definition: aw_window.hxx:348
ED4_terminal * get_terminal() const
bool completely_shows(int x1, int y1, int x2, int y2) const
Definition: ED4_base.cxx:219
static bool ignore_selected_SAI_changes_cb
Definition: ED4_cursor.cxx:437
ED4_returncode refresh_all_windows(bool redraw)
Definition: ED4_root.cxx:168
AW_window_simple * win
has_base_at(int seq_pos_, bool want_base_)
#define NULp
Definition: cxxforward.h:97
GBDATA * GBT_find_species(GBDATA *gb_main, const char *name)
Definition: aditem.cxx:139
const ED4_remap * remap() const
Definition: ed4_class.hxx:1780
void ED4_finish_and_show_notFoundMessage()
Definition: ED4_cursor.cxx:571
GB_ERROR write_string(const char *aw_string)
static void clear()
ED4_CursorType
Definition: ed4_class.hxx:601
int is_sequence_terminal() const
Definition: ed4_class.hxx:1082
void ED4_setup_gaps_and_alitype(const char *gap_chars, GB_alignment_type alitype)
Definition: ED4_main.cxx:253
int get_base_position(const ED4_terminal *base, int sequence_position)
char * GBT_get_default_alignment(GBDATA *gb_main)
Definition: adali.cxx:675
bool gotData() const
Definition: BI_basepos.hxx:74
void set_vertical_scrollbar_position(int position)
Definition: AW_window.cxx:986
void build_consensus_string_to(char *consensus_string, ExplicitRange range, const ConsensusBuildParams &BK) const
Definition: chartable.cxx:386
char * resolve_pointer_to_string_copy(int *str_len=NULp) const FINAL_OVERRIDE
void adjacent_screen_positions(int seq_pos, int &screen_pos_left, int &screen_pos_right)
#define OUTER_HEIGHT
ED4_cursor_move
Definition: ed4_defs.hxx:194
virtual void flush()
Definition: AW_device.cxx:268
int get_sequence_pos() const
Definition: ED4_cursor.cxx:393
AW_window_menu_modes * aww
Definition: ed4_class.hxx:704
GB_transaction ta(gb_var)
bool partly_shows(int x1, int y1, int x2, int y2) const
Definition: ED4_base.cxx:208
void ED4_scrollbar_change_cb(AW_window *aww)
GBDATA * gb_main
Definition: adname.cxx:33
long window_left_clip_point
Definition: ed4_defs.hxx:323
bool is_partly_visible() const
static RandomNumberGenerator gen(time(NULp))
void ED4_get_and_jump_to_selected_SAI(AW_window *aww)
Definition: ED4_cursor.cxx:630
GB_CSTR GBT_get_name_or_description(GBDATA *gb_item)
Definition: aditem.cxx:441
static ED4_terminal * get_upper_lower_cursor_pos(ED4_manager *starting_point, ED4_cursor_move cursor_move, AW_pos current_y, bool isScreen, const ED4_TerminalPredicate &predicate)
ED4_terminal * get_prev_terminal()
Definition: ED4_base.cxx:467
int get_screen_relative_pos() const
Definition: ED4_cursor.cxx:909
ED4_manager * get_parent(ED4_level lev) const
Definition: ed4_class.hxx:1820
struct ED4_base::@7 flag
const char * GB_CSTR
Definition: arbdb_base.h:25
#define LOWER_OFFSET
GB_ERROR write_int(long aw_int)
const char * ED4_SearchPositionTypeId[SEARCH_PATTERNS+1]
Definition: ED4_search.cxx:35
long ED4_index
Definition: ed4_defs.hxx:114
bool allowed_to_draw
Definition: ed4_class.hxx:642
#define CWIDTH
static bool ignore_selected_species_changes_cb
Definition: ED4_cursor.cxx:436
static ED4_species_name_terminal * insert_new_species_terminal(GB_CSTR species_name, bool is_SAI)
Definition: ED4_cursor.cxx:583
GB_write_int const char s
Definition: AW_awar.cxx:156