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

Go to the SVN repository for this file.

1 /* $Id: seq_text_panel.cpp 36516 2016-10-03 19:16:16Z katargir $
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: Roman Katargin
27  *
28  */
29 
30 #include <ncbi_pch.hpp>
31 
32 #include <wx/sizer.h>
33 #include <wx/choice.h>
34 #include <wx/stattext.h>
35 #include <wx/bitmap.h>
36 #include <wx/icon.h>
37 #include <wx/textctrl.h>
38 #include <wx/button.h>
39 
43 
44 ////@begin includes
45 ////@end includes
46 
49 
50 ////@begin XPM images
51 ////@end XPM images
52 
53 /*!
54  * CSeqTextPanel type definition
55  */
56 
57 IMPLEMENT_DYNAMIC_CLASS( CSeqTextPanel, wxPanel )
58 
59 
60 /*!
61  * CSeqTextPanel event table definition
62  */
63 
64 BEGIN_EVENT_TABLE( CSeqTextPanel, wxPanel )
65 
66 ////@begin CSeqTextPanel event table entries
67  EVT_BUTTON( ID_BUTTON, CSeqTextPanel::OnFindBwdClick )
68  EVT_BUTTON( ID_BUTTON1, CSeqTextPanel::OnFindFwdClick )
69  EVT_BUTTON( ID_BUTTON2, CSeqTextPanel::OnStopClick )
70  EVT_CHOICE( ID_CHOICE1, CSeqTextPanel::OnFeatureTypeSelected )
71 ////@end CSeqTextPanel event table entries
72 
74 
75 
76 /*!
77  * CSeqTextPanel constructors
78  */
79 
80 CSeqTextPanel::CSeqTextPanel()
81 {
82  Init();
83 }
84 
85 CSeqTextPanel::CSeqTextPanel( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style )
86 {
87  Init();
88  Create(parent, id, pos, size, style);
89 }
90 
91 
92 /*!
93  * CSeqTextPanel creator
94  */
95 
96 bool CSeqTextPanel::Create( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style )
97 {
98 ////@begin CSeqTextPanel creation
99  wxPanel::Create( parent, id, pos, size, style );
100 
101  CreateControls();
102  if (GetSizer())
103  {
104  GetSizer()->SetSizeHints(this);
105  }
106  Centre();
107 ////@end CSeqTextPanel creation
108  return true;
109 }
110 
111 
112 /*!
113  * CSeqTextPanel destructor
114  */
115 
117 {
118 ////@begin CSeqTextPanel destruction
119  // job is canceled if main window is destroyed
120  if (m_JobAdapter) {
121  m_JobAdapter->Cancel();
122  }
123 ////@end CSeqTextPanel destruction
124 }
125 
126 
127 /*!
128  * Member initialisation
129  */
130 
132 {
133 ////@begin CSeqTextPanel member initialisation
134  m_BwdButton = NULL;
135  m_FwdButton = NULL;
136  m_StopButton = NULL;
137  m_MousePos = NULL;
139 ////@end CSeqTextPanel member initialisation
140 }
141 
142 
143 /*!
144  * Control creation for CSeqTextPanel
145  */
146 
148 {
149 ////@begin CSeqTextPanel content construction
150  CSeqTextPanel* itemPanel1 = this;
151 
152  wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL);
153  itemPanel1->SetSizer(itemBoxSizer2);
154 
155  wxBoxSizer* itemBoxSizer3 = new wxBoxSizer(wxHORIZONTAL);
156  itemBoxSizer2->Add(itemBoxSizer3, 0, wxALIGN_LEFT|wxALL, 5);
157 
158  wxStaticText* itemStaticText4 = new wxStaticText( itemPanel1, wxID_STATIC, _("Find"), wxDefaultPosition, wxDefaultSize, 0 );
159  itemBoxSizer3->Add(itemStaticText4, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
160 
161  wxTextCtrl* itemTextCtrl5 = new wxTextCtrl( itemPanel1, ID_TEXTCTRL1, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
162  itemBoxSizer3->Add(itemTextCtrl5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
163 
164  m_BwdButton = new wxButton( itemPanel1, ID_BUTTON, _("Bwd"), wxDefaultPosition, wxDefaultSize, 0 );
165  itemBoxSizer3->Add(m_BwdButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
166 
167  m_FwdButton = new wxButton( itemPanel1, ID_BUTTON1, _("Fwd"), wxDefaultPosition, wxDefaultSize, 0 );
168  itemBoxSizer3->Add(m_FwdButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
169 
170  m_StopButton = new wxButton( itemPanel1, ID_BUTTON2, _("Stop"), wxDefaultPosition, wxDefaultSize, 0 );
171  m_StopButton->Enable(false);
172  itemBoxSizer3->Add(m_StopButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
173 
174  wxStaticText* itemStaticText9 = new wxStaticText( itemPanel1, wxID_STATIC, _("Current Position:"), wxDefaultPosition, wxDefaultSize, 0 );
175  itemBoxSizer3->Add(itemStaticText9, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
176 
177  m_MousePos = new wxStaticText( itemPanel1, wxID_STATIC, wxEmptyString, wxDefaultPosition, wxSize(itemPanel1->ConvertDialogToPixels(wxSize(100, -1)).x, -1), wxNO_BORDER );
178  itemBoxSizer3->Add(m_MousePos, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
179 
180  wxStaticText* itemStaticText11 = new wxStaticText( itemPanel1, wxID_STATIC, _("Show"), wxDefaultPosition, wxDefaultSize, 0 );
181  itemBoxSizer3->Add(itemStaticText11, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
182 
183  wxArrayString itemChoice12Strings;
184  itemChoice12Strings.Add(_("None"));
185  itemChoice12Strings.Add(_("Gene"));
186  itemChoice12Strings.Add(_("CDS"));
187  itemChoice12Strings.Add(_("mRNA"));
188  itemChoice12Strings.Add(_("misc_RNA"));
189  itemChoice12Strings.Add(_("STS"));
190  wxChoice* itemChoice12 = new wxChoice( itemPanel1, ID_CHOICE1, wxDefaultPosition, wxDefaultSize, itemChoice12Strings, 0 );
191  itemChoice12->SetStringSelection(_("None"));
192  itemBoxSizer3->Add(itemChoice12, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
193 
194  m_SeqTextWidget = new CSeqTextWidget(itemPanel1, ID_WINDOW, wxDefaultPosition, itemPanel1->ConvertDialogToPixels(wxSize(300, 200)), wxSUNKEN_BORDER | wxTAB_TRAVERSAL);
195  itemBoxSizer2->Add(m_SeqTextWidget, 1, wxGROW|wxALL, 0);
196 
197 ////@end CSeqTextPanel content construction
199  m_SeqTextWidget->SetHost(this);
200 
201  int subtype = m_SeqTextWidget->GetCaseFeatureSubtype();
202  wxChoice* choice = (wxChoice*)FindWindow(ID_CHOICE1);
203 
204  switch (subtype) {
205  case objects::CSeqFeatData::eSubtype_gene:
206  choice->SetSelection (1);
207  break;
208  case objects::CSeqFeatData::eSubtype_cdregion:
209  choice->SetSelection (2);
210  break;
211  case objects::CSeqFeatData::eSubtype_mRNA:
212  choice->SetSelection (3);
213  break;
214  case objects::CSeqFeatData::eSubtype_misc_RNA:
215  choice->SetSelection (4);
216  break;
217  case objects::CSeqFeatData::eSubtype_STS:
218  choice->SetSelection (5);
219  break;
220  }
221  m_SeqTextWidget->SetFocus();
222 }
223 
224 
225 /*!
226  * Should we show tooltips?
227  */
228 
230 {
231  return true;
232 }
233 
234 /*!
235  * Get bitmap resources
236  */
237 
238 wxBitmap CSeqTextPanel::GetBitmapResource( const wxString& name )
239 {
240  // Bitmap retrieval
241 ////@begin CSeqTextPanel bitmap retrieval
242  wxUnusedVar(name);
243  return wxNullBitmap;
244 ////@end CSeqTextPanel bitmap retrieval
245 }
246 
247 /*!
248  * Get icon resources
249  */
250 
251 wxIcon CSeqTextPanel::GetIconResource( const wxString& name )
252 {
253  // Icon retrieval
254 ////@begin CSeqTextPanel icon retrieval
255  wxUnusedVar(name);
256  return wxNullIcon;
257 ////@end CSeqTextPanel icon retrieval
258 }
259 
261 {
262  wxBusyCursor wait;
263 
264  const CSeq_id* id = dynamic_cast<const CSeq_id*>(object.object.GetPointer());
265  if (id) {
266  CBioseq_Handle handle = object.scope->GetBioseqHandle(*id);
267  m_DataSource.Reset(new CSeqTextDataSource(handle, *object.scope));
269  return true;
270  }
271 
272  const CSeq_entry* seq_entry = dynamic_cast<const CSeq_entry*>(object.object.GetPointer());
273  if (seq_entry) {
274  m_DataSource.Reset(new CSeqTextDataSource(*const_cast<CSeq_entry*>(seq_entry), *object.scope));
276  return true;
277  }
278 
279  const CBioseq_Handle* handle = dynamic_cast<const CBioseq_Handle*>(object.object.GetPointer());
280  if (handle) {
281  m_DataSource.Reset(new CSeqTextDataSource(*handle, *object.scope));
283  return true;
284  }
285 
286  const CSeq_loc* loc = dynamic_cast<const CSeq_loc*>(object.object.GetPointer());
287  if (loc) {
288  m_DataSource.Reset(new CSeqTextDataSource(*const_cast<CSeq_loc*>(loc), *object.scope));
290  return true;
291  }
292 
293  return false;
294 }
295 
297 {
298  m_MousePos->SetLabel(ToWxString(NStr::IntToString(pos)));
299 }
300 
301 
302 void CSeqTextPanel::OnFeatureTypeSelected( wxCommandEvent& event )
303 {
304  objects::CSeqFeatData::ESubtype subtype = objects::CSeqFeatData::eSubtype_bad;
305  switch (event.GetInt()) {
306  case 1:
307  subtype = objects::CSeqFeatData::eSubtype_gene;
308  break;
309  case 2:
310  subtype = objects::CSeqFeatData::eSubtype_cdregion;
311  break;
312  case 3:
313  subtype = objects::CSeqFeatData::eSubtype_mRNA;
314  break;
315  case 4:
316  subtype = objects::CSeqFeatData::eSubtype_misc_RNA;
317  break;
318  case 5:
319  subtype = objects::CSeqFeatData::eSubtype_STS;
320  break;
321  }
322 
324 }
325 
326 
327 void CSeqTextPanel::OnFindBwdClick( wxCommandEvent& event )
328 {
329  m_FwdButton->Enable(false);
330  m_BwdButton->Enable(false);
331  m_StopButton->Enable(true);
332  x_StartSearch(false);
333 }
334 
335 void CSeqTextPanel::OnFindFwdClick( wxCommandEvent& event )
336 {
337  m_FwdButton->Enable(false);
338  m_BwdButton->Enable(false);
339  m_StopButton->Enable(true);
340  x_StartSearch(true);
341 }
342 
343 void CSeqTextPanel::OnStopClick(wxCommandEvent& event)
344 {
348 }
349 
351 {
352  m_FwdButton->Enable(true);
353  m_BwdButton->Enable(true);
354  m_StopButton->Enable(false);
355 }
356 
357 namespace {
358  struct SSeqSearchInput {
359  string m_Term;
360  bool m_Forward;
361  CSeqTextWidget* m_TextWidget;
362 
363  SSeqSearchInput(const string& search_term, bool forward, CSeqTextWidget* widget)
364  : m_Term(search_term), m_Forward(forward), m_TextWidget(widget) {}
365  };
366 
367  struct SSeqSearchOutput {
369  string m_Term;
370  bool m_Found;
371 
372  SSeqSearchOutput() : m_Term(kEmptyStr), m_Found(false) {}
373  };
374 }
375 
376 static bool s_SearchInSeqText(SSeqSearchInput& input, SSeqSearchOutput& output, string& error, ICanceled& canceled)
377 {
378  try {
379  LOG_POST(Info << "Searching for " << input.m_Term);
380 
381  output.m_Term = input.m_Term;
382  output.m_Found = false;
383 
384  if (canceled.IsCanceled())
385  return false;
386 
387  CSeqTextWidget* widget = input.m_TextWidget;
388  CSeqTextDataSource* pDS = widget->GetDS();
389  if (!pDS)
390  return false;
391 
392 
393  CSeqTextPane& pane = widget->GetPane();
394  output.m_Result = pane.GetTextSearchData(); // receive the data related to previous search from the pane
395  CSeqTextPane::CSeqTextSearch& res = output.m_Result;
396 
397  if (!NStr::EqualNocase(res.m_LastSearch, input.m_Term)) {
398  pDS->FindSequenceFragmentList(input.m_Term, res.m_FoundList, &canceled);
399  if (canceled.IsCanceled()) {
400  return false;
401  }
402  TSeqPos curr_scroll = pane.STG_GetSequenceByWindow(0, 0);
403  res.m_CurrFindPos = 0;
404  while (res.m_CurrFindPos < res.m_FoundList.size() && res.m_FoundList[res.m_CurrFindPos] < curr_scroll) {
405  res.m_CurrFindPos++;
406  }
407  if (res.m_CurrFindPos >= res.m_FoundList.size()) {
408  res.m_CurrFindPos = 0;
409  }
410  } else {
411  // searching forward for the previous term
412  if (input.m_Forward) {
413  res.m_CurrFindPos++;
414  if (res.m_CurrFindPos >= res.m_FoundList.size()) {
415  res.m_CurrFindPos = 0;
416  }
417  } else { // searching backwards for the previous term
418  if (res.m_CurrFindPos > 0) {
419  --res.m_CurrFindPos;
420  } else {
421  res.m_CurrFindPos = res.m_FoundList.size() - 1;
422  }
423  }
424  }
425 
426  if (res.m_FoundList.size() > res.m_CurrFindPos) {
427  widget->ScrollToPosition(res.m_FoundList[res.m_CurrFindPos]);
428  output.m_Found = true;
429  }
430 
431  res.m_LastSearch = input.m_Term;
432  }
433  catch (const CException& e) {
434  LOG_POST(Error << e.GetMsg());
435  return false;
436  }
437  catch (const std::exception& e) {
438  LOG_POST(Error << e.what());
439  return false;
440  }
441  return true;
442 }
443 
445 {
447  if (jobResult) {
448  const SSeqSearchOutput& res = jobResult->GetData();
449  m_SeqTextWidget->GetPane().SetTextSearchData(res.m_Result);
450 
451  if (!res.m_Found) {
452  NcbiInfoBox("Search string was not found");
453  }
454  }
456  m_SeqTextWidget->GetPane().Refresh();
457 
459 }
460 
461 void CSeqTextPanel::OnJobFailed(const string& errMsg, CJobAdapter&)
462 {
463  string err_msg = "Failed: ";
464  if (!errMsg.empty()) {
465  err_msg += errMsg;
466  }
467  else {
468  err_msg += "Unknown fatal error";
469  }
470 
471  NcbiErrorBox(err_msg);
473  m_SeqTextWidget->GetPane().Refresh();
475 }
476 
478 {
479  wxTextCtrl* find = (wxTextCtrl*)FindWindow(ID_TEXTCTRL1);
480  string value = ToStdString(find->GetValue());
481  value = NStr::TruncateSpaces(value);
482  if (value.empty()) {
483  NcbiInfoBox("The search string is empty.");
485  return;
486  }
487 
489 
490  SSeqSearchInput input(value, forward, m_SeqTextWidget);
491  m_JobAdapter.Reset(LaunchAdapterJob<SSeqSearchInput, SSeqSearchOutput>
492  (this, input, s_SearchInSeqText, "CSeqTextSearchJob", "Search for a string in Sequence Text View"));
493 }
494 
Interface for testing cancellation request in a long lasting operation.
Definition: icanceled.hpp:50
CBioseq_Handle –.
static string TruncateSpaces(const string &str, ETrunc where=eTrunc_Both)
Truncate spaces in a string.
Definition: ncbistr.cpp:3081
Definition: dbpivot.c:60
void x_RestoreButtonStates()
static bool ShowToolTips()
Should we show tooltips?
class CSeqTextPane
unsigned int TSeqPos
Type for sequence locations and lengths.
Definition: ncbimisc.hpp:850
EDialogReturnValue NcbiInfoBox(const string &message, const string &title="Info")
specialized Message Box function for reporting general information messages
END_EVENT_TABLE()
CRef< CJobAdapter > m_JobAdapter
wxString ToWxString(const char *s)
Definition: wx_utils.hpp:157
USING_SCOPE(objects)
virtual void SetDataSource(CSeqTextDataSource &ds)
CSeqTextPane & GetPane()
bool Create(wxWindow *parent, wxWindowID id=ID_CSEQTEXTPANEL, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(400, 300), long style=wxTAB_TRAVERSAL)
Creation.
void Cancel()
Definition: job_adapter.cpp:48
virtual void OnJobResult(CObject *result, CJobAdapter &adapter)
wxBitmap GetBitmapResource(const wxString &name)
Retrieves bitmap resources.
#define ID_BUTTON
#define NULL
Definition: ncbistd.hpp:225
static const unsigned char res[3][32]
Definition: ccm.c:389
void ResetTextSearchData()
wxButton * m_BwdButton
#define kEmptyStr
Definition: ncbistr.hpp:120
CSeqTextWidget * m_SeqTextWidget
class CSeqTextWidget
wxButton * m_StopButton
void x_StartSearch(bool forward)
void ChooseCaseFeature(objects::CSeqFeatData::ESubtype subtype)
CSeqTextDefs::TSeqPosVector m_FoundList
static string IntToString(int value, TNumToStringFlags flags=0, int base=10)
Convert int to string.
Definition: ncbistr.hpp:5079
void SetTextSearchData(const CSeqTextSearch &data)
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:101
void Init()
Initialises member variables.
wxStaticText * m_MousePos
CSeqTextDataSource implements Adapter design pattern.
#define ID_CHOICE1
void OnFeatureTypeSelected(wxCommandEvent &event)
wxEVT_COMMAND_CHOICE_SELECTED event handler for ID_CHOICE1
CRef< CSeqTextDataSource > m_DataSource
#define LOG_POST(message)
This macro is deprecated and it's strongly recomended to move in all projects (except tests) to macro...
Definition: ncbidiag.hpp:198
int size
~CSeqTextPanel()
Destructor.
char value[7]
Definition: config.c:428
void OnStopClick(wxCommandEvent &event)
void OnFindBwdClick(wxCommandEvent &event)
CSeqTextPanel event handler declarations
void FindSequenceFragmentList(const string &fragment, CSeqTextDefs::TSeqPosVector &locations, ICanceled *cancel)
virtual TSeqPos STG_GetSequenceByWindow(int x, int y)
virtual void STWH_ReportMouseOverPos(TSeqPos pos)
const CSeqTextSearch & GetTextSearchData() const
void Error(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1041
void OnFindFwdClick(wxCommandEvent &event)
wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_BUTTON1
virtual CSeqTextDataSource * GetDS()
Definition: Seq_entry.hpp:55
void ScrollToPosition(TSeqPos pos, bool notify=true)
static void Init(void)
Definition: cursor6.c:79
void Info(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1029
CObject –.
Definition: ncbiobj.hpp:180
static bool s_SearchInSeqText(SSeqSearchInput &input, SSeqSearchOutput &output, string &error, ICanceled &canceled)
void SetHost(ISeqTextWidgetHost *pHost)
#define _(proto)
Definition: ct_nlmzip_i.h:78
else result
Definition: token2.c:20
#define ID_BUTTON1
static bool EqualNocase(const CTempString str, SIZE_TYPE pos, SIZE_TYPE n, const char *pattern)
Case-insensitive equality of a substring with a pattern.
Definition: ncbistr.hpp:5358
wxIcon GetIconResource(const wxString &name)
Retrieves icon resources.
virtual void OnJobFailed(const string &, CJobAdapter &adapter)
const T & GetData()
Definition: job_adapter.hpp:84
wxButton * m_FwdButton
void CreateControls()
Creates the controls and sizers.
bool InitObject(SConstScopedObject &object)
CSeqTextPanel()
Constructors.
virtual bool IsCanceled(void) const =0
string ToStdString(const wxString &s)
Definition: wx_utils.hpp:145
const string & GetMsg(void) const
Get message string.
Definition: ncbiexpt.cpp:448
void NcbiErrorBox(const string &message, const string &title="Error")
specialized Message Box function for reporting critical errors
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:98
virtual void Create()
creates controls and performs basic initialization
void Reset(void)
Reset reference object.
Definition: ncbiobj.hpp:756
#define ID_BUTTON2
static int input()
Modified on Mon Nov 20 15:49:27 2017 by modify_doxy.py rev. 546573