NCBI C++ ToolKit
paint_sequence.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1  /* $Id: paint_sequence.cpp 47482 2023-05-02 13:59:42Z ucko $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Authors: Igor Filippov
27  */
28 
29 
30 #include <ncbi_pch.hpp>
31 
32 #include <wx/graphics.h>
33 #include <wx/settings.h>
34 #include <wx/clipbrd.h>
35 #include <wx/msgdlg.h>
36 #include <wx/evtloop.h>
37 #include <objmgr/util/sequence.hpp>
41 
43 
44 static const int space_between_groups = 1;
45 static const int chars_per_group = 10;
46 
47 IMPLEMENT_DYNAMIC_CLASS( CPaintSequence, wxVScrolledWindow )
48 
49 
50 BEGIN_EVENT_TABLE(CPaintSequence, wxVScrolledWindow)
51  EVT_PAINT(CPaintSequence::OnPaint)
52  EVT_ERASE_BACKGROUND(CPaintSequence::OnEraseBackground)
53  EVT_SIZE(CPaintSequence::OnResize)
54  EVT_LEFT_UP(CPaintSequence::OnMouseClick)
55  EVT_KEY_DOWN(CPaintSequence::OnKeyDown)
56  EVT_CHAR(CPaintSequence::OnChar)
57  EVT_MOTION(CPaintSequence::OnMouseDrag)
58  EVT_LEFT_DOWN(CPaintSequence::OnMouseDown)
60 
61 
62 CPaintSequence::CPaintSequence(wxWindow *parent, const string &seq, const vector<int> &seq_len, const vector<vector<pair<TSeqPos,TSeqPos> > > &feat_ranges,
63  const vector<pair<string,objects::CSeqFeatData::ESubtype> > &feat_types,
64  const vector<objects::CBioseq_Handle::EVectorStrand> &feat_strand,
65  const vector<int> &feat_frames,
66  const vector< CRef<CGenetic_code> > &genetic_code, const vector<bool> &feat_partial5,
67  const string &allowed_char_set, const vector<string> &real_prot, const vector<bool> &read_only,
68  const unordered_map<int, vector<vector<pair<TSeqPos,TSeqPos> > > > &prot_feat_ranges, const int start,
69  wxWindowID id, const wxPoint &pos, const wxSize &size)
70 : wxVScrolledWindow(parent,id, pos, size, wxFULL_REPAINT_ON_RESIZE|wxWANTS_CHARS), m_Seq(seq), m_SeqLen(seq_len), m_FeatRanges(feat_ranges), m_FeatTypes(feat_types), m_FeatStrand(feat_strand),
71  m_FeatFrames(feat_frames), m_GeneticCode(genetic_code), m_Feat5Partial(feat_partial5),
72  m_AllowedCharSet(allowed_char_set), m_RealProt(real_prot), m_read_only(read_only), m_start(start), m_ProtFeatRanges(prot_feat_ranges),
73  m_EnableTranslation(true), m_EnableTranslation1(true), m_EnableTranslation2(true), m_EnableComplement(true), m_EnableFeatures(true), m_EnableOnTheFly(true), m_EnableMismatch(true),
74  m_EnableRevTranslation(true), m_EnableRevTranslation1(true), m_EnableRevTranslation2(true), m_Down(false)
75 {
76  SetBackgroundStyle(wxBG_STYLE_PAINT);
77  NStr::ToLower(m_AllowedCharSet);
78  SetBackgroundColour(*wxWHITE);
79  m_Font = wxFont(9, wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
80  m_FontHeight = 9;
81  m_FontWidth = 9;
82  m_NumRows = 1;
83  m_NumCols = 1;
84  m_LastRowLength = 0;
85  NStr::ToLower(m_Seq);
86  m_CursorCol = 0;
87  m_CursorRow = 0;
88  m_CursorSeq = -1;
89  m_DragMin = -1;
90  m_DragMax = -1;
91  m_FeatureStart = pair<int,int>(-1,-1);
92  m_FeatureStop = pair<int,int>(-1,-1);
93  if (!m_Seq.empty())
94  m_Seq += " ";
95  UpdateData();
96  TranslateCDS();
97  m_EnableTranslation = false;
98  m_EnableTranslation1 = false;
99  m_EnableTranslation2 = false;
100  m_EnableRevTranslation = false;
101  m_EnableRevTranslation1 = false;
102  m_EnableRevTranslation2 = false;
103  m_EnableComplement = false;
104  m_EnableFeatures = false;
105  m_EnableOnTheFly = false;
106  m_EnableMismatch = false;
107  m_ShowTripletMismatch = -1;
108  m_ShowTripletTranslation = -4;
109  m_Clean = true;
110  m_Parent = NULL;
111  wxWindow *win = GetParent();
112  while (win)
113  {
114  CEditSequence *base = dynamic_cast<CEditSequence *>(win);
115  if (base)
116  m_Parent = base;
117  win = win->GetParent();
118  }
119  GetFeatWholeRange();
120 }
121 
123 {
124  if (!m_Seq.empty())
125  {
126  wxGraphicsContext *gc = wxGraphicsContext::Create();
127  gc->SetFont(m_Font, *wxBLACK);
130  m_NumRows = static_cast<int>(m_Seq.size() / m_NumCols);
131  }
132  SetRowCount(m_NumRows);
133 }
134 
135 wxCoord CPaintSequence::OnGetRowHeight( size_t row ) const
136 {
137  int r = 0;
138  vector<unsigned int> feats_in_row = GetFeaturesInRow(static_cast<int>(row));
139  map<unsigned int, vector<unsigned int> > feats_with_exons = GetFeatsWithExons(static_cast<int>(row), feats_in_row);
140  DrawLabelCell(0,0,r,static_cast<int>(row),feats_in_row,feats_with_exons,NULL);
141  return r;
142 }
143 
145 {
146 }
147 
148 void CPaintSequence::UpdateFeatures(const vector<vector<pair<TSeqPos,TSeqPos> > > &feat_ranges,
149  const vector<pair<string,objects::CSeqFeatData::ESubtype> > &feat_types,
150  const vector<objects::CBioseq_Handle::EVectorStrand> &feat_strand,
151  const vector<int> &feat_frames,
152  const vector< CRef<CGenetic_code> > &genetic_code,
153  const vector<bool> &feat_partial5,
154  const vector<string> &real_prot,
155  const unordered_map<int, vector<vector<pair<TSeqPos,TSeqPos> > > > &prot_feat_ranges)
156 {
157  m_FeatRanges = feat_ranges;
158  m_FeatTypes = feat_types;
159  m_FeatStrand = feat_strand;
160  m_FeatFrames = feat_frames;
161  m_GeneticCode = genetic_code;
162  m_Feat5Partial = feat_partial5;
163  m_RealProt = real_prot;
164  m_ProtFeatRanges = prot_feat_ranges;
166  UpdateData();
167  TranslateCDS();
168 }
169 
171 {
172  SeqPosToColRow();
175  Refresh();
176 }
177 
179 {
180  m_EnableTranslation = enable;
181  if (!enable)
184 }
185 
187 {
188  m_EnableTranslation1 = enable;
189  if (!enable)
192 }
193 
195 {
196  m_EnableTranslation2 = enable;
197  if (!enable)
200 }
201 
203 {
204  m_EnableRevTranslation = enable;
205  if (!enable)
208 }
209 
211 {
212  m_EnableRevTranslation1 = enable;
213  if (!enable)
216 }
217 
219 {
220  m_EnableRevTranslation2 = enable;
221  if (!enable)
224 }
225 
226 
228 {
229  m_EnableComplement = enable;
231 }
232 
234 {
235  m_EnableFeatures = enable;
237 }
238 
240 {
241  m_EnableOnTheFly = enable;
242  if (!enable)
245 }
246 
248 {
249  m_EnableMismatch = enable;
250  if (!enable)
253 }
254 
256 {
257  bool minus = false;
258  bool plus = false;
259  for (unsigned int i=0; i < m_FeatStrand.size(); i++)
260  if (m_FeatStrand[i] == objects::CBioseq_Handle::eStrand_Minus)
261  {
262  minus = true;
263  }
264  else
265  {
266  plus = true;
267  }
268 
270  {
272  }
274  {
276  }
278  {
280  }
281  if (m_EnableComplement)
282  {
283  CSeqManip::Complement(m_Seq, CSeqUtil::e_Iupacna, 0, static_cast<int>(m_Seq.size()), m_Complement);
285  }
286 
287  string rev_comp;
289  {
290  CSeqManip::ReverseComplement(m_Seq, CSeqUtil::e_Iupacna, 0, static_cast<int>(m_Seq.size()), rev_comp);
291  NStr::ToLower(rev_comp);
292  }
293 
295  {
297  }
298 
300  {
302  }
303 
305  {
307  }
308 }
309 
311 {
312  return NStr::TruncateSpaces(m_Seq);
313 }
314 
316 {
317  return m_SeqLen;
318 }
319 
321 {
322  int start = 0;
323  unsigned int i=0;
324  while ( i < m_SeqLen.size()-1) // if not found in any segment place in the last one
325  {
326  if (m_CursorSeq >= start && m_CursorSeq < start+m_SeqLen[i])
327  break;
328  start += m_SeqLen[i];
329  i++;
330  }
331  return i;
332 }
333 
334 void CPaintSequence::SetClean(bool clean)
335 {
336  m_Clean = clean;
337  m_Parent->EnableCommit(!clean);
338 }
339 
341 {
342  return m_Clean;
343 }
344 
346 {
347  if (m_CursorSeq < 0)
348  ColRowToSeqPos();
349  unsigned int seg = PosToSegment();
350  if (m_read_only[seg])
351  {
353  return;
354  }
355  string str1;
356  if (m_CursorSeq > 0)
357  str1 = m_Seq.substr(0,m_CursorSeq);
358  string str2 = m_Seq.substr(m_CursorSeq);
359  str1.push_back(tolower(uc));
360  m_Seq = str1+str2;
361  m_SeqLen[seg]++;
362  m_CursorSeq++;
363  SeqPosToColRow();
364  UpdateData();
366  SetClean(false);
367 }
368 
370 {
371  string result = CutSelection();
372  if (!result.empty())
373  return;
374  if (m_CursorSeq < 0 || m_CursorSeq >= m_Seq.size() - 1)
375  return;
376  if (m_Seq.size() == 2)
377  {
378  wxMessageBox (_("Unable to delete the whole sequence"), _("Error"), wxOK|wxICON_ERROR);
379  return;
380  }
381  unsigned int seg = PosToSegment();
382  if (m_read_only[seg])
383  {
385  return;
386  }
387  string str1;
388  if (m_CursorSeq > 0)
389  str1 = m_Seq.substr(0,m_CursorSeq);
390  string str2;
391  if (m_CursorSeq < m_Seq.size()-1)
392  str2 = m_Seq.substr(m_CursorSeq+1);
393  m_Seq = str1+str2;
394  m_SeqLen[seg]--;
395  if (m_SeqLen[seg] < 0)
396  m_SeqLen[seg] = 0;
397  UpdateData();
399  SetClean(false);
400 }
401 
403 {
404  if (m_CursorRow < GetVisibleRowsBegin() || m_CursorRow > GetVisibleRowsEnd() - 1)
405  ScrollToRow(m_CursorRow);
406 }
407 
408 void CPaintSequence::OnChar(wxKeyEvent& event)
409 {
410  int uc = tolower(event.GetKeyCode());
411  if ( !event.HasModifiers() && uc != WXK_NONE && uc >= 32 && uc < 255 && m_AllowedCharSet.find(uc) != string::npos)
412  {
413  InsertChar(uc);
416  Refresh();
417  }
418  event.Skip();
419 }
420 
421 void CPaintSequence::OnKeyDown(wxKeyEvent& event)
422 {
423  wxSize sz = GetClientSize();
424  int num_rows = static_cast<int>(GetVisibleRowsEnd() - GetVisibleRowsBegin());
425 
426  int uc = event.GetKeyCode();
427  switch ( uc )
428  {
429  case WXK_LEFT : m_CursorCol--; m_CursorSeq = -1; break;
430  case WXK_RIGHT : m_CursorCol++; m_CursorSeq = -1; break;
431  case WXK_UP : m_CursorRow--; m_CursorSeq = -1; break;
432  case WXK_DOWN : m_CursorRow++; m_CursorSeq = -1; break;
433  case WXK_END : m_CursorSeq = static_cast<int>(m_Seq.size() - 1); SeqPosToColRow(); break;
434  case WXK_HOME : m_CursorSeq = 0; SeqPosToColRow(); break;
435  case WXK_PAGEUP : m_CursorRow = static_cast<int>(GetVisibleRowsBegin() - num_rows); m_CursorSeq = -1; break;
436  case WXK_PAGEDOWN : m_CursorRow = static_cast<int>(GetVisibleRowsBegin() + num_rows); m_CursorSeq = -1; break;
437  case WXK_DELETE:
438  DeleteChar();
439  break;
440  case WXK_BACK :
441  m_CursorSeq--;
442  DeleteChar();
443  if (m_CursorSeq < 0)
444  m_CursorSeq = 0;
445  SeqPosToColRow();
446  break;
447  case WXK_INSERT :
448  if (m_CursorSeq >= 0 && m_CursorSeq < m_Seq.size() - 1)
449  {
450  if (m_DragMin < 0)
452  else if (m_DragMax < 0)
454  else
455  {
458  else
460  }
461  }
462  break;
463  case WXK_SPACE:
464  event.Skip();
465  break;
466  default:
467  event.Skip();
468  return;
469  break;
470  }
471 
474  Refresh();
475 }
476 
478 {
479  if (m_CursorCol < 0)
480  m_CursorCol = 0;
481  if (m_CursorCol >= m_NumCols)
483  if (m_CursorRow < 0)
484  m_CursorRow = 0;
485  if (m_CursorRow >= m_NumRows)
489 }
490 
492 {
493  return (5 + chars_per_group * m_FontWidth + 5);
494 }
495 
496 int CPaintSequence::FindRowByCoord(int y, int &y_row)
497 {
498  y_row = TopMarginHeight();
499  if (y <= 0)
500  return 0;
501  int row = static_cast<int>(GetVisibleRowsBegin());
502  int row_height = OnGetRowHeight(row);
503  while ( y_row < y && row <= GetVisibleRowsEnd()+1 )
504  {
505  y_row += row_height;
506  row++;
507  row_height = OnGetRowHeight(row);
508  }
509  row--;
510  y_row -= OnGetRowHeight(row);
511  return row;
512 }
513 
514 bool CPaintSequence::MouseToSeqPos(wxPoint p, int &row, int &y_row)
515 {
516  bool found = false;
517  row = FindRowByCoord(p.y, y_row);
518  int col = (p.x - LeftMarginWidth()) / m_FontWidth;
519  if (col < 0)
520  return false;
521  int num_groups = col / (chars_per_group + space_between_groups);
522  int pos_in_group = col % (chars_per_group + space_between_groups);
523  if (pos_in_group < chars_per_group)
524  {
525  m_CursorCol = num_groups * chars_per_group + pos_in_group;
526  m_CursorRow = row;
527  ColRowToSeqPos();
528  found = true;
529  }
530  return found;
531 }
532 
533 void CPaintSequence::MouseToFeature(wxPoint p, int row, int y0)
534 {
535  if (!m_EnableFeatures)
536  return;
537  vector<unsigned int> feats_in_row = GetFeaturesInRow(row);
538  map<unsigned int, vector<unsigned int> > feats_with_exons = GetFeatsWithExons(row, feats_in_row);
539  DrawLabelCell(0,0,y0,row,feats_in_row,feats_with_exons,NULL);
540  int y1 = 0;
541  DrawFeatureLabels( row, 0, y1, feats_in_row, feats_with_exons, NULL);
542  y0 -= y1;
543  y0 -= 5;
544 
545  for (unsigned int k = 0; k < feats_in_row.size(); k++)
546  {
547  unsigned int i = feats_in_row[k];
548  auto it = feats_with_exons.find(i);
549 
550  bool found = false;
551  if (it != feats_with_exons.end())
552  {
553  for (unsigned int m = 0; m < it->second.size(); m++)
554  {
555  unsigned int j = it->second[m];
556  TSeqPos start = m_FeatRanges[i][j].first;
557  TSeqPos stop = m_FeatRanges[i][j].second;
558  if (start == numeric_limits<int>::max() || stop == numeric_limits<int>::max())
559  continue;
560  if (p.y >= y0 && p.y < y0 + m_FontHeight)
561  {
562  if (m_CursorSeq == start || m_CursorSeq == start-1 || m_CursorSeq == start+1)
563  {
564  m_FeatureStart = pair<int,int>(i,j);
565  m_FeatureStop = pair<int,int>(-1,-1);
566  found = true;
567  break;
568  }
569  if (m_CursorSeq == stop || m_CursorSeq == stop-1 || m_CursorSeq == stop+1)
570  {
571  m_FeatureStart = pair<int,int>(-1,-1);
572  m_FeatureStop = pair<int,int>(i,j);
573  found = true;
574  break;
575  }
576  }
577  }
578  }
579  y0 += m_FontHeight;
580  bool is_exon_present = (it != feats_with_exons.end() && m_FeatTypes[i].second == CSeqFeatData::eSubtype_cdregion);
581  DrawMismatchLabel(0, y0, is_exon_present, NULL);
582  DrawOnTheFlyLabel(0, y0, is_exon_present, NULL);
583  if (found)
584  break;
585  }
586 }
587 
588 void CPaintSequence::OnMouseClick(wxMouseEvent& evt)
589 {
590  if (!m_Down)
591  {
592  evt.Skip();
593  return;
594  }
595  m_Down = false;
596  if (evt.GetModifiers() == wxMOD_SHIFT)
597  {
598  wxPoint p = evt.GetPosition();
599  //wxPoint p = this->ScreenToClient(wxGetMousePosition());
600  int y_row;
601  int current_row;
602  bool found = MouseToSeqPos(p, current_row, y_row);
603  if (m_CursorSeq >= 0 && m_CursorSeq < m_Seq.size() - 1)
604  {
605  if (m_DragMin < 0)
607  else if (m_DragMax < 0)
609  else
610  {
613  else
615  }
616  }
619  Refresh();
620  return;
621  }
622  if (m_FeatureStart.first >= 0 || m_FeatureStop.first >= 0)
623  {
624  TranslateCDS();
625  }
626  m_FeatureStart = pair<int,int>(-1,-1);
627  m_FeatureStop = pair<int,int>(-1,-1);
628  wxPoint p = evt.GetPosition();
629  //wxPoint p = this->ScreenToClient(wxGetMousePosition());
630  int y_row;
631  int current_row;
632  bool found = MouseToSeqPos(p, current_row, y_row);
633  if (found )
634  {
637  {
638  int current = p.y - y_row;
639  int y = m_FontHeight;
640  y += m_FontHeight; // top line numbers
641  y += 16;
642  DrawComplementLabel(current_row,0,y,NULL);
643 
644  int y_trial = y;
645  DrawTranslationLabels(current_row,0,y_trial,NULL);
646  if (m_ShowTripletTranslation > -4)
647  {
648  if ( current > y && current < y_trial)
650  }
651  else
652  {
654  {
655  if ( current > y && current < y+m_FontHeight)
656  {
659  }
660  y += m_FontHeight;
661  }
663  {
664  if ( current > y && current < y+m_FontHeight)
665  {
668  }
669  y += m_FontHeight;
670  }
672  {
673  if ( current > y && current < y+m_FontHeight)
674  {
677  }
678  y += m_FontHeight;
679  }
681  {
682  if ( current > y && current < y+m_FontHeight)
683  {
686  }
687  y += m_FontHeight;
688  }
690  {
691  if ( current > y && current < y+m_FontHeight)
692  {
695  }
696  y += m_FontHeight;
697  }
699  {
700  if ( current > y && current < y+m_FontHeight)
701  {
704  }
705  y += m_FontHeight;
706  }
707  }
708 
709 
710  {
711  vector<unsigned int> feats_in_row = GetFeaturesInRow(current_row);
712  map<unsigned int, vector<unsigned int> > feats_with_exons = GetFeatsWithExons(current_row, feats_in_row);
713  y = y_trial;
714  for (size_t k = 0; k < feats_in_row.size(); k++)
715  {
716  if (m_EnableFeatures)
717  y += m_FontHeight;
718  unsigned int i = feats_in_row[k];
719  int y_next = y;
720  bool is_exon_present = (feats_with_exons.find(i) != feats_with_exons.end()) && (m_FeatTypes[i].second == CSeqFeatData::eSubtype_cdregion);
721  DrawMismatchLabel(0,y_next,is_exon_present,NULL);
722  DrawOnTheFlyLabel(0,y_next,is_exon_present,NULL);
723  if ( current > y && current < y_next)
724  {
725  if (m_ShowTripletMismatch < 0)
726  {
729  }
730  else
732  }
733  y = y_next;
734  }
735  }
736 
737  }
738  Refresh();
739  }
740  evt.Skip();
741 }
742 
743 void CPaintSequence::OnMouseDrag(wxMouseEvent& evt)
744 {
745  if (m_Down && evt.Dragging()) // && evt.GetModifiers() != wxMOD_SHIFT
746  {
747  int row, y_row;
748  //wxPoint p = this->ScreenToClient(wxGetMousePosition());
749  wxPoint p = evt.GetPosition();
750  bool found = MouseToSeqPos(p, row, y_row);
751  if (found )
752  {
753  if (m_FeatureStart.first >= 0 && m_CursorSeq < m_Seq.size() - 1 && m_CursorSeq >= 0)
754  {
755  if (m_FeatWholeRange[m_FeatureStart.first].first == m_FeatRanges[m_FeatureStart.first][m_FeatureStart.second].first)
757  m_FeatRanges[m_FeatureStart.first][m_FeatureStart.second].first = m_CursorSeq;
758  SetClean(false);
759  }
760  else if (m_FeatureStop.first >= 0 && m_CursorSeq < m_Seq.size() - 1 && m_CursorSeq >= 0)
761  {
762  if (m_FeatWholeRange[m_FeatureStop.first].second == m_FeatRanges[m_FeatureStop.first][m_FeatureStop.second].second)
764  m_FeatRanges[m_FeatureStop.first][m_FeatureStop.second].second = m_CursorSeq;
765  SetClean(false);
766  }
767  else
768  {
769  if ( m_DragMin < 0)
771  else
773  }
774 
775 
776  if (m_DragMin >= 0 && m_DragMin > m_Seq.size() - 2)
777  m_DragMin = static_cast<int>(m_Seq.size() - 2);
778  if (m_DragMax >= 0 && m_DragMax > m_Seq.size() - 2)
779  m_DragMax = static_cast<int>(m_Seq.size() - 2);
780 
781  Refresh();
782  }
783  }
784  evt.Skip();
785 }
786 
787 void CPaintSequence::OnMouseDown(wxMouseEvent& evt)
788 {
789  m_Down = true;
790  int row, y_row;
791  //wxPoint p = this->ScreenToClient(wxGetMousePosition());
792  wxPoint p = evt.GetPosition();
793  bool found = MouseToSeqPos(p, row, y_row);
794  if (found )
795  {
796  MouseToFeature(p, row, y_row);
797  }
798  if (m_DragMin >= 0 && m_DragMax >= 0 && evt.GetModifiers() != wxMOD_SHIFT)
799  {
800  m_DragMin = -1;
801  m_DragMax = -1;
802  Refresh();
803  }
804  evt.Skip();
805 }
806 
808 {
809  if (m_CursorSeq < 0)
810  return;
813 }
814 
816 {
818 }
819 
821 {
822  m_CursorSeq = pos - 1;
823  if (m_CursorSeq < 0)
824  m_CursorSeq = 0;
825  if (m_CursorSeq >= m_Seq.size())
826  m_CursorSeq = static_cast<int>(m_Seq.size() - 1);
827  SeqPosToColRow();
829  Refresh();
830 }
831 
832 void CPaintSequence::SetRange(int pos1, int pos2)
833 {
834  m_DragMin = pos1 - 1;
835  m_DragMax = pos2 - 1;
836  m_CursorSeq = pos1 - 1;
837  if (m_CursorSeq < 0)
838  m_CursorSeq = 0;
839  if (m_CursorSeq >= m_Seq.size())
840  m_CursorSeq = static_cast<int>(m_Seq.size() - 1);
841  SeqPosToColRow();
843  Refresh();
844 }
845 
846 void CPaintSequence::Search(const string &val)
847 {
849  if (pos == m_CursorSeq && m_CursorSeq+val.size() < m_Seq.size()-1)
850  pos = NStr::FindNoCase(m_Seq,val,m_CursorSeq+val.size());
851  if (pos == NPOS)
852  return;
853  m_CursorSeq = static_cast<int>(pos);
854  if (m_CursorSeq >= m_Seq.size())
855  m_CursorSeq = static_cast<int>(m_Seq.size() - 1);
856  SeqPosToColRow();
858  Refresh();
859 }
860 
862 {
863  if (IsShownOnScreen())
864  {
865  m_CursorSeq = m_start - 1;
866  m_start = 0;
868  SeqPosToColRow();
870  CEditSequence *parent = dynamic_cast<CEditSequence*>(GetParent()->GetParent());
871  if (parent)
872  {
873  if ( m_CursorSeq >=0 )
874  {
875  parent->ReportPos(m_CursorSeq+1);
876  }
877  }
878  }
879 }
880 
881 /// Painting
882 void CPaintSequence::OnPaint(wxPaintEvent& event)
883 {
884  wxAutoBufferedPaintDC dc(this);
885  wxGraphicsContext *gc = wxGraphicsContext::Create( dc );
886  if (gc && !m_Seq.empty())
887  {
888  ClearScreen(gc);
889  gc->SetFont(m_Font, *wxBLACK);
891  m_NumRows = static_cast<int>(m_Seq.size() / m_NumCols);
892  m_LastRowLength = m_Seq.size() % m_NumCols;
893  if (m_LastRowLength > 0)
894  m_NumRows++;
895  SetRowCount(m_NumRows);
896  if (m_CursorSeq >= 0)
897  SeqPosToColRow();
898  else
899  ColRowToSeqPos();
900  size_t hidden_rows = GetVisibleRowsBegin();
901  size_t start= hidden_rows * m_NumCols;
902  size_t row = hidden_rows;
903  int client_y = GetClientSize().y;
904  size_t seq_pos = start;
905  int y = TopMarginHeight();
906  while (start < m_Seq.size())
907  {
908  string substr = m_Seq.substr(start,m_NumCols);
909  DrawTextLine(substr, y, static_cast<int>(row), gc, seq_pos);
910  if (y > client_y)
911  break;
912  start += m_NumCols;
913  row++;
914  }
915  delete gc;
916  }
917 
918  CEditSequence *parent = dynamic_cast<CEditSequence*>(GetParent()->GetParent());
919  if (parent)
920  {
921  int pos1 = m_DragMin;
922  int pos2 = m_DragMax;
923 
924  if ( m_CursorSeq >=0 )
925  {
926  parent->ReportPos(m_CursorSeq+1);
928  if ( pos != m_highlights.end())
929  {
930  pos1 = *pos;
931  if (pos != m_highlights.begin())
932  {
933  pos--;
934  while ((*pos) + 1 == pos1)
935  {
936  pos1 = *pos;
937  if (pos == m_highlights.begin())
938  break;
939  pos--;
940  }
941  }
942  if (*pos != pos1)
943  pos++;
944  pos2 = *pos;
945  pos++;
946  if (pos != m_highlights.end())
947  {
948  while ((*pos) - 1 == pos2)
949  {
950  pos2 = *pos;
951  pos++;
952  if (pos == m_highlights.end())
953  break;
954  }
955  }
956  }
957  }
958  if (pos1 > pos2)
959  swap(pos1, pos2);
960  parent->ReportRange(pos1+1, pos2+1);
961  }
962  if (m_start > 0)
963  {
964  CallAfter(&CPaintSequence::SetStartPos);
965  }
966 }
967 
968 
969 // Empty implementation, to prevent flicker
970 void CPaintSequence::OnEraseBackground(wxEraseEvent& event)
971 {
972 }
973 
974 ////////////////////////////////////////////////////////////
975 /// Notification for the derived class that moment is good
976 /// for doing its update and drawing stuff
977 ////////////////////////////////////////////////////////////
979 {
980 
981 }
982 
983 void CPaintSequence::OnResize(wxSizeEvent& event)
984 {
985 
986 }
987 
988 void CPaintSequence::ClearScreen(wxGraphicsContext *gc)
989 {
990  wxColour backgroundColour = GetBackgroundColour();
991  if (!backgroundColour.Ok())
992  backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
993  wxSize sz = GetClientSize();
994  wxRect windowRect(wxPoint(0,0), sz);
995  gc->SetBrush(wxBrush(backgroundColour));
996  gc->SetPen(wxPen(backgroundColour, 1));
997  gc->DrawRectangle(windowRect.GetX(),windowRect.GetY(),windowRect.GetWidth(),windowRect.GetHeight());
998 }
999 
1001 {
1002  wxDouble width;
1003  wxDouble height;
1004  wxDouble descent;
1005  wxDouble externalLeading;
1006  if (m_Seq.size() > 1000)
1007  {
1008  gc->GetTextExtent(wxString(m_Seq.substr(0,1000)), &width, &height, &descent, &externalLeading);
1009  width /= 1000;
1010  }
1011  else
1012  {
1013  gc->GetTextExtent(wxString(m_Seq), &width, &height, &descent, &externalLeading);
1014  width /= m_Seq.size();
1015  }
1016  width = ceil(1+width);
1017  height = ceil(2+height);
1018  m_FontHeight = height;
1019  m_FontWidth = width;
1020 }
1021 
1023 {
1024  int width = int(GetClientSize().x);
1025  width -= LeftMarginWidth();
1026  int line_length = width / m_FontWidth;
1027  int num_groups = line_length / (chars_per_group + space_between_groups);
1028  if (num_groups == 0)
1029  num_groups = 1;
1030  if (num_groups > 1 && width - (chars_per_group + space_between_groups) * num_groups * m_FontWidth < space_between_groups * m_FontWidth) // TODO verify
1031  num_groups--;
1032  line_length = chars_per_group * num_groups;
1033  return line_length;
1034 }
1035 
1036 void CPaintSequence::DrawTextLine(const string & substr, int &y_label, int row, wxGraphicsContext *gc, size_t &seq_pos)
1037 {
1038  int x = 5;
1039  m_ContinueFeatures = false;
1040  unsigned int orig_pos = static_cast<int>(seq_pos);
1041  int orig_y = y_label;
1042  vector<unsigned int> feats_in_row = GetFeaturesInRow(row);
1043  map<unsigned int, vector<unsigned int> > feats_with_exons = GetFeatsWithExons(row, feats_in_row);
1044  DrawLabelCell(orig_pos,x,y_label,row, feats_in_row, feats_with_exons, gc);
1045  x += LeftMarginWidth() - 5;
1046  for (unsigned int i=0; i<substr.size(); i++)
1047  {
1048  int y = orig_y;
1049  DrawTextCell(wxString(substr[i]),i,row,static_cast<unsigned int>(seq_pos),x,y, feats_in_row, feats_with_exons, gc);
1050  seq_pos++;
1051  x += m_FontWidth;
1052  if (i % chars_per_group == chars_per_group - 1)
1053  {
1055  m_ContinueFeatures = true;
1056  }
1057  else
1058  {
1059  m_ContinueFeatures = false;
1060  }
1061  }
1063  //DrawLineNumber(orig_pos+m_NumCols-1, x, orig_y, gc);
1064 }
1065 
1066 void CPaintSequence::DrawLabelCell(unsigned int pos, int x, int &y, int row, const vector<unsigned int> &feats_in_row, const map<unsigned int, vector<unsigned int> > &feats_with_exons, wxGraphicsContext *gc) const
1067 {
1068  y += m_FontHeight; // top line numbers
1069  y += 16;
1070  DrawLineNumber(pos, x, y, gc);
1071  DrawComplementLabel(row, x, y, gc);
1072  DrawTranslationLabels(row, x, y,gc);
1073  DrawFeatureLabels(row, x, y, feats_in_row, feats_with_exons, gc);
1074  y += 5;
1075 }
1076 
1077 void CPaintSequence::DrawTextCell(const wxString &substr, int col, int row, unsigned int seq_pos, int x, int &y, const vector<unsigned int> &feats_in_row, const map<unsigned int, vector<unsigned int> > &feats_with_exons, wxGraphicsContext *gc) const
1078 {
1079  if (gc)
1080  {
1081  wxString label;
1082  label << seq_pos + 1 + (chars_per_group - ((col + 1) % chars_per_group));
1083  if ((col + label.Length()) % chars_per_group == 0 )
1084  {
1085  gc->SetFont(m_Font, wxColour(255,0,255));
1086  gc->DrawText(label,x,y); // TODO
1087  gc->SetFont(m_Font,*wxBLACK);
1088  }
1089  }
1090  y += m_FontHeight;
1091  if (gc)
1092  {
1093  gc->SetPen(wxPen(wxColour(255,0,255)));
1094  if ( (col +1 ) % chars_per_group == 0)
1095  gc->StrokeLine(x+m_FontWidth/2, y, x+m_FontWidth/2, y+16);
1096  else if ( (col + 1) % chars_per_group == chars_per_group / 2)
1097  gc->StrokeLine(x+m_FontWidth/2, y+8, x+m_FontWidth/2, y+16);
1098  }
1099  y += 16;
1100  if (gc)
1101  {
1102  // printing actual sequence
1103  if (m_highlights.find(seq_pos) != m_highlights.end())
1104  {
1105  gc->SetFont(m_Font, wxColour(237,222,14));
1106  }
1107  else
1108  {
1109  gc->SetFont(m_Font,*wxBLACK);
1110  }
1111  int pos1 = m_DragMin;
1112  int pos2 = m_DragMax;
1113  if (pos1 > pos2)
1114  swap(pos1, pos2);
1115  if (pos1 >= 0 && pos2 >= 0 && seq_pos >= pos1 && seq_pos <= pos2)
1116  gc->DrawText(substr,x,y, gc->CreateBrush(*wxLIGHT_GREY_BRUSH));
1117  else
1118  gc->DrawText(substr,x,y);
1119  gc->SetFont(m_Font,*wxBLACK);
1120  if (m_ShowTripletTranslation > -4)
1121  {
1122  gc->SetPen( *wxGREY_PEN);
1123 
1124  if (m_ShowTripletTranslation >= 0 && seq_pos % 3 == m_ShowTripletTranslation)
1125  {
1126  gc->StrokeLine(x, y+m_FontHeight/2, x, y+m_FontHeight);
1127  }
1128  else if (m_ShowTripletTranslation < 0 && (m_Seq.size() - 2 - seq_pos) % 3 == -1 - m_ShowTripletTranslation && seq_pos < m_Seq.size()-1)
1129  {
1130  gc->StrokeLine(x+m_FontWidth, y+m_FontHeight/2, x+m_FontWidth, y+m_FontHeight);
1131  }
1132  }
1133  }
1134  int y_base = y;
1135  y += m_FontHeight;
1136  DrawCursor(col,row,x,y,gc);
1137  DrawComplement(x,y,seq_pos,gc);
1138  DrawTranslation(x,y,seq_pos,gc);
1139  DrawFeatures(row,seq_pos,x,y,y_base,feats_in_row,feats_with_exons,gc);
1140  y += 5;
1141 }
1142 
1143 void CPaintSequence::DrawCursor(int col, int row, int x, int &y, wxGraphicsContext *gc) const
1144 {
1145  if (col == m_CursorCol && row == m_CursorRow && gc)
1146  {
1147  gc->SetPen( *wxRED_PEN);
1148  gc->StrokeLine(x,y,x+m_FontWidth,y);
1149  }
1150  //y += 1;
1151 }
1152 
1153 void CPaintSequence::DrawTranslation(int x, int &y, unsigned int seq_pos, wxGraphicsContext *gc) const
1154 {
1155  if (m_EnableTranslation)
1156  {
1157  int offset = 0;
1158  DrawOffsetTranslation(x,y,seq_pos,offset,m_Prot,gc);
1159  y += m_FontHeight;
1160  }
1162  {
1163  int offset = 1;
1164  DrawOffsetTranslation(x,y,seq_pos,offset,m_Prot1,gc);
1165  y += m_FontHeight;
1166  }
1168  {
1169  int offset = 2;
1170  DrawOffsetTranslation(x,y,seq_pos,offset,m_Prot2,gc);
1171  y += m_FontHeight;
1172  }
1174  {
1175  int offset = 0;
1176  DrawOffsetTranslation(x,y,static_cast<unsigned int>(m_Seq.size()-2-seq_pos),offset,m_RevProt,gc);
1177  y += m_FontHeight;
1178  }
1180  {
1181  int offset = 1;
1182  DrawOffsetTranslation(x,y,static_cast<unsigned int>(m_Seq.size()-2-seq_pos),offset,m_RevProt1,gc);
1183  y += m_FontHeight;
1184  }
1186  {
1187  int offset = 2;
1188  DrawOffsetTranslation(x,y,static_cast<unsigned int>(m_Seq.size()-2-seq_pos),offset,m_RevProt2,gc);
1189  y += m_FontHeight;
1190  }
1191 }
1192 
1193 void CPaintSequence::DrawOffsetTranslation(int x, int y, unsigned int seq_pos, int offset, const string &prot, wxGraphicsContext *gc) const
1194 {
1195 
1196  if ( seq_pos >= offset+1 && (seq_pos - 1 - offset) % 3 == 0 )
1197  {
1198  int prot_pos = (seq_pos - 1 - offset) / 3 ;
1199  if (gc && prot_pos < prot.size() && prot_pos >= 0)
1200  gc->DrawText (wxString(prot[prot_pos]),x,y);
1201  }
1202 
1203 }
1204 
1205 char CPaintSequence::TranslateOnTheFly(unsigned int seq_pos, int i, const vector<unsigned int> &ranges, const vector<string> & translation, bool &left, bool &right) const
1206 {
1207  char prot = 0;
1208  left = false;
1209  right = false;
1210  if (m_FeatStrand[i] == objects::CBioseq_Handle::eStrand_Plus)
1211  for (unsigned int m = 0; m < ranges.size(); m++)
1212  {
1213  unsigned int j = ranges[m];
1214  TSeqPos start = m_FeatRanges[i][j].first;
1215  TSeqPos stop = m_FeatRanges[i][j].second;
1216  if (seq_pos >= start && seq_pos <= stop )
1217  {
1218  int prot_pos = m_FeatLengthBefore[i][j] + seq_pos - start - m_FeatFrames[i];
1219  if (prot_pos >= 0)
1220  {
1221  if ( prot_pos % 3 == 1)
1222  {
1223  if (i < translation.size() && prot_pos / 3 < translation[i].size())
1224  prot = translation[i][prot_pos / 3];
1225  }
1226  else if (prot_pos % 3 == 0)
1227  left = true;
1228  else if (prot_pos % 3 == 2)
1229  right = true;
1230  break;
1231  }
1232  }
1233  }
1234  if (m_FeatStrand[i] == objects::CBioseq_Handle::eStrand_Minus)
1235  for (int m = static_cast<int>(ranges.size()) - 1; m >= 0; m--)
1236  {
1237  unsigned int j = ranges[m];
1238  TSeqPos start = m_FeatRanges[i][j].first;
1239  TSeqPos stop = m_FeatRanges[i][j].second;
1240  if (seq_pos >= start && seq_pos <= stop )
1241  {
1242  int prot_pos = m_FeatTotalLength[i] - m_FeatLengthBefore[i][j] - (stop - start + 1) + stop - seq_pos - m_FeatFrames[i];
1243  if (prot_pos >= 0)
1244  {
1245  if ( prot_pos % 3 == 1)
1246  {
1247  if (i < translation.size() && prot_pos / 3 < translation[i].size())
1248  prot = translation[i][prot_pos / 3];
1249  }
1250  else if (prot_pos % 3 == 0)
1251  right = true;
1252  else if (prot_pos % 3 == 2)
1253  left = true;
1254  break;
1255  }
1256  }
1257  }
1258 
1259  return prot;
1260 }
1261 
1262 void CPaintSequence::DrawTripletMismatch(int x, int y, int y_base, int i, wxGraphicsContext *gc) const
1263 {
1264  if (m_ShowTripletMismatch == i)
1265  {
1266  gc->SetPen( *wxGREY_PEN);
1267  gc->StrokeLine(x, y, x, y+m_FontHeight);
1268  gc->StrokeLine(x, y_base, x, y_base+m_FontHeight);
1269  }
1270 }
1271 
1272 void CPaintSequence::DrawOnTheFly(int x, int &y, int y_base, unsigned int seq_pos, int i, const map<unsigned int, vector<unsigned int> > &feats_with_exons, wxGraphicsContext *gc) const
1273 {
1274  map<unsigned int, vector<unsigned int> >::const_iterator f = feats_with_exons.find(i);
1275  bool is_exon_present = (f != feats_with_exons.end()) && (m_FeatTypes[i].second == CSeqFeatData::eSubtype_cdregion);
1276  if (m_EnableOnTheFly && is_exon_present)
1277  {
1278  bool left, right;
1279  char prot = TranslateOnTheFly(seq_pos, i, f->second, m_Translated, left, right);
1280  if (gc)
1281  {
1282  if (prot != 0)
1283  {
1284  gc->SetFont(m_Font, *wxBLUE);
1285  gc->DrawText (wxString(prot),x,y);
1286  gc->SetFont(m_Font,*wxBLACK);
1287  }
1288  if (left)
1289  DrawTripletMismatch(x,y,y_base,i,gc);
1290  if (right)
1291  DrawTripletMismatch(x+m_FontWidth,y,y_base,i,gc);
1292  }
1293  y += m_FontHeight;
1294  }
1295 }
1296 
1297 
1298 void CPaintSequence::DrawMismatch(int x, int &y, int y_base, unsigned int seq_pos, int i, const map<unsigned int, vector<unsigned int> > &feats_with_exons, wxGraphicsContext *gc) const
1299 {
1300  map<unsigned int, vector<unsigned int> >::const_iterator f = feats_with_exons.find(i);
1301  bool is_exon_present = (f != feats_with_exons.end()) && (m_FeatTypes[i].second == CSeqFeatData::eSubtype_cdregion);
1302  if (m_EnableMismatch && is_exon_present)
1303  {
1304  bool left, right;
1305  char translated_prot = TranslateOnTheFly(seq_pos, i, f->second, m_Translated, left, right);
1306  char prot = TranslateOnTheFly(seq_pos, i, f->second, m_RealProt, left, right);
1307  if (gc)
1308  {
1309  if (prot != 0)
1310  {
1311  if (prot != translated_prot)
1312  gc->SetFont(m_Font,*wxRED);
1313  else
1314  gc->SetFont(m_Font, *wxBLUE);
1315  gc->DrawText(wxString(prot),x,y);
1316  gc->SetFont(m_Font,*wxBLACK);
1317  }
1318  if (left)
1319  DrawTripletMismatch(x,y,y_base,i,gc);
1320  if (right)
1321  DrawTripletMismatch(x+m_FontWidth,y,y_base,i,gc);
1322  }
1323  y += m_FontHeight;
1324  }
1325 }
1326 
1327 
1328 void CPaintSequence::DrawMismatchLabel(int x, int &y, bool is_exon_present, wxGraphicsContext *gc) const
1329 {
1330  if (m_EnableMismatch && is_exon_present)
1331  {
1332  y += m_FontHeight;
1333  }
1334 }
1335 
1336 void CPaintSequence::DrawComplement(int x, int &y, unsigned int seq_pos, wxGraphicsContext *gc) const
1337 {
1338  if (m_EnableComplement)
1339  {
1340  if (gc && seq_pos < m_Complement.size())
1341  gc->DrawText (wxString(m_Complement[seq_pos]),x,y);
1342  y += m_FontHeight;
1343  }
1344 }
1345 
1346 const wxPen* CPaintSequence::GetColorForFeature(objects::CSeqFeatData::ESubtype subtype) const
1347 {
1348  const wxPen* pen = wxBLACK_PEN;
1349  switch(subtype)
1350  {
1351  case CSeqFeatData::eSubtype_cdregion : pen = wxBLUE_PEN; break;
1352  default : pen = wxBLACK_PEN; break;
1353  }
1354  return pen;
1355 }
1356 
1357 void CPaintSequence::DrawLineNumber(unsigned int seq_pos, int x, int &y, wxGraphicsContext *gc) const
1358 {
1359  wxString label;
1360  label << seq_pos+1;
1361  if (gc)
1362  {
1363  gc->SetFont(m_Font, wxColour(255,0,255));
1364  gc->DrawText(label,x,y);
1365  gc->SetFont(m_Font,*wxBLACK);
1366  }
1367  y += m_FontHeight;
1368 }
1369 
1370 
1371 void CPaintSequence::DrawFeatureLabels(int row, int x, int &y, const vector<unsigned int> &feats_in_row, const map<unsigned int, vector<unsigned int> > &feats_with_exons, wxGraphicsContext *gc) const
1372 {
1373  for (unsigned int k = 0; k < feats_in_row.size(); k++)
1374  {
1375  unsigned int i = feats_in_row[k];
1376  if (m_EnableFeatures)
1377  {
1378  string label = m_FeatTypes[i].first.substr(0,10); // only take first 10 characters of the label
1379  if (gc)
1380  {
1382  gc->SetFont(m_Font,*wxBLUE);
1383  gc->DrawText(wxString(label),x,y);
1384  gc->SetFont(m_Font,*wxBLACK);
1385  }
1386  y += m_FontHeight;
1387  }
1388  bool is_exon_present = (feats_with_exons.find(i) != feats_with_exons.end()) && (m_FeatTypes[i].second == CSeqFeatData::eSubtype_cdregion);
1389  DrawMismatchLabel(x, y, is_exon_present, gc);
1390  DrawOnTheFlyLabel(x, y, is_exon_present, gc);
1391  }
1392 }
1393 
1394 vector<unsigned int> CPaintSequence::GetFeaturesInRow(int row) const
1395 {
1396  vector<unsigned int> feats_in_row;
1397 
1398  for (size_t i = 0; i < m_FeatWholeRange.size(); i++)
1399  {
1400  TSeqPos start = m_FeatWholeRange[i].first;
1401  TSeqPos stop = m_FeatWholeRange[i].second;
1402  int row_start = row * m_NumCols;
1403  int row_end = row_start + m_NumCols - 1;
1404  if ( (row_start >= start && row_end <= stop) ||
1405  (start >= row_start && start <= row_end) ||
1406  (stop >= row_start && stop <= row_end) )
1407  {
1408  feats_in_row.push_back(static_cast<unsigned int>(i));
1409  }
1410 
1411  }
1412  return feats_in_row;
1413 }
1414 
1415 void CPaintSequence::DrawComplementLabel(int row, int x, int &y, wxGraphicsContext *gc) const
1416 {
1417  if (m_EnableComplement)
1418  {
1419  if (gc)
1420  {
1421  gc->DrawText(_("complement"),x,y);
1422  }
1423  y += m_FontHeight;
1424  }
1425 }
1426 
1427 void CPaintSequence::DrawOnTheFlyLabel(int x, int &y, bool is_exon_present, wxGraphicsContext *gc) const
1428 {
1429  if (m_EnableOnTheFly && is_exon_present)
1430  {
1431  if (gc)
1432  {
1433  gc->SetFont(m_Font, *wxBLUE);
1434  gc->DrawText (_("on-the-fly"),x,y);
1435  gc->SetFont(m_Font, *wxBLACK);
1436  }
1437  y += m_FontHeight;
1438  }
1439 }
1440 
1441 void CPaintSequence::DrawTranslationLabels(int row, int x, int &y, wxGraphicsContext *gc) const
1442 {
1443  if (m_EnableTranslation)
1444  {
1445  if (gc)
1446  gc->DrawText (_("frame +1"),x,y);
1447  y += m_FontHeight;
1448  }
1450  {
1451  if (gc)
1452  gc->DrawText (_("frame +2"),x,y);
1453  y += m_FontHeight;
1454  }
1456  {
1457  if (gc)
1458  gc->DrawText (_("frame +3"),x,y);
1459  y += m_FontHeight;
1460  }
1462  {
1463  if (gc)
1464  gc->DrawText (_("frame -1"),x,y);
1465  y += m_FontHeight;
1466  }
1468  {
1469  if (gc)
1470  gc->DrawText (_("frame -2"),x,y);
1471  y += m_FontHeight;
1472  }
1474  {
1475  if (gc)
1476  gc->DrawText (_("frame -3"),x,y);
1477  y += m_FontHeight;
1478  }
1479 }
1480 
1481 void CPaintSequence::DrawFeatures(int row, unsigned int seq_pos, int x, int &y, int y_base, const vector<unsigned int> &feats_in_row, const map<unsigned int, vector<unsigned int> > &feats_with_exons, wxGraphicsContext *gc) const
1482 {
1483  for (unsigned int k = 0; k < feats_in_row.size(); k++)
1484  {
1485  unsigned int i = feats_in_row[k];
1486  map<unsigned int, vector<unsigned int> >::const_iterator f = feats_with_exons.find(i);
1487 
1488  if (m_EnableFeatures)
1489  {
1490  bool found = false;
1491  bool startpoint = false;
1492  bool endpoint = false;
1493 
1494  if (f != feats_with_exons.end())
1495  {
1496  for (unsigned int m = 0; m < f->second.size(); m++)
1497  {
1498  unsigned int j = f->second[m];
1499  TSeqPos start = m_FeatRanges[i][j].first;
1500  TSeqPos stop = m_FeatRanges[i][j].second;
1501 
1502  if (seq_pos >= start && seq_pos <= stop)
1503  {
1504  found = true;
1505  if (seq_pos == start)
1506  startpoint = true;
1507  if (seq_pos == stop)
1508  endpoint = true;
1509  break;
1510  }
1511  }
1512  }
1513 
1514 
1515  if (gc && seq_pos >= m_FeatWholeRange[i].first && seq_pos <= m_FeatWholeRange[i].second)
1516  {
1517  gc->SetPen( *GetColorForFeature(m_FeatTypes[i].second));
1518  gc->SetBrush(*wxBLACK_BRUSH);
1519  gc->StrokeLine(x, y+m_FontHeight/2, x+m_FontWidth, y+m_FontHeight/2);
1520  if (found)
1521  gc->StrokeLine(x, y+m_FontHeight/2+1, x+m_FontWidth, y+m_FontHeight/2+1);
1522  if (m_ContinueFeatures && !startpoint)
1523  {
1524  gc->StrokeLine(x - space_between_groups * m_FontWidth, y+m_FontHeight/2, x ,y+m_FontHeight/2);
1525  if (found)
1526  gc->StrokeLine(x - space_between_groups * m_FontWidth, y+m_FontHeight/2+1, x ,y+m_FontHeight/2+1);
1527  }
1528  if (m_FeatStrand[i] == objects::CBioseq_Handle::eStrand_Plus)
1529  {
1530  if (startpoint)
1531  gc->DrawRectangle(x, y+m_FontHeight/2-3, 6, 6);
1532  if (endpoint)
1533  {
1534  wxPoint2DDouble lines[] = {wxPoint2DDouble(x+m_FontWidth-4, y-4+m_FontHeight/2), wxPoint2DDouble(x+m_FontWidth-4, y+4+m_FontHeight/2), wxPoint2DDouble(x+m_FontWidth,y+m_FontHeight/2)};
1535  gc->DrawLines(3,lines);
1536  }
1537  }
1538  else
1539  {
1540  if (startpoint)
1541  {
1542  wxPoint2DDouble lines[] = {wxPoint2DDouble(x+4, y-4+m_FontHeight/2), wxPoint2DDouble(x+4, y+4+m_FontHeight/2), wxPoint2DDouble(x,y+m_FontHeight/2)};
1543  gc->DrawLines(3,lines);
1544  }
1545  if (endpoint)
1546  gc->DrawRectangle(x+m_FontWidth-6, y+m_FontHeight/2-3, 6, 6);
1547  }
1548  }
1549  y += m_FontHeight;
1550  }
1551 
1552  DrawMismatch(x,y,y_base,seq_pos,i,feats_with_exons,gc);
1553  DrawOnTheFly(x,y,y_base,seq_pos,i,feats_with_exons,gc);
1554  }
1555 }
1556 
1557 void CPaintSequence::OnCopy( wxCommandEvent& event )
1558 {
1559  if (wxTheClipboard->Open())
1560  {
1561  // This data objects are held by the clipboard,
1562  // so do not delete them in the app.
1563  int pos1 = m_DragMin;
1564  int pos2 = m_DragMax;
1565  if (pos1 > pos2)
1566  swap(pos1, pos2);
1567  if (pos1 >= 0 && pos2 >= 0)
1568  wxTheClipboard->SetData( new wxTextDataObject(m_Seq.substr(pos1, pos2 - pos1 + 1)) );
1569  wxTheClipboard->Close();
1570  }
1571 }
1572 
1573 
1575 {
1576  string result;
1577  int pos1 = m_DragMin;
1578  int pos2 = m_DragMax;
1579  if (pos1 > pos2)
1580  swap(pos1, pos2);
1581  if (pos1 >= 0 && pos2 >= 0)
1582  {
1583  if (pos1 == 0 && pos2 == m_Seq.size() - 2)
1584  {
1585  wxMessageBox (_("Unable to delete the whole sequence"), _("Error"), wxOK|wxICON_ERROR);
1586  result = m_Seq;
1587  return result;
1588  }
1589  bool read_only = false;
1590  int old_pos = m_CursorSeq;
1591  for (int i = pos1; i <= pos2; i++)
1592  {
1593  m_CursorSeq = i;
1594  unsigned int seg = PosToSegment();
1595  if (m_read_only[seg])
1596  {
1597  read_only = true;
1598  break;
1599  }
1600  }
1601  m_CursorSeq = old_pos;
1602  if (read_only)
1603  {
1605  return result;
1606  }
1607 
1608  result = m_Seq.substr(pos1, pos2 - pos1 + 1);
1609  string str1;
1610  if (pos1 > 0)
1611  str1 = m_Seq.substr(0, pos1);
1612  string str2;
1613  if (pos2 + 1 < m_Seq.size())
1614  str2 = m_Seq.substr(pos2 + 1);
1615  m_Seq = str1+str2;
1616  m_CursorSeq = pos1;
1617  for (int i = pos1; i <= pos2; i++)
1618  {
1619  unsigned int seg = PosToSegment();
1620  m_SeqLen[seg]--;
1621  if (m_SeqLen[seg] < 0)
1622  m_SeqLen[seg] = 0;
1623  }
1624  AdjustFeatureRange(pos1, -(pos2 - pos1 + 1));
1625  m_DragMin = -1;
1626  m_DragMax = -1;
1627  SeqPosToColRow();
1628  UpdateData();
1629  SetClean(false);
1630  ScrollWithCursor();
1631  Refresh();
1632  }
1633  return result;
1634 }
1635 
1636 void CPaintSequence::OnCut( wxCommandEvent& event )
1637 {
1638 
1639  if (wxTheClipboard->Open())
1640  {
1641  string result = CutSelection();
1642  if (!result.empty())
1643  {
1644  // This data objects are held by the clipboard,
1645  // so do not delete them in the app.
1646  wxTheClipboard->SetData( new wxTextDataObject(result) );
1647  }
1648 
1649  wxTheClipboard->Close();
1650  }
1651 
1652 }
1653 
1654 void CPaintSequence::OnPaste( wxCommandEvent& event )
1655 {
1656  unsigned int seg = PosToSegment();
1657  if (m_read_only[seg])
1658  {
1660  return;
1661  }
1662  if (wxTheClipboard->Open())
1663  {
1664  if (wxTheClipboard->IsSupported( wxDF_UNICODETEXT ) && m_CursorSeq >= 0)
1665  {
1666  wxTextDataObject data;
1667  wxTheClipboard->GetData( data );
1668  string str = data.GetText().ToStdString();
1669  NStr::ToLower(str);
1670  bool allowed = true;
1671  for (size_t i=0; i<str.size(); i++)
1672  if (m_AllowedCharSet.find(str[i]) == string::npos)
1673  {
1674  allowed = false;
1675  break;
1676  }
1677  if (!str.empty() && allowed)
1678  {
1679  string str1;
1680  if (m_CursorSeq > 0)
1681  str1 = m_Seq.substr(0,m_CursorSeq);
1682  string str2 = m_Seq.substr(m_CursorSeq);
1683  m_Seq = str1+str+str2;
1684  m_SeqLen[seg] += str.size();
1685  AdjustFeatureRange(m_CursorSeq,static_cast<int>(str.size()));
1686  m_CursorSeq += str.size();
1687  m_DragMin = -1;
1688  m_DragMax = -1;
1689  SeqPosToColRow();
1690  UpdateData();
1691  SetClean(false);
1692  ScrollWithCursor();
1693  Refresh();
1694  }
1695  }
1696  wxTheClipboard->Close();
1697  }
1698 }
1699 
1701 {
1702  bool found = false;
1703  if (wxTheClipboard->Open())
1704  {
1705  if (wxTheClipboard->IsSupported( wxDF_UNICODETEXT ))
1706  {
1707  wxTextDataObject data;
1708  wxTheClipboard->GetData( data );
1709  string str = data.GetText().ToStdString();
1710  NStr::ToLower(str);
1711  bool allowed = true;
1712  for (size_t i=0; i<str.size(); i++)
1713  if (m_AllowedCharSet.find(str[i]) == string::npos)
1714  {
1715  allowed = false;
1716  break;
1717  }
1718  if (!str.empty() && allowed)
1719  {
1720  found = true;
1721  }
1722  }
1723  wxTheClipboard->Close();
1724  }
1725  return found;
1726 }
1727 
1729 {
1730  bool found = false;
1731  if (m_DragMin >= 0 && m_DragMax >= 0)
1732  found = true;
1733  return found;
1734 }
1735 
1737 {
1738  int pos1 = m_DragMin;
1739  int pos2 = m_DragMax;
1740  if (pos1 > pos2)
1741  swap(pos1, pos2);
1742  return pair<int,int>(pos1, pos2);
1743 }
1744 
1745 string * CPaintSequence::GetFindString(bool is_nuc, bool is_revcomp, const string &choice)
1746 {
1747  string *str = NULL;
1748  if (is_nuc)
1749  {
1750  if (is_revcomp)
1751  str = &m_Complement;
1752  else
1753  str = &m_Seq;
1754  }
1755  else
1756  {
1757  if (choice == "+1")
1758  str = &m_Prot;
1759  if (choice == "+2")
1760  str = &m_Prot1;
1761  if (choice == "+3")
1762  str = &m_Prot2;
1763  if (choice == "-1")
1764  str = &m_RevProt;
1765  if (choice == "-2")
1766  str = &m_RevProt1;
1767  if (choice == "-3")
1768  str = &m_RevProt2;
1769  }
1770  return str;
1771 }
1772 
1774 {
1775  return static_cast<int>(m_Seq.size() - 1);
1776 }
1777 
1779 {
1780  m_DragMin = -1;
1781  m_DragMax = -1;
1782  return m_highlights;
1783 }
1784 
1785 
1787 {
1788  m_Translated.clear();
1789  m_Translated.resize(m_FeatRanges.size());
1790  for (unsigned int i = 0; i < m_FeatRanges.size(); i++)
1792  {
1793  string seq;
1794  for (unsigned int j=0; j<m_FeatRanges[i].size(); j++)
1795  {
1796  TSeqPos start = m_FeatRanges[i][j].first;
1797  TSeqPos stop = m_FeatRanges[i][j].second;
1798  if (start != numeric_limits<int>::max() && stop != numeric_limits<int>::max())
1799  seq += m_Seq.substr(start, stop-start+1);
1800  }
1801 
1802  string rev_comp;
1803  if (m_FeatStrand[i] == objects::CBioseq_Handle::eStrand_Minus)
1804  {
1805  CSeqManip::ReverseComplement(seq, CSeqUtil::e_Iupacna, 0, static_cast<TSeqPos>(seq.size()), rev_comp);
1806  NStr::ToLower(rev_comp);
1807  swap(rev_comp,seq);
1808  }
1809  CGenetic_code *code = NULL;
1810  if (m_GeneticCode[i])
1811  code = m_GeneticCode[i].GetPointer();
1813  if (m_Feat5Partial[i])
1816  }
1817 }
1818 
1820 {
1821  if (m_FeatStrand[i] == objects::CBioseq_Handle::eStrand_Minus)
1822  return m_FeatRanges[i][m_FeatRanges[i].size() - 1 - j].first;
1823  return m_FeatRanges[i][j].first;
1824 }
1825 
1827 {
1828  if (m_FeatStrand[i] == objects::CBioseq_Handle::eStrand_Minus)
1829  return m_FeatRanges[i][m_FeatRanges[i].size() - 1 - j].second;
1830  return m_FeatRanges[i][j].second;
1831 }
1832 
1834 {
1835  for (unsigned int i = 0; i < m_FeatRanges.size(); i++)
1836  {
1837  for (unsigned int j=0; j<m_FeatRanges[i].size(); j++)
1838  {
1839  int start = m_FeatRanges[i][j].first;
1840  int stop = m_FeatRanges[i][j].second;
1841  AdjustFeatStartStop(origin, offset, start, stop);
1842  m_FeatRanges[i][j].first = start;
1843  m_FeatRanges[i][j].second = stop;
1844  }
1846  }
1848  TranslateCDS();
1849 }
1850 
1852 {
1853  if (m_ProtFeatRanges.find(i) == m_ProtFeatRanges.end())
1854  return;
1855  for (unsigned int k = 0; k < m_ProtFeatRanges[i].size(); k++)
1856  {
1857  for (unsigned int j=0; j<m_ProtFeatRanges[i][k].size(); j++)
1858  {
1859  int start = m_ProtFeatRanges[i][k][j].first;
1860  int stop = m_ProtFeatRanges[i][k][j].second;
1861  AdjustFeatStartStop(origin, offset, start, stop);
1862  m_ProtFeatRanges[i][k][j].first = start;
1863  m_ProtFeatRanges[i][k][j].second = stop;
1864  }
1865  }
1866 }
1867 
1868 void CPaintSequence::AdjustFeatStartStop(int origin, int offset, int &start, int &stop)
1869 {
1870  if (offset < 0 && origin <= start && origin - offset >= stop)
1871  {
1872  start = numeric_limits<int>::max();
1873  stop = numeric_limits<int>::max();
1874  }
1875  else
1876  {
1877  if (start >= origin)
1878  {
1879  if (offset >= 0)
1880  {
1881  start += offset;
1882  }
1883  else
1884  {
1885  if (origin - offset <= start)
1886  {
1887  start += offset;
1888  }
1889  else
1890  {
1891  start = origin;
1892  }
1893  }
1894  }
1895  if (stop >= origin)
1896  {
1897  if (offset >= 0)
1898  {
1899  stop += offset;
1900  }
1901  else
1902  {
1903  if (origin - offset <= stop)
1904  {
1905  stop += offset;
1906  }
1907  else
1908  {
1909  stop = origin;
1910  }
1911  }
1912  }
1913  }
1914  if (start < 0)
1915  start = 0;
1916  if (stop < 0)
1917  stop = 0;
1918  if (start > m_Seq.size() - 2 && start != numeric_limits<int>::max())
1919  start = static_cast<int>(m_Seq.size() - 2);
1920  if (stop > m_Seq.size() - 2 && stop != numeric_limits<int>::max())
1921  stop = static_cast<int>(m_Seq.size() - 2);
1922 
1923  if (stop < start)
1924  {
1925  start = numeric_limits<int>::max();
1926  stop = numeric_limits<int>::max();
1927  }
1928 }
1929 
1931 {
1932  m_FeatWholeRange.clear();
1933  m_FeatLengthBefore.clear();
1934  m_FeatTotalLength.clear();
1935  for (size_t i = 0; i < m_FeatRanges.size(); i++)
1936  {
1938  TSeqPos stop = 0;
1939  TSeqPos length = 0;
1940  vector<TSeqPos> length_before;
1941  for (size_t j = 0; j < m_FeatRanges[i].size(); j++)
1942  {
1943  if (m_FeatRanges[i][j].first < start && m_FeatRanges[i][j].first != numeric_limits<int>::max())
1944  start = m_FeatRanges[i][j].first;
1945  if (m_FeatRanges[i][j].second > stop && m_FeatRanges[i][j].second != numeric_limits<int>::max())
1946  stop = m_FeatRanges[i][j].second;
1947  length_before.push_back(length);
1949  length += m_FeatRanges[i][j].second - m_FeatRanges[i][j].first + 1;
1950  }
1951  m_FeatWholeRange.push_back(pair<TSeqPos,TSeqPos>(start,stop));
1952  m_FeatTotalLength.push_back(length);
1953  m_FeatLengthBefore.push_back(length_before);
1954  }
1955 }
1956 
1957 vector<unsigned int> CPaintSequence::IsExonPresent(int i, int row) const
1958 {
1959  vector<unsigned int> ranges;
1960  for (unsigned int j=0; j<m_FeatRanges[i].size(); j++)
1961  {
1962  TSeqPos start = m_FeatRanges[i][j].first;
1963  TSeqPos stop = m_FeatRanges[i][j].second;
1964  int row_start = row * m_NumCols;
1965  int row_end = row_start + m_NumCols - 1;
1966  if ( (row_start >= start && row_end <= stop) ||
1967  (start >= row_start && start <= row_end) ||
1968  (stop >= row_start && stop <= row_end) )
1969  {
1970  ranges.push_back(j);
1971  }
1972  }
1973 
1974  return ranges;
1975 }
1976 
1977 map<unsigned int, vector<unsigned int> > CPaintSequence::GetFeatsWithExons(int row, const vector<unsigned int> &feats_in_row) const
1978 {
1979  map<unsigned int, vector<unsigned int> > feats_with_exons;
1980  for (unsigned int k = 0; k < feats_in_row.size(); k++)
1981  {
1982  unsigned int i = feats_in_row[k];
1983  vector<unsigned int> ranges = IsExonPresent(i, row);
1984  if (!ranges.empty())
1985  feats_with_exons[i] = ranges;
1986  }
1987  return feats_with_exons;
1988 }
1989 
1990 // test: CP005969.asn1: length 6094821
CBioseq_Handle –.
void ReportRange(int pos1, int pos2)
void ReportPos(int pos)
void ShowReadOnlyWarning()
void EnableCommit(bool enable)
set< int > & SetHighlights()
vector< vector< pair< TSeqPos, TSeqPos > > > m_FeatRanges
virtual wxCoord OnGetRowHeight(size_t row) const
vector< CRef< objects::CGenetic_code > > m_GeneticCode
void EnableRevTranslation1(bool enable)
virtual ~CPaintSequence()
void DrawOnTheFlyLabel(int x, int &y, bool is_exon_present, wxGraphicsContext *gc) const
void EnableOnTheFly(bool enable)
vector< pair< TSeqPos, TSeqPos > > m_FeatWholeRange
void DrawLineNumber(unsigned int seq_pos, int x, int &y, wxGraphicsContext *gc) const
const wxPen * GetColorForFeature(objects::CSeqFeatData::ESubtype subtype) const
void DrawLabelCell(unsigned int pos, int x, int &y, int row, const vector< unsigned int > &feats_in_row, const map< unsigned int, vector< unsigned int > > &feats_with_exons, wxGraphicsContext *gc) const
vector< bool > m_Feat5Partial
void SetStartPos(void)
vector< string > m_RealProt
vector< int > m_SeqLen
vector< int > m_FeatFrames
void AdjustFeatStartStop(int origin, int offset, int &start, int &stop)
void DrawOffsetTranslation(int x, int y, unsigned int seq_pos, int offset, const string &prot, wxGraphicsContext *gc) const
vector< string > m_Translated
CEditSequence * m_Parent
void OnChar(wxKeyEvent &event)
vector< unsigned int > GetFeaturesInRow(int row) const
void ClearScreen(wxGraphicsContext *gc)
void OnCut(wxCommandEvent &event)
set< int > m_highlights
vector< bool > m_read_only
virtual void OnEraseBackground(wxEraseEvent &event)
vector< int > & GetSeqLen()
void SetPos(int pos)
void InsertChar(int uc)
pair< int, int > m_FeatureStart
string * GetFindString(bool is_nuc, bool is_revcomp, const string &choice)
pair< int, int > GetSelection()
void DrawMismatch(int x, int &y, int y_base, unsigned int seq_pos, int i, const map< unsigned int, vector< unsigned int > > &feats_with_exons, wxGraphicsContext *gc) const
void DrawOnTheFly(int x, int &y, int y_base, unsigned int seq_pos, int i, const map< unsigned int, vector< unsigned int > > &feats_with_exons, wxGraphicsContext *gc) const
void DrawTranslation(int x, int &y, unsigned int seq_pos, wxGraphicsContext *gc) const
void EnableMismatch(bool enable)
void DrawMismatchLabel(int x, int &y, bool is_exon_present, wxGraphicsContext *gc) const
void DrawCursor(int col, int row, int x, int &y, wxGraphicsContext *gc) const
void EnableComplement(bool enable)
void DrawTranslationLabels(int row, int x, int &y, wxGraphicsContext *gc) const
void OnMouseDrag(wxMouseEvent &evt)
int FindRowByCoord(int y, int &y_row)
void UpdateFeatures(const vector< vector< pair< TSeqPos, TSeqPos > > > &feat_ranges, const vector< pair< string, objects::CSeqFeatData::ESubtype > > &feat_types, const vector< objects::CBioseq_Handle::EVectorStrand > &feat_strand, const vector< int > &feat_frames, const vector< CRef< objects::CGenetic_code > > &genetic_code, const vector< bool > &feat_partial5, const vector< string > &real_prot, const unordered_map< int, vector< vector< pair< TSeqPos, TSeqPos > > > > &prot_feat_ranges)
void OnPaste(wxCommandEvent &event)
void DrawFeatures(int row, unsigned int seq_pos, int x, int &y, int y_base, const vector< unsigned int > &feats_in_row, const map< unsigned int, vector< unsigned int > > &feats_with_exons, wxGraphicsContext *gc) const
void OnKeyDown(wxKeyEvent &event)
void EnableTranslation1(bool enable)
void SetRange(int pos1, int pos2)
void DrawComplement(int x, int &y, unsigned int seq_pos, wxGraphicsContext *gc) const
void OnMouseClick(wxMouseEvent &evt)
void OnCopy(wxCommandEvent &event)
void DrawFeatureLabels(int row, int x, int &y, const vector< unsigned int > &feats_in_row, const map< unsigned int, vector< unsigned int > > &feats_with_exons, wxGraphicsContext *gc) const
void EnableRevTranslation(bool enable)
void MouseToFeature(wxPoint p, int row, int y0)
bool MouseToSeqPos(wxPoint p, int &row, int &y_row)
void DrawTextLine(const string &substr, int &y_label, int row, wxGraphicsContext *gc, size_t &seq_pos)
void NormalizeCursorColRows()
void EnableTranslation2(bool enable)
virtual void OnUpdate()
Notification for the derived class that moment is good for doing its update and drawing stuff.
void AdjustProtFeatRange(int origin, int offset, int i)
void OnResize(wxSizeEvent &)
void EnableTranslation(bool enable)
void AdjustFeatureRange(int origin, int offset)
char TranslateOnTheFly(unsigned int seq_pos, int i, const vector< unsigned int > &ranges, const vector< string > &translation, bool &left, bool &right) const
void Search(const string &val)
virtual void OnPaint(wxPaintEvent &event)
Painting.
void EnableRevTranslation2(bool enable)
vector< pair< string, objects::CSeqFeatData::ESubtype > > m_FeatTypes
void DrawTextCell(const wxString &substr, int col, int row, unsigned int seq_pos, int x, int &y, const vector< unsigned int > &feats_in_row, const map< unsigned int, vector< unsigned int > > &feats_with_exons, wxGraphicsContext *gc) const
void SetClean(bool clean)
vector< TSeqPos > m_FeatTotalLength
TSeqPos GetFeatureStop(int i, int j)
vector< vector< TSeqPos > > m_FeatLengthBefore
vector< unsigned int > IsExonPresent(int i, int row) const
pair< int, int > m_FeatureStop
unsigned int PosToSegment()
void EnableFeatures(bool enable)
void CalculateFontWidthAndHeight(wxGraphicsContext *gc)
unordered_map< int, vector< vector< pair< TSeqPos, TSeqPos > > > > m_ProtFeatRanges
map< unsigned int, vector< unsigned int > > GetFeatsWithExons(int row, const vector< unsigned int > &feats_in_row) const
vector< objects::CBioseq_Handle::EVectorStrand > m_FeatStrand
void OnMouseDown(wxMouseEvent &evt)
void DrawTripletMismatch(int x, int y, int y_base, int i, wxGraphicsContext *gc) const
TSeqPos GetFeatureStart(int i, int j)
void DrawComplementLabel(int row, int x, int &y, wxGraphicsContext *gc) const
CRef –.
Definition: ncbiobj.hpp:618
static SIZE_TYPE ReverseComplement(const string &src, TCoding src_coding, TSeqPos pos, TSeqPos length, string &dst)
static SIZE_TYPE Complement(const string &src, TCoding src_coding, TSeqPos pos, TSeqPos length, string &dst)
@ e_Iupacna
Definition: sequtil.hpp:47
const_iterator end() const
Definition: map.hpp:152
const_iterator find(const key_type &key) const
Definition: map.hpp:153
Definition: map.hpp:338
Definition: set.hpp:45
const_iterator begin() const
Definition: set.hpp:135
const_iterator find(const key_type &key) const
Definition: set.hpp:137
const_iterator end() const
Definition: set.hpp:136
#define _(proto)
Definition: ct_nlmzip_i.h:78
static uch flags
#define true
Definition: bool.h:35
#define false
Definition: bool.h:36
static DLIST_TYPE *DLIST_NAME() first(DLIST_LIST_TYPE *list)
Definition: dlist.tmpl.h:46
static const char * str(char *buf, int n)
Definition: stats.c:84
int offset
Definition: replacements.h:160
char data[12]
Definition: iconv.c:80
unsigned int TSeqPos
Type for sequence locations and lengths.
Definition: ncbimisc.hpp:875
void swap(NCBI_NS_NCBI::pair_base_member< T1, T2 > &pair1, NCBI_NS_NCBI::pair_base_member< T1, T2 > &pair2)
Definition: ncbimisc.hpp:1508
#define NULL
Definition: ncbistd.hpp:225
static void Translate(const string &seq, string &prot, const CGenetic_code *code, bool include_stop=true, bool remove_trailing_X=false, bool *alt_start=NULL, bool is_5prime_complete=true, bool is_3prime_complete=true)
Translate a string using a specified genetic code.
Definition: sequence.cpp:4095
@ fIs5PrimePartial
= 0x4 Translate first codon even if not start codon (because sequence is 5' partial)
Definition: sequence.hpp:984
@ fRemoveTrailingX
= 0x2 Remove trailing Xs from protein
Definition: sequence.hpp:983
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
static SIZE_TYPE FindNoCase(const CTempString str, const CTempString pattern, SIZE_TYPE start, SIZE_TYPE end, EOccurrence which=eFirst)
Find the pattern in the specified range of a string using a case insensitive search.
Definition: ncbistr.cpp:2993
#define NPOS
Definition: ncbistr.hpp:133
static string TruncateSpaces(const string &str, ETrunc where=eTrunc_Both)
Truncate spaces in a string.
Definition: ncbistr.cpp:3186
static string & ToLower(string &str)
Convert string to lower case – string& version.
Definition: ncbistr.cpp:405
static const char label[]
unsigned int
A callback function used to compare two keys in a database.
Definition: types.hpp:1210
END_EVENT_TABLE()
int i
const struct ncbi::grid::netcache::search::fields::SIZE size
#define abs(a)
Definition: ncbi_heapmgr.c:130
int tolower(Uchar c)
Definition: ncbictype.hpp:72
T max(T x_, T y_)
T minus(T x_)
T plus(T x_)
double r(size_t dimension_, const Int4 *score_, const double *prob_, double theta_)
double f(double x_, const double &y_)
Definition: njn_root.hpp:188
static const GLdouble origin[]
static const int chars_per_group
static const int space_between_groups
BOOL UpdateData(HWND hDlg, CProjBulderApp *pApp, BOOL bGet)
Definition: ptb_gui.cpp:62
#define row(bind, expected)
Definition: string_bind.c:73
Definition: inftrees.h:24
else result
Definition: token2.c:20
#define const
Definition: zconf.h:232
Modified on Wed Jun 12 11:15:23 2024 by modify_doxy.py rev. 669887