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 47479 2023-05-02 13:24:02Z 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: 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
71 ////@end CSeqTextPanel event table entries
72 
74 
75 
76 /*!
77  * CSeqTextPanel constructors
78  */
79 
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 #ifdef __WXOSX_COCOA__ // GB-8581
99  SetBackgroundStyle(wxBG_STYLE_COLOUR);
100  SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_FRAMEBK));
101 #endif
102 ////@begin CSeqTextPanel creation
103  wxPanel::Create( parent, id, pos, size, style );
104 
105  CreateControls();
106  if (GetSizer())
107  {
108  GetSizer()->SetSizeHints(this);
109  }
110  Centre();
111 ////@end CSeqTextPanel creation
112  return true;
113 }
114 
115 
116 /*!
117  * CSeqTextPanel destructor
118  */
119 
121 {
122 ////@begin CSeqTextPanel destruction
123  // job is canceled if main window is destroyed
124  if (m_JobAdapter) {
125  m_JobAdapter->Cancel();
126  }
127 ////@end CSeqTextPanel destruction
128 }
129 
130 
131 /*!
132  * Member initialisation
133  */
134 
136 {
137 ////@begin CSeqTextPanel member initialisation
138  m_BwdButton = NULL;
139  m_FwdButton = NULL;
140  m_StopButton = NULL;
141  m_MousePos = NULL;
143 ////@end CSeqTextPanel member initialisation
144 }
145 
146 
147 /*!
148  * Control creation for CSeqTextPanel
149  */
150 
152 {
153 ////@begin CSeqTextPanel content construction
154  CSeqTextPanel* itemPanel1 = this;
155 
156  wxBoxSizer* itemBoxSizer2 = new wxBoxSizer(wxVERTICAL);
157  itemPanel1->SetSizer(itemBoxSizer2);
158 
159  wxBoxSizer* itemBoxSizer3 = new wxBoxSizer(wxHORIZONTAL);
160  itemBoxSizer2->Add(itemBoxSizer3, 0, wxALIGN_LEFT|wxALL, 5);
161 
162  wxStaticText* itemStaticText4 = new wxStaticText( itemPanel1, wxID_STATIC, _("Find"), wxDefaultPosition, wxDefaultSize, 0 );
163  itemBoxSizer3->Add(itemStaticText4, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
164 
165  wxTextCtrl* itemTextCtrl5 = new wxTextCtrl( itemPanel1, ID_TEXTCTRL1, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
166  itemBoxSizer3->Add(itemTextCtrl5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
167 
168  m_BwdButton = new wxButton( itemPanel1, ID_BUTTON, _("Bwd"), wxDefaultPosition, wxDefaultSize, 0 );
169  itemBoxSizer3->Add(m_BwdButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
170 
171  m_FwdButton = new wxButton( itemPanel1, ID_BUTTON1, _("Fwd"), wxDefaultPosition, wxDefaultSize, 0 );
172  itemBoxSizer3->Add(m_FwdButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
173 
174  m_StopButton = new wxButton( itemPanel1, ID_BUTTON2, _("Stop"), wxDefaultPosition, wxDefaultSize, 0 );
175  m_StopButton->Enable(false);
176  itemBoxSizer3->Add(m_StopButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
177 
178  wxStaticText* itemStaticText9 = new wxStaticText( itemPanel1, wxID_STATIC, _("Current Position:"), wxDefaultPosition, wxDefaultSize, 0 );
179  itemBoxSizer3->Add(itemStaticText9, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
180 
181  m_MousePos = new wxStaticText( itemPanel1, wxID_STATIC, wxEmptyString, wxDefaultPosition, wxSize(itemPanel1->ConvertDialogToPixels(wxSize(100, -1)).x, -1), wxNO_BORDER );
182  itemBoxSizer3->Add(m_MousePos, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
183 
184  wxStaticText* itemStaticText11 = new wxStaticText( itemPanel1, wxID_STATIC, _("Show"), wxDefaultPosition, wxDefaultSize, 0 );
185  itemBoxSizer3->Add(itemStaticText11, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
186 
187  wxArrayString itemChoice12Strings;
188  itemChoice12Strings.Add(_("None"));
189  itemChoice12Strings.Add(_("Gene"));
190  itemChoice12Strings.Add(_("CDS"));
191  itemChoice12Strings.Add(_("mRNA"));
192  itemChoice12Strings.Add(_("misc_RNA"));
193  itemChoice12Strings.Add(_("STS"));
194  wxChoice* itemChoice12 = new wxChoice( itemPanel1, ID_CHOICE1, wxDefaultPosition, wxDefaultSize, itemChoice12Strings, 0 );
195  itemChoice12->SetStringSelection(_("None"));
196  itemBoxSizer3->Add(itemChoice12, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
197 
198  m_SeqTextWidget = new CSeqTextWidget(itemPanel1, ID_WINDOW, wxDefaultPosition, itemPanel1->ConvertDialogToPixels(wxSize(300, 200)), wxSUNKEN_BORDER | wxTAB_TRAVERSAL);
199  itemBoxSizer2->Add(m_SeqTextWidget, 1, wxGROW|wxALL, 0);
200 
201 ////@end CSeqTextPanel content construction
203  m_SeqTextWidget->SetHost(this);
204 
205  int subtype = m_SeqTextWidget->GetCaseFeatureSubtype();
206  wxChoice* choice = (wxChoice*)FindWindow(ID_CHOICE1);
207 
208  switch (subtype) {
209  case objects::CSeqFeatData::eSubtype_gene:
210  choice->SetSelection (1);
211  break;
212  case objects::CSeqFeatData::eSubtype_cdregion:
213  choice->SetSelection (2);
214  break;
215  case objects::CSeqFeatData::eSubtype_mRNA:
216  choice->SetSelection (3);
217  break;
218  case objects::CSeqFeatData::eSubtype_misc_RNA:
219  choice->SetSelection (4);
220  break;
221  case objects::CSeqFeatData::eSubtype_STS:
222  choice->SetSelection (5);
223  break;
224  }
225  m_SeqTextWidget->SetFocus();
226 }
227 
228 
229 /*!
230  * Should we show tooltips?
231  */
232 
234 {
235  return true;
236 }
237 
238 /*!
239  * Get bitmap resources
240  */
241 
242 wxBitmap CSeqTextPanel::GetBitmapResource( const wxString& name )
243 {
244  // Bitmap retrieval
245 ////@begin CSeqTextPanel bitmap retrieval
246  wxUnusedVar(name);
247  return wxNullBitmap;
248 ////@end CSeqTextPanel bitmap retrieval
249 }
250 
251 /*!
252  * Get icon resources
253  */
254 
255 wxIcon CSeqTextPanel::GetIconResource( const wxString& name )
256 {
257  // Icon retrieval
258 ////@begin CSeqTextPanel icon retrieval
259  wxUnusedVar(name);
260  return wxNullIcon;
261 ////@end CSeqTextPanel icon retrieval
262 }
263 
265 {
266  wxBusyCursor wait;
267 
268  const CSeq_id* id = dynamic_cast<const CSeq_id*>(object.object.GetPointer());
269  if (id) {
270  CBioseq_Handle handle = object.scope->GetBioseqHandle(*id);
271  if (!handle) {
272  string str;
273  id->GetLabel(&str);
274  ReportIDError(str, id->IsLocal(), "Sequence Text View");
275  return false;
276  }
277  m_DataSource.Reset(new CSeqTextDataSource(handle, *object.scope));
279  return true;
280  }
281 
282  const CSeq_entry* seq_entry = dynamic_cast<const CSeq_entry*>(object.object.GetPointer());
283  if (seq_entry) {
284  m_DataSource.Reset(new CSeqTextDataSource(*const_cast<CSeq_entry*>(seq_entry), *object.scope));
286  return true;
287  }
288 
289  const CBioseq_Handle* handle = dynamic_cast<const CBioseq_Handle*>(object.object.GetPointer());
290  if (handle) {
291  m_DataSource.Reset(new CSeqTextDataSource(*handle, *object.scope));
293  return true;
294  }
295 
296  const CSeq_loc* loc = dynamic_cast<const CSeq_loc*>(object.object.GetPointer());
297  if (loc && loc->GetId()) {
298  auto handle = object.scope->GetBioseqHandle(*loc->GetId());
299  if (!handle) {
300  string str;
301  loc->GetId()->GetLabel(&str);
302  ReportIDError(str, loc->GetId()->IsLocal(), "Sequence Text View");
303  return false;
304  }
305 
306  m_DataSource.Reset(new CSeqTextDataSource(*const_cast<CSeq_loc*>(loc), *object.scope));
308  return true;
309  }
310 
311  return false;
312 }
313 
315 {
316  m_MousePos->SetLabel(ToWxString(NStr::IntToString(pos)));
317 }
318 
319 
320 void CSeqTextPanel::OnFeatureTypeSelected( wxCommandEvent& event )
321 {
322  objects::CSeqFeatData::ESubtype subtype = objects::CSeqFeatData::eSubtype_bad;
323  switch (event.GetInt()) {
324  case 1:
325  subtype = objects::CSeqFeatData::eSubtype_gene;
326  break;
327  case 2:
328  subtype = objects::CSeqFeatData::eSubtype_cdregion;
329  break;
330  case 3:
331  subtype = objects::CSeqFeatData::eSubtype_mRNA;
332  break;
333  case 4:
334  subtype = objects::CSeqFeatData::eSubtype_misc_RNA;
335  break;
336  case 5:
337  subtype = objects::CSeqFeatData::eSubtype_STS;
338  break;
339  }
340 
342 }
343 
344 
345 void CSeqTextPanel::OnFindBwdClick( wxCommandEvent& event )
346 {
347  m_FwdButton->Enable(false);
348  m_BwdButton->Enable(false);
349  m_StopButton->Enable(true);
350  x_StartSearch(false);
351 }
352 
353 void CSeqTextPanel::OnFindFwdClick( wxCommandEvent& event )
354 {
355  m_FwdButton->Enable(false);
356  m_BwdButton->Enable(false);
357  m_StopButton->Enable(true);
358  x_StartSearch(true);
359 }
360 
361 void CSeqTextPanel::OnStopClick(wxCommandEvent& event)
362 {
366 }
367 
369 {
370  m_FwdButton->Enable(true);
371  m_BwdButton->Enable(true);
372  m_StopButton->Enable(false);
373 }
374 
375 namespace {
376  struct SSeqSearchInput {
377  string m_Term;
378  bool m_Forward;
379  CSeqTextWidget* m_TextWidget;
380 
381  SSeqSearchInput(const string& search_term, bool forward, CSeqTextWidget* widget)
382  : m_Term(search_term), m_Forward(forward), m_TextWidget(widget) {}
383  };
384 
385  struct SSeqSearchOutput {
387  string m_Term;
388  bool m_Found;
389 
390  SSeqSearchOutput() : m_Term(kEmptyStr), m_Found(false) {}
391  };
392 }
393 
394 static bool s_SearchInSeqText(SSeqSearchInput& input, SSeqSearchOutput& output, string& error, ICanceled& canceled)
395 {
396  try {
397  LOG_POST(Info << "Searching for " << input.m_Term);
398 
399  output.m_Term = input.m_Term;
400  output.m_Found = false;
401 
402  if (canceled.IsCanceled())
403  return false;
404 
405  CSeqTextWidget* widget = input.m_TextWidget;
406  CSeqTextDataSource* pDS = widget->GetDS();
407  if (!pDS)
408  return false;
409 
410 
411  CSeqTextPane& pane = widget->GetPane();
412  output.m_Result = pane.GetTextSearchData(); // receive the data related to previous search from the pane
413  CSeqTextPane::CSeqTextSearch& res = output.m_Result;
414 
415  if (!NStr::EqualNocase(res.m_LastSearch, input.m_Term)) {
416  pDS->FindSequenceFragmentList(input.m_Term, res.m_FoundList, &canceled);
417  if (canceled.IsCanceled()) {
418  return false;
419  }
420  TSeqPos curr_scroll = pane.STG_GetSequenceByWindow(0, 0);
421  res.m_CurrFindPos = 0;
422  while (res.m_CurrFindPos < res.m_FoundList.size() && res.m_FoundList[res.m_CurrFindPos] < curr_scroll) {
423  res.m_CurrFindPos++;
424  }
425  if (res.m_CurrFindPos >= res.m_FoundList.size()) {
426  res.m_CurrFindPos = 0;
427  }
428  } else {
429  // searching forward for the previous term
430  if (input.m_Forward) {
431  res.m_CurrFindPos++;
432  if (res.m_CurrFindPos >= res.m_FoundList.size()) {
433  res.m_CurrFindPos = 0;
434  }
435  } else { // searching backwards for the previous term
436  if (res.m_CurrFindPos > 0) {
437  --res.m_CurrFindPos;
438  } else {
439  res.m_CurrFindPos = static_cast<TSeqPos>(res.m_FoundList.size() - 1);
440  }
441  }
442  }
443 
444  if (res.m_FoundList.size() > res.m_CurrFindPos) {
445  widget->ScrollToPosition(res.m_FoundList[res.m_CurrFindPos]);
446  output.m_Found = true;
447  }
448 
449  res.m_LastSearch = input.m_Term;
450  }
451  catch (const CException& e) {
452  LOG_POST(Error << e.GetMsg());
453  return false;
454  }
455  catch (const std::exception& e) {
456  LOG_POST(Error << e.what());
457  return false;
458  }
459  return true;
460 }
461 
463 {
465  if (jobResult) {
466  const SSeqSearchOutput& res = jobResult->GetData();
467  m_SeqTextWidget->GetPane().SetTextSearchData(res.m_Result);
468 
469  if (!res.m_Found) {
470  NcbiInfoBox("Search string was not found");
471  }
472  }
474  m_SeqTextWidget->GetPane().Refresh();
475 
477 }
478 
479 void CSeqTextPanel::OnJobFailed(const string& errMsg, CJobAdapter&)
480 {
481  string err_msg = "Failed: ";
482  if (!errMsg.empty()) {
483  err_msg += errMsg;
484  }
485  else {
486  err_msg += "Unknown fatal error";
487  }
488 
489  NcbiErrorBox(err_msg);
491  m_SeqTextWidget->GetPane().Refresh();
493 }
494 
496 {
497  wxTextCtrl* find = (wxTextCtrl*)FindWindow(ID_TEXTCTRL1);
498  string value = ToStdString(find->GetValue());
500  if (value.empty()) {
501  NcbiInfoBox("The search string is empty.");
503  return;
504  }
505 
507 
508  SSeqSearchInput input(value, forward, m_SeqTextWidget);
509  m_JobAdapter.Reset(LaunchAdapterJob<SSeqSearchInput, SSeqSearchOutput>
510  (this, input, s_SearchInSeqText, "CSeqTextSearchJob", "Search for a string in Sequence Text View"));
511 }
512 
#define false
Definition: bool.h:36
#define ID_CHOICE1
CBioseq_Handle –.
virtual void Create()
creates controls and performs basic initialization
CObject –.
Definition: ncbiobj.hpp:180
CSeqTextDataSource implements Adapter design pattern.
void FindSequenceFragmentList(const string &fragment, CSeqTextDefs::TSeqPosVector &locations, ICanceled *cancel)
CSeqTextDefs::TSeqPosVector m_FoundList
class CSeqTextPane
const CSeqTextSearch & GetTextSearchData() const
void SetTextSearchData(const CSeqTextSearch &data)
virtual TSeqPos STG_GetSequenceByWindow(int x, int y)
void ResetTextSearchData()
virtual void OnJobFailed(const string &, CJobAdapter &adapter)
wxButton * m_FwdButton
void Init()
Initialises member variables.
virtual void OnJobResult(CObject *result, CJobAdapter &adapter)
wxIcon GetIconResource(const wxString &name)
Retrieves icon resources.
wxButton * m_BwdButton
CSeqTextWidget * m_SeqTextWidget
static bool ShowToolTips()
Should we show tooltips?
~CSeqTextPanel()
Destructor.
void OnFeatureTypeSelected(wxCommandEvent &event)
wxEVT_COMMAND_CHOICE_SELECTED event handler for ID_CHOICE1
CRef< CJobAdapter > m_JobAdapter
wxButton * m_StopButton
virtual void STWH_ReportMouseOverPos(TSeqPos pos)
void OnStopClick(wxCommandEvent &event)
bool InitObject(SConstScopedObject &object)
wxBitmap GetBitmapResource(const wxString &name)
Retrieves bitmap resources.
void CreateControls()
Creates the controls and sizers.
CRef< CSeqTextDataSource > m_DataSource
void OnFindBwdClick(wxCommandEvent &event)
@begin CSeqTextPanel event handler declarations
bool Create(wxWindow *parent, wxWindowID id=ID_CSEQTEXTPANEL, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(400, 300), long style=wxTAB_TRAVERSAL)
Creation.
void x_RestoreButtonStates()
void OnFindFwdClick(wxCommandEvent &event)
wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_BUTTON1
CSeqTextPanel()
Constructors.
void x_StartSearch(bool forward)
wxStaticText * m_MousePos
class CSeqTextWidget
void SetHost(ISeqTextWidgetHost *pHost)
virtual CSeqTextDataSource * GetDS()
void ScrollToPosition(TSeqPos pos, bool notify=true)
CSeqTextPane & GetPane()
virtual void SetDataSource(CSeqTextDataSource &ds)
void ChooseCaseFeature(objects::CSeqFeatData::ESubtype subtype)
Definition: Seq_entry.hpp:56
Interface for testing cancellation request in a long lasting operation.
Definition: icanceled.hpp:51
char value[7]
Definition: config.c:431
#define _(proto)
Definition: ct_nlmzip_i.h:78
static void Init(void)
Definition: cursor6.c:76
#define ID_BUTTON1
#define ID_BUTTON2
unsigned int TSeqPos
Type for sequence locations and lengths.
Definition: ncbimisc.hpp:875
#define NULL
Definition: ncbistd.hpp:225
#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:226
void Error(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1197
const string & GetMsg(void) const
Get message string.
Definition: ncbiexpt.cpp:461
virtual const char * what(void) const noexcept
Standard report (includes full backlog).
Definition: ncbiexpt.cpp:342
void Info(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1185
EDialogReturnValue NcbiInfoBox(const string &message, const string &title="Info")
specialized Message Box function for reporting general information messages
void NcbiErrorBox(const string &message, const string &title="Error")
specialized Message Box function for reporting critical errors
void Cancel()
Definition: job_adapter.cpp:48
const T & GetData()
Definition: job_adapter.hpp:84
void GetLabel(string *label, ELabelType type=eDefault, TLabelFlags flags=fLabel_Default) const
Append a label for this Seq-id to the supplied string.
Definition: Seq_id.cpp:2039
const CSeq_id * GetId(void) const
Get the id of the location return NULL if has multiple ids or no id at all.
Definition: Seq_loc.hpp:941
void Reset(void)
Reset reference object.
Definition: ncbiobj.hpp:773
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
virtual bool IsCanceled(void) const =0
#define kEmptyStr
Definition: ncbistr.hpp:123
static string IntToString(int value, TNumToStringFlags flags=0, int base=10)
Convert int to string.
Definition: ncbistr.hpp:5084
static bool EqualNocase(const CTempString s1, SIZE_TYPE pos, SIZE_TYPE n, const char *s2)
Case-insensitive equality of a substring with another string.
Definition: ncbistr.hpp:5353
static string TruncateSpaces(const string &str, ETrunc where=eTrunc_Both)
Truncate spaces in a string.
Definition: ncbistr.cpp:3182
bool IsLocal(void) const
Check if variant Local is selected.
Definition: Seq_id_.hpp:775
END_EVENT_TABLE()
static int input()
const struct ncbi::grid::netcache::search::fields::SIZE size
static SQLCHAR output[256]
Definition: print.c:5
USING_SCOPE(objects)
static bool s_SearchInSeqText(SSeqSearchInput &input, SSeqSearchOutput &output, string &error, ICanceled &canceled)
static const char * str(char *buf, int n)
Definition: stats.c:84
else result
Definition: token2.c:20
#define ID_BUTTON
void ReportIDError(const string &id_label, bool is_local, const string &title="Error message")
Definition: wx_utils.cpp:99
wxString ToWxString(const string &s)
Definition: wx_utils.hpp:173
string ToStdString(const wxString &s)
Definition: wx_utils.hpp:161
Modified on Mon Feb 26 03:59:27 2024 by modify_doxy.py rev. 669887