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) {
304 
305  typedef map<ED4_window*, int> CursorPositions;
306  CursorPositions at_base;
307 
308  for (ED4_window *win = ED4_ROOT->first_window; win; win = win->next) {
309  ED4_cursor& cursor = win->cursor;
310  if (cursor.owner_of_cursor) at_base[win] = cursor.get_base_position();
311  }
312 
313 
314  switch (block.get_type()) {
315  case ED4_BT_NOBLOCK: {
316  aw_message("No block marked -- use right mouse button");
317  break;
318  }
319  case ED4_BT_LINEBLOCK:
321  case ED4_BT_COLUMNBLOCK: {
323  while (listElem && !error) {
324  ED4_species_name_terminal *nameTerm = listElem->elem()->object;
325  ED4_sequence_terminal *seqTerm = nameTerm->corresponding_sequence_terminal();
326 
327  error = block.get_type() == ED4_BT_LINEBLOCK
328  ? perform_block_operation_on_whole_sequence(block_operator, seqTerm)
329  : perform_block_operation_on_part_of_sequence(block_operator, seqTerm);
330 
331  listElem = listElem->next();
332  }
333  break;
334  }
335  default: {
336  error = "Illegal blocktype";
337  break;
338  }
339  }
340 
341  if (error) error = GBS_global_string("[In block operation] %s", error);
342  GB_end_transaction_show_error(gb_main, error, aw_message);
343 
344  if (!error) {
345  for (CursorPositions::iterator ab = at_base.begin(); ab != at_base.end(); ++ab) {
346  ED4_window *win = ab->first;
347  win->cursor.jump_base_pos(ab->second, ED4_JUMP_KEEP_VISIBLE); // restore cursor at same base
348  }
349  }
350 }
351 
352 bool ED4_get_selected_range(ED4_terminal *term, PosRange& range) { // @@@ function will get useless, when multi-column-blocks are possible
353  if (block.get_type() == ED4_BT_NOBLOCK) return false;
354  if (!term->containing_species_manager()->is_selected()) return false;
355 
356  range = block.get_range_according_to_type();
357  return true;
358 }
359 
361 void ED4_setBlocktype(ED4_blocktype bt) { block.set_type(bt); }
364 
366  static ED4_sequence_terminal *last_term1, *last_term2;
367  static PosRange last_range;
368 
369  if (!term1) return; // e.g. when 1st click was into consensus
370 
371  if (pos1>pos2) {
372  block.set_range(PosRange(pos2, pos1));
373  }
374  else {
375  block.set_range(PosRange(pos1, pos2));
376  }
377 
378  if (block.get_type()==ED4_BT_MODIFIED_COLUMNBLOCK) {
379  refresh_selected(false);
380  }
381  else {
382  { // ensure term1 is the upper terminal
383  AW_pos dummy, y1, y2;
384 
385  term1->calc_world_coords(&dummy, &y1);
386  term2->calc_world_coords(&dummy, &y2);
387 
388  if (y1>y2) {
389  ED4_sequence_terminal *t = term1; term1 = term2; term2 = t;
390  AW_pos y = y1; y1 = y2; y2 = y;
391  }
392  }
393 
394  int do_above = 1; // we have to update terminals between last_term1 and term1
395  int do_below = 1; // we have to update terminals between term2 and last_term2
396 
397  ED4_terminal *term = term1;
398 
399  bool xRangeChanged = block.get_range_according_to_type() != last_range;
400 
401  while (term) {
402  if (term->is_sequence_terminal()) {
403  ED4_sequence_terminal *seq_term = term->to_sequence_terminal();
404 
405  if (seq_term==last_term1) {
406  do_above = 0;
407  }
408  if (seq_term==last_term2) {
409  do_below = 0;
410  }
411 
412  ED4_species_name_terminal *name_term = seq_term->corresponding_species_name_terminal();
413  ED4_species_manager *species_man = name_term->containing_species_manager();
414  if (species_man->is_selected()) { // already selected
415  if (xRangeChanged) {
417  }
418  }
419  else { // select it
420  if (!species_man->is_consensus_manager()) {
421  ED4_ROOT->add_to_selected(name_term);
422  }
423  }
424  }
425  if (term==term2) {
426  break;
427  }
428  term = term->get_next_terminal();
429  }
430 
431  if (!initial_call) {
432  if (do_below) {
433  while (term) {
434  if (term->is_species_name_terminal()) {
435  ED4_species_manager *species_man = term->containing_species_manager();
436  if (species_man->is_selected() && !species_man->is_consensus_manager()) {
437  ED4_ROOT->remove_from_selected(term->to_species_name_terminal());
438  }
439  }
440  if (term==last_term2) break;
441  term = term->get_next_terminal();
442  }
443  }
444 
445  if (do_above) {
446  term = last_term1->corresponding_species_name_terminal();
447  while (term && term!=term1) {
448  if (term->is_species_name_terminal()) {
449  ED4_species_manager *species_man = term->containing_species_manager();
450  if (species_man->is_selected() && !species_man->is_consensus_manager()) {
451  ED4_ROOT->remove_from_selected(term->to_species_name_terminal());
452  }
453  }
454  term = term->get_next_terminal();
455  }
456  }
457  }
458  }
459 
460  last_term1 = term1;
461  last_term2 = term2;
462  last_range = block.get_range_according_to_type();
463 }
464 
466  static ED4_sequence_terminal *fix_term = NULp;
467  static ED4_index fix_pos = 0;
468 
469  ED4_index seq_pos;
470  {
471  AW_pos termw_x, termw_y;
472  seq_term->calc_world_coords(&termw_x, &termw_y);
473 
474  ED4_index scr_pos = ED4_ROOT->pixel2pos(event->x - termw_x);
475  ED4_remap *remap = ED4_ROOT->root_group_man->remap();
476  seq_pos = remap->screen_to_sequence(scr_pos);
477  }
478 
479  switch (event->type) {
480  case AW_Mouse_Press: {
481  if (block.get_type() == ED4_BT_NOBLOCK) { // initial columnblock
482  if (!seq_term->is_consensus_terminal()) {
484 
485  fix_term = seq_term;
486  fix_pos = seq_pos;
487 
488  select_and_update(fix_term, seq_term, fix_pos, seq_pos, 1);
489  }
490  }
491  else if (block.get_type()==ED4_BT_LINEBLOCK) { // change lineblock to columnblock
493 
494  fix_term = seq_term;
495  if (seq_pos<(MAXSEQUENCECHARACTERLENGTH/2)) { // in first half of sequence
496  fix_pos = MAXSEQUENCECHARACTERLENGTH;
497  }
498  else {
499  fix_pos = 0;
500  }
501 
502  select_and_update(fix_term, seq_term, fix_pos, seq_pos, 1);
503  }
504  else { // expand columnblock (search nearest corner/border -> fix opposite corner/border)
506 
508  e4_assert(listElem);
509 
510  if (block.get_type()==ED4_BT_COLUMNBLOCK) {
511  AW_pos min_term_y = LONG_MAX;
512  AW_pos max_term_y = LONG_MIN;
513  ED4_species_name_terminal *min_term = NULp;
514  ED4_species_name_terminal *max_term = NULp;
515  AW_pos xpos, ypos;
516 
517  while (listElem) {
518  ED4_species_name_terminal *name_term = listElem->elem()->object;
519  name_term->calc_world_coords(&xpos, &ypos);
520 
521  if (ypos<min_term_y) {
522  min_term_y = ypos;
523  min_term = name_term;
524  }
525  if (ypos>max_term_y) {
526  max_term_y = ypos;
527  max_term = name_term;
528  }
529 
530  listElem = listElem->next();
531  }
532 
533  seq_term->calc_world_coords(&xpos, &ypos);
534  ED4_species_name_terminal *fix_name_term;
535  if (fabs(ypos-min_term_y)<fabs(ypos-max_term_y)) { // seq_term is closer to min_term
536  fix_name_term = max_term; // select max_term as fixed corner
537  }
538  else {
539  fix_name_term = min_term;
540  }
541  e4_assert(fix_name_term);
542  fix_term = fix_name_term->corresponding_sequence_terminal();
543  }
544 
545  AW_screen_area area_rect;
546  {
547  AW_pos ex = event->x;
548  AW_pos ey = event->y;
549  current_ed4w()->world_to_win_coords(&ex, &ey);
550 
551  if (ED4_ROOT->get_area_rectangle(&area_rect, ex, ey)!=ED4_R_OK) {
552  e4_assert(0);
553  break;
554  }
555  }
556 
557 
558  const ED4_remap *rm = ED4_ROOT->root_group_man->remap();
559 
560  PosRange screen_range = rm->clip_screen_range(seq_term->calc_interval_displayed_in_rectangle(&area_rect));
561  int scr_pos = rm->sequence_to_screen(seq_pos);
562 
563  PosRange block_screen_range = rm->sequence_to_screen(block.get_colblock_range());
564  PosRange block_visible_part = intersection(screen_range, block_screen_range);
565 
566  if (block_visible_part.is_empty()) {
567  if (scr_pos>block_screen_range.end()) {
568  fix_pos = block.get_colblock_range().start();
569  }
570  else {
571  e4_assert(scr_pos<block_screen_range.start());
572  fix_pos = block.get_colblock_range().end();
573  }
574  }
575  else {
576  int dist_left = abs(scr_pos-block_visible_part.start());
577  int dist_right = abs(scr_pos-block_visible_part.end());
578 
579  if (dist_left < dist_right) { // click nearer to left border of visible part of block
580  fix_pos = block.get_colblock_range().end(); // keep right block-border
581  }
582  else {
583  fix_pos = block.get_colblock_range().start();
584  }
585  }
586 
587  select_and_update(fix_term, seq_term, fix_pos, seq_pos, 0);
588  }
589  break;
590  }
591  case AW_Mouse_Drag: {
592  select_and_update(fix_term, seq_term, fix_pos, seq_pos, 0);
593  break;
594  }
595  case AW_Mouse_Release: {
596  select_and_update(fix_term, seq_term, fix_pos, seq_pos, 0);
597  break;
598  }
599  default: {
600  e4_assert(0);
601  break;
602  }
603  }
604 }
605 
606 // --------------------------------------------------------------------------------
607 // Replace
608 
609 inline bool matchesUsingWildcard(GB_CSTR s1, GB_CSTR s2, int len) {
610  // s2 may contain '?' as wildcard
611  int cmp = 0;
612 
613  for (int i = 0; i<len && !cmp; ++i) {
614  cmp = int(s1[i])-int(s2[i]);
615  if (cmp && s2[i] == '?') cmp = 0;
616  }
617 
618  return !cmp;
619 }
620 
621 class replace_op : public ED4_block_operator { // derived from Noncopyable
622  const char *oldString;
623  const char *newString;
624 
625  int olen;
626  int nlen;
627 
628 public:
629  replace_op(const char *oldString_, const char *newString_)
630  : oldString(oldString_),
631  newString(newString_)
632  {
633  olen = strlen(oldString);
634  nlen = strlen(newString);
635  }
636 
637  char* operate(const SeqPart& part, int& new_len) const OVERRIDE {
638  int maxlen;
639  int len = part.length();
640  int max_o = len-olen;
641 
642  if (nlen<=olen) {
643  maxlen = len;
644  }
645  else {
646  maxlen = (len/olen+1)*nlen;
647  }
648 
649  char *new_seq = ARB_alloc<char>(maxlen+1);
650  int replaced = 0;
651  int o = 0;
652  int n = 0;
653 
654  const char *sequence = part.data();
655  while (o<len) {
656  if (o <= max_o && matchesUsingWildcard(sequence+o, oldString, olen)) {
657  memcpy(new_seq+n, newString, nlen);
658  n += nlen;
659  o += olen;
660  replaced++;
661  }
662  else {
663  new_seq[n++] = sequence[o++];
664  }
665  }
666  new_seq[n] = 0;
667 
668  if (replaced) {
669  new_len = n;
670  }
671  else {
672  freenull(new_seq);
673  }
674 
675  return new_seq;
676  }
677 };
678 
680  AW_root *awr = ED4_ROOT->aw_root;
684 }
685 
687  AW_window_simple *aws = new AW_window_simple;
688 
689  aws->init(root, "REPLACE", "Search & Replace");
690  aws->load_xfig("edit4/replace.fig");
691 
692  aws->at("close");
693  aws->callback(AW_POPDOWN);
694  aws->create_button("CLOSE", "Close", "C");
695 
696  aws->at("help");
697  aws->callback(makeHelpCallback("e4_replace.hlp"));
698  aws->create_button("HELP", "Help", "H");
699 
700  aws->at("spattern");
701  aws->create_input_field(ED4_AWAR_REP_SEARCH_PATTERN, 30);
702 
703  aws->at("rpattern");
704  aws->create_input_field(ED4_AWAR_REP_REPLACE_PATTERN, 30);
705 
706  aws->at("go");
707  aws->callback(replace_in_block);
708  aws->create_button("GO", "Go", "G");
709 
710  return aws;
711 }
712 
713 // --------------------------------------------------------------------------------
714 // Other block operations
715 
716 inline char *dont_return_unchanged(char *result, int& new_len, const SeqPart& part) {
717  if (result) {
718  if (new_len == part.length()) {
719  if (memcmp(result, part.data(), new_len) == 0) {
720  freenull(result);
721  }
722  }
723  }
724  return result;
725 }
726 
727 class case_op : public ED4_block_operator {
728  bool to_upper;
729 public:
730  case_op(bool to_upper_) : to_upper(to_upper_) {}
731 
732  char *operate(const SeqPart& part, int& new_len) const OVERRIDE {
733  int len = part.length();
734  const char *seq = part.data();
735  char *new_seq = ARB_alloc<char>(len+1);
736 
737  if (to_upper) {
738  for (int i=0; i<len; i++) new_seq[i] = toupper(seq[i]);
739  }
740  else {
741  for (int i=0; i<len; i++) new_seq[i] = tolower(seq[i]);
742  }
743  new_seq[len] = 0;
744 
745  new_len = len;
746  return dont_return_unchanged(new_seq, new_len, part);
747  }
748 };
749 
751  bool reverse;
752  bool complement;
753  char T_or_U;
754 
755 public:
756  revcomp_op(GB_alignment_type aliType, bool reverse_, bool complement_)
757  : reverse(reverse_),
758  complement(complement_),
759  T_or_U(0)
760  {
761  if (complement) {
762  error = GBT_determine_T_or_U(aliType, &T_or_U, reverse ? "reverse-complement" : "complement");
763  }
764  }
765 
766  char *operate(const SeqPart& part, int& new_len) const OVERRIDE {
767  char *result = NULp;
768  if (!error) {
769  int len = part.length();
770  if (complement) {
771  result = GBT_complementNucSequence(part.data(), len, T_or_U);
772  if (reverse) freeset(result, GBT_reverseNucSequence(result, len));
773  }
774  else if (reverse) result = GBT_reverseNucSequence(part.data(), len);
775 
776  new_len = len;
777  }
778  return dont_return_unchanged(result, new_len, part);
779  }
780 
781 };
782 
784  int direction;
785 public:
786  unalign_op(int direction_) : direction(direction_) {}
787 
788  char *operate(const SeqPart& part, int& new_len) const OVERRIDE {
789  int len = part.length();
790  const char *seq = part.data();
791  char *result = ARB_alloc<char>(len+1);
792 
793  int o = 0;
794  int n = 0;
795 
796  while (o<len) {
797  if (!ED4_is_gap_character(seq[o])) result[n++] = seq[o];
798  o++;
799  }
800 
801  if (n<len) { // (move and) dot rest
802  int gapcount = len-n;
803  switch (direction) {
804  case 1: // rightwards
805  memmove(result+gapcount, result, n);
806  memset(result, part.left_gap(), gapcount);
807  break;
808  case 0: { // center
809  int leftgaps = gapcount/2;
810  int rightgaps = gapcount-leftgaps;
811 
812  memmove(result+leftgaps, result, n);
813  memset(result, part.left_gap(), leftgaps);
814  memset(result+leftgaps+n, part.right_gap(), rightgaps);
815 
816  break;
817  }
818  case -1: // leftwards
819  memset(result+n, part.right_gap(), gapcount);
820  break;
821  }
822  }
823  result[len] = 0;
824  new_len = len;
825 
826  return dont_return_unchanged(result, new_len, part);
827  }
828 
829 
830 };
831 
832 class shift_op : public ED4_block_operator {
833  int direction;
834 
835  char *shift_left_sequence(const SeqPart& part, int& new_len) const {
836  char *result = NULp;
837  const char *seq = part.data();
838 
839  if (!ED4_is_gap_character(seq[0])) {
840  error = "Need a gap at block start for shifting left";
841  }
842  else {
843  int len = part.length();
844  ARB_alloc(result, len+1);
845  result[len] = 0;
846  new_len = len;
847  result[len-1] = part.right_gap();
848  memcpy(result, seq+1, len-1);
849  }
850  return result;
851  }
852 
853  char *shift_right_sequence(const SeqPart& part, int& new_len) const {
854  char *result = NULp;
855  const char *seq = part.data();
856  int len = part.length();
857 
858  if (!ED4_is_gap_character(seq[len-1])) {
859  error = "Need a gap at block end for shifting right";
860  }
861  else {
862  ARB_alloc(result, len+1);
863  result[len] = 0;
864  new_len = len;
865  result[0] = part.left_gap();
866  memcpy(result+1, seq, len-1);
867  }
868  return result;
869  }
870 
871 
872 public:
873  shift_op(int direction_) : direction(direction_) {}
874 
875  char *operate(const SeqPart& part, int& new_len) const OVERRIDE {
876  char *result = direction<0
877  ? shift_left_sequence(part, new_len)
878  : shift_right_sequence(part, new_len);
879  return dont_return_unchanged(result, new_len, part);
880  }
881 };
882 
884  switch (operationType) {
885  case ED4_BO_UPPER_CASE: ED4_with_whole_block(case_op(true)); break;
886  case ED4_BO_LOWER_CASE: ED4_with_whole_block(case_op(false)); break;
887 
891 
895 
898 
899  default: {
900  e4_assert(0);
901  break;
902  }
903  }
904 }
905 
906 // --------------------------------------
907 // modify range of selected sai
908 
909 #define AWAR_MOD_SAI_SCRIPT "modsai/script"
910 
911 static void modsai_cb(AW_window *aww) {
912  ED4_MostRecentWinContext context;
913 
914  ED4_cursor *cursor = &current_cursor();
915  GB_ERROR error = NULp;
916 
917  if (!cursor->in_SAI_terminal()) {
918  error = "Please select the SAI you like to modify";
919  }
920  else if (block.get_type() == ED4_BT_NOBLOCK) {
921  error = "Please select the range where the SAI shall be modified";
922  }
923  else {
924  AW_root *aw_root = aww->get_root();
925  char *script = aw_root->awar(AWAR_MOD_SAI_SCRIPT)->read_string();
926  const char *sainame = aw_root->awar(AWAR_SAI_NAME)->read_char_pntr();
927 
929  GB_transaction ta(gb_main);
930  GBDATA *gb_sai = GBT_find_SAI(gb_main, sainame);
931 
932  if (!gb_sai) {
933  error = GB_have_error()
934  ? GB_await_error()
935  : GBS_global_string("Failed to find SAI '%s'", sainame);
936  }
937  else {
938  GBDATA *gb_data = GBT_find_sequence(gb_sai, ED4_ROOT->alignment_name);
939 
940  if (!gb_data) error = GB_await_error();
941  else {
942  char *seq = GB_read_string(gb_data); // @@@ NOT_ALL_SAI_HAVE_DATA
943  int len = GB_read_string_count(gb_data);
944 
945  ExplicitRange range(block.get_range_according_to_type(), len);
946  char *part = range.dup_corresponding_part(seq, len);
947 
948  char *result = GB_command_interpreter_in_env(part, script, GBL_simple_call_env(gb_sai));
949  if (!result) error = GB_await_error();
950  else {
951  int reslen = strlen(result);
952  if (reslen>range.size()) {
953  error = GBS_global_string("Cannot insert modified range (result too long; %i>%i)", reslen, range.size());
954  }
955  else {
956  memcpy(seq+range.start(), result, reslen);
957  int rest = range.size()-reslen;
958  if (rest>0) memset(seq+range.start()+reslen, '-', rest);
959 
960  error = GB_write_string(gb_data, seq);
961  }
962  free(result);
963  }
964 
965  free(part);
966  free(seq);
967  }
968  }
969  free(script);
970  error = ta.close(error);
971  }
972 
973  aw_message_if(error);
974 }
975 
978 
979  AW_window_simple *aws = new AW_window_simple;
980  aws->init(root, "modsai", "Modify SAI range");
981  aws->load_xfig("edit4/modsai.fig");
982 
983  aws->at("close");
984  aws->callback(AW_POPDOWN);
985  aws->create_button("CLOSE", "Close", "C");
986 
987  aws->at("help");
988  aws->callback(makeHelpCallback("e4_modsai.hlp"));
989  aws->create_button("HELP", "Help", "H");
990 
992  GB_ERROR error;
993  {
994  StorableSelectionList storable_sellist(TypedSelectionList("sellst", sellist, "SRT/ACI scripts", "srt_aci"));
995  error = storable_sellist.load(GB_path_in_ARBLIB("sellists/mod_sequence*.sellst"), false);
996  }
997  aw_message_if(error);
998 
999  aws->at("go");
1000  aws->callback(modsai_cb);
1001  aws->create_button("go", "GO");
1002 
1003  return aws;
1004 }
1005 
1006 
1007 // --------------------------------------------------------------------------------
1008 
1009 #ifdef UNIT_TESTS
1010 #ifndef TEST_UNIT_H
1011 #include <test_unit.h>
1012 #endif
1013 
1014 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) {
1015  int whole_len = strlen(oversized_input);
1016  SeqPart part(oversized_input, 1, whole_len-2);
1017  int new_len = 0;
1018  char *result = blockop.operate(part, new_len);
1019 
1020  using namespace arb_test;
1021 
1022  expectation_group expectations;
1023  expectations.add(part_of_error
1024  ? that(blockop.get_error()).does_contain(part_of_error)
1025  : that(blockop.get_error()).is_equal_to_NULL());
1026  expectations.add(that(result).is_equal_to(expected_result));
1027  if (expected_result) expectations.add(that(new_len).is_equal_to(whole_len-2));
1028 
1029  free(result);
1030 
1031  return all().ofgroup(expectations);
1032 }
1033 
1034 #define TEST_EXPECT_BLOCKOP_PERFORMS(oversized_input,blockop,expected) TEST_EXPECTATION(blockop_expected_io(blockop, oversized_input, expected, NULp))
1035 #define TEST_EXPECT_BLOCKOP_PERFORMS__BROKEN(oversized_input,blockop,expected) TEST_EXPECTATION__BROKEN(blockop_expected_io(blockop, oversized_input, expected, NULp))
1036 #define TEST_EXPECT_BLOCKOP_ERRORHAS(oversized_input,blockop,expected) TEST_EXPECTATION(blockop_expected_io(blockop, oversized_input, NULp, expected))
1037 #define TEST_EXPECT_BLOCKOP_ERRORHAS__BROKEN(oversized_input,blockop,expected) TEST_EXPECTATION__BROKEN(blockop_expected_io(blockop, oversized_input, NULp, expected))
1038 
1039 void TEST_block_operators() {
1041 
1042  // Note: make sure tests perform an identity block operation at least once for each operator
1043 
1044  // replace_op
1045  TEST_EXPECT_BLOCKOP_PERFORMS("-A-C--", replace_op("-", "."), "A.C.");
1046  TEST_EXPECT_BLOCKOP_PERFORMS("-A-C--", replace_op("?", "."), "....");
1047  TEST_EXPECT_BLOCKOP_PERFORMS("AACAG-", replace_op("AC", "CA"), "CAAG");
1048  TEST_EXPECT_BLOCKOP_PERFORMS("-ACAG-", replace_op("A?", "Ax"), "AxAx");
1049 
1050  TEST_EXPECT_BLOCKOP_PERFORMS("GACAG-", replace_op("GA", "AG"), NULp); // unchanged
1051  TEST_EXPECT_BLOCKOP_PERFORMS("GAGAGA", replace_op("GA", "AG"), "AAGG");
1052  TEST_EXPECT_BLOCKOP_PERFORMS("GACAGA", replace_op("GA", "AG"), NULp);
1053  TEST_EXPECT_BLOCKOP_PERFORMS("AGAGAG", replace_op("GA", "AG"), "AGAG");
1054 
1055  // case_op
1056  TEST_EXPECT_BLOCKOP_PERFORMS("-AcGuT-", case_op(true), "ACGUT");
1057  TEST_EXPECT_BLOCKOP_PERFORMS("-AcGuT-", case_op(false), "acgut");
1058  TEST_EXPECT_BLOCKOP_PERFORMS("-acgut-", case_op(false), NULp);
1059  TEST_EXPECT_BLOCKOP_PERFORMS("-------", case_op(false), NULp);
1060 
1061  // revcomp_op
1062  TEST_EXPECT_BLOCKOP_PERFORMS("-Ac-GuT-", revcomp_op(GB_AT_RNA, false, false), NULp); // noop
1063  TEST_EXPECT_BLOCKOP_PERFORMS("-Ac-GuT-", revcomp_op(GB_AT_RNA, true, false), "TuG-cA");
1064  TEST_EXPECT_BLOCKOP_PERFORMS("-Ac-GuT-", revcomp_op(GB_AT_RNA, false, true), "Ug-CaA");
1065  TEST_EXPECT_BLOCKOP_PERFORMS("-Ac-GuT-", revcomp_op(GB_AT_RNA, true, true), "AaC-gU");
1066  TEST_EXPECT_BLOCKOP_PERFORMS("-Ac-GuT-", revcomp_op(GB_AT_DNA, true, true), "AaC-gT");
1067  TEST_EXPECT_BLOCKOP_PERFORMS("-AcGCgT-", revcomp_op(GB_AT_DNA, true, true), NULp);
1068  TEST_EXPECT_BLOCKOP_PERFORMS("--------", revcomp_op(GB_AT_DNA, true, true), NULp);
1069 
1070  TEST_EXPECT_BLOCKOP_PERFORMS("-AR-DQF-", revcomp_op(GB_AT_AA, false, false), NULp); // noop
1071  TEST_EXPECT_BLOCKOP_PERFORMS("-AR-DQF-", revcomp_op(GB_AT_AA, true, false), "FQD-RA");
1072  TEST_EXPECT_BLOCKOP_ERRORHAS("-AR-DQF-", revcomp_op(GB_AT_AA, false, true), "complement not available");
1073  TEST_EXPECT_BLOCKOP_ERRORHAS("-AR-DQF-", revcomp_op(GB_AT_AA, true, true), "reverse-complement not available");
1074 
1075  // unalign_op
1076  TEST_EXPECT_BLOCKOP_PERFORMS("-A-c-G--T-", unalign_op(-1), "AcGT----");
1077  TEST_EXPECT_BLOCKOP_PERFORMS("-A-c-G-T-T", unalign_op(-1), "AcGT----");
1078  TEST_EXPECT_BLOCKOP_PERFORMS("-A-c-G--TT", unalign_op(-1), "AcGT----");
1079  TEST_EXPECT_BLOCKOP_PERFORMS("-A-c-G--T.", unalign_op(-1), "AcGT....");
1080  TEST_EXPECT_BLOCKOP_PERFORMS("-A-c-G-T.T", unalign_op(-1), "AcGT....");
1081 
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("A.Ac-G--T-", unalign_op(+1), "....AcGT");
1085  TEST_EXPECT_BLOCKOP_PERFORMS(".A-c-G--T-", unalign_op(+1), "....AcGT");
1086  TEST_EXPECT_BLOCKOP_PERFORMS("AA-c-G--T-", unalign_op(+1), "----AcGT");
1087 
1088  TEST_EXPECT_BLOCKOP_PERFORMS("AA-c-G--TT", unalign_op(0), "--AcGT--");
1089  TEST_EXPECT_BLOCKOP_PERFORMS(".A-c-G--T-", unalign_op(0), "..AcGT--");
1090  TEST_EXPECT_BLOCKOP_PERFORMS(".A-c-G--T.", unalign_op(0), "..AcGT..");
1091  TEST_EXPECT_BLOCKOP_PERFORMS("-A-c-G--T.", unalign_op(0), "--AcGT..");
1092  TEST_EXPECT_BLOCKOP_PERFORMS("-A-c-Gc-T.", unalign_op(0), "-AcGcT..");
1093 
1094  TEST_EXPECT_BLOCKOP_PERFORMS("-AcGcT.", unalign_op(0), NULp);
1095  TEST_EXPECT_BLOCKOP_PERFORMS("-AcGcT..", unalign_op(0), NULp);
1096  TEST_EXPECT_BLOCKOP_PERFORMS("--AcGcT.", unalign_op(0), "AcGcT.");
1097 
1098  TEST_EXPECT_BLOCKOP_PERFORMS("-ACGT-", unalign_op(-1), NULp);
1099  TEST_EXPECT_BLOCKOP_PERFORMS("-ACGT-", unalign_op(+1), NULp);
1100  TEST_EXPECT_BLOCKOP_PERFORMS("------", unalign_op(+1), NULp);
1101 
1102  // shift_op
1103  TEST_EXPECT_BLOCKOP_PERFORMS("-A-C--", shift_op(+1), "-A-C"); // take gap outside region
1104  TEST_EXPECT_BLOCKOP_PERFORMS(".A-C--", shift_op(+1), ".A-C"); // -"-
1105  TEST_EXPECT_BLOCKOP_PERFORMS("-.AC--", shift_op(+1), "..AC"); // take gap inside region
1106 
1107  TEST_EXPECT_BLOCKOP_PERFORMS("--A-C-", shift_op(-1), "A-C-"); // same for other direction
1108  TEST_EXPECT_BLOCKOP_PERFORMS("--A-C.", shift_op(-1), "A-C.");
1109  TEST_EXPECT_BLOCKOP_PERFORMS("--AC..", shift_op(-1), "AC..");
1110  TEST_EXPECT_BLOCKOP_PERFORMS("------", shift_op(-1), NULp);
1111 
1112  TEST_EXPECT_BLOCKOP_PERFORMS("G-TTAC", shift_op(-1), "TTA-"); // no gap reachable
1113 
1114  TEST_EXPECT_BLOCKOP_ERRORHAS("GATTAC", shift_op(-1), "Need a gap at block"); // no space
1115  TEST_EXPECT_BLOCKOP_ERRORHAS("GATTAC", shift_op(+1), "Need a gap at block"); // no space
1116 }
1117 
1118 #endif // UNIT_TESTS
1119 
1120 // --------------------------------------------------------------------------------
1121 
unalign_op(int direction_)
Definition: ED4_block.cxx:786
GB_ERROR GB_begin_transaction(GBDATA *gbd)
Definition: arbdb.cxx:2516
char * operate(const SeqPart &part, int &new_len) const OVERRIDE
Definition: ED4_block.cxx:766
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:1431
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:976
GB_ERROR GB_write_string(GBDATA *gbd, const char *s)
Definition: arbdb.cxx:1385
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:947
const char * data() const
Definition: ED4_block.cxx:92
char * operate(const SeqPart &part, int &new_len) const OVERRIDE
Definition: ED4_block.cxx:637
char * operate(const SeqPart &part, int &new_len) const OVERRIDE
Definition: ED4_block.cxx:732
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:2004
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:365
int start() const
Definition: pos_range.h:57
ExplicitRange clip_screen_range(PosRange screen_range) const
Definition: ed4_class.hxx:1769
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:873
void ED4_setBlocktype(ED4_blocktype bt)
Definition: ED4_block.cxx:361
char * dont_return_unchanged(char *result, int &new_len, const SeqPart &part)
Definition: ED4_block.cxx:716
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:768
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:2572
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:643
int get_base_position() const
Definition: ed4_class.hxx:670
static PosRange whole()
Definition: pos_range.h:52
bool in_SAI_terminal() const
Definition: ed4_class.hxx:1853
bool is_empty() const
Definition: pos_range.h:69
FILE * seq
Definition: rns.c:46
#define e4_assert(bed)
Definition: ed4_class.hxx:11
virtual char * operate(const SeqPart &part, int &new_len) const =0
void ED4_correctBlocktypeAfterSelection()
Definition: ED4_block.cxx:363
void world_to_win_coords(AW_pos *xPtr, AW_pos *yPtr) const
Definition: ed4_class.hxx:353
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
PosRange get_range_according_to_type()
Definition: ED4_block.cxx:51
size_t GB_read_string_count(GBDATA *gbd)
Definition: arbdb.cxx:910
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:609
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)
GBDATA * get_gb_main() const
Definition: ed4_class.hxx:1420
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:362
char * alignment_name
Definition: ed4_class.hxx:1438
static void modsai_cb(AW_window *aww)
Definition: ED4_block.cxx:911
case_op(bool to_upper_)
Definition: ED4_block.cxx:730
#define false
Definition: ureadseq.h:13
ED4_window * first_window
Definition: ed4_class.hxx:1426
ED4_terminal * get_next_terminal()
Definition: ED4_base.cxx:454
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:721
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:1430
PosRange calc_interval_displayed_in_rectangle(AW_screen_area *area_rect)
Definition: ED4_base.cxx:545
bool ED4_get_selected_range(ED4_terminal *term, PosRange &range)
Definition: ED4_block.cxx:352
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:982
replace_op(const char *oldString_, const char *newString_)
Definition: ED4_block.cxx:629
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:1124
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:1439
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:788
ED4_blocktype ED4_getBlocktype()
Definition: ED4_block.cxx:360
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:1847
AW_event_type type
Definition: aw_window.hxx:81
ED4_cursor & current_cursor()
Definition: ed4_class.hxx:1399
GB_ERROR get_error() const
Definition: ed4_block.hxx:51
ED4_species_name_terminal * corresponding_species_name_terminal() const
Definition: ed4_class.hxx:1940
int MAXSEQUENCECHARACTERLENGTH
Definition: ED4_main.cxx:55
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:465
#define to_upper(c)
Definition: ureadseq.h:23
#define OVERRIDE
Definition: cxxforward.h:93
char * GB_read_string(GBDATA *gbd)
Definition: arbdb.cxx:903
ED4_window * current_ed4w()
Definition: ed4_class.hxx:1397
AW_root * aw_root
Definition: ed4_class.hxx:1423
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:756
#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:1927
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:1829
AW_window_simple * win
#define NULp
Definition: cxxforward.h:97
const ED4_remap * remap() const
Definition: ed4_class.hxx:1780
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:1082
void ED4_setup_gaps_and_alitype(const char *gap_chars, GB_alignment_type alitype)
Definition: ED4_main.cxx:253
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)
GBDATA * gb_main
Definition: adname.cxx:33
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:909
AW_window * ED4_create_replace_window(AW_root *root)
Definition: ED4_block.cxx:686
char * operate(const SeqPart &part, int &new_len) const OVERRIDE
Definition: ED4_block.cxx:875
long ED4_index
Definition: ed4_defs.hxx:114
void ED4_perform_block_operation(ED4_blockoperation_type operationType)
Definition: ED4_block.cxx:883
int is_species_name_terminal() const
Definition: ed4_class.hxx:1079
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:679
GB_ERROR GB_write_autoconv_string(GBDATA *gbd, const char *val)
Definition: arbdb.cxx:1477