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

Go to the SVN repository for this file.

1 /* $Id: seq_text_widget.cpp 47464 2023-04-20 00:19:10Z evgeniev $
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: Colleen Bollin (adapted from a file by Andrey Yazhuk)
27  *
28  * File Description:
29  *
30  */
31 
32 #include <ncbi_pch.hpp>
33 
34 
35 #include <gui/opengl/glfont.hpp>
37 #include <gui/types.hpp>
38 //#include <gui/widgets/wx/message_box.hpp>
41 
42 #include <gui/utils/menu_item.hpp>
43 
46 
47 #include <objmgr/util/sequence.hpp>
48 #include <objmgr/util/feature.hpp>
50 
51 #include <list>
52 
53 #include <wx/msgdlg.h>
54 #include <wx/scrolbar.h>
55 #include <wx/menu.h>
56 
59 
60 ////////////////////////////////////////////////////////////////////////////////
61 /// class CSeqTextWidget
62 
63 CSeqTextWidget::CSeqTextWidget(wxWindow* parent, wxWindowID id,
64  const wxPoint& pos, const wxSize& size,
65  long style)
66  : CGlWidgetBase(parent, id, pos, size, style),
67  m_DataSource(NULL),
68  m_PopupMenuSourcePos(0),
69  m_pHost(NULL),
70  m_LastSourcePos (0)
71 {
72  // setup Port
74  m_Port.SetMinScaleX(1 / 30.0);
76 
77  m_Port.EnableZoom (false, false);
78 }
79 
80 
82 {
83 
84 }
85 
86 
88 {
89  return m_DataSource;
90 }
91 
92 
94 {
95  CRef<CSeqTextDataSource> guard = m_DataSource; // keep it alive until update is completed
96  TModelRect model_rect;
97 
98  m_DataSource.Reset(&ds);
99 
100  m_LastSourcePos = 0;
101  if (m_SequencePane.get() == NULL) {
102  x_CreatePane();
103  }
104  x_Update();
105 }
106 
107 
108 static
109 WX_DEFINE_MENU(sPopupMenu)
110  WX_MENU_ITEM(wxID_COPY)
113 WX_END_MENU()
114 
115 
116 
117 BEGIN_EVENT_TABLE(CSeqTextWidget, CGlWidgetBase)
118  EVT_MENU(eCmdSettings, CSeqTextWidget::Configure )
119  EVT_MENU(eCmdZoomSel, CSeqTextWidget::OnScrollToSelection)
120  EVT_MENU(wxID_COPY, CSeqTextWidget::OnCopySelection)
121  EVT_UPDATE_UI(wxID_COPY, CSeqTextWidget::OnHasSelection)
122 
123  EVT_MENU(wxID_CLEAR, CSeqTextWidget::OnClearSelection)
124  EVT_UPDATE_UI(wxID_CLEAR, CSeqTextWidget::OnHasSelection)
125 
126  EVT_UPDATE_UI(wxID_PASTE, CSeqTextWidget::OnDisableCommands)
127  EVT_UPDATE_UI(wxID_CUT, CSeqTextWidget::OnDisableCommands)
128  EVT_UPDATE_UI(wxID_DELETE, CSeqTextWidget::OnDisableCommands)
129  EVT_UPDATE_UI(wxID_SELECTALL, CSeqTextWidget::OnDisableCommands)
130 
131 
132  EVT_UPDATE_UI(eCmdSettings, CSeqTextWidget::OnUpdateSettings)
134 
135 void CSeqTextWidget::OnUpdateSettings(wxUpdateUIEvent& event)
136 {
137  event.Enable(true);
138 }
139 
141 {
142  m_SequencePane.reset(new CSeqTextPane(this));
143 }
144 
145 
147 {
148  return static_cast<CGlWidgetPane*>(m_SequencePane.get());
149 }
150 
151 
153 {
154  TModelPoint character_size = m_SequencePane->CharacterSize();
155  TModelRect rc_model = m_SequencePane->GetPreferredModelRect();
156  if (character_size.m_Y > 0 && character_size.m_X > 0)
157  {
158  rc_model.SetTop (rc_model.Top() + m_SequencePane->GetBottomRulerModelAdjustmentHeight());
159  m_Port.SetModelLimitsRect(rc_model);
160  TModelUnit scale_y = 1.0 / character_size.m_Y;
161  TModelUnit scale_x = 1.0 / character_size.m_X;
162  m_Port.SetScale(scale_x, scale_y);
163  }
164 }
165 
166 
168 {
169  x_SetPortLimits();
170 
171  x_UpdatePane();
173 
175 }
176 
178 {
179  m_SequencePane->Update();
180 }
181 
182 
184 {
185  return m_Port;
186 }
187 
188 
190 {
191  return m_Port;
192 }
193 
194 
196 {
197 }
198 
199 
201 {
202  TModelPoint character_size = m_SequencePane->CharacterSize();
203  if (character_size.m_Y > 0 && character_size.m_X > 0)
204  {
205  TModelRect old_limits = m_Port.GetModelLimitsRect ();
206  x_SetPortLimits();
207  TModelRect new_limits = m_Port.GetModelLimitsRect ();
208  if (old_limits.Left() != new_limits.Left()
209  || old_limits.Right() != new_limits.Right()
210  || old_limits.Top() != new_limits.Top()
211  || old_limits.Bottom() != new_limits.Bottom()) {
214  } else {
216  }
217  }
218 }
219 
220 
222 {
223  // use host interface to pass information to view
224  if (m_pHost != NULL) {
226  }
227  m_PopupMenuSourcePos = pos;
228 }
229 
230 
232 {
233  int max_val = 0;
234 
235  TSeqPos chars_in_line, lines_in_seq;
236  m_SequencePane->STG_GetLineInfo(chars_in_line, lines_in_seq);
237  max_val = lines_in_seq + m_SequencePane->GetScrollAdjustmentForLastLineVariations();
238  return max_val;
239 }
240 
241 
243 {
244  TSeqPos curr_pos = 0, chars_in_line, lines_in_seq;
245 
246  m_SequencePane->STG_GetLineInfo(chars_in_line, lines_in_seq);
247  if (chars_in_line > 0) {
248  curr_pos = source_pos / chars_in_line;
249  }
250  return curr_pos;
251 }
252 
253 
255 {
256  wxScrollBar* scroll_bar_v = (wxScrollBar*)FindWindow(ID_VSCROPLLBAR);
257  wxScrollBar* scroll_bar_h = (wxScrollBar*)FindWindow(ID_HSCROPLLBAR);
258 
259  if (scroll_bar_v) {
260  TModelRect rcVisible = m_Port.GetVisibleRect();
261  TSeqPos curr_pos, max_val;
262 
264  max_val = x_GetVScrollMax ();
265  if (curr_pos > max_val) curr_pos = max_val;
266 
267  int page_size = (int) (rcVisible.Height() - m_SequencePane->GetBottomRulerModelAdjustmentHeight());
268  if (page_size < 0) page_size = 0;
269  int thumb_size = page_size;
270  if (max_val <= (TSeqPos) page_size) {
271 // scroll_bar_v->Hide();
272  scroll_bar_v->SetScrollbar (0, 0, 0, 0, true);
273  } else {
274 // scroll_bar_v->Show();
275  scroll_bar_v->SetScrollbar (curr_pos, thumb_size, max_val, page_size, true);
276  x_MakePortMatchScrollValue (curr_pos);
277  }
278  }
279  if (scroll_bar_h) {
280  scroll_bar_h->Hide();
281  }
282 }
283 
284 
286 {
287  int curr_pos = 0;
288  TModelRect rcVisible = m_Port.GetVisibleRect();
290 
291  //wxScrollBar* scroll_bar_v = (wxScrollBar*)FindWindow(ID_VSCROPLLBAR);
292 
293  curr_pos = (int) ceil(rcAll.Top() - rcVisible.Top());
294  return curr_pos;
295 }
296 
297 
299 {
300  int curr_pos = GetPortScrollValue();
301 
302  TSeqPos chars_in_line, lines_in_seq;
303  m_SequencePane->STG_GetLineInfo(chars_in_line, lines_in_seq);
304 
305  return curr_pos * chars_in_line;
306 }
307 
309 {
311  TModelRect rcVisible = m_Port.GetVisibleRect();
312  double desired_pos = rcAll.Top() - pos;
313  double dY = desired_pos - rcVisible.Top();
314  m_Port.Scroll(0, dY);
315 }
316 
317 
319 {
320  //wxScrollBar* scroll_bar_v = (wxScrollBar*)FindWindow(ID_VSCROPLLBAR);
321 
324 
326 
327  // translate the notification to the standard message
329  Send(&evt, ePool_Parent);
330 }
331 
332 
334 {
335  // do nothing. no horizontal scrolling.
336 }
337 
338 
340 {
341  m_SequencePane->ScrollToPosition (pos, notify);
342  int scroll_pos = x_GetScrollValueForSourcePos (pos);
343  x_SetScrollPosition (scroll_pos);
344  m_LastSourcePos = pos;
345 }
346 
347 
349 {
350  bool found_in_source;
351  pos = m_SequencePane->STG_GetSourcePosBySequencePos(pos, &found_in_source);
352 
353  m_SequencePane->ScrollToPosition (pos, notify);
354  int scroll_pos = x_GetScrollValueForSourcePos (pos);
355  x_SetScrollPosition (scroll_pos);
356  m_LastSourcePos = pos;
357 }
358 
359 
361 {
362  if (m_SequencePane->GetShowAbsolutePosition()) {
363  ScrollToSequencePosition (pos, notify);
364  } else {
365  ScrollToSourcePosition(pos, notify);
366  }
367 }
368 
369 
370 void CSeqTextWidget::ScrollToText(const string& fragment, TSeqPos start_search)
371 {
372  if (m_DataSource) {
373  int source_pos = m_DataSource->FindSequenceFragment(fragment, start_search);
374  if (source_pos >= 0) {
375  ScrollToSourcePosition (source_pos);
377  range.Set(source_pos, static_cast<TSeqPos>(source_pos + fragment.length() - 1));
378  TRangeColl segs;
379  segs.clear();
380  segs.CombineWith(range);
381  SetRangeSelection(segs);
382  }
383  }
384 }
385 
387 {
389 }
390 
392 {
393  wxScrollBar* scroll_bar_v = (wxScrollBar*)FindWindow(ID_VSCROPLLBAR);
394 
395  if (scroll_bar_v) {
396  // set scroll position
397  int max_val = x_GetVScrollMax ();
398  TModelRect rcVisible = m_Port.GetVisibleRect();
399 
400  int page_size = (int) (rcVisible.Height() - m_SequencePane->GetBottomRulerModelAdjustmentHeight());
401  if (page_size < 0) page_size = 0;
402  int thumb_size = page_size;
403  if (max_val <= page_size) {
404 // scroll_bar_v->Hide();
405  scroll_bar_v->SetScrollbar (0, 0, 0, 0, true);
406  } else {
407 // scroll_bar_v->Show();
408  scroll_bar_v->SetScrollbar (scroll_pos, thumb_size, max_val, page_size, true);
409  x_MakePortMatchScrollValue (scroll_pos);
410  }
411  }
412 }
413 
414 
415 void CSeqTextWidget::OnScrollToSelection (wxCommandEvent& event)
416 {
417  const CSeqTextWidget::TRangeColl& s_coll = GetSelection();
418  TSeqPos first_selection_start = 0;
419  TSeqPos translated_start;
420 
421  if(! s_coll.empty()) {
422  ITERATE(CRangeCollection<TSeqPos>, it_r, s_coll) { // for each range in mark
423  first_selection_start = it_r->GetFrom();
424  translated_start = m_DataSource->SequencePosToSourcePos (first_selection_start);
425  if (first_selection_start == m_DataSource->SourcePosToSequencePos (translated_start)) {
426  ScrollToSourcePosition (translated_start);
427  return;
428  }
429  }
430  }
431 }
432 
433 void CSeqTextWidget::OnCopySelection(wxCommandEvent& event)
434 {
436  if (!m_DataSource)
437  return;
438  m_SequencePane->OnCopy();
439 }
440 
441 void CSeqTextWidget::OnClearSelection(wxCommandEvent& event)
442 {
443  const CSeqTextWidget::TRangeColl& s_coll = GetSelection();
444  if (s_coll.empty())
445  return;
446  m_SequencePane->ResetRangeSelection();
447 }
448 
449 void CSeqTextWidget::OnHasSelection(wxUpdateUIEvent& event)
450 {
451  event.Enable(m_DataSource && !GetSelection().empty());
452 }
453 
454 void CSeqTextWidget::OnDisableCommands(wxUpdateUIEvent& event)
455 {
456  event.Enable(false);
457 }
458 
459 
462 {
463  return m_SequencePane->GetSelection();
464 }
465 
466 
468 {
469  m_SequencePane->SetRangeSelection(segs);
470 }
471 
472 
474 {
475  m_SequencePane->DeSelectObject (obj);
476 }
477 
478 
480 {
481  m_SequencePane->SelectObject (obj);
482 }
483 
484 
486 {
487  m_SequencePane->ResetObjectSelection();
488 }
489 
490 
492 {
493  if (m_DataSource) {
494  TSeqPos seq_start, seq_stop;
495  m_SequencePane->STG_GetVisibleRange (seq_start, seq_stop);
496 
497  CSeq_loc* visible_range = new CSeq_loc();
498 
499  visible_range->SetInt().SetFrom(m_DataSource->SourcePosToSequencePos (seq_start));
500  visible_range->SetInt().SetTo(m_DataSource->SourcePosToSequencePos (seq_stop));
501  visible_range->SetId(*(m_DataSource->GetId()));
502  return visible_range;
503  } else {
504  return NULL;
505  }
506 }
507 
508 
509 // Functions for configuring the widget
510 
511 // configure from menu
512 void CSeqTextWidget::Configure(wxCommandEvent& event)
513 {
514  m_SequencePane->Configure();
515 }
516 
517 
519 {
520  m_SequencePane->ChooseCaseFeature(subtype);
521 }
522 
523 
525 {
526  return m_SequencePane->GetCaseFeatureSubtype();
527 }
528 
529 
530 void CSeqTextWidget::SetFontSize(int font_size)
531 {
532  m_SequencePane->SetFontSize(font_size);
534 }
535 
536 
538 {
539  return m_SequencePane->GetFontSize();
540 }
541 
542 
544 {
545  m_pHost = pHost;
546 }
547 
548 
550 {
551  // use host interface to pass information to view
552  if (m_pHost != NULL) {
554  }
555 }
556 
557 
559 {
560  if (do_lower) {
561  m_SequencePane->ShowFeaturesInLowerCase();
562  } else {
563  m_SequencePane->ShowFeaturesInUpperCase();
564  }
565 }
566 
568 {
569  return m_SequencePane->GetShowFeaturesInLowerCase();
570 }
571 
572 
573 // Popup menu when right-clicking widget
575 {
577  unique_ptr<wxMenu> root(cmd_reg.CreateMenu(sPopupMenu));
578  PopupMenu(root.get());
579 }
580 
581 
582 
583 
584 
EVT_UPDATE_UI(eCmdAlnShowMethodsDlg, CAlnMultiWidget::OnUpdateShowMethodDlg) EVT_UPDATE_UI(eCmdMethodProperties
CEvent - generic event implementation TODO TODO - Attachments.
Definition: event.hpp:86
class CGlPane
Definition: glpane.hpp:62
class CGlWidgetBase
virtual void x_RedrawControls(void)
CGlWidgetPane represent a window component residing in CGlWidgetBase client area.
CObject –.
Definition: ncbiobj.hpp:180
TThisType & CombineWith(const TRange &r)
Definition: range_coll.hpp:195
bool empty() const
Definition: range_coll.hpp:102
CSeqTextDataSource implements Adapter design pattern.
TIdRef GetId() const
int FindSequenceFragment(const string &fragment, TSeqPos start_search)
TSeqPos SequencePosToSourcePos(TSeqPos sequence_pos, bool *found_in_source=NULL)
TSeqPos SourcePosToSequencePos(TSeqPos source_pos)
class CSeqTextPane
class CSeqTextWidget
TSeqPos m_PopupMenuSourcePos
bool GetShowFeaturesInLowerCase()
void SetHost(ISeqTextWidgetHost *pHost)
objects::CSeq_loc * GetVisibleRange()
void ScrollToSequencePosition(TSeqPos pos, bool notify=true)
void SetFontSize(int font_size)
virtual void x_OnScrollX(int pos)
void x_SetScrollPosition(int scroll_pos)
virtual CGlPane & GetPort()
implement these 2 functions in derived classes
virtual void x_UpdatePane()
virtual void x_SetPortLimits()
updates model limits of the Master CGlPane
virtual CSeqTextDataSource * GetDS()
void OnDisableCommands(wxUpdateUIEvent &event)
void OnHasSelection(wxUpdateUIEvent &event)
virtual void SetScaleX(TModelUnit scale_x, const TModelPoint &point)
void ShowFeaturesInLowerCase(bool do_lower)
virtual void x_CreatePane()
factory method creating master pane, called form x_CreateControls()
virtual void x_UpdateScrollbars()
TSeqPos x_GetSourcePosForPortScrollValue()
unique_ptr< CSeqTextPane > m_SequencePane
void ScrollToPosition(TSeqPos pos, bool notify=true)
virtual ~CSeqTextWidget()
virtual void x_OnScrollY(int pos)
CSeqTextWidget(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=0)
class CSeqTextWidget
void OnCopySelection(wxCommandEvent &event)
ISeqTextWidgetHost * m_pHost
void AdjustModelForSequenceAndWindowSize()
void SelectObject(const CObject *obj)
void DeSelectObject(const CObject *obj)
void ReportMouseOverPos(TSeqPos pos)
virtual void SetDataSource(CSeqTextDataSource &ds)
const TRangeColl & GetSelection() const
TSeqPos x_GetScrollValueForSourcePos(TSeqPos source_pos)
void OnScrollToSelection(wxCommandEvent &event)
CRef< CSeqTextDataSource > m_DataSource
void ChooseCaseFeature(objects::CSeqFeatData::ESubtype subtype)
void SetRangeSelection(const TRangeColl &segs)
void x_MakePortMatchScrollValue(int pos)
virtual void x_Update()
Update handlers.
void OnClearSelection(wxCommandEvent &event)
virtual CGlWidgetPane * x_GetPane()
void ScrollToText(const string &fragment, TSeqPos start_search)
void Configure(wxCommandEvent &event)
void ScrollToSourcePosition(TSeqPos pos, bool notify=true)
CUICommandRegistry is a centralized registry where all application commands should be registered.
Definition: ui_command.hpp:146
static CUICommandRegistry & GetInstance()
the main instance associated with the application
Definition: ui_command.cpp:176
wxMenu * CreateMenu(const SwxMenuItemRec *items)
create a menu from a static definition (see WX_*_MENU macros)
Definition: ui_command.cpp:349
@ eWidgetRangeChanged
notification from child to parent that the visible range has changed
Definition: view_event.hpp:58
class ISeqTextWidgetHost
virtual void STWH_ReportMouseOverPos(TSeqPos pos)=0
virtual void STWH_ChangeConfig()=0
unsigned int TSeqPos
Type for sequence locations and lengths.
Definition: ncbimisc.hpp:875
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
#define NULL
Definition: ncbistd.hpp:225
GLdouble TModelUnit
Definition: gltypes.hpp:48
void SetModelLimitsRect(const TModelRect &R)
Definition: glpane.hpp:342
T Height() const
Definition: glrect.hpp:90
T Top() const
Definition: glrect.hpp:84
T Bottom() const
Definition: glrect.hpp:82
T Right() const
Definition: glrect.hpp:83
void SetScale(TModelUnit scale_x, TModelUnit scale_y, TModelPoint p_center)
Definition: glpane.cpp:361
TModelRect & GetModelLimitsRect(void)
Definition: glpane.hpp:347
T Left() const
Definition: glrect.hpp:81
void Scroll(TModelUnit dx, TModelUnit dy)
Definition: glpane.cpp:602
void SetAdjustmentPolicy(int adjust_x, int adjust_y)
Definition: glpane.hpp:383
void EnableZoom(bool en_x, bool en_y)
Definition: glpane.hpp:462
TModelRect & GetVisibleRect(void)
Definition: glpane.hpp:357
void SetMinScaleX(TModelUnit scale)
Definition: glpane.hpp:442
void SetTop(T top)
Definition: glrect.hpp:115
void SetOriginType(EOriginType type_x, EOriginType type_y)
Definition: glpane.hpp:377
@ eOriginBottom
Definition: glpane.hpp:74
@ eOriginLeft
Definition: glpane.hpp:72
@ fAdjustAll
Definition: glpane.hpp:94
virtual bool Send(CEvent *evt, EDispatch disp_how=eDispatch_Default, int pool_name=ePool_Default)
Sends an event synchronously.
@ eCmdSettings
Definition: command.hpp:85
@ eCmdZoomSel
Definition: command.hpp:73
@ eEvent_Message
message from one class to another
Definition: event.hpp:99
void SetId(CSeq_id &id)
set the 'id' field in all parts of this location
Definition: Seq_loc.cpp:3474
void SetInt(TInt &v)
Definition: Seq_loc.hpp:983
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
unsigned int
A callback function used to compare two keys in a database.
Definition: types.hpp:1210
END_EVENT_TABLE()
range(_Ty, _Ty) -> range< _Ty >
constexpr bool empty(list< Ts... >) noexcept
const struct ncbi::grid::netcache::search::fields::SIZE size
USING_SCOPE(ncbi::objects)
ViewerWindowBase::OnEditMenu ViewerWindowBase::OnJustification EVT_MENU(MID_SHOW_GEOM_VLTNS, ViewerWindowBase::OnShowGeomVltns) EVT_MENU(MID_FIND_PATTERN
#define _ASSERT
#define WX_DEFINE_MENU(name)
New macros for defining menus for use with CUICommandRegistry.
Definition: ui_command.hpp:266
#define WX_END_MENU()
Definition: ui_command.hpp:294
#define WX_MENU_ITEM(cmd)
Definition: ui_command.hpp:270
Modified on Fri Sep 20 14:57:08 2024 by modify_doxy.py rev. 669887