ARB
ED4_block.cxx
Go to the documentation of this file.
1 #include "ed4_awars.hxx"
2 #include "ed4_class.hxx"
3 #include "ed4_tools.hxx"
4 #include "ed4_block.hxx"
5 #include "ed4_edit_string.hxx"
6 #include "ed4_list.hxx"
7 
8 #include <awt_sel_boxes.hxx>
9 #include <fast_aligner.hxx>
10 
11 #include <aw_awars.hxx>
12 #include <aw_msg.hxx>
13 #include <aw_root.hxx>
14 #include <aw_select.hxx>
15 
16 #include <arbdbt.h>
17 #include <gb_aci.h>
18 
19 #include <climits>
20 #include <cctype>
21 #include <map>
22 
23 using namespace std;
24 
25 // --------------------------------------------------------------------------------
26 
27 class ED4_block : virtual Noncopyable {
28  // stores columnrange of selected region
29  // (linerange is stored in EDIT4 marks)
31  bool columnBlockUsed;
32  PosRange range;
33 
34 public:
36  : type(ED4_BT_NOBLOCK),
37  columnBlockUsed(false)
38  {}
39 
40  ED4_blocktype get_type() const { return type; }
41  void set_type(ED4_blocktype bt);
42  void toggle_type();
43  void autocorrect_type();
44 
45  const PosRange& get_colblock_range() const {
46  e4_assert(type == ED4_BT_COLUMNBLOCK || type == ED4_BT_MODIFIED_COLUMNBLOCK); // otherwise range may be undefined
47  return range;
48  }
49  void set_range(const PosRange& new_range) { range = new_range; }
50 
52  PosRange res;
53 
54  switch (type) {
55  case ED4_BT_NOBLOCK:
56  res = PosRange::empty();
57  break;
58 
59  case ED4_BT_COLUMNBLOCK:
61  res = get_colblock_range();
62  break;
63 
64  case ED4_BT_LINEBLOCK:
65  res = PosRange::whole();
66  break;
67  }
68 
69  return res;
70  }
71 };
72 
74 
75 // --------------------------------------------------------------------------------
76 
77 class SeqPart {
78  const char *seq;
79 
80  int offset;
81  int len; // of part
82 
83  static char to_gap(char c) { return ED4_is_gap_character(c) ? c : 0; }
84 
85 public:
86  SeqPart(const char *seq_, int offset_, int len_)
87  : seq(seq_),
88  offset(offset_),
89  len(len_)
90  {}
91 
92  const char *data() const { return seq+offset; }
93  int length() const { return len; }
94 
95  // detect which gap to use at border of SeqPart:
96  char left_gap() const {
97  char gap = to_gap(seq[offset]);
98  if (!gap && offset) gap = to_gap(seq[offset-1]);
99  if (!gap) gap = '-';
100  return gap;
101  }
102  char right_gap() const {
103  char gap = to_gap(seq[offset+len-1]);
104  if (!gap) gap = to_gap(seq[offset+len]);
105  if (!gap) gap = '-';
106  return gap;
107  }
108 };
109 
110 // --------------------------------------------------------------------------------
111 
113  seq_term->request_refresh();
114  ED4_columnStat_terminal *colStatTerm = seq_term->corresponding_columnStat_terminal();
115  if (colStatTerm) colStatTerm->request_refresh();
116 }
117 
118 static void refresh_selected(bool refresh_name_terminals) {
120  while (listElem) {
121  ED4_species_name_terminal *name_term = listElem->elem()->object;
122  ED4_sequence_terminal *seq_term = name_term->corresponding_sequence_terminal();
123 
124  if (refresh_name_terminals) name_term->request_refresh();
125  if (seq_term) col_block_refresh_on_seq_term(seq_term);
126 
127  listElem = listElem->next();
128  }
129 }
130 
131 // --------------------------------------------------------------------------------
132 
134  if (type != bt) {
135  type = bt;
136  refresh_selected(true);
138  columnBlockUsed = true;
139  }
140  }
141 }
142 
144  switch (type) {
145  case ED4_BT_NOBLOCK: {
146  aw_message("No block selected.");
147  break;
148  }
149  case ED4_BT_LINEBLOCK: {
150  if (columnBlockUsed) {
152  }
153  else {
154  aw_message("No columnblock marked so far - I can't guess the column range");
155  }
156  break;
157  }
159  case ED4_BT_COLUMNBLOCK: {
161  break;
162  }
163  }
164 }
165 
167  // this has to be called every time the selection has changed
168 
169  if (!ED4_ROOT->selected_objects->head()) { // no objects are selected
171  }
172  else {
173  switch (type) {
174  case ED4_BT_NOBLOCK: {
176  break;
177  }
178  case ED4_BT_COLUMNBLOCK: {
180  break;
181  }
182  case ED4_BT_LINEBLOCK:
184  break;
185  }
186  }
187  }
188 }
189 
190 // --------------------------------------------------------------------------------
191 
192 // if block_operation returns NULp => no changes will be made to database
193 // otherwise the changed sequence(part) will be written to the database
194 
196  GBDATA *gbd = term->get_species_pointer();
197  GB_ERROR error = NULp;
198 
199  if (gbd) {
200  char *seq = GB_read_string(gbd);
201  int len = GB_read_string_count(gbd);
202 
203  int new_len;
204  char *new_seq = block_operator.operate(SeqPart(seq, 0, len), new_len);
205  error = block_operator.get_error();
206 
207  if (new_seq) {
208  if (new_len<len) {
209  memcpy(seq, new_seq, new_len);
210  char gap = ED4_is_gap_character(seq[len-1]) ? seq[len-1] : '.';
211  int l;
212  for (l=new_len; l<len; l++) {
213  seq[l] = gap;
214  }
215  seq[l] = 0;
216  }
217  else if (new_len>len) {
218  for (int l=new_len-1; l>=len; l--) {
219  if (!ED4_is_gap_character(new_seq[l])) {
220  error = "Result of block-operation to large (not enough gaps at end of sequence data)";
221  break;
222  }
223  }
224 
225  if (!error) { // there are enough gaps at end of sequence
226  memcpy(seq, new_seq, len);
227  }
228  }
229  else {
230  memcpy(seq, new_seq, len);
231  }
232 
233  if (!error) {
234  error = GB_write_string(gbd, seq);
235  if (!error) term->request_refresh();
236  }
237  free(new_seq);
238  }
239  free(seq);
240  }
241 
242  return error;
243 }
244 
245 // uses range_col1 till range_col2 as range
247  GBDATA *gbd = term->get_species_pointer();
248  GB_ERROR error = NULp;
249 
250  if (gbd) {
251  char *seq = GB_read_string(gbd);
252  int len = GB_read_string_count(gbd);
253 
254  ExplicitRange range(block.get_colblock_range(), len);
255 
256  int len_part = range.size();
257  char *seq_part = seq+range.start();
258  int new_len;
259  char *new_seq_part = block_operator.operate(SeqPart(seq, range.start(), len_part), new_len);
260  error = block_operator.get_error();
261 
262  if (new_seq_part) {
263  if (new_len<len_part) {
264  memcpy(seq_part, new_seq_part, new_len);
265  char gap = '-';
266  if (seq_part[len_part-1] == '.' || seq_part[len_part] == '.') gap = '.';
267 
268  for (int l=new_len; l<len_part; l++) {
269  seq_part[l] = gap;
270  }
271  }
272  else if (new_len>len_part) {
273  for (int l=new_len-1; l>=len_part; l--) {
274  if (!ED4_is_gap_character(new_seq_part[l])) {
275  error = "Result of block-operation to large (not enough gaps at end of marked columnblock)";
276  break;
277  }
278  }
279 
280  if (!error) { // there are enough gaps at end of sequence
281  memcpy(seq_part, new_seq_part, len_part);
282  }
283  }
284  else {
285  memcpy(seq_part, new_seq_part, len_part);
286  }
287  delete new_seq_part;
288 
289  if (!error) {
290  error = GB_write_autoconv_string(gbd, seq);
291  if (!error) term->request_refresh();
292  }
293  }
294 
295  delete seq;
296  }
297 
298  return error;
299 }
300 
301 static void ED4_with_whole_block(const ED4_block_operator& block_operator) {
303 
304  typedef map<ED4_window*, int> CursorPositions;
305  CursorPositions at_base;
306 
307  for (ED4_window *win = ED4_ROOT->first_window; win; win = win->next) {
308  ED4_cursor& cursor = win->cursor;
309  if (cursor.owner_of_cursor) at_base[win] = cursor.get_base_position();
310  }
311 
312 
313  switch (block.get_type()) {
314  case ED4_BT_NOBLOCK: {
315  aw_message("No block marked -- use right mouse button");
316  break;
317  }
318  case ED4_BT_LINEBLOCK:
320  case ED4_BT_COLUMNBLOCK: {
322  while (listElem && !error) {
323  ED4_species_name_terminal *nameTerm = listElem->elem()->object;
324  ED4_sequence_terminal *seqTerm = nameTerm->corresponding_sequence_terminal();
325 
326  error = block.get_type() == ED4_BT_LINEBLOCK
327  ? perform_block_operation_on_whole_sequence(block_operator, seqTerm)
328  : perform_block_operation_on_part_of_sequence(block_operator, seqTerm);
329 
330  listElem = listElem->next();
331  }
332  break;
333  }
334  default: {
335  error = "Illegal blocktype";
336  break;
337  }
338  }
339 
340  if (error) error = GBS_global_string("[In block operation] %s", error);
342 
343  if (!error) {
344  for (CursorPositions::iterator ab = at_base.begin(); ab != at_base.end(); ++ab) {
345  ED4_window *win = ab->first;
346  win->cursor.jump_base_pos(ab->second, ED4_JUMP_KEEP_VISIBLE); // restore cursor at same base
347  }
348  }
349 }
350 
351 bool ED4_get_selected_range(ED4_terminal *term, PosRange& range) { // @@@ function will get useless, when multi-column-blocks are possible
352  if (block.get_type() == ED4_BT_NOBLOCK) return false;
353  if (!term->containing_species_manager()->is_selected()) return false;
354 
355  range = block.get_range_according_to_type();
356  return true;
357 }
358 
360 void ED4_setBlocktype(ED4_blocktype bt) { block.set_type(bt); }
363 
365  static ED4_sequence_terminal *last_term1, *last_term2;
366  static PosRange last_range;
367 
368  if (!term1) return; // e.g. when 1st click was into consensus
369 
370  if (pos1>pos2) {
371  block.set_range(PosRange(pos2, pos1));
372  }
373  else {
374  block.set_range(PosRange(pos1, pos2));
375  }
376 
377  if (block.get_type()==ED4_BT_MODIFIED_COLUMNBLOCK) {
378  refresh_selected(false);
379  }
380  else {
381  { // ensure term1 is the upper terminal
382  AW_pos dummy, y1, y2;
383 
384  term1->calc_world_coords(&dummy, &y1);
385  term2->calc_world_coords(&dummy, &y2);
386 
387  if (y1>y2) {
388  ED4_sequence_terminal *t = term1; term1 = term2; term2 = t;
389  AW_pos y = y1; y1 = y2; y2 = y;
390  }
391  }
392 
393  int do_above = 1; // we have to update terminals between last_term1 and term1
394  int do_below = 1; // we have to update terminals between term2 and last_term2
395 
396  ED4_terminal *term = term1;
397 
398  bool xRangeChanged = block.get_range_according_to_type() != last_range;
399 
400  while (term) {
401  if (term->is_sequence_terminal()) {
402  ED4_sequence_terminal *seq_term = term->to_sequence_terminal();
403 
404  if (seq_term==last_term1) {
405  do_above = 0;
406  }
407  if (seq_term==last_term2) {
408  do_below = 0;
409  }
410 
411  ED4_species_name_terminal *name_term = seq_term->corresponding_species_name_terminal();
412  ED4_species_manager *species_man = name_term->containing_species_manager();
413  if (species_man->is_selected()) { // already selected
414  if (xRangeChanged) {
416  }
417  }
418  else { // select it
419  if (!species_man->is_consensus_manager()) {
420  ED4_ROOT->add_to_selected(name_term);
421  }
422  }
423  }
424  if (term==term2) {
425  break;
426  }
427  term = term->get_next_terminal();
428  }
429 
430  if (!initial_call) {
431  if (do_below) {
432  while (term) {
433  if (term->is_species_name_terminal()) {
434  ED4_species_manager *species_man = term->containing_species_manager();
435  if (species_man->is_selected() && !species_man->is_consensus_manager()) {
436  ED4_ROOT->remove_from_selected(term->to_species_name_terminal());
437  }
438  }
439  if (term==last_term2) break;
440  term = term->get_next_terminal();
441  }
442  }
443 
444  if (do_above) {
445  term = last_term1->corresponding_species_name_terminal();
446  while (term && term!=term1) {
447  if (term->is_species_name_terminal()) {
448  ED4_species_manager *species_man = term->containing_species_manager();
449  if (species_man->is_selected() && !species_man->is_consensus_manager()) {
450  ED4_ROOT->remove_from_selected(term->to_species_name_terminal());
451  }
452  }
453  term = term->get_next_terminal();
454  }
455  }
456  }
457  }
458 
459  last_term1 = term1;
460  last_term2 = term2;
461  last_range = block.get_range_according_to_type();
462 }
463 
465  static ED4_sequence_terminal *fix_term = NULp;
466  static ED4_index fix_pos = 0;
467 
468  ED4_index seq_pos;
469  {
470  AW_pos termw_x, termw_y;
471  seq_term->calc_world_coords(&termw_x, &termw_y);
472 
473  ED4_index scr_pos = ED4_ROOT->pixel2pos(event->x - termw_x);
474  ED4_remap *remap = ED4_ROOT->root_group_man->remap();
475  seq_pos = remap->screen_to_sequence(scr_pos);
476  }
477 
478  switch (event->type) {
479  case AW_Mouse_Press: {
480  if (block.get_type() == ED4_BT_NOBLOCK) { // initial columnblock
481  if (!seq_term->is_consensus_terminal()) {
483 
484  fix_term = seq_term;
485  fix_pos = seq_pos;
486 
487  select_and_update(fix_term, seq_term, fix_pos, seq_pos, 1);
488  }
489  }
490  else if (block.get_type()==ED4_BT_LINEBLOCK) { // change lineblock to columnblock
492 
493  fix_term = seq_term;
494  if (seq_pos<(MAXSEQUENCECHARACTERLENGTH/2)) { // in first half of sequence
495  fix_pos = MAXSEQUENCECHARACTERLENGTH;
496  }
497  else {
498  fix_pos = 0;
499  }
500 
501  select_and_update(fix_term, seq_term, fix_pos, seq_pos, 1);
502  }
503  else { // expand columnblock (search nearest corner/border -> fix opposite corner/border)
505 
507  e4_assert(listElem);
508 
509  if (block.get_type()==ED4_BT_COLUMNBLOCK) {
510  AW_pos min_term_y = LONG_MAX;
511  AW_pos max_term_y = LONG_MIN;
512  ED4_species_name_terminal *min_term = NULp;
513  ED4_species_name_terminal *max_term = NULp;
514  AW_pos xpos, ypos;
515 
516  while (listElem) {
517  ED4_species_name_terminal *name_term = listElem->elem()->object;
518  name_term->calc_world_coords(&xpos, &ypos);
519 
520  if (ypos<min_term_y) {
521  min_term_y = ypos;
522  min_term = name_term;
523  }
524  if (ypos>max_term_y) {
525  max_term_y = ypos;
526  max_term = name_term;
527  }
528 
529  listElem = listElem->next();
530  }
531 
532  seq_term->calc_world_coords(&xpos, &ypos);
533  ED4_species_name_terminal *fix_name_term;
534  if (fabs(ypos-min_term_y)<fabs(ypos-max_term_y)) { // seq_term is closer to min_term
535  fix_name_term = max_term; // select max_term as fixed corner
536  }
537  else {
538  fix_name_term = min_term;
539  }
540  e4_assert(fix_name_term);
541  fix_term = fix_name_term->corresponding_sequence_terminal();
542  }
543 
544  AW_screen_area area_rect;
545  {
546  AW_pos ex = event->x;
547  AW_pos ey = event->y;
548  current_ed4w()->world_to_win_coords(&ex, &ey);
549 
550  if (ED4_ROOT->get_area_rectangle(&area_rect, ex, ey)!=ED4_R_OK) {
551  e4_assert(0);
552  break;
553  }
554  }
555 
556 
557  const ED4_remap *rm = ED4_ROOT->root_group_man->remap();
558 
559  PosRange screen_range = rm->clip_screen_range(seq_term->calc_interval_displayed_in_rectangle(&area_rect));
560  int scr_pos = rm->sequence_to_screen(seq_pos);
561 
562  PosRange block_screen_range = rm->sequence_to_screen(block.get_colblock_range());
563  PosRange block_visible_part = intersection(screen_range, block_screen_range);
564 
565  if (block_visible_part.is_empty()) {
566  if (scr_pos>block_screen_range.end()) {
567  fix_pos = block.get_colblock_range().start();
568  }
569  else {
570  e4_assert(scr_pos<block_screen_range.start());
571  fix_pos = block.get_colblock_range().end();
572  }
573  }
574  else {
575  int dist_left = abs(scr_pos-block_visible_part.start());
576  int dist_right = abs(scr_pos-block_visible_part.end());
577 
578  if (dist_left < dist_right) { // click nearer to left border of visible part of block
579  fix_pos = block.get_colblock_range().end(); // keep right block-border
580  }
581  else {
582  fix_pos = block.get_colblock_range().start();
583  }
584  }
585 
586  select_and_update(fix_term, seq_term, fix_pos, seq_pos, 0);
587  }
588  break;
589  }
590  case AW_Mouse_Drag: {
591  select_and_update(fix_term, seq_term, fix_pos, seq_pos, 0);
592  break;
593  }
594  case AW_Mouse_Release: {
595  select_and_update(fix_term, seq_term, fix_pos, seq_pos, 0);
596  break;
597  }
598  default: {
599  e4_assert(0);
600  break;
601  }
602  }
603 }
604 
605 // --------------------------------------------------------------------------------
606 // Replace
607 
608 inline bool matchesUsingWildcard(GB_CSTR s1, GB_CSTR s2, int len) {
609  // s2 may contain '?' as wildcard
610  int cmp = 0;
611 
612  for (int i = 0; i<len && !cmp; ++i) {
613  cmp = int(s1[i])-int(s2[i]);
614  if (cmp && s2[i] == '?') cmp = 0;
615  }
616 
617  return !cmp;
618 }
619 
620 class replace_op : public ED4_block_operator { // derived from Noncopyable
621  const char *oldString;
622  const char *newString;
623 
624  int olen;
625  int nlen;
626 
627 public:
628  replace_op(const char *oldString_, const char *newString_)
629  : oldString(oldString_),
630  newString(newString_)
631  {
632  olen = strlen(oldString);
633  nlen = strlen(newString);
634  }
635 
636  char* operate(const SeqPart& part, int& new_len) const OVERRIDE {
637  int maxlen;
638  int len = part.length();
639  int max_o = len-olen;
640 
641  if (nlen<=olen) {
642  maxlen = len;
643  }
644  else {
645  maxlen = (len/olen+1)*nlen;
646  }
647 
648  char *new_seq = ARB_alloc<char>(maxlen+1);
649  int replaced = 0;
650  int o = 0;
651  int n = 0;
652 
653  const char *sequence = part.data();
654  while (o<len) {
655  if (o <= max_o && matchesUsingWildcard(sequence+o, oldString, olen)) {
656  memcpy(new_seq+n, newString, nlen);
657  n += nlen;
658  o += olen;
659  replaced++;
660  }
661  else {
662  new_seq[n++] = sequence[o++];
663  }
664  }
665  new_seq[n] = 0;
666 
667  if (replaced) {
668  new_len = n;
669  }
670  else {
671  freenull(new_seq);
672  }
673 
674  return new_seq;
675  }
676 };
677 
679  AW_root *awr = ED4_ROOT->aw_root;
683 }
684 
686  AW_window_simple *aws = new AW_window_simple;
687 
688  aws->init(root, "REPLACE", "Search & Replace");
689  aws->load_xfig("edit4/replace.fig");
690 
691  aws->at("close");
692  aws->callback(AW_POPDOWN);
693  aws->create_button("CLOSE", "Close", "C");
694 
695  aws->at("help");
696  aws->callback(makeHelpCallback("e4_replace.hlp"));
697  aws->create_button("HELP", "Help", "H");
698 
699  aws->at("spattern");
700  aws->create_input_field(ED4_AWAR_REP_SEARCH_PATTERN, 30);
701 
702  aws->at("rpattern");
703  aws->create_input_field(ED4_AWAR_REP_REPLACE_PATTERN, 30);
704 
705  aws->at("go");
706  aws->callback(replace_in_block);
707  aws->create_button("GO", "Go", "G");
708 
709  return aws;
710 }
711 
712 // --------------------------------------------------------------------------------
713 // Other block operations
714 
715 inline char *dont_return_unchanged(char *result, int& new_len, const SeqPart& part) {
716  if (result) {
717  if (new_len == part.length()) {
718  if (memcmp(result, part.data(), new_len) == 0) {
719  freenull(result);
720  }
721  }
722  }
723  return result;
724 }
725 
726 class case_op : public ED4_block_operator {
727  bool to_upper;
728 public:
729  case_op(bool to_upper_) : to_upper(to_upper_) {}
730 
731  char *operate(const SeqPart& part, int& new_len) const OVERRIDE {
732  int len = part.length();
733  const char *seq = part.data();
734  char *new_seq = ARB_alloc<char>(len+1);
735 
736  if (to_upper) {
737  for (int i=0; i<len; i++) new_seq[i] = toupper(seq[i]);
738  }
739  else {
740  for (int i=0; i<len; i++) new_seq[i] = tolower(seq[i]);
741  }
742  new_seq[len] = 0;
743 
744  new_len = len;
745  return dont_return_unchanged(new_seq, new_len, part);
746  }
747 };
748 
750  bool reverse;
751  bool complement;
752  char T_or_U;
753 
754 public:
755  revcomp_op(GB_alignment_type aliType, bool reverse_, bool complement_)
756  : reverse(reverse_),
757  complement(complement_),
758  T_or_U(0)
759  {
760  if (complement) {
761  error = GBT_determine_T_or_U(aliType, &T_or_U, reverse ? "reverse-complement" : "complement");
762  }
763  }
764 
765  char *operate(const SeqPart& part, int& new_len) const OVERRIDE {
766  char *result = NULp;
767  if (!error) {
768  int len = part.length();
769  if (complement) {
770  result = GBT_complementNucSequence(part.data(), len, T_or_U);
771  if (reverse) freeset(result, GBT_reverseNucSequence(result, len));
772  }
773  else if (reverse) result = GBT_reverseNucSequence(part.data(), len);
774 
775  new_len = len;
776  }
777  return dont_return_unchanged(result, new_len, part);
778  }
779 
780 };
781 
783  int direction;
784 public:
785  unalign_op(int direction_) : direction(direction_) {}
786 
787  char *operate(const SeqPart& part, int& new_len) const OVERRIDE {
788  int len = part.length();
789  const char *seq = part.data();
790  char *result = ARB_alloc<char>(len+1);
791 
792  int o = 0;
793  int n = 0;
794 
795  while (o<len) {
796  if (!ED4_is_gap_character(seq[o])) result[n++] = seq[o];
797  o++;
798  }
799 
800  if (n<len) { // (move and) dot rest
801  int gapcount = len-n;
802  switch (direction) {
803  case 1: // rightwards
804  memmove(result+gapcount, result, n);
805  memset(result, part.left_gap(), gapcount);
806  break;
807  case 0: { // center
808  int leftgaps = gapcount/2;
809  int rightgaps = gapcount-leftgaps;
810 
811  memmove(result+leftgaps, result, n);
812  memset(result, part.left_gap(), leftgaps);
813  memset(result+leftgaps+n, part.right_gap(), rightgaps);
814 
815  break;
816  }
817  case -1: // leftwards
818  memset(result+n, part.right_gap(), gapcount);
819  break;
820  }
821  }
822  result[len] = 0;
823  new_len = len;
824 
825  return dont_return_unchanged(result, new_len, part);
826  }
827 
828 
829 };
830 
831 class shift_op : public ED4_block_operator {
832  int direction;
833 
834  char *shift_left_sequence(const SeqPart& part, int& new_len) const {
835  char *result = NULp;
836  const char *seq = part.data();
837 
838  if (!ED4_is_gap_character(seq[0])) {
839  error = "Need a gap at block start for shifting left";
840  }
841  else {
842  int len = part.length();
843  ARB_alloc(result, len+1);
844  result[len] = 0;
845  new_len = len;
846  result[len-1] = part.right_gap();
847  memcpy(result, seq+1, len-1);
848  }
849  return result;
850  }
851 
852  char *shift_right_sequence(const SeqPart& part, int& new_len) const {
853  char *result = NULp;
854  const char *seq = part.data();
855  int len = part.length();
856 
857  if (!ED4_is_gap_character(seq[len-1])) {
858  error = "Need a gap at block end for shifting right";
859  }
860  else {
861  ARB_alloc(result, len+1);
862  result[len] = 0;
863  new_len = len;
864  result[0] = part.left_gap();
865  memcpy(result+1, seq, len-1);
866  }
867  return result;
868  }
869 
870 
871 public:
872  shift_op(int direction_) : direction(direction_) {}
873 
874  char *operate(const SeqPart& part, int& new_len) const OVERRIDE {
875  char *result = direction<0
876  ? shift_left_sequence(part, new_len)
877  : shift_right_sequence(part, new_len);
878  return dont_return_unchanged(result, new_len, part);
879  }
880 };
881 
883  switch (operationType) {
884  case ED4_BO_UPPER_CASE: ED4_with_whole_block(case_op(true)); break;
885  case ED4_BO_LOWER_CASE: ED4_with_whole_block(case_op(false)); break;
886 
890 
894 
897 
898  default: {
899  e4_assert(0);
900  break;
901  }
902  }
903 }
904 
905 // --------------------------------------
906 // modify range of selected sai
907 
908 #define AWAR_MOD_SAI_SCRIPT "modsai/script"
909 
910 static void modsai_cb(AW_window *aww) {
911  ED4_MostRecentWinContext context;
912 
913  ED4_cursor *cursor = &current_cursor();
914  GB_ERROR error = NULp;
915 
916  if (!cursor->in_SAI_terminal()) {
917  error = "Please select the SAI you like to modify";
918  }
919  else if (block.get_type() == ED4_BT_NOBLOCK) {
920  error = "Please select the range where the SAI shall be modified";
921  }
922  else {
923  AW_root *aw_root = aww->get_root();
924  char *script = aw_root->awar(AWAR_MOD_SAI_SCRIPT)->read_string();
925  const char *sainame = aw_root->awar(AWAR_SAI_NAME)->read_char_pntr();
926 
928  GBDATA *gb_sai = GBT_find_SAI(GLOBAL_gb_main, sainame);
929 
930  if (!gb_sai) {
931  error = GB_have_error()
932  ? GB_await_error()
933  : GBS_global_string("Failed to find SAI '%s'", sainame);
934  }
935  else {
936  GBDATA *gb_data = GBT_find_sequence(gb_sai, ED4_ROOT->alignment_name);
937 
938  if (!gb_data) error = GB_await_error();
939  else {
940  char *seq = GB_read_string(gb_data);
941  int len = GB_read_string_count(gb_data);
942 
943  ExplicitRange range(block.get_range_according_to_type(), len);
944  char *part = range.dup_corresponding_part(seq, len);
945 
946  char *result = GB_command_interpreter_in_env(part, script, GBL_simple_call_env(gb_sai));
947  if (!result) error = GB_await_error();
948  else {
949  int reslen = strlen(result);
950  if (reslen>range.size()) {
951  error = GBS_global_string("Cannot insert modified range (result too long; %i>%i)", reslen, range.size());
952  }
953  else {
954  memcpy(seq+range.start(), result, reslen);
955  int rest = range.size()-reslen;
956  if (rest>0) memset(seq+range.start()+reslen, '-', rest);
957 
958  error = GB_write_string(gb_data, seq);
959  }
960  free(result);
961  }
962 
963  free(part);
964  free(seq);
965  }
966  }
967  free(script);
968  error = ta.close(error);
969  }
970 
971  aw_message_if(error);
972 }
973 
976 
977  AW_window_simple *aws = new AW_window_simple;
978  aws->init(root, "modsai", "Modify SAI range");
979  aws->load_xfig("edit4/modsai.fig");
980 
981  aws->at("close");
982  aws->callback(AW_POPDOWN);
983  aws->create_button("CLOSE", "Close", "C");
984 
985  aws->at("help");
986  aws->callback(makeHelpCallback("e4_modsai.hlp"));
987  aws->create_button("HELP", "Help", "H");
988 
990  GB_ERROR error;
991  {
992  StorableSelectionList storable_sellist(TypedSelectionList("sellst", sellist, "SRT/ACI scripts", "srt_aci"));
993  error = storable_sellist.load(GB_path_in_ARBLIB("sellists/mod_sequence*.sellst"), false);
994  }
995  aw_message_if(error);
996 
997  aws->at("go");
998  aws->callback(modsai_cb);
999  aws->create_button("go", "GO");
1000 
1001  return aws;
1002 }
1003 
1004 
1005 // --------------------------------------------------------------------------------
1006 
1007 #ifdef UNIT_TESTS
1008 #ifndef TEST_UNIT_H
1009 #include <test_unit.h>
1010 #endif
1011 
1012 static arb_test::match_expectation blockop_expected_io(const ED4_block_operator& blockop, const char *oversized_input, const char *expected_result, const char *part_of_error) {
1013  int whole_len = strlen(oversized_input);
1014  SeqPart part(oversized_input, 1, whole_len-2);
1015  int new_len = 0;
1016  char *result = blockop.operate(part, new_len);
1017 
1018  using namespace arb_test;
1019 
1020  expectation_group expectations;
1021  expectations.add(part_of_error
1022  ? that(blockop.get_error()).does_contain(part_of_error)
1023  : that(blockop.get_error()).is_equal_to_NULL());
1024  expectations.add(that(result).is_equal_to(expected_result));
1025  if (expected_result) expectations.add(that(new_len).is_equal_to(whole_len-2));
1026 
1027  free(result);
1028 
1029  return all().ofgroup(expectations);
1030 }
1031 
1032 #define TEST_EXPECT_BLOCKOP_PERFORMS(oversized_input,blockop,expected) TEST_EXPECTATION(blockop_expected_io(blockop, oversized_input, expected, NULp))
1033 #define TEST_EXPECT_BLOCKOP_PERFORMS__BROKEN(oversized_input,blockop,expected) TEST_EXPECTATION__BROKEN(blockop_expected_io(blockop, oversized_input, expected, NULp))
1034 #define TEST_EXPECT_BLOCKOP_ERRORHAS(oversized_input,blockop,expected) TEST_EXPECTATION(blockop_expected_io(blockop, oversized_input, NULp, expected))
1035 #define TEST_EXPECT_BLOCKOP_ERRORHAS__BROKEN(oversized_input,blockop,expected) TEST_EXPECTATION__BROKEN(blockop_expected_io(blockop, oversized_input, NULp, expected))
1036 
1037 void TEST_block_operators() {
1039 
1040  // Note: make sure tests perform an identity block operation at least once for each operator
1041 
1042  // replace_op
1043  TEST_EXPECT_BLOCKOP_PERFORMS("-A-C--", replace_op("-", "."), "A.C.");
1044  TEST_EXPECT_BLOCKOP_PERFORMS("-A-C--", replace_op("?", "."), "....");
1045  TEST_EXPECT_BLOCKOP_PERFORMS("AACAG-", replace_op("AC", "CA"), "CAAG");
1046  TEST_EXPECT_BLOCKOP_PERFORMS("-ACAG-", replace_op("A?", "Ax"), "AxAx");
1047 
1048  TEST_EXPECT_BLOCKOP_PERFORMS("GACAG-", replace_op("GA", "AG"), NULp); // unchanged
1049  TEST_EXPECT_BLOCKOP_PERFORMS("GAGAGA", replace_op("GA", "AG"), "AAGG");
1050  TEST_EXPECT_BLOCKOP_PERFORMS("GACAGA", replace_op("GA", "AG"), NULp);
1051  TEST_EXPECT_BLOCKOP_PERFORMS("AGAGAG", replace_op("GA", "AG"), "AGAG");
1052 
1053  // case_op
1054  TEST_EXPECT_BLOCKOP_PERFORMS("-AcGuT-", case_op(true), "ACGUT");
1055  TEST_EXPECT_BLOCKOP_PERFORMS("-AcGuT-", case_op(false), "acgut");
1056  TEST_EXPECT_BLOCKOP_PERFORMS("-acgut-", case_op(false), NULp);
1057  TEST_EXPECT_BLOCKOP_PERFORMS("-------", case_op(false), NULp);
1058 
1059  // revcomp_op
1060  TEST_EXPECT_BLOCKOP_PERFORMS("-Ac-GuT-", revcomp_op(GB_AT_RNA, false, false), NULp); // noop
1061  TEST_EXPECT_BLOCKOP_PERFORMS("-Ac-GuT-", revcomp_op(GB_AT_RNA, true, false), "TuG-cA");
1062  TEST_EXPECT_BLOCKOP_PERFORMS("-Ac-GuT-", revcomp_op(GB_AT_RNA, false, true), "Ug-CaA");
1063  TEST_EXPECT_BLOCKOP_PERFORMS("-Ac-GuT-", revcomp_op(GB_AT_RNA, true, true), "AaC-gU");
1064  TEST_EXPECT_BLOCKOP_PERFORMS("-Ac-GuT-", revcomp_op(GB_AT_DNA, true, true), "AaC-gT");
1065  TEST_EXPECT_BLOCKOP_PERFORMS("-AcGCgT-", revcomp_op(GB_AT_DNA, true, true), NULp);
1066  TEST_EXPECT_BLOCKOP_PERFORMS("--------", revcomp_op(GB_AT_DNA, true, true), NULp);
1067 
1068  TEST_EXPECT_BLOCKOP_PERFORMS("-AR-DQF-", revcomp_op(GB_AT_AA, false, false), NULp); // noop
1069  TEST_EXPECT_BLOCKOP_PERFORMS("-AR-DQF-", revcomp_op(GB_AT_AA, true, false), "FQD-RA");
1070  TEST_EXPECT_BLOCKOP_ERRORHAS("-AR-DQF-", revcomp_op(GB_AT_AA, false, true), "complement not available");
1071  TEST_EXPECT_BLOCKOP_ERRORHAS("-AR-DQF-", revcomp_op(GB_AT_AA, true, true), "reverse-complement not available");
1072 
1073  // unalign_op
1074  TEST_EXPECT_BLOCKOP_PERFORMS("-A-c-G--T-", unalign_op(-1), "AcGT----");
1075  TEST_EXPECT_BLOCKOP_PERFORMS("-A-c-G-T-T", unalign_op(-1), "AcGT----");
1076  TEST_EXPECT_BLOCKOP_PERFORMS("-A-c-G--TT", unalign_op(-1), "AcGT----");
1077  TEST_EXPECT_BLOCKOP_PERFORMS("-A-c-G--T.", unalign_op(-1), "AcGT....");
1078  TEST_EXPECT_BLOCKOP_PERFORMS("-A-c-G-T.T", unalign_op(-1), "AcGT....");
1079 
1080  TEST_EXPECT_BLOCKOP_PERFORMS("A-Ac-G--T-", unalign_op(+1), "----AcGT");
1081  TEST_EXPECT_BLOCKOP_PERFORMS("-A-c-G--T-", unalign_op(+1), "----AcGT");
1082  TEST_EXPECT_BLOCKOP_PERFORMS("A.Ac-G--T-", unalign_op(+1), "....AcGT");
1083  TEST_EXPECT_BLOCKOP_PERFORMS(".A-c-G--T-", unalign_op(+1), "....AcGT");
1084  TEST_EXPECT_BLOCKOP_PERFORMS("AA-c-G--T-", unalign_op(+1), "----AcGT");
1085 
1086  TEST_EXPECT_BLOCKOP_PERFORMS("AA-c-G--TT", unalign_op(0), "--AcGT--");
1087  TEST_EXPECT_BLOCKOP_PERFORMS(".A-c-G--T-", unalign_op(0), "..AcGT--");
1088  TEST_EXPECT_BLOCKOP_PERFORMS(".A-c-G--T.", unalign_op(0), "..AcGT..");
1089  TEST_EXPECT_BLOCKOP_PERFORMS("-A-c-G--T.", unalign_op(0), "--AcGT..");
1090  TEST_EXPECT_BLOCKOP_PERFORMS("-A-c-Gc-T.", unalign_op(0), "-AcGcT..");
1091 
1092  TEST_EXPECT_BLOCKOP_PERFORMS("-AcGcT.", unalign_op(0), NULp);
1093  TEST_EXPECT_BLOCKOP_PERFORMS("-AcGcT..", unalign_op(0), NULp);
1094  TEST_EXPECT_BLOCKOP_PERFORMS("--AcGcT.", unalign_op(0), "AcGcT.");
1095 
1096  TEST_EXPECT_BLOCKOP_PERFORMS("-ACGT-", unalign_op(-1), NULp);
1097  TEST_EXPECT_BLOCKOP_PERFORMS("-ACGT-", unalign_op(+1), NULp);
1098  TEST_EXPECT_BLOCKOP_PERFORMS("------", unalign_op(+1), NULp);
1099 
1100  // shift_op
1101  TEST_EXPECT_BLOCKOP_PERFORMS("-A-C--", shift_op(+1), "-A-C"); // take gap outside region
1102  TEST_EXPECT_BLOCKOP_PERFORMS(".A-C--", shift_op(+1), ".A-C"); // -"-
1103  TEST_EXPECT_BLOCKOP_PERFORMS("-.AC--", shift_op(+1), "..AC"); // take gap inside region
1104 
1105  TEST_EXPECT_BLOCKOP_PERFORMS("--A-C-", shift_op(-1), "A-C-"); // same for other direction
1106  TEST_EXPECT_BLOCKOP_PERFORMS("--A-C.", shift_op(-1), "A-C.");
1107  TEST_EXPECT_BLOCKOP_PERFORMS("--AC..", shift_op(-1), "AC..");
1108  TEST_EXPECT_BLOCKOP_PERFORMS("------", shift_op(-1), NULp);
1109 
1110  TEST_EXPECT_BLOCKOP_PERFORMS("G-TTAC", shift_op(-1), "TTA-"); // no gap reachable
1111 
1112  TEST_EXPECT_BLOCKOP_ERRORHAS("GATTAC", shift_op(-1), "Need a gap at block"); // no space
1113  TEST_EXPECT_BLOCKOP_ERRORHAS("GATTAC", shift_op(+1), "Need a gap at block"); // no space
1114 }
1115 
1116 #endif // UNIT_TESTS
1117 
1118 // --------------------------------------------------------------------------------
1119 
unalign_op(int direction_)
Definition: ED4_block.cxx:785
GB_ERROR GB_begin_transaction(GBDATA *gbd)
Definition: arbdb.cxx:2492
char * operate(const SeqPart &part, int &new_len) const OVERRIDE
Definition: ED4_block.cxx:765
static void refresh_selected(bool refresh_name_terminals)
Definition: ED4_block.cxx:118
const char * GB_ERROR
Definition: arb_core.h:25
string result
ED4_selected_list * selected_objects
Definition: ed4_class.hxx:1433
GB_TYPES type
int screen_to_sequence(int screen_pos) const
group_matcher all()
Definition: test_unit.h:1000
static GB_ERROR perform_block_operation_on_whole_sequence(const ED4_block_operator&block_operator, ED4_sequence_terminal *term)
Definition: ED4_block.cxx:195
static char * y[maxsp+1]
char left_gap() const
Definition: ED4_block.cxx:96
#define ED4_AWAR_REP_REPLACE_PATTERN
Definition: ed4_awars.hxx:64
AW_window * ED4_create_modsai_window(AW_root *root)
Definition: ED4_block.cxx:974
GB_ERROR GB_write_string(GBDATA *gbd, const char *s)
Definition: arbdb.cxx:1361
void load_xfig(const char *file, bool resize=true)
Definition: AW_window.cxx:717
PosRange intersection(PosRange r1, PosRange r2)
Definition: pos_range.h:98
GBDATA * get_species_pointer() const
Definition: ed4_class.hxx:953
const char * data() const
Definition: ED4_block.cxx:92
char * operate(const SeqPart &part, int &new_len) const OVERRIDE
Definition: ED4_block.cxx:636
char * operate(const SeqPart &part, int &new_len) const OVERRIDE
Definition: ED4_block.cxx:731
char * GBT_complementNucSequence(const char *s, int len, char T_or_U)
Definition: adRevCompl.cxx:78
ED4_columnStat_terminal * corresponding_columnStat_terminal() const
Definition: ed4_class.hxx:2007
static void select_and_update(ED4_sequence_terminal *term1, ED4_sequence_terminal *term2, ED4_index pos1, ED4_index pos2, int initial_call)
Definition: ED4_block.cxx:364
int start() const
Definition: pos_range.h:57
ExplicitRange clip_screen_range(PosRange screen_range) const
Definition: ed4_class.hxx:1772
static void ED4_with_whole_block(const ED4_block_operator&block_operator)
Definition: ED4_block.cxx:301
shift_op(int direction_)
Definition: ED4_block.cxx:872
void ED4_setBlocktype(ED4_blocktype bt)
Definition: ED4_block.cxx:360
char * dont_return_unchanged(char *result, int &new_len, const SeqPart &part)
Definition: ED4_block.cxx:715
static int pos1
Definition: ClustalV.cxx:58
ED4_returncode get_area_rectangle(AW_screen_area *rect, AW_pos x, AW_pos y)
Definition: ED4_root.cxx:766
char * GBT_reverseNucSequence(const char *s, int len)
Definition: adRevCompl.cxx:66
void GB_end_transaction_show_error(GBDATA *gbd, GB_ERROR error, void(*error_handler)(GB_ERROR))
Definition: arbdb.cxx:2548
void remove_from_selected(ED4_species_name_terminal *object)
Definition: ED4_root.cxx:328
const char * GBS_global_string(const char *templat,...)
Definition: arb_msg.cxx:204
ED4_root * ED4_ROOT
Definition: ED4_main.cxx:48
bool GB_have_error()
Definition: arb_msg.cxx:349
STL namespace.
void AW_POPDOWN(AW_window *window)
Definition: AW_window.cxx:52
int size() const
Definition: pos_range.h:66
ED4_terminal * owner_of_cursor
Definition: ed4_class.hxx:649
int get_base_position() const
Definition: ed4_class.hxx:676
static PosRange whole()
Definition: pos_range.h:52
bool in_SAI_terminal() const
Definition: ed4_class.hxx:1856
bool is_empty() const
Definition: pos_range.h:69
FILE * seq
Definition: rns.c:46
#define e4_assert(bed)
Definition: ed4_class.hxx:11
GBDATA * GLOBAL_gb_main
Definition: DI_main.cxx:27
virtual char * operate(const SeqPart &part, int &new_len) const =0
void ED4_correctBlocktypeAfterSelection()
Definition: ED4_block.cxx:362
void world_to_win_coords(AW_pos *xPtr, AW_pos *yPtr) const
Definition: ed4_class.hxx:359
GBDATA * GBT_find_SAI(GBDATA *gb_main, const char *name)
Definition: aditem.cxx:172
const char * read_char_pntr() const
Definition: AW_awar.cxx:171
PosRange get_range_according_to_type()
Definition: ED4_block.cxx:51
size_t GB_read_string_count(GBDATA *gbd)
Definition: arbdb.cxx:886
GB_ERROR GB_await_error()
Definition: arb_msg.cxx:353
double AW_pos
Definition: aw_base.hxx:29
WindowCallback makeHelpCallback(const char *helpfile)
Definition: aw_window.hxx:106
TYPE * ARB_alloc(size_t nelem)
Definition: arb_mem.h:56
T * elem() const
Definition: ed4_list.hxx:25
#define is_equal_to_NULL()
Definition: test_unit.h:1017
void set_type(ED4_blocktype bt)
Definition: ED4_block.cxx:133
static PosRange empty()
Definition: pos_range.h:51
bool matchesUsingWildcard(GB_CSTR s1, GB_CSTR s2, int len)
Definition: ED4_block.cxx:608
static void col_block_refresh_on_seq_term(ED4_sequence_terminal *seq_term)
Definition: ED4_block.cxx:112
ED4_blocktype get_type() const
Definition: ED4_block.cxx:40
void jump_base_pos(int base_pos, ED4_CursorJumpType jump_type)
int sequence_to_screen(int sequence_pos) const
ED4_returncode add_to_selected(ED4_species_name_terminal *object)
Definition: ED4_root.cxx:380
void ED4_toggle_block_type()
Definition: ED4_block.cxx:361
char * alignment_name
Definition: ed4_class.hxx:1440
static void modsai_cb(AW_window *aww)
Definition: ED4_block.cxx:910
case_op(bool to_upper_)
Definition: ED4_block.cxx:729
#define false
Definition: ureadseq.h:13
ED4_window * first_window
Definition: ed4_class.hxx:1427
ED4_terminal * get_next_terminal()
Definition: ED4_base.cxx:452
SeqPart(const char *seq_, int offset_, int len_)
Definition: ED4_block.cxx:86
static void error(const char *msg)
Definition: mkptypes.cxx:96
ED4_cursor cursor
Definition: ed4_class.hxx:727
expectation_group & add(const expectation &e)
Definition: test_unit.h:801
#define that(thing)
Definition: test_unit.h:1032
ED4_root_group_manager * root_group_man
Definition: ed4_class.hxx:1431
PosRange calc_interval_displayed_in_rectangle(AW_screen_area *area_rect)
Definition: ED4_base.cxx:543
bool ED4_get_selected_range(ED4_terminal *term, PosRange &range)
Definition: ED4_block.cxx:351
char right_gap() const
Definition: ED4_block.cxx:102
#define AWAR_SAI_NAME
#define cmp(h1, h2)
Definition: admap.cxx:50
void calc_world_coords(AW_pos *x, AW_pos *y) const
Definition: ed4_class.hxx:988
replace_op(const char *oldString_, const char *newString_)
Definition: ED4_block.cxx:628
char * read_string() const
Definition: AW_awar.cxx:201
ED4_blocktype
Definition: ed4_block.hxx:15
GB_CSTR GB_path_in_ARBLIB(const char *relative_path)
Definition: adsocket.cxx:1103
AW_awar * awar(const char *awar)
Definition: AW_root.cxx:554
static int pos2
Definition: ClustalV.cxx:59
void set_type(TYPE type)
Definition: probe_tree.h:59
GBDATA * GBT_find_sequence(GBDATA *gb_species, const char *aliname)
Definition: adali.cxx:670
ED4_list_elem * next() const
Definition: ed4_list.hxx:24
GB_alignment_type alignment_type
Definition: ed4_class.hxx:1441
void autocorrect_type()
Definition: ED4_block.cxx:166
#define is_equal_to(val)
Definition: test_unit.h:1014
char * operate(const SeqPart &part, int &new_len) const OVERRIDE
Definition: ED4_block.cxx:787
ED4_blocktype ED4_getBlocktype()
Definition: ED4_block.cxx:359
AW_selection_list * awt_create_selection_list_with_input_field(AW_window *aww, const char *awar_name, const char *at_box, const char *at_field)
GB_alignment_type
Definition: arbdb_base.h:61
void toggle_type()
Definition: ED4_block.cxx:143
#define does_contain(val)
Definition: test_unit.h:1029
bool is_consensus_terminal() const
Definition: ed4_class.hxx:1850
AW_event_type type
Definition: aw_window.hxx:81
ED4_cursor & current_cursor()
Definition: ed4_class.hxx:1405
GB_ERROR get_error() const
Definition: ed4_block.hxx:51
ED4_species_name_terminal * corresponding_species_name_terminal() const
Definition: ed4_class.hxx:1943
int MAXSEQUENCECHARACTERLENGTH
Definition: ED4_main.cxx:56
GB_ERROR close(GB_ERROR error)
Definition: arbdbpp.cxx:32
int length() const
Definition: ED4_block.cxx:93
static GB_ERROR perform_block_operation_on_part_of_sequence(const ED4_block_operator&block_operator, ED4_sequence_terminal *term)
Definition: ED4_block.cxx:246
void ED4_setColumnblockCorner(AW_event *event, ED4_sequence_terminal *seq_term)
Definition: ED4_block.cxx:464
#define to_upper(c)
Definition: ureadseq.h:23
#define OVERRIDE
Definition: cxxforward.h:93
char * GB_read_string(GBDATA *gbd)
Definition: arbdb.cxx:879
ED4_window * current_ed4w()
Definition: ed4_class.hxx:1403
AW_root * aw_root
Definition: ed4_class.hxx:1424
ED4_list_elem< T > * head() const
Definition: ed4_list.hxx:45
revcomp_op(GB_alignment_type aliType, bool reverse_, bool complement_)
Definition: ED4_block.cxx:755
#define abs(x)
Definition: f2c.h:151
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
ED4_index pixel2pos(AW_pos click_x)
Definition: ED4_root.cxx:1887
AW_root * get_root()
Definition: aw_window.hxx:348
void set_range(const PosRange &new_range)
Definition: ED4_block.cxx:49
ED4_species_manager * containing_species_manager() const
Definition: ed4_class.hxx:1832
AW_window_simple * win
#define NULp
Definition: cxxforward.h:97
const ED4_remap * remap() const
Definition: ed4_class.hxx:1783
ED4_blockoperation_type
Definition: ed4_block.hxx:22
int end() const
Definition: pos_range.h:61
const PosRange & get_colblock_range() const
Definition: ED4_block.cxx:45
GB_ERROR write_string(const char *aw_string)
#define offset(field)
Definition: GLwDrawA.c:73
char * dup_corresponding_part(const char *source, size_t source_len) const
Definition: pos_range.cxx:27
int is_sequence_terminal() const
Definition: ed4_class.hxx:1088
void ED4_setup_gaps_and_alitype(const char *gap_chars, GB_alignment_type alitype)
Definition: ED4_main.cxx:254
static ED4_block block
Definition: ED4_block.cxx:73
NOT4PERL char * GB_command_interpreter_in_env(const char *str, const char *commands, const GBL_call_env &callEnv)
Definition: gb_aci.cxx:361
GB_ERROR load(const char *filemask, bool append) const
GB_transaction ta(gb_var)
AW_awar * awar_string(const char *var_name, const char *default_value="", AW_default default_file=AW_ROOT_DEFAULT)
Definition: AW_root.cxx:570
#define ED4_AWAR_REP_SEARCH_PATTERN
Definition: ed4_awars.hxx:63
#define AWAR_MOD_SAI_SCRIPT
Definition: ED4_block.cxx:908
AW_window * ED4_create_replace_window(AW_root *root)
Definition: ED4_block.cxx:685
char * operate(const SeqPart &part, int &new_len) const OVERRIDE
Definition: ED4_block.cxx:874
long ED4_index
Definition: ed4_defs.hxx:115
void ED4_perform_block_operation(ED4_blockoperation_type operationType)
Definition: ED4_block.cxx:882
int is_species_name_terminal() const
Definition: ed4_class.hxx:1085
void aw_message_if(GB_ERROR error)
Definition: aw_msg.hxx:21
NOT4PERL GB_ERROR GBT_determine_T_or_U(GB_alignment_type alignment_type, char *T_or_U, const char *supposed_target)
Definition: adRevCompl.cxx:90
static void replace_in_block(AW_window *)
Definition: ED4_block.cxx:678
GB_ERROR GB_write_autoconv_string(GBDATA *gbd, const char *val)
Definition: arbdb.cxx:1453